package builtin import ( "context" "encoding/json" "fmt" "nub/internal/tool" ) // QuestionTool stellt eine generische Rückfrage an den Nutzer — anders als // Permissions (system-/config-entschieden, boolesch) entscheidet hier das // Modell selbst, dass es etwas klären will, und bekommt eine Text-Antwort // als normales Tool-Ergebnis zurück. Kein Permission-Gate: das Tool ist // von sich aus interaktiv, eine Rückfrage auf die Rückfrage ergäbe keinen // Sinn. type QuestionTool struct{} func (QuestionTool) Name() string { return "question" } func (QuestionTool) Description() string { return "Stellt dem Nutzer eine Rückfrage, wenn eine Aufgabe mehrdeutig ist oder eine Entscheidung nötig ist, bevor es weitergeht." } func (QuestionTool) Schema() json.RawMessage { return json.RawMessage(`{ "type": "object", "properties": { "question": {"type": "string"}, "options": { "type": "array", "items": {"type": "string"}, "description": "Optionale Vorschläge, die dem Nutzer zusätzlich zur Frage angezeigt werden" } }, "required": ["question"] }`) } type questionInput struct { Question string `json:"question"` Options []string `json:"options"` } func (QuestionTool) Run(ctx context.Context, input json.RawMessage, env tool.Env) (tool.Result, error) { var in questionInput if err := json.Unmarshal(input, &in); err != nil { return tool.Result{ForModel: "invalid input: " + err.Error(), IsError: true}, nil } if in.Question == "" { return tool.Result{ForModel: "question must not be empty", IsError: true}, nil } if env.Ask == nil { return tool.Result{ ForModel: "interactive questions are not supported in this mode (e.g. print mode) — proceed with your best judgment, or state your assumption in your next reply instead of asking", IsError: true, }, nil } answer, err := env.Ask(ctx, in.Question, in.Options) if err != nil { return tool.Result{ForModel: fmt.Sprintf("question failed: %v", err), IsError: true}, nil } return tool.Result{ ForModel: answer, ForUI: QuestionResult{Question: in.Question, Options: in.Options, Answer: answer}, }, nil } type QuestionResult struct { Question string Options []string Answer string }