Buckets:
| export * as QuestionTool from "./question" | |
| import { ToolFailure } from "@opencode-ai/llm" | |
| import { Effect, Layer, Schema } from "effect" | |
| import { PermissionV2 } from "../permission" | |
| import { QuestionV2 } from "../question" | |
| import { Tool } from "./tool" | |
| import { Tools } from "./tools" | |
| export const name = "question" | |
| export const description = `Use this tool when you need to ask the user questions during execution. This allows you to: | |
| 1. Gather user preferences or requirements | |
| 2. Clarify ambiguous instructions | |
| 3. Get decisions on implementation choices as you work | |
| 4. Offer choices to the user about what direction to take. | |
| Usage notes: | |
| - When \`custom\` is enabled (default), a "Type your own answer" option is added automatically; don't include "Other" or catch-all options | |
| - Answers are returned as arrays of labels; set \`multiple: true\` to allow selecting more than one | |
| - If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label` | |
| export const Input = Schema.Struct({ | |
| questions: Schema.Array(QuestionV2.Prompt).annotate({ description: "Questions to ask" }), | |
| }) | |
| export const Output = Schema.Struct({ | |
| answers: Schema.Array(QuestionV2.Answer), | |
| }) | |
| export type Output = typeof Output.Type | |
| export const toModelOutput = ( | |
| questions: ReadonlyArray<QuestionV2.Prompt>, | |
| answers: ReadonlyArray<QuestionV2.Answer>, | |
| ) => { | |
| const formatted = questions | |
| .map( | |
| (question, index) => | |
| `"${question.question}"="${answers[index]?.length ? answers[index].join(", ") : "Unanswered"}"`, | |
| ) | |
| .join(", ") | |
| return `User has answered your questions: ${formatted}. You can now continue with the user's answers in mind.` | |
| } | |
| export const layer = Layer.effectDiscard( | |
| Effect.gen(function* () { | |
| const tools = yield* Tools.Service | |
| const question = yield* QuestionV2.Service | |
| const permission = yield* PermissionV2.Service | |
| yield* tools | |
| .register({ | |
| [name]: Tool.make({ | |
| description, | |
| input: Input, | |
| output: Output, | |
| toModelOutput: ({ input, output }) => [ | |
| { type: "text", text: toModelOutput(input.questions, output.answers) }, | |
| ], | |
| execute: (input, context) => | |
| permission | |
| .assert({ | |
| action: "question", | |
| resources: ["*"], | |
| sessionID: context.sessionID, | |
| agent: context.agent, | |
| source: { type: "tool", messageID: context.assistantMessageID, callID: context.toolCallID }, | |
| }) | |
| .pipe( | |
| Effect.mapError(() => new ToolFailure({ message: "Permission denied: question" })), | |
| Effect.andThen( | |
| question | |
| .ask({ | |
| sessionID: context.sessionID, | |
| questions: input.questions, | |
| tool: { messageID: context.assistantMessageID, callID: context.toolCallID }, | |
| }) | |
| .pipe(Effect.orDie), | |
| ), | |
| Effect.map((answers) => ({ answers })), | |
| ), | |
| }), | |
| }) | |
| .pipe(Effect.orDie) | |
| }), | |
| ) | |
Xet Storage Details
- Size:
- 3.19 kB
- Xet hash:
- 1cfbbfa415c067a211eef202dead4a67fac42c4f82a469297ed0122bc6607790
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.