@oh-my-pi/pi-coding-agent 17.0.1 → 17.0.3
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/CHANGELOG.md +162 -40
- package/dist/cli.js +4559 -4543
- package/dist/types/advisor/config.d.ts +14 -6
- package/dist/types/advisor/runtime.d.ts +20 -11
- package/dist/types/autolearn/controller.d.ts +1 -0
- package/dist/types/config/model-discovery.d.ts +17 -0
- package/dist/types/config/model-resolver.d.ts +6 -2
- package/dist/types/config/settings-schema.d.ts +39 -10
- package/dist/types/config/settings.d.ts +50 -0
- package/dist/types/cursor.d.ts +11 -0
- package/dist/types/discovery/helpers.d.ts +5 -2
- package/dist/types/eval/agent-bridge.d.ts +7 -19
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/managed-timers.d.ts +15 -0
- package/dist/types/extensibility/extensions/runner.d.ts +7 -0
- package/dist/types/extensibility/extensions/types.d.ts +18 -0
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +55 -1
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/extensibility/utils.d.ts +2 -2
- package/dist/types/lsp/client.d.ts +2 -0
- package/dist/types/lsp/types.d.ts +3 -0
- package/dist/types/mcp/transports/stdio.d.ts +42 -1
- package/dist/types/modes/components/advisor-config.d.ts +8 -1
- package/dist/types/modes/components/agent-hub.d.ts +15 -0
- package/dist/types/modes/components/hook-editor.d.ts +7 -0
- package/dist/types/modes/components/model-hub.d.ts +5 -2
- package/dist/types/modes/components/session-selector.d.ts +2 -0
- package/dist/types/modes/controllers/command-controller.d.ts +8 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +3 -1
- package/dist/types/modes/print-mode.d.ts +1 -1
- package/dist/types/modes/warp-events.d.ts +24 -0
- package/dist/types/modes/warp-events.test.d.ts +1 -0
- package/dist/types/plan-mode/model-transition.d.ts +47 -0
- package/dist/types/plan-mode/model-transition.test.d.ts +1 -0
- package/dist/types/registry/agent-lifecycle.d.ts +26 -1
- package/dist/types/registry/persisted-agents.d.ts +3 -0
- package/dist/types/sdk.d.ts +27 -5
- package/dist/types/session/agent-session.d.ts +34 -10
- package/dist/types/session/session-entries.d.ts +6 -1
- package/dist/types/session/session-history-format.d.ts +10 -0
- package/dist/types/session/session-manager.d.ts +19 -0
- package/dist/types/slash-commands/helpers/active-oauth-account.d.ts +9 -0
- package/dist/types/task/executor.d.ts +26 -1
- package/dist/types/task/index.d.ts +1 -1
- package/dist/types/task/label.d.ts +1 -1
- package/dist/types/task/parallel.d.ts +14 -0
- package/dist/types/task/structured-subagent.d.ts +111 -0
- package/dist/types/task/types.d.ts +51 -0
- package/dist/types/telemetry-export.d.ts +34 -9
- package/dist/types/tools/approval.d.ts +8 -0
- package/dist/types/tools/bash.d.ts +2 -0
- package/dist/types/tools/essential-tools.d.ts +29 -0
- package/dist/types/tools/fetch.d.ts +4 -5
- package/dist/types/tools/hub/messaging.d.ts +5 -1
- package/dist/types/tools/image-gen.d.ts +2 -1
- package/dist/types/tools/index.d.ts +17 -1
- package/dist/types/tools/todo.d.ts +31 -0
- package/dist/types/tools/xdev.d.ts +11 -2
- package/dist/types/tui/tree-list.d.ts +7 -0
- package/dist/types/utils/markit.d.ts +11 -0
- package/dist/types/utils/title-generator.d.ts +2 -1
- package/dist/types/web/search/providers/kimi.d.ts +4 -1
- package/dist/types/web/search/types.d.ts +1 -1
- package/package.json +21 -16
- package/src/advisor/__tests__/advisor.test.ts +1304 -42
- package/src/advisor/__tests__/config.test.ts +58 -2
- package/src/advisor/config.ts +76 -24
- package/src/advisor/runtime.ts +445 -92
- package/src/autolearn/controller.ts +23 -28
- package/src/cli/file-processor.ts +1 -2
- package/src/cli.ts +5 -1
- package/src/config/model-discovery.ts +81 -21
- package/src/config/model-registry.ts +25 -6
- package/src/config/model-resolver.ts +14 -7
- package/src/config/settings-schema.ts +46 -9
- package/src/config/settings.ts +405 -25
- package/src/cursor.ts +20 -3
- package/src/debug/report-bundle.ts +40 -4
- package/src/discovery/helpers.ts +28 -5
- package/src/eval/__tests__/agent-bridge.test.ts +133 -47
- package/src/eval/__tests__/prelude-agent.test.ts +29 -0
- package/src/eval/agent-bridge.ts +104 -477
- package/src/eval/jl/prelude.jl +7 -6
- package/src/eval/js/shared/prelude.txt +5 -4
- package/src/eval/py/prelude.py +11 -39
- package/src/eval/rb/prelude.rb +5 -6
- package/src/exec/bash-executor.ts +14 -5
- package/src/extensibility/custom-tools/loader.ts +3 -3
- package/src/extensibility/custom-tools/wrapper.ts +2 -1
- package/src/extensibility/extensions/loader.ts +3 -3
- package/src/extensibility/extensions/managed-timers.ts +83 -0
- package/src/extensibility/extensions/runner.ts +26 -0
- package/src/extensibility/extensions/types.ts +18 -0
- package/src/extensibility/extensions/wrapper.ts +2 -1
- package/src/extensibility/hooks/loader.ts +3 -3
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +149 -8
- package/src/extensibility/plugins/legacy-pi-compat.ts +225 -22
- package/src/extensibility/plugins/manager.ts +2 -2
- package/src/extensibility/shared-events.ts +6 -0
- package/src/extensibility/utils.ts +91 -25
- package/src/irc/bus.ts +22 -3
- package/src/launch/broker.ts +3 -2
- package/src/launch/client.ts +2 -2
- package/src/launch/presence.ts +2 -2
- package/src/lsp/client.ts +58 -1
- package/src/lsp/index.ts +62 -6
- package/src/lsp/types.ts +3 -0
- package/src/main.ts +11 -8
- package/src/mcp/manager.ts +9 -3
- package/src/mcp/oauth-flow.ts +20 -0
- package/src/mcp/transports/stdio.test.ts +269 -1
- package/src/mcp/transports/stdio.ts +255 -24
- package/src/modes/components/advisor-config.ts +65 -3
- package/src/modes/components/agent-hub.ts +1 -72
- package/src/modes/components/ask-dialog.ts +1 -1
- package/src/modes/components/bash-execution.ts +7 -3
- package/src/modes/components/eval-execution.ts +3 -1
- package/src/modes/components/hook-editor.ts +18 -3
- package/src/modes/components/model-hub.ts +138 -42
- package/src/modes/components/session-selector.ts +4 -0
- package/src/modes/components/status-line/component.test.ts +1 -0
- package/src/modes/components/status-line/segments.ts +21 -6
- package/src/modes/controllers/command-controller.ts +167 -47
- package/src/modes/controllers/event-controller.ts +5 -0
- package/src/modes/controllers/extension-ui-controller.ts +4 -22
- package/src/modes/controllers/input-controller.ts +12 -12
- package/src/modes/controllers/selector-controller.ts +191 -31
- package/src/modes/interactive-mode.ts +169 -62
- package/src/modes/print-mode.ts +3 -3
- package/src/modes/rpc/host-tools.ts +2 -1
- package/src/modes/rpc/rpc-mode.ts +19 -4
- package/src/modes/warp-events.test.ts +794 -0
- package/src/modes/warp-events.ts +232 -0
- package/src/plan-mode/model-transition.test.ts +60 -0
- package/src/plan-mode/model-transition.ts +51 -0
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/tools/eval.md +5 -2
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/task.md +12 -8
- package/src/prompts/tools/write.md +1 -1
- package/src/registry/agent-lifecycle.ts +133 -18
- package/src/registry/persisted-agents.ts +74 -0
- package/src/sdk.ts +343 -122
- package/src/session/agent-session.ts +1359 -368
- package/src/session/session-entries.ts +6 -1
- package/src/session/session-history-format.ts +20 -5
- package/src/session/session-manager.ts +57 -0
- package/src/session/streaming-output.ts +41 -1
- package/src/slash-commands/builtin-registry.ts +7 -0
- package/src/slash-commands/helpers/active-oauth-account.ts +16 -0
- package/src/system-prompt.ts +7 -2
- package/src/task/executor.ts +100 -22
- package/src/task/index.ts +258 -429
- package/src/task/label.ts +2 -0
- package/src/task/parallel.ts +43 -0
- package/src/task/persisted-revive.ts +19 -7
- package/src/task/structured-subagent.ts +642 -0
- package/src/task/types.ts +58 -0
- package/src/telemetry-export.ts +453 -97
- package/src/tools/__tests__/eval-description.test.ts +1 -1
- package/src/tools/approval.ts +11 -0
- package/src/tools/bash.ts +71 -38
- package/src/tools/essential-tools.ts +45 -0
- package/src/tools/fetch.ts +28 -105
- package/src/tools/gh.ts +169 -2
- package/src/tools/hub/messaging.ts +16 -3
- package/src/tools/image-gen.ts +69 -7
- package/src/tools/index.ts +50 -15
- package/src/tools/path-utils.ts +1 -0
- package/src/tools/read.ts +62 -29
- package/src/tools/todo.ts +126 -13
- package/src/tools/write.ts +22 -4
- package/src/tools/xdev.ts +14 -3
- package/src/tui/tree-list.ts +39 -0
- package/src/utils/markit.ts +12 -0
- package/src/utils/title-generator.ts +15 -4
- package/src/utils/zip.ts +16 -1
- package/src/web/search/providers/kimi.ts +18 -12
- package/src/web/search/types.ts +6 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { ImageContent, MessageAttribution, ServiceTierByFamily, TextContent } from "@oh-my-pi/pi-ai";
|
|
3
|
+
import type { StructuredSubagentSchemaMode } from "../task/types";
|
|
3
4
|
|
|
4
5
|
export const CURRENT_SESSION_VERSION = 3;
|
|
5
6
|
|
|
@@ -164,8 +165,12 @@ export interface SessionInitEntry extends SessionEntryBase {
|
|
|
164
165
|
task: string;
|
|
165
166
|
/** Tools available to the agent */
|
|
166
167
|
tools: string[];
|
|
167
|
-
/** Output schema if structured output was requested */
|
|
168
|
+
/** Output schema if structured output was requested. */
|
|
168
169
|
outputSchema?: unknown;
|
|
170
|
+
/** Enforcement policy recorded with the output schema for faithful revival. */
|
|
171
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
172
|
+
/** Whether revival must retain only the explicitly persisted tool names. */
|
|
173
|
+
restrictToolNames?: boolean;
|
|
169
174
|
/** Spawn allowlist the subagent ran with ("" = none, "*" = any, else CSV); absent on pre-spawns files. */
|
|
170
175
|
spawns?: string;
|
|
171
176
|
/** The agent's `readSummarize` setting (`false` = read summarization disabled); absent uses the session default. */
|
|
@@ -46,6 +46,15 @@ export interface HistoryFormatOptions {
|
|
|
46
46
|
* this so it sees what changed without re-reading the file.
|
|
47
47
|
*/
|
|
48
48
|
expandEditDiffs?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Chunked rendering support: a caller formatting one logical transcript in
|
|
51
|
+
* several calls (the advisor's chunked delta render) passes a result index
|
|
52
|
+
* built over the WHOLE delta plus one shared consumed-id set, so a toolCall
|
|
53
|
+
* finds its toolResult across chunk boundaries and the result is never
|
|
54
|
+
* re-rendered as an orphan in a later chunk.
|
|
55
|
+
*/
|
|
56
|
+
toolResultIndex?: ReadonlyMap<string, ToolResultMessage>;
|
|
57
|
+
consumedToolCallIds?: Set<string>;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
/** Max length of the primary-arg summary inside `→ tool(...)` lines. */
|
|
@@ -273,13 +282,19 @@ export function formatSessionHistoryMarkdown(messages: unknown[], opts?: History
|
|
|
273
282
|
}
|
|
274
283
|
|
|
275
284
|
// Index tool results by call id so each toolCall collapses to one line.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
285
|
+
// Chunked callers supply a whole-delta index + shared consumed set so
|
|
286
|
+
// call/result pairs resolve across chunk boundaries.
|
|
287
|
+
let resultsByCallId = opts?.toolResultIndex;
|
|
288
|
+
if (!resultsByCallId) {
|
|
289
|
+
const local = new Map<string, ToolResultMessage>();
|
|
290
|
+
for (const msg of typed) {
|
|
291
|
+
if (msg.role === "toolResult") {
|
|
292
|
+
local.set(msg.toolCallId, msg);
|
|
293
|
+
}
|
|
280
294
|
}
|
|
295
|
+
resultsByCallId = local;
|
|
281
296
|
}
|
|
282
|
-
const consumed = new Set<string>();
|
|
297
|
+
const consumed = opts?.consumedToolCallIds ?? new Set<string>();
|
|
283
298
|
// In watched mode, consecutive same-role messages collapse under one label
|
|
284
299
|
// (the watched agent emits one assistant message per tool call, so otherwise
|
|
285
300
|
// every call repeats `**agent**:`). Cleared whenever a
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
stringifyJson,
|
|
19
19
|
toError,
|
|
20
20
|
} from "@oh-my-pi/pi-utils";
|
|
21
|
+
import type { StructuredSubagentSchemaMode } from "../task/types";
|
|
21
22
|
import { ArtifactManager } from "./artifacts";
|
|
22
23
|
import { type BlobPutOptions, type BlobPutResult, BlobStore } from "./blob-store";
|
|
23
24
|
import {
|
|
@@ -935,6 +936,26 @@ export class SessionManager {
|
|
|
935
936
|
};
|
|
936
937
|
}
|
|
937
938
|
|
|
939
|
+
/**
|
|
940
|
+
* Create an independent manager for the current logical session and branch.
|
|
941
|
+
* The clone shares the storage backend but owns its entry index and writer, so
|
|
942
|
+
* callers can finish session-owned work after this manager switches elsewhere.
|
|
943
|
+
* Set `persist` false when the original session is intentionally being dropped.
|
|
944
|
+
*/
|
|
945
|
+
cloneCurrentSession(options?: { persist?: boolean }): SessionManager {
|
|
946
|
+
const persist = options?.persist ?? this.#persist;
|
|
947
|
+
const clone = new SessionManager(this.#cwd, this.#sessionDir, persist, this.#storage);
|
|
948
|
+
clone.#suppressBreadcrumb = true;
|
|
949
|
+
clone.restoreState(this.captureState());
|
|
950
|
+
if (!persist) {
|
|
951
|
+
clone.#sessionFile = undefined;
|
|
952
|
+
clone.#fileIsCurrent = false;
|
|
953
|
+
clone.#rewriteRequired = false;
|
|
954
|
+
clone.#forceFileCreation = false;
|
|
955
|
+
}
|
|
956
|
+
return clone;
|
|
957
|
+
}
|
|
958
|
+
|
|
938
959
|
restoreState(snapshot: SessionManagerStateSnapshot): void {
|
|
939
960
|
this.#closeWriterEventually();
|
|
940
961
|
this.#diskTail = Promise.resolve();
|
|
@@ -1470,6 +1491,34 @@ export class SessionManager {
|
|
|
1470
1491
|
return entry.id;
|
|
1471
1492
|
}
|
|
1472
1493
|
|
|
1494
|
+
/**
|
|
1495
|
+
* Append to a non-active branch without changing the current leaf.
|
|
1496
|
+
* Used by work that retains ownership of a branch across tree navigation.
|
|
1497
|
+
*/
|
|
1498
|
+
appendMessageToBranch(
|
|
1499
|
+
message:
|
|
1500
|
+
| Message
|
|
1501
|
+
| CustomMessage
|
|
1502
|
+
| HookMessage
|
|
1503
|
+
| BashExecutionMessage
|
|
1504
|
+
| PythonExecutionMessage
|
|
1505
|
+
| FileMentionMessage,
|
|
1506
|
+
parentId: string | null,
|
|
1507
|
+
): string {
|
|
1508
|
+
if (parentId !== null && !this.#index.has(parentId)) throw new Error(`Entry ${parentId} not found`);
|
|
1509
|
+
const activeLeafId = this.#index.leafId();
|
|
1510
|
+
const entry: SessionMessageEntry = {
|
|
1511
|
+
type: "message",
|
|
1512
|
+
id: generateId(this.#index),
|
|
1513
|
+
parentId,
|
|
1514
|
+
timestamp: nowIso(),
|
|
1515
|
+
message,
|
|
1516
|
+
};
|
|
1517
|
+
this.#recordEntry(entry);
|
|
1518
|
+
this.#index.setLeaf(activeLeafId);
|
|
1519
|
+
return entry.id;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1473
1522
|
/** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */
|
|
1474
1523
|
appendThinkingLevelChange(thinkingLevel?: string, configured?: string): string {
|
|
1475
1524
|
const entry: ThinkingLevelChangeEntry = {
|
|
@@ -1510,6 +1559,8 @@ export class SessionManager {
|
|
|
1510
1559
|
task: string;
|
|
1511
1560
|
tools: string[];
|
|
1512
1561
|
outputSchema?: unknown;
|
|
1562
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
1563
|
+
restrictToolNames?: boolean;
|
|
1513
1564
|
spawns?: string;
|
|
1514
1565
|
readSummarize?: boolean;
|
|
1515
1566
|
}): string {
|
|
@@ -1948,6 +1999,8 @@ export class SessionManager {
|
|
|
1948
1999
|
task: string;
|
|
1949
2000
|
tools: string[];
|
|
1950
2001
|
outputSchema?: unknown;
|
|
2002
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
2003
|
+
restrictToolNames?: boolean;
|
|
1951
2004
|
spawns?: string;
|
|
1952
2005
|
readSummarize?: boolean;
|
|
1953
2006
|
} | null;
|
|
@@ -1966,6 +2019,8 @@ export class SessionManager {
|
|
|
1966
2019
|
task: string;
|
|
1967
2020
|
tools: string[];
|
|
1968
2021
|
outputSchema?: unknown;
|
|
2022
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
2023
|
+
restrictToolNames?: boolean;
|
|
1969
2024
|
spawns?: string;
|
|
1970
2025
|
readSummarize?: boolean;
|
|
1971
2026
|
} | null = null;
|
|
@@ -1977,6 +2032,8 @@ export class SessionManager {
|
|
|
1977
2032
|
task: entry.task,
|
|
1978
2033
|
tools: entry.tools,
|
|
1979
2034
|
outputSchema: entry.outputSchema,
|
|
2035
|
+
outputSchemaMode: entry.outputSchemaMode,
|
|
2036
|
+
restrictToolNames: entry.restrictToolNames,
|
|
1980
2037
|
readSummarize: entry.readSummarize,
|
|
1981
2038
|
spawns: entry.spawns,
|
|
1982
2039
|
};
|
|
@@ -22,6 +22,7 @@ export const ARTIFACT_DEFAULT_MAX_BYTES = 0;
|
|
|
22
22
|
export const ARTIFACT_DEFAULT_HEAD_BYTES = 3 * 1024 * 1024; // 3 MiB
|
|
23
23
|
|
|
24
24
|
const NL = "\n";
|
|
25
|
+
const CR = "\r";
|
|
25
26
|
const ELLIPSIS = "…";
|
|
26
27
|
|
|
27
28
|
// =============================================================================
|
|
@@ -737,6 +738,7 @@ export class OutputSink {
|
|
|
737
738
|
#truncated = false;
|
|
738
739
|
#lastChunkTime = 0;
|
|
739
740
|
#pendingChunk = "";
|
|
741
|
+
#pendingCarriageReturn = false;
|
|
740
742
|
#pendingChunkTimer: Timer | undefined;
|
|
741
743
|
|
|
742
744
|
// Per-line column cap streaming state (persists across `push` calls so a
|
|
@@ -802,12 +804,45 @@ export class OutputSink {
|
|
|
802
804
|
this.#artifactTailBudget = Math.max(0, this.#artifactMaxBytes - this.#artifactHeadBudget);
|
|
803
805
|
}
|
|
804
806
|
|
|
807
|
+
/**
|
|
808
|
+
* Converts carriage-return progress updates into line boundaries while
|
|
809
|
+
* collapsing CRLF to one newline. A trailing CR is held until the next
|
|
810
|
+
* chunk so split CRLF sequences do not create blank lines.
|
|
811
|
+
*/
|
|
812
|
+
#normalizeCarriageReturns(text: string): string {
|
|
813
|
+
if (text.length === 0 || (!this.#pendingCarriageReturn && !text.includes(CR))) return text;
|
|
814
|
+
|
|
815
|
+
let cursor = 0;
|
|
816
|
+
let normalized = "";
|
|
817
|
+
if (this.#pendingCarriageReturn) {
|
|
818
|
+
this.#pendingCarriageReturn = false;
|
|
819
|
+
normalized = NL;
|
|
820
|
+
if (text.startsWith(NL)) cursor = 1;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
while (cursor < text.length) {
|
|
824
|
+
const carriageReturn = text.indexOf(CR, cursor);
|
|
825
|
+
if (carriageReturn === -1) {
|
|
826
|
+
normalized += text.substring(cursor);
|
|
827
|
+
break;
|
|
828
|
+
}
|
|
829
|
+
normalized += text.substring(cursor, carriageReturn);
|
|
830
|
+
if (carriageReturn === text.length - 1) {
|
|
831
|
+
this.#pendingCarriageReturn = true;
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
normalized += NL;
|
|
835
|
+
cursor = text.startsWith(NL, carriageReturn + 1) ? carriageReturn + 2 : carriageReturn + 1;
|
|
836
|
+
}
|
|
837
|
+
return normalized;
|
|
838
|
+
}
|
|
839
|
+
|
|
805
840
|
/**
|
|
806
841
|
* Push a chunk of output. The buffer management and onChunk callback run
|
|
807
842
|
* synchronously. File sink writes are deferred and serialized internally.
|
|
808
843
|
*/
|
|
809
844
|
push(chunk: string): void {
|
|
810
|
-
chunk = sanitizeWithOptionalSixelPassthrough(chunk, sanitizeText);
|
|
845
|
+
chunk = sanitizeWithOptionalSixelPassthrough(chunk, text => sanitizeText(this.#normalizeCarriageReturns(text)));
|
|
811
846
|
|
|
812
847
|
// Throttled onChunk: coalesce chunks arriving inside the throttle window.
|
|
813
848
|
// A timer flushes quiet tails at the throttle boundary; dump() catches a
|
|
@@ -1137,6 +1172,7 @@ export class OutputSink {
|
|
|
1137
1172
|
this.#columnDroppedBytes = 0;
|
|
1138
1173
|
this.#columnTruncatedLines = 0;
|
|
1139
1174
|
this.#pendingChunk = "";
|
|
1175
|
+
this.#pendingCarriageReturn = false;
|
|
1140
1176
|
}
|
|
1141
1177
|
|
|
1142
1178
|
#clearPendingChunkTimer(): void {
|
|
@@ -1208,6 +1244,10 @@ export class OutputSink {
|
|
|
1208
1244
|
}
|
|
1209
1245
|
|
|
1210
1246
|
async dump(notice?: string): Promise<OutputSummary> {
|
|
1247
|
+
if (this.#pendingCarriageReturn) {
|
|
1248
|
+
this.#pendingCarriageReturn = false;
|
|
1249
|
+
this.push(NL);
|
|
1250
|
+
}
|
|
1211
1251
|
const noticeLine = notice ? `[${notice}]\n` : "";
|
|
1212
1252
|
|
|
1213
1253
|
// Flush any chunk still held back by the throttle so the live preview
|
|
@@ -1389,6 +1389,7 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1389
1389
|
},
|
|
1390
1390
|
{
|
|
1391
1391
|
name: "new",
|
|
1392
|
+
aliases: ["clear"],
|
|
1392
1393
|
description: "Start a new session",
|
|
1393
1394
|
handleTui: async (_command, runtime) => {
|
|
1394
1395
|
runtime.ctx.editor.setText("");
|
|
@@ -1704,6 +1705,11 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1704
1705
|
} catch {
|
|
1705
1706
|
return usage(`Directory does not exist: ${resolvedPath}`, runtime);
|
|
1706
1707
|
}
|
|
1708
|
+
try {
|
|
1709
|
+
await runtime.settings.flush();
|
|
1710
|
+
} catch (err) {
|
|
1711
|
+
return usage(`Failed to save pending settings: ${errorMessage(err)}`, runtime);
|
|
1712
|
+
}
|
|
1707
1713
|
try {
|
|
1708
1714
|
await runtime.sessionManager.moveTo(resolvedPath);
|
|
1709
1715
|
} catch (err) {
|
|
@@ -2320,6 +2326,7 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
2320
2326
|
},
|
|
2321
2327
|
{
|
|
2322
2328
|
name: "quit",
|
|
2329
|
+
aliases: ["q"],
|
|
2323
2330
|
description: "Quit the application",
|
|
2324
2331
|
handleTui: shutdownHandlerTui,
|
|
2325
2332
|
},
|
|
@@ -5,6 +5,22 @@ function normalizeIdentityValue(value: unknown): string | undefined {
|
|
|
5
5
|
return typeof value === "string" && value.trim() ? value.trim().toLowerCase() : undefined;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Session marker label for an active OAuth identity: the base identifier
|
|
10
|
+
* (email → accountId → projectId) suffixed with the organization when present
|
|
11
|
+
* and distinct. Same-email Anthropic multi-org accounts share the base, so the
|
|
12
|
+
* org suffix is the only field that tells the session's quota pool apart —
|
|
13
|
+
* mirrors the account-list rows (`formatUsageReportAccount`) and login success.
|
|
14
|
+
* Returns `undefined` when no identifier is recoverable.
|
|
15
|
+
*/
|
|
16
|
+
export function formatActiveAccountLabel(identity: OAuthAccountIdentity | undefined): string | undefined {
|
|
17
|
+
if (!identity) return undefined;
|
|
18
|
+
const base = identity.email || identity.accountId || identity.projectId;
|
|
19
|
+
if (!base) return undefined;
|
|
20
|
+
const org = identity.orgName || identity.orgId;
|
|
21
|
+
return org && org !== base ? `${base} (${org})` : base;
|
|
22
|
+
}
|
|
23
|
+
|
|
8
24
|
/**
|
|
9
25
|
* True when a single usage-limit column belongs to the given OAuth identity.
|
|
10
26
|
*
|
package/src/system-prompt.ts
CHANGED
|
@@ -729,13 +729,18 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
|
|
|
729
729
|
if (!toolPromptNames.has(mounted.name)) toolPromptNames.set(mounted.name, mounted.name);
|
|
730
730
|
}
|
|
731
731
|
const toolRefs = Object.fromEntries(toolPromptNames.entries());
|
|
732
|
-
const
|
|
732
|
+
const xdevToolNames = new Set(xdevTools.map(mounted => mounted.name));
|
|
733
|
+
// A direct custom tool can share a name with a retained built-in device.
|
|
734
|
+
// Presence in both toolNames and tools proves it still has a top-level definition.
|
|
735
|
+
const inventoryToolNames =
|
|
736
|
+
xdevToolNames.size === 0 ? toolNames : toolNames.filter(name => tools?.has(name) || !xdevToolNames.has(name));
|
|
737
|
+
const toolInfo = inventoryToolNames.map(name => ({
|
|
733
738
|
name: toolPromptNames.get(name) ?? name,
|
|
734
739
|
internalName: name,
|
|
735
740
|
label: tools?.get(name)?.label ?? "",
|
|
736
741
|
description: tools?.get(name)?.description ?? "",
|
|
737
742
|
}));
|
|
738
|
-
const inventoryTools =
|
|
743
|
+
const inventoryTools = inventoryToolNames.map(name => {
|
|
739
744
|
const meta = tools?.get(name);
|
|
740
745
|
return {
|
|
741
746
|
name: toolPromptNames.get(name) ?? name,
|
package/src/task/executor.ts
CHANGED
|
@@ -61,6 +61,9 @@ import {
|
|
|
61
61
|
MAX_OUTPUT_BYTES,
|
|
62
62
|
MAX_OUTPUT_LINES,
|
|
63
63
|
type SingleResult,
|
|
64
|
+
type StructuredSubagentOutput,
|
|
65
|
+
type StructuredSubagentSchemaMode,
|
|
66
|
+
type StructuredSubagentSchemaSource,
|
|
64
67
|
TASK_SUBAGENT_EVENT_CHANNEL,
|
|
65
68
|
TASK_SUBAGENT_LIFECYCLE_CHANNEL,
|
|
66
69
|
TASK_SUBAGENT_PROGRESS_CHANNEL,
|
|
@@ -292,7 +295,12 @@ export interface ExecutorOptions {
|
|
|
292
295
|
*/
|
|
293
296
|
parentActiveModelPattern?: string;
|
|
294
297
|
thinkingLevel?: ConfiguredThinkingLevel;
|
|
298
|
+
/** Schema used to validate the final structured completion. */
|
|
295
299
|
outputSchema?: unknown;
|
|
300
|
+
/** Enforcement policy for {@link outputSchema}; defaults to legacy permissive behavior. */
|
|
301
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
302
|
+
/** Origin of the selected schema, preserved in {@link SingleResult.structuredOutput}. */
|
|
303
|
+
outputSchemaSource?: StructuredSubagentSchemaSource;
|
|
296
304
|
/**
|
|
297
305
|
* Caller supplied a schema that supersedes the agent's native output prompt.
|
|
298
306
|
* Eval `agent(..., schema=...)` sets this so built-in agents ignore stale yield labels.
|
|
@@ -307,7 +315,20 @@ export interface ExecutorOptions {
|
|
|
307
315
|
* watchdog is already suspended for the call's duration.
|
|
308
316
|
*/
|
|
309
317
|
maxRuntimeMs?: number;
|
|
318
|
+
/** Include IRC only when the invocation policy permits collaboration. */
|
|
319
|
+
enableIrc?: boolean;
|
|
310
320
|
enableLsp?: boolean;
|
|
321
|
+
/**
|
|
322
|
+
* Enable MCP capabilities for this child. `false` suppresses both inherited
|
|
323
|
+
* MCP proxy tools and session MCP discovery; it never consults the
|
|
324
|
+
* process-global MCP manager. Defaults to `true`.
|
|
325
|
+
*/
|
|
326
|
+
enableMCP?: boolean;
|
|
327
|
+
/**
|
|
328
|
+
* Limit the child to its explicit host tool names and the required yield
|
|
329
|
+
* tool, suppressing discovered and always-included capabilities.
|
|
330
|
+
*/
|
|
331
|
+
restrictToolNames?: boolean;
|
|
311
332
|
signal?: AbortSignal;
|
|
312
333
|
onProgress?: (progress: AgentProgress) => void;
|
|
313
334
|
/**
|
|
@@ -450,6 +471,8 @@ interface FinalizeSubprocessOutputArgs {
|
|
|
450
471
|
signalAborted: boolean;
|
|
451
472
|
yieldItems?: YieldItem[];
|
|
452
473
|
outputSchema: unknown;
|
|
474
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
475
|
+
outputSchemaSource?: StructuredSubagentSchemaSource;
|
|
453
476
|
lastAssistantText?: string;
|
|
454
477
|
}
|
|
455
478
|
|
|
@@ -459,6 +482,7 @@ interface FinalizeSubprocessOutputResult {
|
|
|
459
482
|
stderr: string;
|
|
460
483
|
abortedViaYield: boolean;
|
|
461
484
|
hasYield: boolean;
|
|
485
|
+
structuredOutput?: StructuredSubagentOutput;
|
|
462
486
|
}
|
|
463
487
|
export const SUBAGENT_WARNING_SCHEMA_OVERRIDDEN =
|
|
464
488
|
"SYSTEM WARNING: Subagent exhausted schema-retry budget; result was accepted despite failing the output schema.";
|
|
@@ -494,6 +518,10 @@ function buildSchemaViolationOutcome(
|
|
|
494
518
|
export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult {
|
|
495
519
|
let { rawOutput, exitCode, stderr } = args;
|
|
496
520
|
const { yieldItems, doneAborted, signalAborted, outputSchema, lastAssistantText } = args;
|
|
521
|
+
const mode = args.outputSchemaMode ?? "permissive";
|
|
522
|
+
const source = args.outputSchemaSource ?? (outputSchema === undefined ? "none" : "session");
|
|
523
|
+
const includeStructuredOutput = source !== "none";
|
|
524
|
+
let structuredOutput: StructuredSubagentOutput | undefined;
|
|
497
525
|
let abortedViaYield = false;
|
|
498
526
|
const hasYield = Array.isArray(yieldItems) && yieldItems.length > 0;
|
|
499
527
|
const hadFailureBeforeYield = exitCode !== 0 && stderr.trim().length > 0;
|
|
@@ -514,15 +542,35 @@ export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): Fi
|
|
|
514
542
|
if (!assembled || assembled.missingData) {
|
|
515
543
|
rawOutput = rawOutput ? `${SUBAGENT_WARNING_NULL_YIELD}\n\n${rawOutput}` : SUBAGENT_WARNING_NULL_YIELD;
|
|
516
544
|
} else {
|
|
517
|
-
const { validator, error: schemaError } = buildOutputValidator(outputSchema);
|
|
545
|
+
const { validator, error: schemaError, normalized } = buildOutputValidator(outputSchema);
|
|
518
546
|
const completeData = assembled.rawText ? assembled.data : parseStringifiedJson(assembled.data ?? null);
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
547
|
+
const validation = validator?.validate(completeData);
|
|
548
|
+
const failure =
|
|
549
|
+
validation && !validation.success
|
|
550
|
+
? summarizeValidationFailure(validation, completeData, validator?.requiredFields ?? [])
|
|
551
|
+
: assembled.schemaOverridden
|
|
552
|
+
? { message: SUBAGENT_WARNING_SCHEMA_OVERRIDDEN, missingRequired: [] }
|
|
553
|
+
: schemaError
|
|
554
|
+
? { message: `invalid output schema: ${schemaError}`, missingRequired: [] }
|
|
555
|
+
: undefined;
|
|
556
|
+
if (includeStructuredOutput) {
|
|
557
|
+
structuredOutput =
|
|
558
|
+
schemaError || normalized === undefined
|
|
559
|
+
? {
|
|
560
|
+
source,
|
|
561
|
+
mode,
|
|
562
|
+
status: "unavailable",
|
|
563
|
+
data: completeData,
|
|
564
|
+
error: schemaError ? `invalid output schema: ${schemaError}` : undefined,
|
|
565
|
+
}
|
|
566
|
+
: failure
|
|
567
|
+
? { source, mode, status: "invalid", data: completeData, error: failure.message }
|
|
568
|
+
: { source, mode, status: "valid", data: completeData };
|
|
569
|
+
}
|
|
570
|
+
const mustReject =
|
|
571
|
+
failure !== undefined && (mode === "strict" || (!assembled.schemaOverridden && !schemaError));
|
|
572
|
+
if (mustReject && failure) {
|
|
573
|
+
const outcome = buildSchemaViolationOutcome(failure, completeData);
|
|
526
574
|
rawOutput = outcome.rawOutput;
|
|
527
575
|
stderr = outcome.stderr;
|
|
528
576
|
exitCode = outcome.exitCode;
|
|
@@ -540,9 +588,7 @@ export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): Fi
|
|
|
540
588
|
exitCode = 0;
|
|
541
589
|
stderr = assembled.schemaOverridden
|
|
542
590
|
? SUBAGENT_WARNING_SCHEMA_OVERRIDDEN
|
|
543
|
-
:
|
|
544
|
-
? `invalid output schema: ${schemaError}`
|
|
545
|
-
: "";
|
|
591
|
+
: (structuredOutput?.error ?? "");
|
|
546
592
|
} else if (!stderr) {
|
|
547
593
|
stderr = "Subagent failed after yielding a result.";
|
|
548
594
|
}
|
|
@@ -560,11 +606,22 @@ export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): Fi
|
|
|
560
606
|
const result = validator?.validate(completeData) ?? { success: true as const };
|
|
561
607
|
if (!result.success) {
|
|
562
608
|
const summary = summarizeValidationFailure(result, completeData, validator?.requiredFields ?? []);
|
|
609
|
+
if (includeStructuredOutput) {
|
|
610
|
+
structuredOutput = { source, mode, status: "invalid", data: completeData, error: summary.message };
|
|
611
|
+
}
|
|
563
612
|
const outcome = buildSchemaViolationOutcome(summary, completeData);
|
|
564
613
|
rawOutput = outcome.rawOutput;
|
|
565
614
|
stderr = outcome.stderr;
|
|
566
615
|
exitCode = outcome.exitCode;
|
|
567
616
|
} else {
|
|
617
|
+
if (includeStructuredOutput) {
|
|
618
|
+
structuredOutput = {
|
|
619
|
+
source,
|
|
620
|
+
mode,
|
|
621
|
+
status: "valid",
|
|
622
|
+
data: completeData,
|
|
623
|
+
};
|
|
624
|
+
}
|
|
568
625
|
try {
|
|
569
626
|
rawOutput = JSON.stringify(completeData, null, 2) ?? "null";
|
|
570
627
|
} catch (err) {
|
|
@@ -587,7 +644,7 @@ export function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): Fi
|
|
|
587
644
|
}
|
|
588
645
|
}
|
|
589
646
|
|
|
590
|
-
return { rawOutput, exitCode, stderr, abortedViaYield, hasYield };
|
|
647
|
+
return { rawOutput, exitCode, stderr, abortedViaYield, hasYield, structuredOutput };
|
|
591
648
|
}
|
|
592
649
|
|
|
593
650
|
/**
|
|
@@ -1052,7 +1109,7 @@ function createSubagentRunMonitor(args: RunMonitorArgs): SubagentRunMonitor {
|
|
|
1052
1109
|
// failures just leave the label unset.
|
|
1053
1110
|
const labelSource = assignment?.trim();
|
|
1054
1111
|
if (!args.description && args.modelRegistry && args.settings && labelSource) {
|
|
1055
|
-
generateTaskLabel(labelSource, args.modelRegistry, args.settings, id)
|
|
1112
|
+
generateTaskLabel(labelSource, args.modelRegistry, args.settings, id, abortSignal)
|
|
1056
1113
|
.then(label => {
|
|
1057
1114
|
if (!label || abortSignal.aborted || progress.description) return;
|
|
1058
1115
|
progress.description = label;
|
|
@@ -1710,6 +1767,8 @@ interface FinalizeRunArgs {
|
|
|
1710
1767
|
assignment?: string;
|
|
1711
1768
|
modelOverride?: string | string[];
|
|
1712
1769
|
outputSchema?: unknown;
|
|
1770
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
1771
|
+
outputSchemaSource?: StructuredSubagentSchemaSource;
|
|
1713
1772
|
signal?: AbortSignal;
|
|
1714
1773
|
artifactsDir?: string;
|
|
1715
1774
|
eventBus?: EventBus;
|
|
@@ -1747,6 +1806,8 @@ async function finalizeRunResult(args: FinalizeRunArgs): Promise<SingleResult> {
|
|
|
1747
1806
|
signalAborted: Boolean(signal?.aborted),
|
|
1748
1807
|
yieldItems,
|
|
1749
1808
|
outputSchema: args.outputSchema,
|
|
1809
|
+
outputSchemaMode: args.outputSchemaMode,
|
|
1810
|
+
outputSchemaSource: args.outputSchemaSource,
|
|
1750
1811
|
lastAssistantText: monitor.lastAssistantSalvageText(),
|
|
1751
1812
|
});
|
|
1752
1813
|
} finally {
|
|
@@ -1841,6 +1902,7 @@ async function finalizeRunResult(args: FinalizeRunArgs): Promise<SingleResult> {
|
|
|
1841
1902
|
output: truncatedOutput,
|
|
1842
1903
|
stderr,
|
|
1843
1904
|
truncated: Boolean(truncated),
|
|
1905
|
+
...(finalized.structuredOutput ? { structuredOutput: finalized.structuredOutput } : {}),
|
|
1844
1906
|
durationMs: Date.now() - args.startTime,
|
|
1845
1907
|
tokens: progress.tokens,
|
|
1846
1908
|
requests: progress.requests,
|
|
@@ -1935,6 +1997,10 @@ export interface FollowUpTurnOptions {
|
|
|
1935
1997
|
message: string;
|
|
1936
1998
|
index?: number;
|
|
1937
1999
|
description?: string;
|
|
2000
|
+
/** Structured-output state retained from the original invocation. */
|
|
2001
|
+
outputSchema?: unknown;
|
|
2002
|
+
outputSchemaMode?: StructuredSubagentSchemaMode;
|
|
2003
|
+
outputSchemaSource?: StructuredSubagentSchemaSource;
|
|
1938
2004
|
signal?: AbortSignal;
|
|
1939
2005
|
onProgress?: (progress: AgentProgress) => void;
|
|
1940
2006
|
eventBus?: EventBus;
|
|
@@ -2019,6 +2085,9 @@ export async function runSubagentFollowUpTurn(options: FollowUpTurnOptions): Pro
|
|
|
2019
2085
|
id,
|
|
2020
2086
|
agent,
|
|
2021
2087
|
task: message,
|
|
2088
|
+
outputSchema: options.outputSchema,
|
|
2089
|
+
outputSchemaMode: options.outputSchemaMode,
|
|
2090
|
+
outputSchemaSource: options.outputSchemaSource,
|
|
2022
2091
|
signal,
|
|
2023
2092
|
artifactsDir: options.artifactsDir,
|
|
2024
2093
|
eventBus: options.eventBus,
|
|
@@ -2107,6 +2176,7 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2107
2176
|
const parentDepth = options.taskDepth ?? 0;
|
|
2108
2177
|
const childDepth = parentDepth + 1;
|
|
2109
2178
|
const atMaxDepth = maxRecursionDepth >= 0 && childDepth >= maxRecursionDepth;
|
|
2179
|
+
const ircEnabled = options.enableIrc !== false && isIrcEnabled(subagentSettings, childDepth);
|
|
2110
2180
|
|
|
2111
2181
|
// Add tools if specified
|
|
2112
2182
|
let toolNames: string[] | undefined;
|
|
@@ -2121,9 +2191,9 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2121
2191
|
if (atMaxDepth && toolNames?.includes("task")) {
|
|
2122
2192
|
toolNames = toolNames.filter(name => name !== "task");
|
|
2123
2193
|
}
|
|
2124
|
-
//
|
|
2125
|
-
//
|
|
2126
|
-
if (toolNames && !toolNames.includes("hub")) {
|
|
2194
|
+
// Ordinary agents retain the host's always-on collaboration capability.
|
|
2195
|
+
// Restricted sessions must not widen their explicit host tool list with hub.
|
|
2196
|
+
if (toolNames && !options.restrictToolNames && !toolNames.includes("hub")) {
|
|
2127
2197
|
toolNames = [...toolNames, "hub"];
|
|
2128
2198
|
}
|
|
2129
2199
|
if (toolNames?.includes("exec")) {
|
|
@@ -2145,7 +2215,6 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2145
2215
|
: agent.spawns.join(",");
|
|
2146
2216
|
|
|
2147
2217
|
const lspEnabled = enableLsp ?? true;
|
|
2148
|
-
const ircEnabled = isIrcEnabled(subagentSettings, childDepth);
|
|
2149
2218
|
const skipPythonPreflight = Array.isArray(toolNames) && !toolNames.includes("eval");
|
|
2150
2219
|
|
|
2151
2220
|
const monitor = createSubagentRunMonitor({
|
|
@@ -2354,8 +2423,10 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2354
2423
|
}
|
|
2355
2424
|
sessionOpenedAt = performance.now();
|
|
2356
2425
|
|
|
2357
|
-
const
|
|
2358
|
-
const enableMCP = !options.
|
|
2426
|
+
const restrictToolNames = options.restrictToolNames === true;
|
|
2427
|
+
const enableMCP = !restrictToolNames && (options.enableMCP ?? true);
|
|
2428
|
+
const mcpManager = enableMCP ? options.mcpManager : undefined;
|
|
2429
|
+
const mcpProxyTools = mcpManager ? createMCPProxyTools(mcpManager) : [];
|
|
2359
2430
|
|
|
2360
2431
|
// Derive subagent-scoped telemetry from the parent's config so the
|
|
2361
2432
|
// child loop's spans nest under the parent's active execute_tool span
|
|
@@ -2411,14 +2482,16 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2411
2482
|
thinkingLevel: effectiveThinkingLevel,
|
|
2412
2483
|
toolNames,
|
|
2413
2484
|
outputSchema,
|
|
2485
|
+
outputSchemaMode: options.outputSchemaMode,
|
|
2486
|
+
restrictToolNames: options.restrictToolNames,
|
|
2414
2487
|
requireYieldTool: true,
|
|
2415
2488
|
contextFiles: options.contextFiles,
|
|
2416
2489
|
skills: options.skills,
|
|
2417
2490
|
promptTemplates: options.promptTemplates,
|
|
2418
2491
|
workspaceTree: options.workspaceTree,
|
|
2419
2492
|
rules: options.rules,
|
|
2420
|
-
preloadedExtensionPaths: options.preloadedExtensionPaths,
|
|
2421
|
-
preloadedCustomToolPaths: options.preloadedCustomToolPaths,
|
|
2493
|
+
preloadedExtensionPaths: restrictToolNames ? [] : options.preloadedExtensionPaths,
|
|
2494
|
+
preloadedCustomToolPaths: restrictToolNames ? [] : options.preloadedCustomToolPaths,
|
|
2422
2495
|
systemPrompt: defaultPrompt => {
|
|
2423
2496
|
const subagentPrompt = prompt.render(subagentSystemPromptTemplate, {
|
|
2424
2497
|
agent: agent.systemPrompt,
|
|
@@ -2447,9 +2520,10 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2447
2520
|
agentId: id,
|
|
2448
2521
|
agentDisplayName: agent.name,
|
|
2449
2522
|
enableLsp: lspEnabled,
|
|
2523
|
+
enableIrc: options.enableIrc,
|
|
2450
2524
|
skipPythonPreflight,
|
|
2451
2525
|
enableMCP,
|
|
2452
|
-
mcpManager
|
|
2526
|
+
mcpManager,
|
|
2453
2527
|
customTools: mcpProxyTools.length > 0 ? mcpProxyTools : undefined,
|
|
2454
2528
|
localProtocolOptions: options.localProtocolOptions,
|
|
2455
2529
|
telemetry: subagentTelemetry,
|
|
@@ -2524,6 +2598,8 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2524
2598
|
spawns: spawnsEnv,
|
|
2525
2599
|
readSummarize: agent.readSummarize,
|
|
2526
2600
|
outputSchema,
|
|
2601
|
+
outputSchemaMode: options.outputSchemaMode,
|
|
2602
|
+
restrictToolNames: restrictToolNames || undefined,
|
|
2527
2603
|
});
|
|
2528
2604
|
|
|
2529
2605
|
abortSignal.addEventListener(
|
|
@@ -2720,6 +2796,8 @@ export async function runSubprocess(options: ExecutorOptions): Promise<SingleRes
|
|
|
2720
2796
|
assignment,
|
|
2721
2797
|
modelOverride,
|
|
2722
2798
|
outputSchema,
|
|
2799
|
+
outputSchemaMode: options.outputSchemaMode,
|
|
2800
|
+
outputSchemaSource: options.outputSchemaSource,
|
|
2723
2801
|
signal,
|
|
2724
2802
|
artifactsDir: options.artifactsDir,
|
|
2725
2803
|
eventBus: options.eventBus,
|