@khalilgharbaoui/opencode-claude-code-plugin 0.16.0 → 0.17.0
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.
- package/README.md +3 -2
- package/dist/index.d.ts +10 -0
- package/dist/index.js +177 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -357,7 +357,7 @@ By default, the plugin proxies `Bash`, `Edit`, `Write`, `WebFetch`, and `Task`.
|
|
|
357
357
|
| `"Edit"` | `Edit`, `MultiEdit` | `mcp__opencode_proxy__edit` |
|
|
358
358
|
| `"Write"` | `Write` | `mcp__opencode_proxy__write` |
|
|
359
359
|
| `"WebFetch"` | `WebFetch` | `mcp__opencode_proxy__webfetch` |
|
|
360
|
-
| `"Task"` | `Agent` | `mcp__opencode_proxy__task` |
|
|
360
|
+
| `"Task"` | `Agent` | `mcp__opencode_proxy__task`, `mcp__opencode_proxy__task_batch` |
|
|
361
361
|
| `"Question"` | `AskUserQuestion` | `mcp__opencode_proxy__question` |
|
|
362
362
|
| `"Compress"` | none | `mcp__opencode_proxy__compress` |
|
|
363
363
|
|
|
@@ -369,6 +369,7 @@ By default, the plugin proxies `Bash`, `Edit`, `Write`, `WebFetch`, and `Task`.
|
|
|
369
369
|
- **Resume:** pass the child session ID back as `task_id` to continue that subagent session. Omit it to create a fresh child.
|
|
370
370
|
- **Nested tasks:** current opencode defaults `subagent_depth` to `1`, so a first-level child cannot launch another child. Increase top-level `subagent_depth` to permit deeper nesting, and explicitly grant `permission.task` on every subagent that should delegate; opencode otherwise adds a task deny to spawned subagent sessions.
|
|
371
371
|
- **Background:** `background: true` returns after starting the child and lets opencode notify the parent when it finishes. Current opencode requires `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` in the environment of the opencode process. Foreground is the default.
|
|
372
|
+
- **Several at once:** `mcp__opencode_proxy__task_batch` takes a `tasks` array of ordinary task inputs and runs them concurrently. It exists because Claude Code sends MCP requests one at a time: when the model emits two `task` calls in one response, the second only leaves the CLI after the first has returned (measured live, 2026-09-06), so "launch two subagents" was always serial. The plugin turns one `task_batch` call into N opencode `task` calls inside a single tool boundary, which opencode executes in parallel, then hands the model every result together, labelled in task order. Same permissions, same 60-minute deadline, same `subagent_type` list. Enabled whenever `Task` is proxied. Designed and first implemented by [@broskees](https://github.com/broskees) on his fork.
|
|
372
373
|
|
|
373
374
|
**Steering models to it.** Headless Claude Code CLIs expose no `Agent`/`Task`
|
|
374
375
|
dispatch tool of their own (verified on 2.1.211), while they *do* expose
|
|
@@ -965,7 +966,7 @@ This plugin absorbs work from its forks directly, cherry-picked with the origina
|
|
|
965
966
|
| [@galvani](https://github.com/galvani) (Jan Kozak) | Per-session working directory for `opencode serve`, so one server spawns each project's `claude` in the right place. Also found the stale `toolCallMap` re-emission three months before it was fixed here. | `9e02ce4`, `2238ed0` |
|
|
966
967
|
| [@HeikoAtGitHub](https://github.com/HeikoAtGitHub) | Stopped sending `AGENTS.md` to the model twice (opencode already forwards it). Independently diagnosed the 5-minute proxy wall. | `25260a4`, `42f426d` |
|
|
967
968
|
| [@bernardofortes](https://github.com/bernardofortes) (Bernardo Fortes) | `idleProcessTimeoutMs`, idle eviction of retained `claude` workers. | `a5f723a` |
|
|
968
|
-
| [@broskees](https://github.com/broskees) (Joseph Roberts) | Task proxy default-on (PR #18), the abort `interrupt` so Esc really stops the CLI, the skill bridge, and the undici 300 s diagnosis of the proxy wall. | PR #18, `68ed142` |
|
|
969
|
+
| [@broskees](https://github.com/broskees) (Joseph Roberts) | Task proxy default-on (PR #18), the abort `interrupt` so Esc really stops the CLI, the skill bridge, `task_batch` for concurrent subagents (and the measurement that the CLI serialises MCP calls), and the undici 300 s diagnosis of the proxy wall. | PR #18, `68ed142` |
|
|
969
970
|
| [@jknlsn](https://github.com/jknlsn) (Jake Nelson) | Per-tool proxy timeouts, subagent dispatch steering, the question proxy, the start watchdog respawn. | `84f3db9`, `94980a6`, `47501d0`, `ffefc24` |
|
|
970
971
|
| [@CollieIsCute](https://github.com/CollieIsCute) (Collie Tsai) | The plan-mode approval bridge. | `8c5b583` |
|
|
971
972
|
| [@flupkede](https://github.com/flupkede) | The compress proxy tool design and the AI-SDK v4 image-part fix. | `4ac319f`, `60a6e9a` |
|
package/dist/index.d.ts
CHANGED
|
@@ -630,6 +630,16 @@ declare class ClaudeCodeLanguageModel implements LanguageModelV3 {
|
|
|
630
630
|
*/
|
|
631
631
|
private ensureProxyServer;
|
|
632
632
|
private extractPendingProxyResult;
|
|
633
|
+
/**
|
|
634
|
+
* The result opencode produced for a pending proxy call, if the prompt
|
|
635
|
+
* carries it. For `task_batch` that means every child's result gathered
|
|
636
|
+
* back onto the parent: opencode runs the children in one step and hands
|
|
637
|
+
* all their results to the next call together, so a partial set is not
|
|
638
|
+
* expected. If it ever happens the batch still resolves, with the gap
|
|
639
|
+
* named in the text, because leaving the parent pending would send this
|
|
640
|
+
* turn down the fresh-envelope path and reject the call as orphaned.
|
|
641
|
+
*/
|
|
642
|
+
private extractPendingProxyResultForCall;
|
|
633
643
|
/**
|
|
634
644
|
* Resolve the session affinity token for this LLM call. Delegates to the
|
|
635
645
|
* exported `resolveSessionAffinity` helper so the logic is unit-testable.
|
package/dist/index.js
CHANGED
|
@@ -523,6 +523,8 @@ var PROXY_DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
|
523
523
|
var PROXY_PER_TOOL_DEFAULT_TIMEOUT_MS = {
|
|
524
524
|
task: 60 * 60 * 1e3,
|
|
525
525
|
// 60 min
|
|
526
|
+
task_batch: 60 * 60 * 1e3,
|
|
527
|
+
// 60 min, same reasoning: it IS task calls
|
|
526
528
|
question: 30 * 60 * 1e3
|
|
527
529
|
// 30 min
|
|
528
530
|
};
|
|
@@ -562,14 +564,58 @@ function resolveProxyClientCeilingMs(overrides) {
|
|
|
562
564
|
function buildProxyTimeoutError(toolName, ms) {
|
|
563
565
|
const key = toolName.toLowerCase();
|
|
564
566
|
const base = `Proxy tool '${toolName}' timed out after ${ms}ms waiting for opencode to resolve the call`;
|
|
565
|
-
if (key === "task") {
|
|
567
|
+
if (key === "task" || key === TASK_BATCH_TOOL_NAME) {
|
|
566
568
|
return new Error(
|
|
567
|
-
base + " (the subagent). The subagent may still be running but its result is no longer reachable in this session. Do not declare the dispatch failed, and do not 'schedule a wake-up' or defer -- that mechanism does not apply here. If the result is required, re-dispatch or verify it directly now."
|
|
569
|
+
base + (key === "task" ? " (the subagent)." : " (the subagents).") + " The subagent may still be running but its result is no longer reachable in this session. Do not declare the dispatch failed, and do not 'schedule a wake-up' or defer -- that mechanism does not apply here. If the result is required, re-dispatch or verify it directly now."
|
|
568
570
|
);
|
|
569
571
|
}
|
|
570
572
|
return new Error(base);
|
|
571
573
|
}
|
|
572
|
-
var TASK_PROXY_NOTE = "This
|
|
574
|
+
var TASK_PROXY_NOTE = "This and task_batch are the ONLY tools that dispatch opencode subagents (including user @-mentions). Claude Code's built-in TaskCreate/TaskUpdate manage a local todo list and cannot dispatch subagents. Do not search config files to verify a subagent type exists: invalid types fail fast with a clear error. Foreground calls block until the subagent finishes; set `background` to request opencode's background execution mode. For two or more independent subagents in one response use task_batch, not several task calls: those run one after another. Task calls get a 60-minute proxy deadline by default (configurable via proxyToolTimeoutMs).";
|
|
575
|
+
var TASK_BATCH_TOOL_NAME = "task_batch";
|
|
576
|
+
var TASK_BATCH_PROXY_NOTE = "Use this instead of several task calls in one response: Claude Code runs MCP tool calls one at a time, so separate task calls run serially even when emitted together, while one task_batch call fans them out as parallel opencode task calls. Each task takes the same fields as the task tool. Results come back in task order, each labelled. Same 60-minute proxy deadline as task (configurable via proxyToolTimeoutMs).";
|
|
577
|
+
var TASK_INPUT_REQUIRED = ["description", "prompt", "subagent_type"];
|
|
578
|
+
function taskBatchInputError(input) {
|
|
579
|
+
const tasks = input?.tasks;
|
|
580
|
+
if (!Array.isArray(tasks) || tasks.length < 2) {
|
|
581
|
+
return "task_batch requires a `tasks` array with at least two items; use `task` for one subagent";
|
|
582
|
+
}
|
|
583
|
+
for (const [index, task] of tasks.entries()) {
|
|
584
|
+
if (task === null || typeof task !== "object" || Array.isArray(task)) {
|
|
585
|
+
return `task_batch tasks[${index}] must be an object`;
|
|
586
|
+
}
|
|
587
|
+
const item = task;
|
|
588
|
+
for (const field of TASK_INPUT_REQUIRED) {
|
|
589
|
+
if (typeof item[field] !== "string") {
|
|
590
|
+
return `task_batch tasks[${index}].${field} must be a string`;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
function taskBatchTasks(input) {
|
|
597
|
+
if (taskBatchInputError(input)) return [];
|
|
598
|
+
return input.tasks;
|
|
599
|
+
}
|
|
600
|
+
function taskBatchChildToolCallId(parentToolCallId, index) {
|
|
601
|
+
return `${parentToolCallId}_task_${index}`;
|
|
602
|
+
}
|
|
603
|
+
function formatTaskBatchResults(children) {
|
|
604
|
+
const total = children.length;
|
|
605
|
+
const sections = children.map(({ task, result }, index) => {
|
|
606
|
+
const label = typeof task.description === "string" ? task.description : `task ${index + 1}`;
|
|
607
|
+
const agent = typeof task.subagent_type === "string" ? ` (${task.subagent_type})` : "";
|
|
608
|
+
const header = `## task ${index + 1} of ${total}: ${label}${agent}`;
|
|
609
|
+
if (!result) return `${header}
|
|
610
|
+
[missing] opencode returned no result for this task in the batch`;
|
|
611
|
+
if (result.kind === "error") return `${header}
|
|
612
|
+
[error] ${result.message}`;
|
|
613
|
+
return `${header}
|
|
614
|
+
${result.isError ? "[error] " : ""}${result.text}`;
|
|
615
|
+
});
|
|
616
|
+
const failed = children.some(({ result }) => !result || result.kind === "error" || result.isError);
|
|
617
|
+
return { kind: "text", text: sections.join("\n\n"), ...failed ? { isError: true } : {} };
|
|
618
|
+
}
|
|
573
619
|
var AGENT_TYPES_HEADING = "Available agent types";
|
|
574
620
|
var AGENT_BLURB_LIMIT = 140;
|
|
575
621
|
var QUESTION_PROXY_NOTE = "This routes structured questions through opencode's native `question` tool, which renders a TUI form with the options you provide and blocks until the operator answers. Claude Code's built-in AskUserQuestion is disabled in this environment; this proxy is the ONLY way to ask the operator for a decision or clarification. Answers come back as arrays of selected labels (set `multiple: true` to allow more than one). If the operator dismisses the form the call returns an error \u2014 treat that as 'no answer' and stop, do not guess. Question calls get a 30-minute proxy deadline by default (configurable via proxyToolTimeoutMs); for long-AFK scenarios prefer fewer, high-signal questions.";
|
|
@@ -597,7 +643,7 @@ function overlayTaskProxyDescription(tools, liveDescription) {
|
|
|
597
643
|
const agentTypes = extractAgentTypeList(liveDescription);
|
|
598
644
|
if (!agentTypes) return tools;
|
|
599
645
|
return tools.map(
|
|
600
|
-
(t) => t.name === "task" ? { ...t, description: `${agentTypes}
|
|
646
|
+
(t) => t.name === "task" || t.name === TASK_BATCH_TOOL_NAME ? { ...t, description: `${agentTypes}
|
|
601
647
|
|
|
602
648
|
${t.description}` } : t
|
|
603
649
|
);
|
|
@@ -615,6 +661,32 @@ function filterQuestionProxyByOpencodeSupport(tools, opencodeHasQuestion) {
|
|
|
615
661
|
if (opencodeHasQuestion) return tools;
|
|
616
662
|
return tools.filter((t) => t.name !== "question");
|
|
617
663
|
}
|
|
664
|
+
var TASK_INPUT_PROPERTIES = {
|
|
665
|
+
description: {
|
|
666
|
+
type: "string",
|
|
667
|
+
description: "A short (3-5 words) description of the task"
|
|
668
|
+
},
|
|
669
|
+
prompt: {
|
|
670
|
+
type: "string",
|
|
671
|
+
description: "The task for the agent to perform"
|
|
672
|
+
},
|
|
673
|
+
subagent_type: {
|
|
674
|
+
type: "string",
|
|
675
|
+
description: "The type of specialized agent to use for this task"
|
|
676
|
+
},
|
|
677
|
+
task_id: {
|
|
678
|
+
type: "string",
|
|
679
|
+
description: "Set this only if you mean to resume a previous task: pass the prior task_id to continue the same subagent session instead of creating a fresh one."
|
|
680
|
+
},
|
|
681
|
+
command: {
|
|
682
|
+
type: "string",
|
|
683
|
+
description: "The command that triggered this task"
|
|
684
|
+
},
|
|
685
|
+
background: {
|
|
686
|
+
type: "boolean",
|
|
687
|
+
description: "Run the task in the background when supported by opencode"
|
|
688
|
+
}
|
|
689
|
+
};
|
|
618
690
|
var DEFAULT_PROXY_TOOLS = [
|
|
619
691
|
{
|
|
620
692
|
name: "bash",
|
|
@@ -708,35 +780,30 @@ var DEFAULT_PROXY_TOOLS = [
|
|
|
708
780
|
{
|
|
709
781
|
name: "task",
|
|
710
782
|
description: "Launch an opencode subagent to handle a complex multi-step task autonomously. Routed through opencode's task tool so subagent orchestration, permission, and lifecycle are handled by opencode. Use `subagent_type` to pick which configured subagent runs (e.g. `build`, `general`, `explore`, or any custom subagent declared in opencode.json). " + TASK_PROXY_NOTE,
|
|
783
|
+
inputSchema: {
|
|
784
|
+
type: "object",
|
|
785
|
+
properties: TASK_INPUT_PROPERTIES,
|
|
786
|
+
required: TASK_INPUT_REQUIRED
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
name: TASK_BATCH_TOOL_NAME,
|
|
791
|
+
description: "Launch two or more independent opencode subagents at the same time and get all their results back together. Put one ordinary task input in `tasks` for each subagent. " + TASK_BATCH_PROXY_NOTE,
|
|
711
792
|
inputSchema: {
|
|
712
793
|
type: "object",
|
|
713
794
|
properties: {
|
|
714
|
-
|
|
715
|
-
type: "
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
type: "string",
|
|
724
|
-
description: "The type of specialized agent to use for this task"
|
|
725
|
-
},
|
|
726
|
-
task_id: {
|
|
727
|
-
type: "string",
|
|
728
|
-
description: "Set this only if you mean to resume a previous task \u2014 pass the prior task_id to continue the same subagent session instead of creating a fresh one."
|
|
729
|
-
},
|
|
730
|
-
command: {
|
|
731
|
-
type: "string",
|
|
732
|
-
description: "The command that triggered this task"
|
|
733
|
-
},
|
|
734
|
-
background: {
|
|
735
|
-
type: "boolean",
|
|
736
|
-
description: "Run the task in the background when supported by opencode"
|
|
795
|
+
tasks: {
|
|
796
|
+
type: "array",
|
|
797
|
+
minItems: 2,
|
|
798
|
+
description: "Independent subagent tasks to run concurrently",
|
|
799
|
+
items: {
|
|
800
|
+
type: "object",
|
|
801
|
+
properties: TASK_INPUT_PROPERTIES,
|
|
802
|
+
required: TASK_INPUT_REQUIRED
|
|
803
|
+
}
|
|
737
804
|
}
|
|
738
805
|
},
|
|
739
|
-
required: ["
|
|
806
|
+
required: ["tasks"]
|
|
740
807
|
}
|
|
741
808
|
},
|
|
742
809
|
{
|
|
@@ -922,6 +989,13 @@ async function createProxyMcpServer(tools = DEFAULT_PROXY_TOOLS, timeoutOverride
|
|
|
922
989
|
});
|
|
923
990
|
return;
|
|
924
991
|
}
|
|
992
|
+
if (toolName === TASK_BATCH_TOOL_NAME) {
|
|
993
|
+
const problem = taskBatchInputError(input);
|
|
994
|
+
if (problem) {
|
|
995
|
+
writeToolCallResult(res, requestId, { kind: "error", message: problem });
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
925
999
|
const interceptor = interceptors?.get(toolName);
|
|
926
1000
|
if (interceptor) {
|
|
927
1001
|
let intercepted;
|
|
@@ -1126,6 +1200,7 @@ function disallowedToolFlags(tools) {
|
|
|
1126
1200
|
grep: ["Grep"],
|
|
1127
1201
|
webfetch: ["WebFetch"],
|
|
1128
1202
|
task: ["Agent"],
|
|
1203
|
+
task_batch: ["Agent"],
|
|
1129
1204
|
// `question` disables Claude Code's built-in `AskUserQuestion` so the
|
|
1130
1205
|
// structured-questions path flows through opencode's native `question`
|
|
1131
1206
|
// tool instead — same UI/permission/audit benefits as the other
|
|
@@ -4599,8 +4674,9 @@ blocker. The user can interrupt or abort at any time; turn endings should
|
|
|
4599
4674
|
mark meaningful checkpoints, not every completed substep.`;
|
|
4600
4675
|
var SUBAGENT_DISPATCH_HINT = `## opencode subagents
|
|
4601
4676
|
|
|
4602
|
-
Subagent dispatch in this environment goes through exactly
|
|
4677
|
+
Subagent dispatch in this environment goes through exactly two tools: \`mcp__opencode_proxy__task\` for one subagent and \`mcp__opencode_proxy__task_batch\` for two or more at once.
|
|
4603
4678
|
|
|
4679
|
+
- Two or more independent subagents in one response: make ONE \`mcp__opencode_proxy__task_batch\` call with a \`tasks\` array (each item is a normal task input). Claude Code runs MCP calls one at a time, so several \`mcp__opencode_proxy__task\` calls in the same response run serially; \`task_batch\` runs them concurrently in opencode and returns every result together, labelled in order.
|
|
4604
4680
|
- When the user mentions \`@<agent>\` or an instruction says "call the task tool with subagent: <name>", call \`mcp__opencode_proxy__task\` with \`subagent_type: "<name>"\`.
|
|
4605
4681
|
- If that tool is not in your visible tool list it is deferred \u2014 load it with ToolSearch (\`select:mcp__opencode_proxy__task\`), then call it.
|
|
4606
4682
|
- Claude Code's built-in TaskCreate/TaskUpdate/TaskList manage a local todo list. They cannot dispatch subagents; creating a task there runs nothing. Never report a subagent as dispatched unless \`mcp__opencode_proxy__task\` returned its result.
|
|
@@ -4804,11 +4880,24 @@ var ClaudeCodeLanguageModel = class {
|
|
|
4804
4880
|
DEFAULT_PROXY_TOOLS.map((t) => [t.name.toLowerCase(), t])
|
|
4805
4881
|
);
|
|
4806
4882
|
const picked = [];
|
|
4883
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4807
4884
|
const unknown = [];
|
|
4885
|
+
const pick = (def) => {
|
|
4886
|
+
if (seen.has(def.name)) return;
|
|
4887
|
+
seen.add(def.name);
|
|
4888
|
+
picked.push(def);
|
|
4889
|
+
};
|
|
4808
4890
|
for (const n of names) {
|
|
4809
4891
|
const def = defsByName.get(String(n).toLowerCase());
|
|
4810
|
-
if (def)
|
|
4811
|
-
|
|
4892
|
+
if (!def) {
|
|
4893
|
+
unknown.push(String(n));
|
|
4894
|
+
continue;
|
|
4895
|
+
}
|
|
4896
|
+
pick(def);
|
|
4897
|
+
if (def.name === "task") {
|
|
4898
|
+
const batch = defsByName.get(TASK_BATCH_TOOL_NAME);
|
|
4899
|
+
if (batch) pick(batch);
|
|
4900
|
+
}
|
|
4812
4901
|
}
|
|
4813
4902
|
if (unknown.length > 0) {
|
|
4814
4903
|
const known = [...defsByName.keys()].join(", ");
|
|
@@ -4998,6 +5087,41 @@ var ClaudeCodeLanguageModel = class {
|
|
|
4998
5087
|
}
|
|
4999
5088
|
return null;
|
|
5000
5089
|
}
|
|
5090
|
+
/**
|
|
5091
|
+
* The result opencode produced for a pending proxy call, if the prompt
|
|
5092
|
+
* carries it. For `task_batch` that means every child's result gathered
|
|
5093
|
+
* back onto the parent: opencode runs the children in one step and hands
|
|
5094
|
+
* all their results to the next call together, so a partial set is not
|
|
5095
|
+
* expected. If it ever happens the batch still resolves, with the gap
|
|
5096
|
+
* named in the text, because leaving the parent pending would send this
|
|
5097
|
+
* turn down the fresh-envelope path and reject the call as orphaned.
|
|
5098
|
+
*/
|
|
5099
|
+
extractPendingProxyResultForCall(prompt, call) {
|
|
5100
|
+
if (call.toolName !== TASK_BATCH_TOOL_NAME) {
|
|
5101
|
+
return this.extractPendingProxyResult(prompt, call.toolCallId);
|
|
5102
|
+
}
|
|
5103
|
+
const tasks = taskBatchTasks(call.input);
|
|
5104
|
+
if (tasks.length === 0) {
|
|
5105
|
+
return { kind: "error", message: "task_batch input is not a list of task objects" };
|
|
5106
|
+
}
|
|
5107
|
+
const children = tasks.map((task, index) => ({
|
|
5108
|
+
task,
|
|
5109
|
+
result: this.extractPendingProxyResult(
|
|
5110
|
+
prompt,
|
|
5111
|
+
taskBatchChildToolCallId(call.toolCallId, index)
|
|
5112
|
+
)
|
|
5113
|
+
}));
|
|
5114
|
+
const answered = children.filter((child) => child.result !== null).length;
|
|
5115
|
+
if (answered === 0) return null;
|
|
5116
|
+
if (answered < children.length) {
|
|
5117
|
+
log.warn("task_batch resolving with child results missing", {
|
|
5118
|
+
toolCallId: call.toolCallId,
|
|
5119
|
+
answered,
|
|
5120
|
+
total: children.length
|
|
5121
|
+
});
|
|
5122
|
+
}
|
|
5123
|
+
return formatTaskBatchResults(children);
|
|
5124
|
+
}
|
|
5001
5125
|
/**
|
|
5002
5126
|
* Resolve the session affinity token for this LLM call. Delegates to the
|
|
5003
5127
|
* exported `resolveSessionAffinity` helper so the logic is unit-testable.
|
|
@@ -5809,7 +5933,7 @@ ${plan}
|
|
|
5809
5933
|
const self = this;
|
|
5810
5934
|
const previousPendingProxyMatches = previousPendingProxyCalls.map((call) => ({
|
|
5811
5935
|
call,
|
|
5812
|
-
result: this.
|
|
5936
|
+
result: this.extractPendingProxyResultForCall(options.prompt, call)
|
|
5813
5937
|
}));
|
|
5814
5938
|
const hasMatchedPendingResults = previousPendingProxyMatches.some(
|
|
5815
5939
|
(m) => m.result !== null
|
|
@@ -6271,20 +6395,34 @@ ${plan}
|
|
|
6271
6395
|
const finishWithToolCalls = (calls) => {
|
|
6272
6396
|
if (controllerClosed) return;
|
|
6273
6397
|
if (calls.length === 0) return;
|
|
6274
|
-
|
|
6398
|
+
const enqueueToolCall = (toolCallId, toolName, input) => {
|
|
6275
6399
|
controller.enqueue({
|
|
6276
6400
|
type: "tool-input-start",
|
|
6277
|
-
id:
|
|
6278
|
-
toolName
|
|
6401
|
+
id: toolCallId,
|
|
6402
|
+
toolName
|
|
6279
6403
|
});
|
|
6280
6404
|
controller.enqueue({
|
|
6281
6405
|
type: "tool-call",
|
|
6282
|
-
toolCallId
|
|
6283
|
-
toolName
|
|
6284
|
-
input: JSON.stringify(
|
|
6406
|
+
toolCallId,
|
|
6407
|
+
toolName,
|
|
6408
|
+
input: JSON.stringify(input),
|
|
6285
6409
|
providerExecuted: false
|
|
6286
6410
|
});
|
|
6287
|
-
skipResultForIds.add(
|
|
6411
|
+
skipResultForIds.add(toolCallId);
|
|
6412
|
+
};
|
|
6413
|
+
for (const call of calls) {
|
|
6414
|
+
if (call.toolName === TASK_BATCH_TOOL_NAME) {
|
|
6415
|
+
for (const [index, task] of taskBatchTasks(call.input).entries()) {
|
|
6416
|
+
enqueueToolCall(
|
|
6417
|
+
taskBatchChildToolCallId(call.toolCallId, index),
|
|
6418
|
+
"task",
|
|
6419
|
+
task
|
|
6420
|
+
);
|
|
6421
|
+
}
|
|
6422
|
+
skipResultForIds.add(call.toolCallId);
|
|
6423
|
+
} else {
|
|
6424
|
+
enqueueToolCall(call.toolCallId, call.toolName, call.input);
|
|
6425
|
+
}
|
|
6288
6426
|
markPendingProxyCallEmitted(call.toolCallId);
|
|
6289
6427
|
}
|
|
6290
6428
|
controller.enqueue({
|