@evandu/super-pi 0.1.39 → 0.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -110,7 +110,18 @@ const WorkflowParameters = Type.Object({
110
110
  type ExtensionApi = { registerTool(tool: ExtensionToolDefinition): void };
111
111
 
112
112
  const extension = (pi: ExtensionApi): void => {
113
- pi.registerTool({ name: "question", label: "Question", description: "Ask the user a blocking single or multiple choice question with an optional extra note.", parameters: QuestionParameters, execute: async (_id, raw) => { const endpoint = process.env.SUPER_PI_QUESTION_ENDPOINT; const conversationId = process.env.SUPER_PI_TASK_CONVERSATION; if (!endpoint || !conversationId) return { error: "Interactive question is unavailable" }; const p = raw as { question: string; options: string[]; multiple?: boolean; extraNote?: boolean }; const response = await fetch(endpoint, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ conversationId, ...p }) }); return await response.json(); } });
113
+ // THE QUESTION TOOL. It blocks on an HTTP request until the person answers, and the answer comes back
114
+ // as the tool result, which is what keeps the run alive across the exchange - the model does not decide
115
+ // to continue, it cannot: the tool has not returned.
116
+ //
117
+ // A REFUSED QUESTION THROWS, and that is the whole of the dismissal semantics. It used to `return`
118
+ // whatever came back, which on a refusal is `{error: "用户没有回答这个问题"}` - a SUCCESSFUL tool call
119
+ // carrying an error object, so the row settled as `ok` and the model carried on from a question nobody
120
+ // answered. Throwing fails the call, and a failed call is what stops the run. OpenCode is the reference
121
+ // and is explicit about it: rejecting a question fails the deferred and the tool dies
122
+ // (`packages/core/src/question.ts:128-141`). Nothing is ever invented to fill the gap - not
123
+ // `options[0]`, not an empty selection, which would look to the model exactly like a real choice.
124
+ pi.registerTool({ name: "question", label: "Question", description: "Ask the user a blocking single or multiple choice question with an optional extra note.", parameters: QuestionParameters, execute: async (_id, raw) => { const endpoint = process.env.SUPER_PI_QUESTION_ENDPOINT; const conversationId = process.env.SUPER_PI_TASK_CONVERSATION; if (!endpoint || !conversationId) throw new Error("This run cannot ask the user anything: the question endpoint is not available."); const p = raw as { question: string; options: string[]; multiple?: boolean; extraNote?: boolean }; const response = await fetch(endpoint, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ conversationId, ...p }) }); const payload = await response.json() as { error?: string; answers?: unknown }; if (!response.ok || payload?.error) throw new Error(payload?.error ?? `The question could not be delivered (HTTP ${response.status}).`); return payload; } });
114
125
  // Read ONCE at load, not per call: the environment cannot change under a running Pi, and `prepareLoadout`
115
126
  // is synchronous - it cannot await a fetch for a roster - so the roster has to already be here.
116
127
  const config = readTaskConfig(process.env);