@oh-my-pi/pi-coding-agent 17.0.0 → 17.0.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 +128 -0
- package/dist/cli.js +4006 -3966
- package/dist/types/advisor/advise-tool.d.ts +5 -2
- 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/cli-commands.d.ts +14 -1
- package/dist/types/config/model-discovery.d.ts +17 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/model-resolver.d.ts +6 -2
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/models-config.d.ts +6 -0
- package/dist/types/config/settings-schema.d.ts +32 -7
- 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/discovery/substitute-plugin-root.d.ts +20 -7
- 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 +40 -0
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/extensibility/utils.d.ts +2 -2
- package/dist/types/internal-urls/agent-protocol.d.ts +1 -0
- package/dist/types/lib/xai-http.d.ts +11 -0
- package/dist/types/mcp/transports/stdio.d.ts +13 -1
- package/dist/types/modes/acp/acp-agent.d.ts +3 -0
- package/dist/types/modes/acp/acp-mode.d.ts +6 -2
- package/dist/types/modes/components/advisor-config.d.ts +8 -1
- package/dist/types/modes/components/assistant-message.d.ts +2 -0
- package/dist/types/modes/components/custom-editor-plugin-ctor.test.d.ts +1 -0
- package/dist/types/modes/components/custom-editor.d.ts +23 -1
- package/dist/types/modes/components/hook-editor.d.ts +16 -2
- package/dist/types/modes/components/login-dialog.test.d.ts +1 -0
- package/dist/types/modes/components/model-hub.d.ts +5 -2
- package/dist/types/modes/components/session-selector.d.ts +4 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -1
- package/dist/types/modes/components/tool-execution.test.d.ts +1 -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/interactive-mode.d.ts +6 -0
- package/dist/types/modes/noninteractive-dispose.test.d.ts +1 -0
- package/dist/types/modes/print-mode.d.ts +1 -1
- package/dist/types/modes/types.d.ts +10 -0
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +2 -2
- 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/sdk.d.ts +13 -2
- package/dist/types/session/agent-session.d.ts +43 -11
- package/dist/types/session/session-history-format.d.ts +10 -0
- package/dist/types/session/session-manager.d.ts +14 -0
- package/dist/types/session/streaming-output.d.ts +2 -0
- package/dist/types/slash-commands/helpers/active-oauth-account.d.ts +9 -0
- package/dist/types/slash-commands/types.d.ts +4 -4
- package/dist/types/system-prompt.d.ts +1 -1
- package/dist/types/task/label.d.ts +1 -1
- 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/browser/registry.d.ts +7 -3
- package/dist/types/tools/browser/tab-supervisor.d.ts +2 -0
- package/dist/types/tools/essential-tools.d.ts +29 -0
- package/dist/types/tools/image-gen.d.ts +2 -1
- package/dist/types/tools/index.d.ts +4 -1
- package/dist/types/tools/manage-skill.d.ts +2 -0
- package/dist/types/tools/xdev.d.ts +11 -2
- package/dist/types/utils/title-generator.d.ts +2 -1
- package/dist/types/web/search/index.d.ts +2 -0
- package/dist/types/web/search/providers/base.d.ts +3 -0
- 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 +1358 -86
- package/src/advisor/__tests__/config.test.ts +58 -2
- package/src/advisor/advise-tool.ts +7 -3
- package/src/advisor/config.ts +76 -24
- package/src/advisor/runtime.ts +445 -92
- package/src/autolearn/controller.ts +23 -28
- package/src/cli/bench-cli.ts +4 -1
- package/src/cli/grep-cli.ts +2 -1
- package/src/cli-commands.ts +57 -23
- package/src/cli.ts +5 -1
- package/src/config/model-discovery.ts +81 -21
- package/src/config/model-registry.ts +34 -6
- package/src/config/model-resolver.ts +57 -12
- package/src/config/models-config-schema.ts +1 -0
- package/src/config/settings-schema.ts +43 -6
- package/src/config/settings.ts +405 -25
- package/src/cursor.ts +20 -3
- package/src/debug/report-bundle.ts +40 -4
- package/src/discovery/codex.ts +14 -4
- package/src/discovery/helpers.ts +28 -5
- package/src/discovery/substitute-plugin-root.ts +23 -7
- package/src/exec/bash-executor.ts +14 -5
- package/src/export/html/template.js +2 -0
- 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 +96 -1
- 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/internal-urls/__tests__/agent-protocol-nested.test.ts +73 -0
- package/src/internal-urls/agent-protocol.ts +73 -39
- 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/lib/xai-http.ts +28 -2
- package/src/lsp/client.ts +1 -1
- package/src/main.ts +11 -8
- package/src/mcp/manager.ts +9 -3
- package/src/mcp/transports/stdio.ts +103 -23
- package/src/modes/acp/acp-agent.ts +28 -9
- package/src/modes/acp/acp-event-mapper.ts +8 -0
- package/src/modes/acp/acp-mode.ts +18 -4
- package/src/modes/components/advisor-config.ts +65 -3
- package/src/modes/components/ask-dialog.ts +1 -1
- package/src/modes/components/assistant-message.ts +35 -14
- package/src/modes/components/chat-transcript-builder.ts +2 -0
- package/src/modes/components/custom-editor-plugin-ctor.test.ts +36 -0
- package/src/modes/components/custom-editor.ts +62 -1
- package/src/modes/components/hook-editor.ts +35 -5
- package/src/modes/components/login-dialog.test.ts +56 -0
- package/src/modes/components/login-dialog.ts +7 -3
- package/src/modes/components/model-hub.ts +138 -42
- package/src/modes/components/plan-review-overlay.ts +51 -10
- package/src/modes/components/session-selector.ts +10 -0
- package/src/modes/components/status-line/component.test.ts +1 -0
- package/src/modes/components/status-line/component.ts +2 -4
- package/src/modes/components/status-line/segments.ts +21 -6
- package/src/modes/components/tool-execution.test.ts +101 -0
- package/src/modes/components/tool-execution.ts +117 -9
- package/src/modes/components/transcript-container.ts +30 -2
- package/src/modes/controllers/command-controller-shared.ts +1 -1
- package/src/modes/controllers/command-controller.ts +168 -48
- package/src/modes/controllers/event-controller.ts +6 -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 +208 -46
- package/src/modes/interactive-mode.ts +205 -65
- package/src/modes/noninteractive-dispose.test.ts +60 -0
- package/src/modes/print-mode.ts +10 -5
- package/src/modes/rpc/host-tools.ts +2 -1
- package/src/modes/rpc/rpc-mode.ts +31 -7
- package/src/modes/theme/theme.ts +2 -2
- package/src/modes/types.ts +10 -0
- package/src/modes/utils/interactive-context-helpers.ts +3 -1
- package/src/modes/utils/transcript-render-helpers.ts +3 -2
- 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/registry/agent-lifecycle.ts +133 -18
- package/src/sdk.ts +227 -44
- package/src/session/agent-session.ts +1364 -382
- package/src/session/session-history-format.ts +20 -5
- package/src/session/session-listing.ts +6 -5
- package/src/session/session-loader.ts +9 -0
- package/src/session/session-manager.ts +48 -0
- package/src/session/session-persistence.ts +11 -0
- package/src/session/streaming-output.ts +3 -1
- package/src/slash-commands/builtin-registry.ts +9 -0
- package/src/slash-commands/helpers/active-oauth-account.ts +16 -0
- package/src/slash-commands/types.ts +4 -4
- package/src/system-prompt.ts +2 -2
- package/src/task/executor.ts +1 -1
- package/src/task/label.ts +2 -0
- package/src/telemetry-export.ts +453 -97
- package/src/tools/approval.ts +11 -0
- package/src/tools/bash.ts +71 -38
- package/src/tools/browser/registry.ts +9 -2
- package/src/tools/browser/tab-supervisor.ts +65 -10
- package/src/tools/browser.ts +4 -3
- package/src/tools/essential-tools.ts +45 -0
- package/src/tools/eval.ts +3 -0
- package/src/tools/gh.ts +169 -2
- package/src/tools/image-gen.ts +624 -513
- package/src/tools/index.ts +10 -6
- package/src/tools/manage-skill.ts +5 -3
- package/src/tools/output-meta.ts +7 -0
- package/src/tools/path-utils.ts +8 -5
- package/src/tools/read.ts +48 -3
- package/src/tools/write.ts +22 -4
- package/src/tools/xdev.ts +14 -3
- package/src/utils/title-generator.ts +15 -4
- package/src/web/search/index.ts +21 -6
- package/src/web/search/providers/base.ts +3 -0
- package/src/web/search/providers/kimi.ts +18 -12
- package/src/web/search/providers/xai.ts +40 -9
- package/src/web/search/types.ts +6 -1
package/src/sdk.ts
CHANGED
|
@@ -2,13 +2,21 @@ import {
|
|
|
2
2
|
Agent,
|
|
3
3
|
type AgentEvent,
|
|
4
4
|
type AgentMessage,
|
|
5
|
+
type AgentOptions,
|
|
5
6
|
type AgentTelemetryConfig,
|
|
6
7
|
type AgentTool,
|
|
7
8
|
AppendOnlyContextManager,
|
|
8
9
|
filterProviderReplayMessages,
|
|
9
10
|
type ThinkingLevel,
|
|
10
11
|
} from "@oh-my-pi/pi-agent-core";
|
|
11
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
Context,
|
|
14
|
+
CredentialDisabledEvent,
|
|
15
|
+
Message,
|
|
16
|
+
Model,
|
|
17
|
+
ProviderSessionState,
|
|
18
|
+
SimpleStreamOptions,
|
|
19
|
+
} from "@oh-my-pi/pi-ai";
|
|
12
20
|
import type { Dialect } from "@oh-my-pi/pi-ai/dialect";
|
|
13
21
|
import {
|
|
14
22
|
getOpenAICodexTransportDetails,
|
|
@@ -154,6 +162,7 @@ import {
|
|
|
154
162
|
createTools,
|
|
155
163
|
createVibeTools,
|
|
156
164
|
type DeferredDiagnosticsEntry,
|
|
165
|
+
defaultLoadModeForToolName,
|
|
157
166
|
discoverStartupLspServers,
|
|
158
167
|
EditTool,
|
|
159
168
|
EvalTool,
|
|
@@ -890,7 +899,7 @@ function customToolToDefinition(tool: CustomTool): ToolDefinition {
|
|
|
890
899
|
description: tool.description,
|
|
891
900
|
parameters: tool.parameters,
|
|
892
901
|
hidden: tool.hidden,
|
|
893
|
-
loadMode: tool.loadMode
|
|
902
|
+
loadMode: defaultLoadModeForToolName(tool.name, tool.loadMode),
|
|
894
903
|
deferrable: tool.deferrable,
|
|
895
904
|
approval: typeof tool.approval === "function" ? tool.approval.bind(tool) : tool.approval,
|
|
896
905
|
mcpServerName: tool.mcpServerName,
|
|
@@ -1055,6 +1064,88 @@ function buildMCPPromptCommands(manager: MCPManager): LoadedCustomCommand[] {
|
|
|
1055
1064
|
}
|
|
1056
1065
|
return commands;
|
|
1057
1066
|
}
|
|
1067
|
+
|
|
1068
|
+
/** Dependencies used to construct an isolated auto-learn capture agent. */
|
|
1069
|
+
export interface AutoLearnCaptureRunnerOptions {
|
|
1070
|
+
sourceAgent: Agent;
|
|
1071
|
+
captureTools: AgentTool[];
|
|
1072
|
+
createAgent: (options: AgentOptions) => Agent;
|
|
1073
|
+
onPayload?: SimpleStreamOptions["onPayload"];
|
|
1074
|
+
onResponse?: SimpleStreamOptions["onResponse"];
|
|
1075
|
+
createSessionId?: () => string;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
/** Build a private capture runner over a detached message snapshot and provider session. */
|
|
1079
|
+
export function createAutoLearnCaptureRunner(
|
|
1080
|
+
options: AutoLearnCaptureRunnerOptions,
|
|
1081
|
+
): (content: string, signal?: AbortSignal) => Promise<void> {
|
|
1082
|
+
return async (content, signal) => {
|
|
1083
|
+
if (options.captureTools.length === 0 || signal?.aborted) return;
|
|
1084
|
+
const captureModel = options.sourceAgent.state.model;
|
|
1085
|
+
if (!captureModel) return;
|
|
1086
|
+
|
|
1087
|
+
const captureSessionId = options.createSessionId?.() ?? Bun.randomUUIDv7();
|
|
1088
|
+
const captureProviderSessionState = new Map<string, ProviderSessionState>();
|
|
1089
|
+
const captureMessages = options.sourceAgent.state.messages.map((message): AgentMessage => {
|
|
1090
|
+
if (message.role === "assistant") {
|
|
1091
|
+
return { ...message, responseId: undefined, providerPayload: undefined };
|
|
1092
|
+
}
|
|
1093
|
+
if (message.role === "user" || message.role === "developer") {
|
|
1094
|
+
return { ...message, providerPayload: undefined };
|
|
1095
|
+
}
|
|
1096
|
+
return message;
|
|
1097
|
+
});
|
|
1098
|
+
const captureAgent = options.createAgent({
|
|
1099
|
+
initialState: {
|
|
1100
|
+
systemPrompt: [...options.sourceAgent.state.systemPrompt],
|
|
1101
|
+
model: captureModel,
|
|
1102
|
+
thinkingLevel: options.sourceAgent.state.thinkingLevel,
|
|
1103
|
+
disableReasoning: options.sourceAgent.state.disableReasoning,
|
|
1104
|
+
tools: options.captureTools,
|
|
1105
|
+
messages: captureMessages,
|
|
1106
|
+
},
|
|
1107
|
+
sessionId: captureSessionId,
|
|
1108
|
+
promptCacheKey: captureSessionId,
|
|
1109
|
+
providerSessionState: captureProviderSessionState,
|
|
1110
|
+
getApiKey: requestModel => options.sourceAgent.getApiKey?.(requestModel),
|
|
1111
|
+
onPayload: options.onPayload,
|
|
1112
|
+
onResponse: options.onResponse,
|
|
1113
|
+
});
|
|
1114
|
+
captureAgent.setMetadataResolver(provider => options.sourceAgent.metadataForProvider(provider));
|
|
1115
|
+
const captureMessage: CustomMessage = {
|
|
1116
|
+
role: "custom",
|
|
1117
|
+
customType: "autolearn-nudge",
|
|
1118
|
+
content,
|
|
1119
|
+
display: false,
|
|
1120
|
+
attribution: "agent",
|
|
1121
|
+
timestamp: Date.now(),
|
|
1122
|
+
};
|
|
1123
|
+
const abortCapture = () => captureAgent.abort(signal?.reason);
|
|
1124
|
+
signal?.addEventListener("abort", abortCapture, { once: true });
|
|
1125
|
+
try {
|
|
1126
|
+
if (signal?.aborted) {
|
|
1127
|
+
abortCapture();
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
await captureAgent.prompt(captureMessage);
|
|
1131
|
+
} catch (error) {
|
|
1132
|
+
if (!signal?.aborted) throw error;
|
|
1133
|
+
} finally {
|
|
1134
|
+
signal?.removeEventListener("abort", abortCapture);
|
|
1135
|
+
for (const [providerKey, state] of captureProviderSessionState) {
|
|
1136
|
+
try {
|
|
1137
|
+
state.close();
|
|
1138
|
+
} catch (error) {
|
|
1139
|
+
logger.warn("Failed to close auto-learn capture provider state", {
|
|
1140
|
+
providerKey,
|
|
1141
|
+
error: String(error),
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
captureProviderSessionState.clear();
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1058
1149
|
/**
|
|
1059
1150
|
* Create an AgentSession with the specified options.
|
|
1060
1151
|
*
|
|
@@ -1557,7 +1648,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1557
1648
|
skipPythonPreflight: options.skipPythonPreflight,
|
|
1558
1649
|
contextFiles,
|
|
1559
1650
|
workspaceTree: resolvedWorkspaceTree,
|
|
1560
|
-
skills
|
|
1651
|
+
get skills() {
|
|
1652
|
+
return session?.skills ?? skills;
|
|
1653
|
+
},
|
|
1654
|
+
refreshSkills: () => session.refreshSkills(),
|
|
1561
1655
|
rules: allRules,
|
|
1562
1656
|
eventBus,
|
|
1563
1657
|
outputSchema: options.outputSchema,
|
|
@@ -2244,31 +2338,50 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2244
2338
|
builtInRegistryToolNames.delete("edit");
|
|
2245
2339
|
}
|
|
2246
2340
|
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
// plan mode unable to exit through the intended path.
|
|
2254
|
-
const hasDeferrableTools = Array.from(toolRegistry.values()).some(tool => tool.deferrable === true);
|
|
2255
|
-
const hasXdevTools = (toolSession.xdevRegistry?.size ?? 0) > 0;
|
|
2256
|
-
const planModeAvailable = settings.get("plan.enabled");
|
|
2257
|
-
if ((hasDeferrableTools || hasXdevTools || planModeAvailable) && !toolRegistry.has("write")) {
|
|
2258
|
-
const writeTool = await logger.time("createTools:write:session", BUILTIN_TOOLS.write, toolSession);
|
|
2259
|
-
if (writeTool) {
|
|
2341
|
+
let writeRegistration: Promise<boolean> | undefined;
|
|
2342
|
+
const ensureWriteRegistered = (): Promise<boolean> => {
|
|
2343
|
+
if (toolRegistry.has("write")) return Promise.resolve(builtInRegistryToolNames.has("write"));
|
|
2344
|
+
writeRegistration ??= (async () => {
|
|
2345
|
+
const writeTool = await logger.time("createTools:write:session", BUILTIN_TOOLS.write, toolSession);
|
|
2346
|
+
if (!writeTool || toolRegistry.has("write")) return builtInRegistryToolNames.has("write");
|
|
2260
2347
|
toolRegistry.set(
|
|
2261
2348
|
writeTool.name,
|
|
2262
2349
|
new ExtensionToolWrapper(wrapToolWithMetaNotice(writeTool), extensionRunner) as Tool,
|
|
2263
2350
|
);
|
|
2264
2351
|
builtInRegistryToolNames.add(writeTool.name);
|
|
2265
|
-
|
|
2352
|
+
return true;
|
|
2353
|
+
})().finally(() => {
|
|
2354
|
+
writeRegistration = undefined;
|
|
2355
|
+
});
|
|
2356
|
+
return writeRegistration;
|
|
2357
|
+
};
|
|
2358
|
+
|
|
2359
|
+
// Existing staged/device paths need write registered before active-set assembly.
|
|
2360
|
+
// Deferred MCP also registers it now, but refresh activates it only after a server connects.
|
|
2361
|
+
const hasDeferrableTools = Array.from(toolRegistry.values()).some(tool => tool.deferrable === true);
|
|
2362
|
+
const hasXdevTools = (toolSession.xdevRegistry?.size ?? 0) > 0;
|
|
2363
|
+
const planModeAvailable = settings.get("plan.enabled");
|
|
2364
|
+
if (hasDeferrableTools || hasXdevTools || planModeAvailable || deferMCPDiscoveryForUI) {
|
|
2365
|
+
await ensureWriteRegistered();
|
|
2266
2366
|
}
|
|
2267
2367
|
|
|
2268
2368
|
let cursorEventEmitter: ((event: AgentEvent) => void) | undefined;
|
|
2369
|
+
// Built-in xd:// devices (ast_edit, debug, browser, lsp, web_search) are
|
|
2370
|
+
// mounted in createTools BEFORE this loop wraps registry entries in
|
|
2371
|
+
// ExtensionToolWrapper, so the registry holds them unwrapped. The normal
|
|
2372
|
+
// `write xd://<tool>` path runs approval through the wrapped `write` tool's
|
|
2373
|
+
// tier gate, but Cursor invokes advertised devices via `tool.execute()`
|
|
2374
|
+
// directly — so wrap unwrapped devices here to keep the approval/deny/prompt
|
|
2375
|
+
// gate. Dynamic mounts (custom/MCP) already come from the wrapped registry.
|
|
2376
|
+
const resolveCursorDevice = (name: string): AgentTool | undefined => {
|
|
2377
|
+
const device = toolSession.xdevRegistry?.get(name);
|
|
2378
|
+
if (!device) return undefined;
|
|
2379
|
+
return device instanceof ExtensionToolWrapper ? device : new ExtensionToolWrapper(device, extensionRunner);
|
|
2380
|
+
};
|
|
2269
2381
|
const cursorExecHandlers = new CursorExecHandlers({
|
|
2270
2382
|
cwd,
|
|
2271
2383
|
tools: toolRegistry,
|
|
2384
|
+
getTool: resolveCursorDevice,
|
|
2272
2385
|
getToolContext: () => toolContextStore.getContext(),
|
|
2273
2386
|
emitEvent: event => cursorEventEmitter?.(event),
|
|
2274
2387
|
});
|
|
@@ -2341,7 +2454,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2341
2454
|
xdevDocs: toolSession.xdevRegistry?.docsAll() ?? "",
|
|
2342
2455
|
autoQaEnabled: isAutoQaEnabled(settings),
|
|
2343
2456
|
resolvedCustomPrompt: options.customSystemPrompt,
|
|
2344
|
-
skills,
|
|
2457
|
+
skills: session?.skills ?? skills,
|
|
2345
2458
|
contextFiles,
|
|
2346
2459
|
tools: promptTools,
|
|
2347
2460
|
toolNames,
|
|
@@ -2410,11 +2523,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2410
2523
|
}
|
|
2411
2524
|
const requestedToolNames = explicitlyRequestedToolNames ?? toolNamesFromRegistry;
|
|
2412
2525
|
const normalizedRequested = requestedToolNames.filter(name => toolRegistry.has(name));
|
|
2413
|
-
const requestedToolNameSet = new Set(normalizedRequested);
|
|
2414
2526
|
const defaultInactiveToolNames = new Set(
|
|
2415
2527
|
registeredTools.filter(tool => tool.definition.defaultInactive).map(tool => tool.definition.name),
|
|
2416
2528
|
);
|
|
2417
2529
|
const requestedActiveToolNames = normalizedRequested.filter(name => name !== "goal");
|
|
2530
|
+
const explicitlyRequestedToolNameSet = explicitlyRequestedToolNames
|
|
2531
|
+
? new Set(explicitlyRequestedToolNames)
|
|
2532
|
+
: undefined;
|
|
2533
|
+
const xdevReadAvailable =
|
|
2534
|
+
builtInRegistryToolNames.has("read") &&
|
|
2535
|
+
(explicitlyRequestedToolNameSet === undefined || explicitlyRequestedToolNameSet.has("read"));
|
|
2418
2536
|
const initialRequestedActiveToolNames = options.toolNames
|
|
2419
2537
|
? requestedActiveToolNames
|
|
2420
2538
|
: requestedActiveToolNames.filter(name => !defaultInactiveToolNames.has(name));
|
|
@@ -2446,24 +2564,32 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2446
2564
|
});
|
|
2447
2565
|
hasRegistered = true;
|
|
2448
2566
|
|
|
2449
|
-
// Partition the initial enabled set for the xd:// transport:
|
|
2450
|
-
// tools become mounted devices
|
|
2451
|
-
//
|
|
2452
|
-
//
|
|
2453
|
-
//
|
|
2454
|
-
// never ship a schema. Presentation only — selection already happened.
|
|
2567
|
+
// Partition the initial enabled set for the xd:// transport: ambient
|
|
2568
|
+
// discoverable tools become mounted devices, while explicitly requested
|
|
2569
|
+
// tools keep their top-level presentation. The registry already holds the
|
|
2570
|
+
// default-set built-in devices from createTools; this reconciles dynamic
|
|
2571
|
+
// mounts (image-gen, TTS, startup MCP, active extension tools).
|
|
2455
2572
|
let initialMountedXdevToolNames: string[] = [];
|
|
2456
2573
|
if (toolSession.xdevRegistry) {
|
|
2457
2574
|
const topLevelToolNames: string[] = [];
|
|
2458
2575
|
const mountedTools: Tool[] = [];
|
|
2459
2576
|
for (const name of initialToolNames) {
|
|
2460
2577
|
const tool = toolRegistry.get(name);
|
|
2461
|
-
|
|
2578
|
+
const explicitlyRequested = explicitlyRequestedToolNameSet?.has(name) === true;
|
|
2579
|
+
if (tool && xdevReadAvailable && !explicitlyRequested && isMountableUnderXdev(tool))
|
|
2580
|
+
mountedTools.push(tool);
|
|
2462
2581
|
else topLevelToolNames.push(name);
|
|
2463
2582
|
}
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2583
|
+
const writeTransportAvailable = mountedTools.length === 0 || (await ensureWriteRegistered());
|
|
2584
|
+
if (writeTransportAvailable) {
|
|
2585
|
+
toolSession.xdevRegistry.reconcile(mountedTools);
|
|
2586
|
+
initialMountedXdevToolNames = mountedTools.map(tool => tool.name);
|
|
2587
|
+
initialToolNames = topLevelToolNames;
|
|
2588
|
+
if (initialMountedXdevToolNames.length > 0 && !initialToolNames.includes("write"))
|
|
2589
|
+
initialToolNames.push("write");
|
|
2590
|
+
} else {
|
|
2591
|
+
toolSession.xdevRegistry.reconcile([]);
|
|
2592
|
+
}
|
|
2467
2593
|
}
|
|
2468
2594
|
|
|
2469
2595
|
setActiveToolNames(initialToolNames);
|
|
@@ -2548,6 +2674,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2548
2674
|
const initialTools = initialToolNames
|
|
2549
2675
|
.map(name => toolRegistry.get(name))
|
|
2550
2676
|
.filter((tool): tool is AgentTool => tool !== undefined);
|
|
2677
|
+
const autoLearnCaptureTools = initialTools.filter(tool => tool.name === "manage_skill" || tool.name === "learn");
|
|
2551
2678
|
|
|
2552
2679
|
const openaiWebsocketSetting = settings.get("providers.openaiWebsockets") ?? "off";
|
|
2553
2680
|
const preferOpenAICodexWebsockets =
|
|
@@ -2574,6 +2701,17 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2574
2701
|
settings,
|
|
2575
2702
|
createSettingsAwareStreamFn(settings),
|
|
2576
2703
|
);
|
|
2704
|
+
const transformToolCallArguments = (args: Record<string, unknown>): Record<string, unknown> => {
|
|
2705
|
+
let result = args;
|
|
2706
|
+
const maxTimeout = settings.get("tools.maxTimeout");
|
|
2707
|
+
if (maxTimeout > 0 && typeof result.timeout === "number") {
|
|
2708
|
+
result = { ...result, timeout: Math.min(result.timeout, maxTimeout) };
|
|
2709
|
+
}
|
|
2710
|
+
if (obfuscator?.hasSecrets()) {
|
|
2711
|
+
result = deobfuscateToolArguments(obfuscator, result);
|
|
2712
|
+
}
|
|
2713
|
+
return result;
|
|
2714
|
+
};
|
|
2577
2715
|
agent = new Agent({
|
|
2578
2716
|
initialState: {
|
|
2579
2717
|
systemPrompt,
|
|
@@ -2626,17 +2764,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2626
2764
|
return settingsAwareStreamFn(streamModel, context, streamOptions);
|
|
2627
2765
|
},
|
|
2628
2766
|
cursorExecHandlers,
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
const maxTimeout = settings.get("tools.maxTimeout");
|
|
2632
|
-
if (maxTimeout > 0 && typeof result.timeout === "number") {
|
|
2633
|
-
result = { ...result, timeout: Math.min(result.timeout, maxTimeout) };
|
|
2634
|
-
}
|
|
2635
|
-
if (obfuscator?.hasSecrets()) {
|
|
2636
|
-
result = deobfuscateToolArguments(obfuscator, result);
|
|
2637
|
-
}
|
|
2638
|
-
return result;
|
|
2639
|
-
},
|
|
2767
|
+
getCursorTools: () => [...(toolSession.xdevRegistry?.list() ?? [])],
|
|
2768
|
+
transformToolCallArguments,
|
|
2640
2769
|
intentTracing: !!intentField,
|
|
2641
2770
|
pruneToolDescriptions: inlineToolDescriptors,
|
|
2642
2771
|
dialect: resolveDialect(settings.get("tools.format"), model),
|
|
@@ -2737,6 +2866,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2737
2866
|
customCommands: customCommandsResult.commands,
|
|
2738
2867
|
skills,
|
|
2739
2868
|
skillWarnings,
|
|
2869
|
+
skillsReloadable: options.skills === undefined,
|
|
2740
2870
|
skillsSettings: settings.getGroup("skills"),
|
|
2741
2871
|
modelRegistry,
|
|
2742
2872
|
toolRegistry,
|
|
@@ -2757,8 +2887,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2757
2887
|
getXdevToolEntries: () => toolSession.xdevRegistry?.entries() ?? [],
|
|
2758
2888
|
xdevRegistry: toolSession.xdevRegistry,
|
|
2759
2889
|
initialMountedXdevToolNames,
|
|
2760
|
-
|
|
2890
|
+
presentationPinnedToolNames: explicitlyRequestedToolNameSet,
|
|
2761
2891
|
setActiveToolNames,
|
|
2892
|
+
ensureWriteRegistered,
|
|
2762
2893
|
getMcpServerInstructions: mcpManager
|
|
2763
2894
|
? () => {
|
|
2764
2895
|
const raw = mcpManager.getServerInstructions();
|
|
@@ -2918,8 +3049,56 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2918
3049
|
});
|
|
2919
3050
|
};
|
|
2920
3051
|
|
|
2921
|
-
|
|
2922
|
-
|
|
3052
|
+
const runAutoLearnCapture = createAutoLearnCaptureRunner({
|
|
3053
|
+
sourceAgent: agent,
|
|
3054
|
+
captureTools: autoLearnCaptureTools,
|
|
3055
|
+
onPayload,
|
|
3056
|
+
onResponse,
|
|
3057
|
+
createAgent: captureOptions => {
|
|
3058
|
+
const captureModel = captureOptions.initialState?.model;
|
|
3059
|
+
const captureSessionId = captureOptions.sessionId;
|
|
3060
|
+
if (!captureModel || !captureSessionId) throw new Error("Auto-learn capture identity is incomplete");
|
|
3061
|
+
return new Agent({
|
|
3062
|
+
...captureOptions,
|
|
3063
|
+
cwd: sessionManager.getCwd(),
|
|
3064
|
+
cwdResolver: () => sessionManager.getCwd(),
|
|
3065
|
+
convertToLlm: convertToLlmFinal,
|
|
3066
|
+
transformContext: async messages => wrapSteeringForModel(messages),
|
|
3067
|
+
transformProviderContext: async (context, transformModel) => {
|
|
3068
|
+
const transformed = obfuscator ? obfuscateProviderContext(obfuscator, context) : context;
|
|
3069
|
+
return clampProviderContextImages(transformed, transformModel);
|
|
3070
|
+
},
|
|
3071
|
+
thinkingBudgets: agent.thinkingBudgets,
|
|
3072
|
+
temperature: agent.temperature,
|
|
3073
|
+
topP: agent.topP,
|
|
3074
|
+
topK: agent.topK,
|
|
3075
|
+
minP: agent.minP,
|
|
3076
|
+
presencePenalty: agent.presencePenalty,
|
|
3077
|
+
repetitionPenalty: agent.repetitionPenalty,
|
|
3078
|
+
serviceTierResolver: agent.serviceTierResolver,
|
|
3079
|
+
hideThinkingSummary: agent.hideThinkingSummary,
|
|
3080
|
+
maxRetryDelayMs: agent.maxRetryDelayMs,
|
|
3081
|
+
kimiApiFormat: settings.get("providers.kimiApiFormat") ?? "anthropic",
|
|
3082
|
+
preferWebsockets: preferOpenAICodexWebsockets,
|
|
3083
|
+
getToolContext: toolCall => toolContextStore.getContext(toolCall),
|
|
3084
|
+
streamFn: settingsAwareStreamFn,
|
|
3085
|
+
transformToolCallArguments,
|
|
3086
|
+
intentTracing: !!intentField,
|
|
3087
|
+
pruneToolDescriptions: inlineToolDescriptors,
|
|
3088
|
+
dialect: resolveDialect(settings.get("tools.format"), captureModel),
|
|
3089
|
+
abortOnFabricatedToolResult: settings.get("tools.abortOnFabricatedResult"),
|
|
3090
|
+
appendOnlyContext: shouldEnableAppendOnlyContext(
|
|
3091
|
+
settings.get("provider.appendOnlyContext"),
|
|
3092
|
+
captureModel,
|
|
3093
|
+
)
|
|
3094
|
+
? new AppendOnlyContextManager()
|
|
3095
|
+
: undefined,
|
|
3096
|
+
});
|
|
3097
|
+
},
|
|
3098
|
+
});
|
|
3099
|
+
|
|
3100
|
+
// Auto-learn can immediately trigger a private capture after the first real
|
|
3101
|
+
// stop. When a memory backend is selected, install that backend's
|
|
2923
3102
|
// per-session state first so the capture turn's `learn` tool observes the
|
|
2924
3103
|
// same initialized state as normal memory tools. Other sessions keep memory
|
|
2925
3104
|
// startup in the background to preserve the existing startup profile.
|
|
@@ -2934,7 +3113,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2934
3113
|
// reference is intentionally discarded (the listener retains it).
|
|
2935
3114
|
if (settings.get("autolearn.enabled") && taskDepth === 0) {
|
|
2936
3115
|
await logger.time("startMemoryStartupTask", startMemoryBackend);
|
|
2937
|
-
new AutoLearnController({
|
|
3116
|
+
new AutoLearnController({
|
|
3117
|
+
session,
|
|
3118
|
+
settings,
|
|
3119
|
+
capture: content => session.runAutolearnCapture(signal => runAutoLearnCapture(content, signal)),
|
|
3120
|
+
});
|
|
2938
3121
|
} else {
|
|
2939
3122
|
void logger.time("startMemoryStartupTask", startMemoryBackend);
|
|
2940
3123
|
}
|