@oh-my-pi/pi-coding-agent 15.3.2 → 15.4.2
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 +110 -0
- package/dist/types/cli/file-processor.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +45 -3
- package/dist/types/config/settings.d.ts +1 -1
- package/dist/types/debug/raw-sse.d.ts +2 -0
- package/dist/types/edit/file-read-cache.d.ts +15 -4
- package/dist/types/edit/index.d.ts +3 -8
- package/dist/types/edit/renderer.d.ts +1 -2
- package/dist/types/eval/__tests__/shared-executors.test.d.ts +1 -0
- package/dist/types/eval/js/shared/local-module-loader.d.ts +16 -0
- package/dist/types/eval/js/shared/rewrite-imports.d.ts +4 -0
- package/dist/types/eval/js/shared/runtime.d.ts +14 -8
- package/dist/types/eval/py/executor.d.ts +1 -2
- package/dist/types/eval/py/kernel.d.ts +6 -0
- package/dist/types/eval/py/tool-bridge.d.ts +1 -5
- package/dist/types/eval/session-id.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +1 -3
- package/dist/types/hashline/anchors.d.ts +15 -9
- package/dist/types/hashline/constants.d.ts +0 -2
- package/dist/types/hashline/diff.d.ts +1 -2
- package/dist/types/hashline/executor.d.ts +52 -0
- package/dist/types/hashline/hash.d.ts +44 -93
- package/dist/types/hashline/index.d.ts +2 -1
- package/dist/types/hashline/input.d.ts +2 -9
- package/dist/types/hashline/recovery.d.ts +3 -9
- package/dist/types/hashline/tokenizer.d.ts +91 -0
- package/dist/types/hashline/types.d.ts +5 -7
- package/dist/types/modes/components/extensions/types.d.ts +0 -4
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +11 -15
- package/dist/types/session/agent-storage.d.ts +11 -10
- package/dist/types/slash-commands/acp-builtins.d.ts +3 -3
- package/dist/types/slash-commands/types.d.ts +0 -5
- package/dist/types/task/executor.d.ts +2 -0
- package/dist/types/tool-discovery/tool-index.d.ts +0 -50
- package/dist/types/tools/index.d.ts +2 -8
- package/dist/types/tools/match-line-format.d.ts +4 -4
- package/dist/types/tools/output-schema-validator.d.ts +64 -0
- package/dist/types/tools/review.d.ts +13 -0
- package/dist/types/tools/search-tool-bm25.d.ts +1 -1
- package/dist/types/tools/search.d.ts +4 -3
- package/dist/types/utils/edit-mode.d.ts +1 -1
- package/dist/types/web/kagi.d.ts +4 -2
- package/dist/types/web/parallel.d.ts +4 -3
- package/dist/types/web/scrapers/types.d.ts +2 -1
- package/dist/types/web/search/index.d.ts +12 -4
- package/dist/types/web/search/provider.d.ts +2 -1
- package/dist/types/web/search/providers/anthropic.d.ts +9 -4
- package/dist/types/web/search/providers/base.d.ts +34 -2
- package/dist/types/web/search/providers/brave.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +13 -9
- package/dist/types/web/search/providers/exa.d.ts +10 -1
- package/dist/types/web/search/providers/gemini.d.ts +20 -23
- package/dist/types/web/search/providers/jina.d.ts +2 -1
- package/dist/types/web/search/providers/kagi.d.ts +4 -1
- package/dist/types/web/search/providers/kimi.d.ts +10 -1
- package/dist/types/web/search/providers/parallel.d.ts +3 -2
- package/dist/types/web/search/providers/perplexity.d.ts +5 -2
- package/dist/types/web/search/providers/searxng.d.ts +2 -1
- package/dist/types/web/search/providers/synthetic.d.ts +5 -8
- package/dist/types/web/search/providers/tavily.d.ts +11 -4
- package/dist/types/web/search/providers/utils.d.ts +8 -6
- package/dist/types/web/search/providers/zai.d.ts +12 -3
- package/package.json +7 -7
- package/src/cli/file-processor.ts +12 -2
- package/src/cli.ts +0 -8
- package/src/commands/commit.ts +8 -8
- package/src/config/prompt-templates.ts +6 -6
- package/src/config/settings-schema.ts +47 -3
- package/src/config/settings.ts +5 -5
- package/src/debug/raw-sse.ts +68 -3
- package/src/edit/file-read-cache.ts +68 -25
- package/src/edit/index.ts +6 -37
- package/src/edit/renderer.ts +9 -47
- package/src/edit/streaming.ts +43 -56
- package/src/eval/__tests__/shared-executors.test.ts +520 -0
- package/src/eval/js/context-manager.ts +64 -53
- package/src/eval/js/shared/local-module-loader.ts +265 -0
- package/src/eval/js/shared/prelude.txt +4 -0
- package/src/eval/js/shared/rewrite-imports.ts +85 -0
- package/src/eval/js/shared/runtime.ts +129 -86
- package/src/eval/js/worker-core.ts +23 -38
- package/src/eval/py/executor.ts +155 -84
- package/src/eval/py/kernel.ts +10 -1
- package/src/eval/py/prelude.py +22 -24
- package/src/eval/py/runner.py +203 -85
- package/src/eval/py/tool-bridge.ts +17 -10
- package/src/eval/session-id.ts +8 -0
- package/src/exec/bash-executor.ts +27 -16
- package/src/extensibility/extensions/runner.ts +0 -1
- package/src/extensibility/extensions/types.ts +1 -3
- package/src/hashline/anchors.ts +56 -65
- package/src/hashline/apply.ts +29 -31
- package/src/hashline/constants.ts +0 -3
- package/src/hashline/diff-preview.ts +4 -5
- package/src/hashline/diff.ts +30 -4
- package/src/hashline/execute.ts +91 -26
- package/src/hashline/executor.ts +239 -0
- package/src/hashline/grammar.lark +12 -10
- package/src/hashline/hash.ts +69 -114
- package/src/hashline/index.ts +2 -1
- package/src/hashline/input.ts +48 -41
- package/src/hashline/prefixes.ts +21 -11
- package/src/hashline/recovery.ts +63 -71
- package/src/hashline/stream.ts +2 -2
- package/src/hashline/tokenizer.ts +467 -0
- package/src/hashline/types.ts +6 -8
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/modes/components/extensions/types.ts +0 -5
- package/src/modes/components/session-observer-overlay.ts +11 -2
- package/src/modes/components/settings-selector.ts +10 -1
- package/src/modes/components/tree-selector.ts +10 -2
- package/src/modes/controllers/command-controller.ts +1 -3
- package/src/modes/controllers/extension-ui-controller.ts +10 -11
- package/src/modes/controllers/selector-controller.ts +5 -5
- package/src/modes/theme/theme.ts +4 -2
- package/src/modes/types.ts +4 -1
- package/src/modes/utils/ui-helpers.ts +4 -0
- package/src/prompts/agents/explore.md +1 -1
- package/src/prompts/tools/ast-edit.md +1 -1
- package/src/prompts/tools/ast-grep.md +1 -1
- package/src/prompts/tools/eval.md +1 -1
- package/src/prompts/tools/hashline.md +73 -94
- package/src/prompts/tools/read.md +4 -4
- package/src/prompts/tools/search.md +3 -3
- package/src/sdk.ts +33 -26
- package/src/session/agent-session.ts +59 -66
- package/src/session/agent-storage.ts +13 -14
- package/src/slash-commands/acp-builtins.ts +3 -3
- package/src/slash-commands/types.ts +0 -6
- package/src/task/executor.ts +26 -57
- package/src/task/index.ts +8 -4
- package/src/tool-discovery/tool-index.ts +0 -134
- package/src/tools/ast-edit.ts +36 -13
- package/src/tools/ast-grep.ts +45 -4
- package/src/tools/browser/tab-worker.ts +3 -2
- package/src/tools/eval.ts +2 -1
- package/src/tools/fetch.ts +23 -14
- package/src/tools/index.ts +2 -8
- package/src/tools/irc.ts +59 -5
- package/src/tools/match-line-format.ts +5 -7
- package/src/tools/output-schema-validator.ts +132 -0
- package/src/tools/read.ts +142 -31
- package/src/tools/review.ts +23 -0
- package/src/tools/search-tool-bm25.ts +3 -30
- package/src/tools/search.ts +48 -16
- package/src/tools/write.ts +3 -3
- package/src/tools/yield.ts +32 -41
- package/src/utils/edit-mode.ts +1 -2
- package/src/utils/file-mentions.ts +2 -2
- package/src/web/kagi.ts +15 -6
- package/src/web/parallel.ts +9 -6
- package/src/web/scrapers/types.ts +7 -1
- package/src/web/scrapers/youtube.ts +13 -7
- package/src/web/search/index.ts +37 -11
- package/src/web/search/provider.ts +5 -3
- package/src/web/search/providers/anthropic.ts +30 -21
- package/src/web/search/providers/base.ts +35 -2
- package/src/web/search/providers/brave.ts +4 -4
- package/src/web/search/providers/codex.ts +118 -89
- package/src/web/search/providers/exa.ts +3 -2
- package/src/web/search/providers/gemini.ts +58 -155
- package/src/web/search/providers/jina.ts +4 -4
- package/src/web/search/providers/kagi.ts +17 -11
- package/src/web/search/providers/kimi.ts +29 -13
- package/src/web/search/providers/parallel.ts +171 -23
- package/src/web/search/providers/perplexity.ts +38 -37
- package/src/web/search/providers/searxng.ts +3 -1
- package/src/web/search/providers/synthetic.ts +16 -19
- package/src/web/search/providers/tavily.ts +23 -18
- package/src/web/search/providers/utils.ts +11 -17
- package/src/web/search/providers/zai.ts +16 -8
- package/dist/types/hashline/parser.d.ts +0 -7
- package/dist/types/mcp/discoverable-tool-metadata.d.ts +0 -7
- package/dist/types/tools/vim.d.ts +0 -58
- package/dist/types/vim/buffer.d.ts +0 -41
- package/dist/types/vim/commands.d.ts +0 -6
- package/dist/types/vim/engine.d.ts +0 -47
- package/dist/types/vim/parser.d.ts +0 -3
- package/dist/types/vim/render.d.ts +0 -25
- package/dist/types/vim/types.d.ts +0 -182
- package/src/hashline/parser.ts +0 -246
- package/src/mcp/discoverable-tool-metadata.ts +0 -24
- package/src/prompts/tools/vim.md +0 -98
- package/src/tools/vim.ts +0 -949
- package/src/vim/buffer.ts +0 -309
- package/src/vim/commands.ts +0 -382
- package/src/vim/engine.ts +0 -2409
- package/src/vim/parser.ts +0 -134
- package/src/vim/render.ts +0 -252
- package/src/vim/types.ts +0 -197
package/src/sdk.ts
CHANGED
|
@@ -51,6 +51,7 @@ import "./discovery";
|
|
|
51
51
|
import { resolveConfigValue } from "./config/resolve-config-value";
|
|
52
52
|
import { initializeWithSettings } from "./discovery";
|
|
53
53
|
import { disposeAllKernelSessions, disposeKernelSessionsByOwner } from "./eval/py/executor";
|
|
54
|
+
import { defaultEvalSessionId } from "./eval/session-id";
|
|
54
55
|
import { TtsrManager } from "./export/ttsr";
|
|
55
56
|
import {
|
|
56
57
|
type CustomCommandsLoadResult,
|
|
@@ -84,11 +85,7 @@ import type { HindsightSessionState } from "./hindsight/state";
|
|
|
84
85
|
import { LocalProtocolHandler, type LocalProtocolOptions } from "./internal-urls";
|
|
85
86
|
import { LSP_STARTUP_EVENT_CHANNEL, type LspStartupEvent } from "./lsp/startup-events";
|
|
86
87
|
import { discoverAndLoadMCPTools, MCPManager, type MCPToolsLoadResult } from "./mcp";
|
|
87
|
-
|
|
88
|
-
collectDiscoverableMCPTools,
|
|
89
|
-
formatDiscoverableMCPToolServerSummary,
|
|
90
|
-
selectDiscoverableMCPToolNamesByServer,
|
|
91
|
-
} from "./mcp/discoverable-tool-metadata";
|
|
88
|
+
|
|
92
89
|
import { resolveMemoryBackend } from "./memory-backend";
|
|
93
90
|
import asyncResultTemplate from "./prompts/tools/async-result.md" with { type: "text" };
|
|
94
91
|
import { AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
|
|
@@ -117,6 +114,9 @@ import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } f
|
|
|
117
114
|
import {
|
|
118
115
|
collectDiscoverableTools,
|
|
119
116
|
type DiscoverableTool,
|
|
117
|
+
filterBySource,
|
|
118
|
+
formatDiscoverableToolServerSummary,
|
|
119
|
+
selectDiscoverableToolNamesByServer,
|
|
120
120
|
summarizeDiscoverableTools,
|
|
121
121
|
} from "./tool-discovery/tool-index";
|
|
122
122
|
import {
|
|
@@ -318,6 +318,8 @@ export interface CreateAgentSessionOptions {
|
|
|
318
318
|
agentRegistry?: AgentRegistry;
|
|
319
319
|
/** Parent task ID prefix for nested artifact naming (e.g., "6-Extensions") */
|
|
320
320
|
parentTaskPrefix?: string;
|
|
321
|
+
/** Inherited eval executor session id for subagents sharing parent eval state. */
|
|
322
|
+
parentEvalSessionId?: string;
|
|
321
323
|
|
|
322
324
|
/** Session manager. Default: session stored under the configured agentDir sessions root */
|
|
323
325
|
sessionManager?: SessionManager;
|
|
@@ -1177,6 +1179,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1177
1179
|
taskDepth: options.taskDepth ?? 0,
|
|
1178
1180
|
getSessionFile: () => sessionManager.getSessionFile() ?? null,
|
|
1179
1181
|
getEvalKernelOwnerId: () => evalKernelOwnerId,
|
|
1182
|
+
getEvalSessionId: () =>
|
|
1183
|
+
session?.getEvalSessionId() ?? options.parentEvalSessionId ?? defaultEvalSessionId(toolSession),
|
|
1180
1184
|
assertEvalExecutionAllowed: () => session?.assertEvalExecutionAllowed(),
|
|
1181
1185
|
trackEvalExecution: (execution, abortController) =>
|
|
1182
1186
|
session ? session.trackEvalExecution(execution, abortController) : execution,
|
|
@@ -1196,8 +1200,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1196
1200
|
getTodoPhases: () => session.getTodoPhases(),
|
|
1197
1201
|
setTodoPhases: phases => session.setTodoPhases(phases),
|
|
1198
1202
|
isMCPDiscoveryEnabled: () => session.isMCPDiscoveryEnabled(),
|
|
1199
|
-
getDiscoverableMCPTools: () => session.getDiscoverableMCPTools(),
|
|
1200
|
-
getDiscoverableMCPSearchIndex: () => session.getDiscoverableMCPSearchIndex(),
|
|
1201
1203
|
getSelectedMCPToolNames: () => session.getSelectedMCPToolNames(),
|
|
1202
1204
|
activateDiscoveredMCPTools: toolNames => session.activateDiscoveredMCPTools(toolNames),
|
|
1203
1205
|
// Generic tool discovery (unified — covers built-in + MCP + extension)
|
|
@@ -1581,7 +1583,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1581
1583
|
tools: Map<string, AgentTool>,
|
|
1582
1584
|
): Promise<BuildSystemPromptResult> => {
|
|
1583
1585
|
toolContextStore.setToolNames(toolNames);
|
|
1584
|
-
const discoverableMCPTools = mcpDiscoveryEnabled
|
|
1586
|
+
const discoverableMCPTools: DiscoverableTool[] = mcpDiscoveryEnabled
|
|
1587
|
+
? filterBySource(collectDiscoverableTools(tools.values()), "mcp")
|
|
1588
|
+
: [];
|
|
1585
1589
|
const activeToolNames = new Set(toolNames);
|
|
1586
1590
|
const discoverableBuiltinTools: DiscoverableTool[] =
|
|
1587
1591
|
effectiveDiscoveryMode === "all"
|
|
@@ -1592,18 +1596,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1592
1596
|
{ source: "builtin" },
|
|
1593
1597
|
)
|
|
1594
1598
|
: [];
|
|
1595
|
-
const discoverableToolsForDesc: DiscoverableTool[] = [
|
|
1596
|
-
...discoverableBuiltinTools,
|
|
1597
|
-
...discoverableMCPTools.map(t => ({
|
|
1598
|
-
name: t.name,
|
|
1599
|
-
label: t.label,
|
|
1600
|
-
summary: t.description,
|
|
1601
|
-
source: "mcp" as const,
|
|
1602
|
-
serverName: t.serverName,
|
|
1603
|
-
mcpToolName: t.mcpToolName,
|
|
1604
|
-
schemaKeys: t.schemaKeys,
|
|
1605
|
-
})),
|
|
1606
|
-
];
|
|
1599
|
+
const discoverableToolsForDesc: DiscoverableTool[] = [...discoverableBuiltinTools, ...discoverableMCPTools];
|
|
1607
1600
|
const discoverableToolSummary = summarizeDiscoverableTools(discoverableToolsForDesc);
|
|
1608
1601
|
const hasDiscoverableTools =
|
|
1609
1602
|
mcpDiscoveryEnabled && toolNames.includes("search_tool_bm25") && discoverableToolsForDesc.length > 0;
|
|
@@ -1647,7 +1640,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1647
1640
|
repeatToolDescriptions,
|
|
1648
1641
|
intentField,
|
|
1649
1642
|
mcpDiscoveryMode: hasDiscoverableTools,
|
|
1650
|
-
mcpDiscoveryServerSummaries: discoverableToolSummary.servers.map(
|
|
1643
|
+
mcpDiscoveryServerSummaries: discoverableToolSummary.servers.map(formatDiscoverableToolServerSummary),
|
|
1651
1644
|
eagerTasks,
|
|
1652
1645
|
secretsEnabled,
|
|
1653
1646
|
workspaceTree: workspaceTreePromise,
|
|
@@ -1665,9 +1658,22 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1665
1658
|
};
|
|
1666
1659
|
|
|
1667
1660
|
const toolNamesFromRegistry = Array.from(toolRegistry.keys());
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1670
|
-
|
|
1661
|
+
const explicitlyRequestedToolNames = options.toolNames
|
|
1662
|
+
? [...new Set(options.toolNames.map(name => name.toLowerCase()))]
|
|
1663
|
+
: undefined;
|
|
1664
|
+
// When `requireYieldTool` is set, the subagent's prompts and idle-reminders demand a
|
|
1665
|
+
// `yield` call to terminate. The tool registry already includes `yield` (see
|
|
1666
|
+
// `createTools`), but an explicit `toolNames` list would otherwise drop it from the
|
|
1667
|
+
// active set — leaving the model unable to satisfy the contract. Mirror the same
|
|
1668
|
+
// invariant `parseAgentFields` enforces on frontmatter `tools`.
|
|
1669
|
+
if (
|
|
1670
|
+
options.requireYieldTool === true &&
|
|
1671
|
+
explicitlyRequestedToolNames &&
|
|
1672
|
+
!explicitlyRequestedToolNames.includes("yield")
|
|
1673
|
+
) {
|
|
1674
|
+
explicitlyRequestedToolNames.push("yield");
|
|
1675
|
+
}
|
|
1676
|
+
const requestedToolNames = explicitlyRequestedToolNames ?? toolNamesFromRegistry;
|
|
1671
1677
|
const normalizedRequested = requestedToolNames.filter(name => toolRegistry.has(name));
|
|
1672
1678
|
const requestedToolNameSet = new Set(normalizedRequested);
|
|
1673
1679
|
// Effective discovery mode: tools.discoveryMode takes precedence; mcp.discoveryMode is back-compat alias.
|
|
@@ -1693,8 +1699,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1693
1699
|
(settings.get("mcp.discoveryDefaultServers") ?? []).map(serverName => serverName.trim()).filter(Boolean),
|
|
1694
1700
|
);
|
|
1695
1701
|
const discoveryDefaultServerToolNames = mcpDiscoveryEnabled
|
|
1696
|
-
?
|
|
1697
|
-
|
|
1702
|
+
? selectDiscoverableToolNamesByServer(
|
|
1703
|
+
filterBySource(collectDiscoverableTools(toolRegistry.values()), "mcp"),
|
|
1698
1704
|
discoveryDefaultServers,
|
|
1699
1705
|
)
|
|
1700
1706
|
: [];
|
|
@@ -1994,6 +2000,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1994
2000
|
agentId: resolvedAgentId,
|
|
1995
2001
|
agentRegistry,
|
|
1996
2002
|
providerSessionId: options.providerSessionId,
|
|
2003
|
+
parentEvalSessionId: options.parentEvalSessionId,
|
|
1997
2004
|
});
|
|
1998
2005
|
hasSession = true;
|
|
1999
2006
|
if (asyncJobManager) {
|
|
@@ -108,6 +108,7 @@ import {
|
|
|
108
108
|
executePython as executePythonCommand,
|
|
109
109
|
type PythonResult,
|
|
110
110
|
} from "../eval/py/executor";
|
|
111
|
+
import { defaultEvalSessionId } from "../eval/session-id";
|
|
111
112
|
import { type BashResult, executeBash as executeBashCommand } from "../exec/bash-executor";
|
|
112
113
|
import { exportSessionToHtml } from "../export/html";
|
|
113
114
|
import type { TtsrManager, TtsrMatchContext } from "../export/ttsr";
|
|
@@ -141,14 +142,6 @@ import { GoalRuntime } from "../goals/runtime";
|
|
|
141
142
|
import type { Goal, GoalModeState } from "../goals/state";
|
|
142
143
|
import type { HindsightSessionState } from "../hindsight/state";
|
|
143
144
|
import { type LocalProtocolOptions, resolveLocalUrlToPath } from "../internal-urls";
|
|
144
|
-
import {
|
|
145
|
-
buildDiscoverableMCPSearchIndex,
|
|
146
|
-
collectDiscoverableMCPTools,
|
|
147
|
-
type DiscoverableMCPSearchIndex,
|
|
148
|
-
type DiscoverableMCPTool,
|
|
149
|
-
isMCPToolName,
|
|
150
|
-
selectDiscoverableMCPToolNamesByServer,
|
|
151
|
-
} from "../mcp/discoverable-tool-metadata";
|
|
152
145
|
import { resolveMemoryBackend } from "../memory-backend";
|
|
153
146
|
import { getCurrentThemeName, theme } from "../modes/theme/theme";
|
|
154
147
|
import type { PlanModeState } from "../plan-mode/state";
|
|
@@ -171,6 +164,9 @@ import {
|
|
|
171
164
|
collectDiscoverableTools,
|
|
172
165
|
type DiscoverableTool,
|
|
173
166
|
type DiscoverableToolSearchIndex,
|
|
167
|
+
filterBySource,
|
|
168
|
+
isMCPToolName,
|
|
169
|
+
selectDiscoverableToolNamesByServer,
|
|
174
170
|
} from "../tool-discovery/tool-index";
|
|
175
171
|
import { assertEditableFile } from "../tools/auto-generated-guard";
|
|
176
172
|
import type { CheckpointState } from "../tools/checkpoint";
|
|
@@ -312,6 +308,8 @@ export interface AgentSessionConfig {
|
|
|
312
308
|
ttsrManager?: TtsrManager;
|
|
313
309
|
/** Secret obfuscator for deobfuscating streaming edit content */
|
|
314
310
|
obfuscator?: SecretObfuscator;
|
|
311
|
+
/** Inherited eval executor session id from a parent agent. */
|
|
312
|
+
parentEvalSessionId?: string;
|
|
315
313
|
/** Logical owner for retained Python kernels created by this session. */
|
|
316
314
|
evalKernelOwnerId?: string;
|
|
317
315
|
/**
|
|
@@ -808,6 +806,7 @@ export class AgentSession {
|
|
|
808
806
|
// Python execution state
|
|
809
807
|
#evalAbortControllers = new Set<AbortController>();
|
|
810
808
|
#evalKernelOwnerId: string;
|
|
809
|
+
#parentEvalSessionId: string | undefined;
|
|
811
810
|
/**
|
|
812
811
|
* AsyncJobManager owned by this session (top-level only). Subagents leave
|
|
813
812
|
* this undefined and **MUST NOT** dispose the global instance on teardown.
|
|
@@ -865,8 +864,7 @@ export class AgentSession {
|
|
|
865
864
|
*/
|
|
866
865
|
#lastAppliedToolSignature: string | undefined;
|
|
867
866
|
#mcpDiscoveryEnabled = false;
|
|
868
|
-
#discoverableMCPTools = new Map<string,
|
|
869
|
-
#discoverableMCPSearchIndex: DiscoverableMCPSearchIndex | null = null;
|
|
867
|
+
#discoverableMCPTools = new Map<string, DiscoverableTool>();
|
|
870
868
|
#selectedMCPToolNames = new Set<string>();
|
|
871
869
|
// Generic tool discovery (covers built-in + MCP + extension when tools.discoveryMode === "all")
|
|
872
870
|
#discoverableToolSearchIndex: DiscoverableToolSearchIndex | null = null;
|
|
@@ -997,6 +995,7 @@ export class AgentSession {
|
|
|
997
995
|
this.settings = config.settings;
|
|
998
996
|
// Power assertions are taken per turn (see #beginInFlight); nothing acquired here.
|
|
999
997
|
this.#evalKernelOwnerId = config.evalKernelOwnerId ?? `agent-session:${Snowflake.next()}`;
|
|
998
|
+
this.#parentEvalSessionId = config.parentEvalSessionId;
|
|
1000
999
|
this.#ownedAsyncJobManager = config.ownedAsyncJobManager;
|
|
1001
1000
|
this.#scopedModels = config.scopedModels ?? [];
|
|
1002
1001
|
this.#thinkingLevel = config.thinkingLevel;
|
|
@@ -2876,11 +2875,12 @@ export class AgentSession {
|
|
|
2876
2875
|
return this.#retryAttempt;
|
|
2877
2876
|
}
|
|
2878
2877
|
|
|
2879
|
-
#collectDiscoverableMCPToolsFromRegistry(): Map<string,
|
|
2880
|
-
|
|
2878
|
+
#collectDiscoverableMCPToolsFromRegistry(): Map<string, DiscoverableTool> {
|
|
2879
|
+
const mcpTools = filterBySource(collectDiscoverableTools(this.#toolRegistry.values()), "mcp");
|
|
2880
|
+
return new Map(mcpTools.map(tool => [tool.name, tool] as const));
|
|
2881
2881
|
}
|
|
2882
2882
|
|
|
2883
|
-
#setDiscoverableMCPTools(discoverableMCPTools: Map<string,
|
|
2883
|
+
#setDiscoverableMCPTools(discoverableMCPTools: Map<string, DiscoverableTool>): void {
|
|
2884
2884
|
this.#discoverableMCPTools = discoverableMCPTools;
|
|
2885
2885
|
this.#invalidateDiscoveryCaches();
|
|
2886
2886
|
}
|
|
@@ -2889,7 +2889,6 @@ export class AgentSession {
|
|
|
2889
2889
|
* affect which tools should be discoverable: registry mutations (refreshMCPTools,
|
|
2890
2890
|
* refreshRpcHostTools) or active-tool mutations (#applyActiveToolsByName). */
|
|
2891
2891
|
#invalidateDiscoveryCaches(): void {
|
|
2892
|
-
this.#discoverableMCPSearchIndex = null;
|
|
2893
2892
|
this.#discoverableToolSearchIndex = null;
|
|
2894
2893
|
}
|
|
2895
2894
|
|
|
@@ -2900,7 +2899,7 @@ export class AgentSession {
|
|
|
2900
2899
|
#getConfiguredDefaultSelectedMCPToolNames(): string[] {
|
|
2901
2900
|
return this.#filterSelectableMCPToolNames([
|
|
2902
2901
|
...this.#defaultSelectedMCPToolNames,
|
|
2903
|
-
...
|
|
2902
|
+
...selectDiscoverableToolNamesByServer(
|
|
2904
2903
|
this.#discoverableMCPTools.values(),
|
|
2905
2904
|
this.#defaultSelectedMCPServerNames,
|
|
2906
2905
|
),
|
|
@@ -2993,28 +2992,6 @@ export class AgentSession {
|
|
|
2993
2992
|
return this.#mcpDiscoveryEnabled;
|
|
2994
2993
|
}
|
|
2995
2994
|
|
|
2996
|
-
/** @deprecated Use {@link getDiscoverableTools} with `{ source: "mcp" }` instead.
|
|
2997
|
-
* Preserves the legacy `description`-bearing MCP shape for back-compat callers. */
|
|
2998
|
-
getDiscoverableMCPTools(): DiscoverableMCPTool[] {
|
|
2999
|
-
return Array.from(this.#discoverableMCPTools.values()).map(t => ({
|
|
3000
|
-
name: t.name,
|
|
3001
|
-
label: t.label,
|
|
3002
|
-
description: t.description,
|
|
3003
|
-
serverName: t.serverName,
|
|
3004
|
-
mcpToolName: t.mcpToolName,
|
|
3005
|
-
schemaKeys: t.schemaKeys,
|
|
3006
|
-
}));
|
|
3007
|
-
}
|
|
3008
|
-
|
|
3009
|
-
/** @deprecated Use {@link getDiscoverableToolSearchIndex} instead.
|
|
3010
|
-
* Returns the legacy MCP search index whose documents expose `tool.description`. */
|
|
3011
|
-
getDiscoverableMCPSearchIndex(): DiscoverableMCPSearchIndex {
|
|
3012
|
-
if (!this.#discoverableMCPSearchIndex) {
|
|
3013
|
-
this.#discoverableMCPSearchIndex = buildDiscoverableMCPSearchIndex(this.#discoverableMCPTools.values());
|
|
3014
|
-
}
|
|
3015
|
-
return this.#discoverableMCPSearchIndex;
|
|
3016
|
-
}
|
|
3017
|
-
|
|
3018
2995
|
getSelectedMCPToolNames(): string[] {
|
|
3019
2996
|
if (!this.#mcpDiscoveryEnabled) {
|
|
3020
2997
|
return this.getActiveToolNames().filter(name => isMCPToolName(name) && this.#toolRegistry.has(name));
|
|
@@ -3062,17 +3039,7 @@ export class AgentSession {
|
|
|
3062
3039
|
// For "mcp-only" mode we only return MCP tools.
|
|
3063
3040
|
const mode = this.#resolveEffectiveDiscoveryMode();
|
|
3064
3041
|
const activeNames = new Set(this.getActiveToolNames());
|
|
3065
|
-
const mcpTools
|
|
3066
|
-
.filter(t => !activeNames.has(t.name))
|
|
3067
|
-
.map(t => ({
|
|
3068
|
-
name: t.name,
|
|
3069
|
-
label: t.label,
|
|
3070
|
-
summary: t.description,
|
|
3071
|
-
source: "mcp" as const,
|
|
3072
|
-
serverName: t.serverName,
|
|
3073
|
-
mcpToolName: t.mcpToolName,
|
|
3074
|
-
schemaKeys: t.schemaKeys,
|
|
3075
|
-
}));
|
|
3042
|
+
const mcpTools = Array.from(this.#discoverableMCPTools.values()).filter(t => !activeNames.has(t.name));
|
|
3076
3043
|
const builtinTools: DiscoverableTool[] = mode === "all" ? this.#collectDiscoverableBuiltinTools() : [];
|
|
3077
3044
|
const allTools = [...builtinTools, ...mcpTools];
|
|
3078
3045
|
return filter?.source ? allTools.filter(t => t.source === filter.source) : allTools;
|
|
@@ -3693,6 +3660,13 @@ export class AgentSession {
|
|
|
3693
3660
|
get sessionId(): string {
|
|
3694
3661
|
return this.#providerSessionId ?? this.sessionManager.getSessionId();
|
|
3695
3662
|
}
|
|
3663
|
+
getEvalSessionId(): string | null {
|
|
3664
|
+
if (this.#parentEvalSessionId !== undefined) return this.#parentEvalSessionId;
|
|
3665
|
+
return defaultEvalSessionId({
|
|
3666
|
+
cwd: this.sessionManager.getCwd(),
|
|
3667
|
+
getSessionFile: () => this.sessionManager.getSessionFile() ?? null,
|
|
3668
|
+
});
|
|
3669
|
+
}
|
|
3696
3670
|
|
|
3697
3671
|
/** Current session display name, if set */
|
|
3698
3672
|
get sessionName(): string | undefined {
|
|
@@ -4225,7 +4199,6 @@ export class AgentSession {
|
|
|
4225
4199
|
void this.dispose();
|
|
4226
4200
|
process.exit(0);
|
|
4227
4201
|
},
|
|
4228
|
-
hasQueuedMessages: () => this.queuedMessageCount > 0,
|
|
4229
4202
|
getContextUsage: () => this.getContextUsage(),
|
|
4230
4203
|
waitForIdle: () => this.waitForIdle(),
|
|
4231
4204
|
newSession: async options => {
|
|
@@ -4558,11 +4531,11 @@ export class AgentSession {
|
|
|
4558
4531
|
}
|
|
4559
4532
|
|
|
4560
4533
|
/**
|
|
4561
|
-
* Send a user message to the agent.
|
|
4562
|
-
* When
|
|
4534
|
+
* Send a user message to the agent.
|
|
4535
|
+
* When deliverAs is set, queue the message instead of starting a new turn.
|
|
4563
4536
|
*
|
|
4564
4537
|
* @param content User message content (string or content array)
|
|
4565
|
-
* @param options.deliverAs Delivery mode
|
|
4538
|
+
* @param options.deliverAs Delivery mode: "steer" or "followUp"
|
|
4566
4539
|
*/
|
|
4567
4540
|
async sendUserMessage(
|
|
4568
4541
|
content: string | (TextContent | ImageContent)[],
|
|
@@ -4588,10 +4561,18 @@ export class AgentSession {
|
|
|
4588
4561
|
if (images.length === 0) images = undefined;
|
|
4589
4562
|
}
|
|
4590
4563
|
|
|
4564
|
+
if (options?.deliverAs === "followUp") {
|
|
4565
|
+
await this.#queueFollowUp(text, images);
|
|
4566
|
+
return;
|
|
4567
|
+
}
|
|
4568
|
+
if (options?.deliverAs === "steer") {
|
|
4569
|
+
await this.#queueSteer(text, images);
|
|
4570
|
+
return;
|
|
4571
|
+
}
|
|
4572
|
+
|
|
4591
4573
|
// Use prompt() with expandPromptTemplates: false to skip command handling and template expansion
|
|
4592
4574
|
await this.prompt(text, {
|
|
4593
4575
|
expandPromptTemplates: false,
|
|
4594
|
-
streamingBehavior: options?.deliverAs,
|
|
4595
4576
|
images,
|
|
4596
4577
|
});
|
|
4597
4578
|
}
|
|
@@ -6781,10 +6762,11 @@ export class AgentSession {
|
|
|
6781
6762
|
#isTransientTransportErrorMessage(errorMessage: string): boolean {
|
|
6782
6763
|
// Match: overloaded_error, provider returned error, rate limit, 429, 500, 502, 503, 504,
|
|
6783
6764
|
// service unavailable, provider-suggested retry, network/connection/socket errors, fetch failed,
|
|
6784
|
-
// terminated, retry delay exceeded
|
|
6765
|
+
// terminated, retry delay exceeded, Bun HTTP/2 stream resets (RST_STREAM / REFUSED_STREAM /
|
|
6766
|
+
// ENHANCE_YOUR_CALM, surfaced verbatim from src/http/h2_client/dispatch.zig)
|
|
6785
6767
|
return (
|
|
6786
6768
|
isUnexpectedSocketCloseMessage(errorMessage) ||
|
|
6787
|
-
/overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|retry your request|network.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|timed? out|timeout|terminated|retry delay|stream stall|no error details in response/i.test(
|
|
6769
|
+
/overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|retry your request|network.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|timed? out|timeout|terminated|retry delay|stream stall|no error details in response|HTTP2(?:StreamReset|RefusedStream|EnhanceYourCalm)/i.test(
|
|
6788
6770
|
errorMessage,
|
|
6789
6771
|
)
|
|
6790
6772
|
);
|
|
@@ -7421,9 +7403,13 @@ export class AgentSession {
|
|
|
7421
7403
|
}
|
|
7422
7404
|
}
|
|
7423
7405
|
|
|
7424
|
-
// Use the same session ID as eval's Python backend for kernel sharing
|
|
7425
|
-
const
|
|
7426
|
-
|
|
7406
|
+
// Use the same session ID as eval's Python backend for kernel sharing.
|
|
7407
|
+
const sessionId =
|
|
7408
|
+
this.getEvalSessionId() ??
|
|
7409
|
+
defaultEvalSessionId({
|
|
7410
|
+
cwd,
|
|
7411
|
+
getSessionFile: () => this.sessionManager.getSessionFile() ?? null,
|
|
7412
|
+
});
|
|
7427
7413
|
const result = await executePythonCommand(code, {
|
|
7428
7414
|
cwd,
|
|
7429
7415
|
sessionId,
|
|
@@ -7562,11 +7548,11 @@ export class AgentSession {
|
|
|
7562
7548
|
* Generate an ephemeral reply to a background message (e.g. an IRC ping from
|
|
7563
7549
|
* another agent) using this session's current model + system prompt + history.
|
|
7564
7550
|
*
|
|
7565
|
-
* The
|
|
7566
|
-
*
|
|
7567
|
-
*
|
|
7568
|
-
*
|
|
7569
|
-
*
|
|
7551
|
+
* The incoming message is queued for injection into the recipient's persisted
|
|
7552
|
+
* history immediately so timeouts/abort still preserve delivery. The reply is
|
|
7553
|
+
* computed via a side-channel `streamSimple` call (analogous to `/btw`) so it
|
|
7554
|
+
* never blocks on the recipient's in-flight tool calls. When a reply is
|
|
7555
|
+
* generated, it is queued separately. Injection happens immediately when the
|
|
7570
7556
|
* session is idle, otherwise it is deferred until streaming ends.
|
|
7571
7557
|
*/
|
|
7572
7558
|
async respondAsBackground(args: {
|
|
@@ -7595,8 +7581,8 @@ export class AgentSession {
|
|
|
7595
7581
|
timestamp: incomingTimestamp,
|
|
7596
7582
|
});
|
|
7597
7583
|
|
|
7584
|
+
this.#queueBackgroundExchangeInjection([incomingRecord]);
|
|
7598
7585
|
if (!awaitReply) {
|
|
7599
|
-
this.#queueBackgroundExchangeInjection([incomingRecord]);
|
|
7600
7586
|
return { replyText: null };
|
|
7601
7587
|
}
|
|
7602
7588
|
|
|
@@ -7626,7 +7612,7 @@ export class AgentSession {
|
|
|
7626
7612
|
kind: "reply",
|
|
7627
7613
|
timestamp: replyRecord.timestamp,
|
|
7628
7614
|
});
|
|
7629
|
-
this.#queueBackgroundExchangeInjection([
|
|
7615
|
+
this.#queueBackgroundExchangeInjection([replyRecord]);
|
|
7630
7616
|
|
|
7631
7617
|
return { replyText };
|
|
7632
7618
|
}
|
|
@@ -7708,10 +7694,17 @@ export class AgentSession {
|
|
|
7708
7694
|
// removes the surface entirely.
|
|
7709
7695
|
tools: [],
|
|
7710
7696
|
};
|
|
7697
|
+
const cacheSessionId = this.sessionId;
|
|
7711
7698
|
const options = this.prepareSimpleStreamOptions(
|
|
7712
7699
|
{
|
|
7713
7700
|
apiKey,
|
|
7714
|
-
|
|
7701
|
+
// Side-channel turns must not share OpenAI/Codex append-only
|
|
7702
|
+
// conversation state with the main agent turn: IRC and /btw can run
|
|
7703
|
+
// while the main turn is mid-tool-call. Keep the prompt-cache key
|
|
7704
|
+
// stable, but give provider routing a unique request lineage.
|
|
7705
|
+
sessionId: `${cacheSessionId}:side:${Snowflake.next()}`,
|
|
7706
|
+
promptCacheKey: cacheSessionId,
|
|
7707
|
+
preferWebsockets: false,
|
|
7715
7708
|
reasoning: toReasoningEffort(this.thinkingLevel),
|
|
7716
7709
|
hideThinkingSummary: this.agent.hideThinkingSummary,
|
|
7717
7710
|
serviceTier: this.serviceTier,
|
|
@@ -240,11 +240,10 @@ FROM model_usage_legacy
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
/**
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
243
|
+
* Reads legacy settings persisted in the agent.db `settings` table.
|
|
244
|
+
* The canonical settings store is `config.yml`; this accessor only
|
|
245
|
+
* exists so the config loader can migrate values from older installs.
|
|
246
246
|
* @returns Settings object, or null if no settings are stored
|
|
247
|
-
* @deprecated Use config.yml instead. This is only for migration.
|
|
248
247
|
*/
|
|
249
248
|
getSettings(): Settings | null {
|
|
250
249
|
const rows = (this.#listSettingsStmt.all() as SettingsRow[]) ?? [];
|
|
@@ -263,16 +262,6 @@ FROM model_usage_legacy
|
|
|
263
262
|
return settings as Settings;
|
|
264
263
|
}
|
|
265
264
|
|
|
266
|
-
/**
|
|
267
|
-
* @deprecated Settings are now stored in config.yml, not agent.db.
|
|
268
|
-
* This method is kept for backward compatibility but does nothing.
|
|
269
|
-
*/
|
|
270
|
-
saveSettings(settings: Settings): void {
|
|
271
|
-
logger.warn("AgentStorage.saveSettings is deprecated - settings are now stored in config.yml", {
|
|
272
|
-
keys: Object.keys(settings),
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
|
|
276
265
|
/**
|
|
277
266
|
* Records model usage, updating the last-used timestamp.
|
|
278
267
|
* @param modelKey - Model key in "provider/modelId" format
|
|
@@ -313,6 +302,16 @@ FROM model_usage_legacy
|
|
|
313
302
|
return this.#authStore.listAuthCredentials().length > 0;
|
|
314
303
|
}
|
|
315
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Returns the underlying {@link AuthCredentialStore} so callers that need
|
|
307
|
+
* the lower-level pi-ai abstraction (e.g. `findAnthropicAuth(store)`) can
|
|
308
|
+
* reuse this storage's open database connection instead of opening their
|
|
309
|
+
* own.
|
|
310
|
+
*/
|
|
311
|
+
get authStore(): AuthCredentialStore {
|
|
312
|
+
return this.#authStore;
|
|
313
|
+
}
|
|
314
|
+
|
|
316
315
|
/**
|
|
317
316
|
* Lists auth credentials, optionally filtered by provider.
|
|
318
317
|
* Only returns active (non-disabled) credentials by default.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { AvailableCommand } from "@agentclientprotocol/sdk";
|
|
2
2
|
import { BUILTIN_SLASH_COMMANDS_INTERNAL, lookupBuiltinSlashCommand } from "./builtin-registry";
|
|
3
3
|
import { parseSlashCommand } from "./helpers/parse";
|
|
4
|
-
import type {
|
|
4
|
+
import type { AcpBuiltinSlashCommandResult, SlashCommandRuntime } from "./types";
|
|
5
5
|
|
|
6
|
-
export type {
|
|
6
|
+
export type { AcpBuiltinSlashCommandResult } from "./types";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Commands advertised to ACP clients. Entries without a text-mode `handle`
|
|
@@ -34,7 +34,7 @@ export const ACP_BUILTIN_SLASH_COMMANDS: AvailableCommand[] = BUILTIN_SLASH_COMM
|
|
|
34
34
|
*/
|
|
35
35
|
export async function executeAcpBuiltinSlashCommand(
|
|
36
36
|
text: string,
|
|
37
|
-
runtime:
|
|
37
|
+
runtime: SlashCommandRuntime,
|
|
38
38
|
): Promise<AcpBuiltinSlashCommandResult> {
|
|
39
39
|
const parsed = parseSlashCommand(text);
|
|
40
40
|
if (!parsed) return false;
|
|
@@ -116,11 +116,5 @@ export interface SlashCommandSpec extends BuiltinSlashCommand {
|
|
|
116
116
|
) => Promise<SlashCommandResult> | SlashCommandResult;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
/**
|
|
120
|
-
* @deprecated Use `SlashCommandRuntime` directly. Retained as an alias so
|
|
121
|
-
* downstream code that imported the ACP-specific name keeps compiling.
|
|
122
|
-
*/
|
|
123
|
-
export type AcpBuiltinCommandRuntime = SlashCommandRuntime;
|
|
124
|
-
|
|
125
119
|
/** Result returned by `executeAcpBuiltinSlashCommand`. */
|
|
126
120
|
export type AcpBuiltinSlashCommandResult = false | { consumed: true } | { prompt: string };
|