@myagentroam/node 0.9.62 → 0.9.65
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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/dist/capabilities.js +110 -2
- package/dist/claude-agent-sdk.js +330 -2
- package/dist/claude-channel.js +44 -2
- package/dist/codex-app-server.js +510 -2
- package/dist/config.js +106 -2
- package/dist/connector/node-connector-options.js +1 -2
- package/dist/connector/node-operation-router.js +22 -2
- package/dist/connector.js +1736 -2
- package/dist/control-outbound-scheduler.js +153 -2
- package/dist/database.js +639 -2
- package/dist/fake-runner.js +129 -2
- package/dist/git-askpass.js +12 -0
- package/dist/git-execution-helper.js +266 -0
- package/dist/health.js +3 -2
- package/dist/main.js +57 -2
- package/dist/mcp-installation-model.js +1 -2
- package/dist/migrations/v004.js +55 -3
- package/dist/migrations/v005.js +13 -3
- package/dist/migrations/v006.js +90 -3
- package/dist/migrations/v007.js +22 -3
- package/dist/migrations/v008.js +18 -3
- package/dist/migrations/v009.js +70 -4
- package/dist/migrations/v010.js +43 -3
- package/dist/migrations/v011.js +20 -3
- package/dist/migrations/v012.js +8 -0
- package/dist/native-jsonl-reader.js +186 -2
- package/dist/native-session-history.js +1143 -2
- package/dist/opencode-runtime.js +80 -2
- package/dist/opencode-server.js +259 -2
- package/dist/operational.js +122 -2
- package/dist/process-tree.js +18 -2
- package/dist/ripgrep-binary.js +31 -2
- package/dist/rotating-log.js +67 -2
- package/dist/runner/abstract-runner.js +260 -2
- package/dist/runner/claude/managed-run-controller.js +355 -2
- package/dist/runner/claude/tool-normalizer.js +120 -2
- package/dist/runner/claude-code-runner.js +303 -2
- package/dist/runner/codex/composer-image-markers.js +8 -2
- package/dist/runner/codex/conversation-parser.js +913 -2
- package/dist/runner/codex/managed-run-controller.js +494 -2
- package/dist/runner/codex/tool-normalizer.js +214 -2
- package/dist/runner/codex-runner.js +585 -2
- package/dist/runner/fake-test-runner.js +47 -2
- package/dist/runner/mar-agent/conversation-normalizer.js +644 -2
- package/dist/runner/mar-agent/executor-stdio-client-transport.js +139 -2
- package/dist/runner/mar-agent/generated-images.js +41 -2
- package/dist/runner/mar-agent/history-projection.js +106 -2
- package/dist/runner/mar-agent/hosted-conversation-runtime.js +446 -2
- package/dist/runner/mar-agent/managed-run-controller.js +785 -2
- package/dist/runner/mar-agent/mcp-client-pool.js +233 -2
- package/dist/runner/mar-agent/runtime-model-factory.js +326 -2
- package/dist/runner/mar-agent-runner.js +458 -2
- package/dist/runner/opencode/conversation-parser.js +221 -2
- package/dist/runner/opencode/managed-run-controller.js +588 -2
- package/dist/runner/opencode/tool-normalizer.js +80 -2
- package/dist/runner/opencode-runner.js +426 -2
- package/dist/runner/runner-registry.js +87 -2
- package/dist/runner-command-engine.js +71 -2
- package/dist/runner-profiles.js +323 -2
- package/dist/runner-usage.js +190 -2
- package/dist/runtime-command-detector.js +73 -2
- package/dist/runtime-model.js +1 -2
- package/dist/runtime-state.js +1509 -2
- package/dist/service/attachment-domain-state.js +7 -2
- package/dist/service/bubblewrap-sandbox-executor.js +543 -2
- package/dist/service/continuous-run-coordinator.js +425 -2
- package/dist/service/conversation-history-service.js +552 -2
- package/dist/service/conversation-hosting-capability-service.js +61 -2
- package/dist/service/conversation-hosting-enablement-service.js +91 -2
- package/dist/service/conversation-hosting-maintenance-service.js +174 -2
- package/dist/service/conversation-segment-service.js +162 -2
- package/dist/service/conversation-template-node-service.js +992 -2
- package/dist/service/external-session-resume-service.js +152 -2
- package/dist/service/fake-managed-run-service.js +60 -2
- package/dist/service/git-execution-service.js +418 -0
- package/dist/service/git-operation-service.js +57 -0
- package/dist/service/hosted-conversation-node-service.js +1982 -2
- package/dist/service/hosted-conversation-store.js +1405 -2
- package/dist/service/managed-runner-session-service.js +35 -2
- package/dist/service/mar-agent-model-transport-test-service.js +88 -2
- package/dist/service/mcp-installation-verifier.js +87 -2
- package/dist/service/mcp-node-operation-service.js +90 -2
- package/dist/service/mission-mcp-server.js +124 -2
- package/dist/service/mission-mcp-stdio.js +40 -2
- package/dist/service/mission-runtime.js +142 -2
- package/dist/service/native-session-projection-service.js +274 -2
- package/dist/service/native-session-watch-service.js +683 -2
- package/dist/service/node-connection-lifecycle-service.js +88 -2
- package/dist/service/node-control-channel.js +85 -2
- package/dist/service/node-control-message-service.js +109 -2
- package/dist/service/node-request-service.js +62 -2
- package/dist/service/node-run-event-bridge.js +88 -2
- package/dist/service/node-terminal-channel.js +202 -2
- package/dist/service/node-upgrade-coordinator.js +137 -2
- package/dist/service/node-workspace-coordinator.js +97 -2
- package/dist/service/recent-run-projection-service.js +99 -2
- package/dist/service/run-attachment-service.js +321 -2
- package/dist/service/run-domain-state.js +4 -2
- package/dist/service/run-event-service.js +246 -2
- package/dist/service/run-ownership-policy.js +22 -2
- package/dist/service/run-workbench-service.js +120 -2
- package/dist/service/runner-channel-message-service.js +20 -2
- package/dist/service/runner-interaction-service.js +243 -2
- package/dist/service/runner-service.js +69 -2
- package/dist/service/runtime-credential-control-service.js +95 -2
- package/dist/service/session-catalog-service.js +404 -2
- package/dist/service/session-command-service.js +125 -2
- package/dist/service/session-context-service.js +128 -2
- package/dist/service/session-domain-state.js +9 -2
- package/dist/service/session-identity-service.js +86 -2
- package/dist/service/session-lifecycle-service.js +248 -2
- package/dist/service/session-message-service.js +270 -2
- package/dist/service/session-presentation-service.js +43 -2
- package/dist/service/session-query-service.js +82 -2
- package/dist/service/session-watch-slot-coordinator.js +21 -2
- package/dist/service/skill-directory-service.js +238 -2
- package/dist/service/skill-install-service.js +434 -2
- package/dist/service/skill-node-operation-service.js +206 -2
- package/dist/service/terminal-relay-state.js +3 -2
- package/dist/service/terminal-service.js +90 -2
- package/dist/service/web-search-error.js +40 -2
- package/dist/service/workbench-event-service.js +21 -2
- package/dist/service/workbench-manifest-service.js +69 -2
- package/dist/service/workspace-change-service.js +290 -2
- package/dist/service/workspace-content-search-service.js +457 -2
- package/dist/service/workspace-domain-state.js +41 -2
- package/dist/service/workspace-file-service.js +150 -2
- package/dist/service/workspace-git-exclude-service.js +119 -2
- package/dist/service/workspace-queue-workbench-service.js +176 -2
- package/dist/service/workspace-service.js +92 -2
- package/dist/service/workspace-session-service.js +154 -2
- package/dist/service/workspace-upload-service.js +262 -2
- package/dist/service/workspace-watch-controller.js +68 -2
- package/dist/service/workspace-watch-service.js +170 -2
- package/dist/service/workspace-watch-snapshot-service.js +218 -2
- package/dist/service/workspace-workbench-service.js +239 -2
- package/dist/service.js +91 -2
- package/dist/storage.js +32 -2
- package/dist/supervisor.js +136 -2
- package/dist/terminal.js +496 -2
- package/dist/util/git-credential-client.js +32 -0
- package/dist/util/node-operation-data.js +9 -2
- package/dist/util/node-operation-parsers.js +382 -2
- package/dist/util/personal-instructions.js +34 -2
- package/dist/util/runner-error.js +70 -2
- package/dist/util/runner-native-session-parsers.js +510 -2
- package/dist/util/safe-error.js +8 -2
- package/dist/util/secret-environment.js +25 -2
- package/dist/workspace.js +1793 -2
- package/package.json +11 -8
- package/vendor/ripgrep/darwin-arm64/rg +0 -0
- package/vendor/ripgrep/darwin-x64/rg +0 -0
- package/vendor/ripgrep/manifest.json +12 -0
- package/README.md +0 -42
- package/dist/event-buffer.js +0 -2
- package/dist/migrations/v001.js +0 -107
- package/dist/migrations/v002.js +0 -2
- package/dist/migrations/v003.js +0 -2
- package/dist/service/mcp-package-installer.js +0 -2
|
@@ -1,2 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { compactRunnerText, compactRunnerValue } from '../../util/node-operation-parsers.js';
|
|
2
|
+
export function normalizeOpenCodeTool(toolName, state) {
|
|
3
|
+
const status = state?.status === 'completed'
|
|
4
|
+
? 'COMPLETED'
|
|
5
|
+
: state?.status === 'error'
|
|
6
|
+
? 'FAILED'
|
|
7
|
+
: 'IN_PROGRESS';
|
|
8
|
+
const input = record(state?.input);
|
|
9
|
+
const normalizedName = toolName.toLowerCase();
|
|
10
|
+
const publicToolName = compactRunnerText(toolName, 128) || 'unknown';
|
|
11
|
+
const subagent = openCodeSubagentProjection(toolName, state?.input, state?.output);
|
|
12
|
+
if (normalizedName === 'bash' || normalizedName === 'shell' || normalizedName === 'cmd')
|
|
13
|
+
return {
|
|
14
|
+
kind: 'command_execution',
|
|
15
|
+
payload: {
|
|
16
|
+
command: compactRunnerText(typeof input?.command === 'string'
|
|
17
|
+
? input.command
|
|
18
|
+
: typeof input?.cmd === 'string'
|
|
19
|
+
? input.cmd
|
|
20
|
+
: publicToolName, 10_000),
|
|
21
|
+
cwd: typeof input?.cwd === 'string' ? compactRunnerText(input.cwd, 4_096) : null,
|
|
22
|
+
outputPreview: typeof state?.output === 'string' ? compactRunnerText(state.output, 10_000) : '',
|
|
23
|
+
outputRef: null,
|
|
24
|
+
exitCode: typeof state?.exitCode === 'number' ? state.exitCode : null,
|
|
25
|
+
durationMs: null,
|
|
26
|
+
truncated: false
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
kind: 'tool_call',
|
|
31
|
+
payload: {
|
|
32
|
+
namespace: 'opencode',
|
|
33
|
+
toolName: publicToolName,
|
|
34
|
+
title: compactRunnerText(typeof state?.title === 'string' ? state.title : toolName, 500) ||
|
|
35
|
+
publicToolName,
|
|
36
|
+
inputSummary: compactRunnerValue(state?.input, 10_000).text || null,
|
|
37
|
+
outputSummary: typeof state?.output === 'string' ? compactRunnerText(state.output, 10_000) : null,
|
|
38
|
+
progressLabel: null,
|
|
39
|
+
errorCode: status === 'FAILED' ? 'OPENCODE_TOOL_FAILED' : null,
|
|
40
|
+
truncated: false,
|
|
41
|
+
...subagent
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function record(value) {
|
|
46
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
47
|
+
? value
|
|
48
|
+
: undefined;
|
|
49
|
+
}
|
|
50
|
+
function openCodeSubagentProjection(toolName, input, output) {
|
|
51
|
+
if (toolName.toLowerCase() !== 'task')
|
|
52
|
+
return undefined;
|
|
53
|
+
const inputData = record(input);
|
|
54
|
+
const taskId = boundedId(inputData?.task_id) ?? boundedId(inputData?.taskId);
|
|
55
|
+
const nativeResult = openCodeTaskResult(output);
|
|
56
|
+
const title = typeof inputData?.description === 'string' ? compactRunnerText(inputData.description, 500) : '';
|
|
57
|
+
return {
|
|
58
|
+
subagentOperation: taskId === undefined ? 'START' : 'RESUME',
|
|
59
|
+
subagentId: taskId ?? nativeResult?.taskId ?? null,
|
|
60
|
+
...(title.length === 0 ? {} : { title }),
|
|
61
|
+
...(nativeResult === undefined
|
|
62
|
+
? {}
|
|
63
|
+
: { outputSummary: compactRunnerText(nativeResult.result, 10_000) || null })
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function openCodeTaskResult(value) {
|
|
67
|
+
if (typeof value !== 'string')
|
|
68
|
+
return undefined;
|
|
69
|
+
const match = /^<task\s+[^>]*\bid="([^"]+)"[^>]*>[\s\S]*?<task_result>([\s\S]*?)<\/task_result>[\s\S]*?<\/task>$/u.exec(value.trim());
|
|
70
|
+
const taskId = boundedId(match?.[1]);
|
|
71
|
+
return taskId === undefined || match?.[2] === undefined
|
|
72
|
+
? undefined
|
|
73
|
+
: { taskId, result: match[2].trim() };
|
|
74
|
+
}
|
|
75
|
+
function boundedId(value) {
|
|
76
|
+
if (typeof value !== 'string')
|
|
77
|
+
return undefined;
|
|
78
|
+
const normalized = value.trim();
|
|
79
|
+
return normalized.length > 0 && normalized.length <= 128 ? normalized : undefined;
|
|
80
|
+
}
|
|
@@ -1,2 +1,426 @@
|
|
|
1
|
-
|
|
2
|
-
function _0x1707(){const _0x381d8d=['y2fJAgu','BgvHC2vZ','ChjVzMLSzuzVCLzHBgLKyxrPB24','Dg9Rzw5Z','C2vZC2LVBI5Yzw1VDMu','BMf0AxzLq29UDhjVBa','AgLZDg9YEs5YzwfK','CgfYzw50suq','CNvUBMvYlM9Wzw5JB2rLlNbYB2zPBguUC2LUz2XLlwzSAwDODc1QB2LUzwq','zw52AxjVBM1LBNrgAw5NzxjWCMLUDa','mtq4mJq5mNHMAKr0sG','ntCYmdu0swrdAKff','DxjS','zgvMyxvSDa','CNvUBMvYlM9Wzw5JB2rLlNbYB2zPBguUChjVDMLKzxjZlMnVBxbSzxrLza','zw52AxjVBM1LBNrdBgLLBNrZ','CNvUBMvYlM9Wzw5JB2rLlNbYB2zPBguUChjVDMLKzxjZlMzHAwXLza','Aw5WDxq','CMvTB3rL','CgfYzw50swq','vu5bvKfjtefcteu','uLvotKvsx1voqvzbsuXbqKXf','ChjVzMLSzunHy2HLs2v5','yxzHAwXHyMXL','C3rYAw5N','t0zgsunjquW','BM93','ChjVzMLSzq','ChjVzMLSzvrPBwvYC0j5v29YA3nWywnL','Bg9JywW','DhvYBI5XDwv1zq','u0vtu0LptL9srvDjtKrFrKfjteve','zgLZy292zxj5u2nVCgu','y2XHDwrLq29Kzq','C29Tzq','DxbKyxrL','Bw9KzwXZqNLxB3jRC3bHy2u','Aw5JBhvKzxm','mJuYmJyZmLLfrKLNrq','AgvHzgvYCW','zxH0zxjUywXtzxnZAw9Uswq','DMfSDwvZ','y29TBwfUza','B2zMAwnPywW','BgvUz3rO','yxjNCW','DxbKyxrLzef0','CMvZDw1LrxH0zxjUywW','Bw9KzwW','CNvUBMvYlM9Wzw5JB2rLlNbYB2zPBguUy2fJAguTAgL0','ChjLC2vUDfnLC3nPB24','CNvUlMnHBMnLBa','CMvHzenVBNrLEhrvC2fNzq','y3jLyxrL','ChjVBw90zq','y29UDgv4DeXPBwL0CW','zxHLy3v0Aw9U','rvHurvjoquXFu0vtu0LptL9pqLnfuLzfx09otfK','CM91BMq','Cgf0Aa','uLvotKvsx0nptu1btKrFvu5bvKfjtefcteu','zMLUywXSEq','BwfUywDLzfr1CM5Z','CM9Szq','C3vTBwfYAxPL','CMvHzenVBNzLCNnHDgLVBKHPC3rVCNK','ywjVCNq','Bg9JywXLq29TCgfYzq','y3jLyxrLu2vZC2LVBG','C3rVCa','Bw9KzwXZ','C3rYAw5NAwz5','B2jQzwn0','zMLUza','zMv0y2HqCM9MAwXL','Aw5MBW','u1resu8','C3rVChbPBMDdBgLLBNrZ','zMLSDgvY','mJiXntC4EefnyvPi','CMvHza','ChvZAa','y2XPzw50','y2XLyxi','y29UzMLNDxjLrw52AxjVBM1LBNq','BwfW','ywnJzxnZ','y3jLyxrLuhjVAMvJDgLVBG','C2vZC2LVBNm','CMvTB3zLtMf0AxzL','DxnLCI1PBNb1Dc5YzxnWB25K','CMvUyw1LtMf0AxzL','BwnWq29UzMLNDxjHDgLVBG','zw50CMLLCW','y29TBwfUzfn0yxrLCW','D29YA3nWywnLugf0Aa','BwfUywDLzfj1BKzVCK5HDgL2zvr1CM4','DhvYBI5PBNrLCNj1Chq','C2HHmJu2','BNvTyMvY','zw5ZDxjLq29UzMLNDxjHDgLVBG','DxbKyxrLu2vZC2LVBG','zxHLy3v0zunVBxbHy3q','zxHWAxjLC0f0','zgvMyxvSDenVBMzPz3vYyxrPB24','Agv4','DgL0Bgu','yxnZAxn0yw50','uLvotKvsx1jfu1vnrv9gquLmruq','DxbKyxrLza','BwfUywDLzenSAwvUDa','BwvZC2fNzxm','rvHurvjoquXFqunusvzf','Bw9KzwXjra','surmrq','BgLUDxG','ywrK','CMvMCMvZAfbYB2zPBgu','ndqYntu2nvPurKnUBa','C29YDa','zgLYzwn0B3j5','BwfUywDLzefJDgL2zq','ChjVDMLKzxjjra','yxbWCM92ywWUCMvZCg9Uza','C3vWCg9YDhndB25MAwD1CMf0Aw9U','v09ss1nqqunfx1jfuvvjuKve','DMfSAwrHDgLVBG','zxzLBNrZlMXPDMu','mJeZmJe2m3jttK5jCW','tufoquDfra','mJu2mduYneD6BhL6Dq','zgLZy292zxjtzxnZAw9UCW','ChjVAMvJDgLVBKzVCG','DhvYBI5ZDgfYDa','zNjVBuvUDhjPzxm','uKvtvu1bqKXf','C2nOzwr1BgvqCM9MAwXLrxHWAxj5','CMvSzwfZzu1HBMfNzwrdBgLLBNq','u0vtu0LptL9srvDjtKrFvu5bvKfjtefcteu','zgLNzxn0','zgvSzxrLu2vZC2LVBG','y2fJAgvKtw9KzwXZ','zxH0zxjUywXby3rPDML0Eq','z2v0','y3DK','AxngAw5PDgu','ywXSu2v0DgXLza','C2v0','C2vZC2LVBI5YzxDPBMq','zw52AxjVBM1LBNq','AxnbCNjHEq','tufoquDfrf9bq1rjvKu','B3bLBMnVzgu','t0jtrvjwrv9ptKXz','zwzMB3j0','CNvUBMvY','zM9YA05HDgL2zq','C2vZC2LVBI5WAw4','y29UDgv4DeXPBwL0C0j5v29YA3nWywnL','zMXHDe1HCa','ywnJzxnZt3b0Aw9UCW','zM9YA1nLC3nPB24','CMvHze9MzMLJAwfSq29UDMvYC2f0Aw9U','D29YA3nWywnLCW','zgvSzxrL','Dw5Yzwy','ChjVzMLSzunHy2HL','ChjVzMLSzvjLzNjLC2HLCW','y29KzxG','C2vZC2LVBI5Yzw5HBwu','C3vWCg9YDgvKrwzMB3j0CW','y2XLyxjqCM9MAwXLvgLTzxi','ChjVDMLKzxjZ','BMfTzq','B3bLBKnVzgu','tufsx01btKfhruq','y2XPzw50rMfJDg9YEq','DhjHBNnWB3j0','DgLTzq'];_0x1707=function(){return _0x381d8d;};return _0x1707();}const _0xb77256=_0x5690;(function(_0x5d76c6,_0x3451ea){const _0x33ef58=_0x5690,_0x3664a6=_0x5d76c6();while(!![]){try{const _0x2659fc=-parseInt(_0x33ef58(0x221))/(-0x1*-0x61f+-0x11f0+0xbd2)+parseInt(_0x33ef58(0x1dc))/(0x2f*-0x97+0x6a2+0xb*0x1eb)+parseInt(_0x33ef58(0x19f))/(0x3b6+0x1*0x4bd+0x4*-0x21c)+parseInt(_0x33ef58(0x1f8))/(-0xa8a+0xa7*-0x2+-0xbdc*-0x1)+-parseInt(_0x33ef58(0x195))/(-0x1eb6+0x164f+-0xc4*-0xb)+-parseInt(_0x33ef58(0x1a1))/(-0x1bfe+-0xa85*0x1+0x5*0x7b5)+-parseInt(_0x33ef58(0x1dd))/(-0x1*0x1669+-0x4ac+-0x2b6*-0xa);if(_0x2659fc===_0x3451ea)break;else _0x3664a6['push'](_0x3664a6['shift']());}catch(_0x5ea4d4){_0x3664a6['push'](_0x3664a6['shift']());}}}(_0x1707,-0xb*-0x5d79+0x7ed64+-0xf651*0x5));import{OpenCodeServerClient}from'../opencode-server.js';import{openCodeContextLimits,openCodeProfileModels}from'../opencode-runtime.js';import{declaredRunnerProfiles}from'../runner-profiles.js';import{AbstractRunner}from'./abstract-runner.js';import{isWithinWorkspace}from'./codex/conversation-parser.js';import{createHash}from'node:crypto';import{openCodeConversationPage}from'./opencode/conversation-parser.js';import{nodeLog}from'../operational.js';function _0x5690(_0x9618dd,_0x1eecb5){_0x9618dd=_0x9618dd-(0x22c5+-0x977*-0x1+-0x2ab2*0x1);const _0x36bfa2=_0x1707();let _0x2ff0c7=_0x36bfa2[_0x9618dd];if(_0x5690['QinCba']===undefined){var _0x3eab11=function(_0x2c0b97){const _0x4e3a56='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5004f6='',_0x341e2a='';for(let _0x3f9a52=0x10ae+0x12*-0x56+-0xaa2,_0x2dc809,_0x105e26,_0x539aee=0x385*0x5+0xbcd+-0x1d66;_0x105e26=_0x2c0b97['charAt'](_0x539aee++);~_0x105e26&&(_0x2dc809=_0x3f9a52%(-0x678+0x1e25+0x7e3*-0x3)?_0x2dc809*(0x13e9+-0x2*-0x130d+0x3*-0x1341)+_0x105e26:_0x105e26,_0x3f9a52++%(-0x59c*-0x1+-0x1*-0x153d+-0x1ad5))?_0x5004f6+=String['fromCharCode'](0x2457+-0x6+-0x2352&_0x2dc809>>(-(-0x225b+-0x1ea*0x5+0x1e9*0x17)*_0x3f9a52&0x12b+0xf9f*-0x2+0x605*0x5)):-0x1*-0x17fd+-0x1*0x187d+0x80){_0x105e26=_0x4e3a56['indexOf'](_0x105e26);}for(let _0x3daa7d=-0x1233*0x1+0x15c*0x1b+0x1*-0x1281,_0x38f0c6=_0x5004f6['length'];_0x3daa7d<_0x38f0c6;_0x3daa7d++){_0x341e2a+='%'+('00'+_0x5004f6['charCodeAt'](_0x3daa7d)['toString'](0xeb1+0x1784+0xf*-0x28b))['slice'](-(0x3*0xaed+-0x47+-0x207e));}return decodeURIComponent(_0x341e2a);};_0x5690['QtaguJ']=_0x3eab11,_0x5690['uqKEya']={},_0x5690['QinCba']=!![];}const _0x22be13=_0x36bfa2[0xd5*-0xa+0x19c0+-0x116e];_0x5690['qVefuv']!==_0x22be13&&(_0x5690['uqKEya']={},_0x5690['qVefuv']=_0x22be13);const _0x565c94=_0x5690['uqKEya'][_0x9618dd];return _0x565c94===undefined?(_0x2ff0c7=_0x5690['QtaguJ'](_0x2ff0c7),_0x5690['uqKEya'][_0x9618dd]=_0x2ff0c7):_0x2ff0c7=_0x565c94,_0x2ff0c7;}const PROFILE_ENTRY_TTL_MS=(0xae6+0x6*0x2b4+0x1b0*-0x10)*(-0x127e7+-0x269*0x98+0x3809f);export class OpenCodeRunner extends AbstractRunner{[_0xb77256(0x224)];[_0xb77256(0x1cf)];[_0xb77256(0x1cc)]=_0xb77256(0x1b7);[_0xb77256(0x1f2)]=_0xb77256(0x19c);[_0xb77256(0x1f6)]=new Map();[_0xb77256(0x1bd)]=new Map();[_0xb77256(0x1ee)]=new Map();[_0xb77256(0x1c5)]=new Map();[_0xb77256(0x1c6)]=new Map();[_0xb77256(0x20a)]=new Map();[_0xb77256(0x210)]=new Map();[_0xb77256(0x1e1)]=new Map();[_0xb77256(0x21f)]=new Set();constructor(_0x55c045=new OpenCodeServerClient(),_0x2f7c42=()=>new OpenCodeServerClient()){const _0x2c6273=_0xb77256;super(),this[_0x2c6273(0x224)]=_0x55c045,this[_0x2c6273(0x1cf)]=_0x2f7c42;}[_0xb77256(0x1ed)](_0x53c7e2){const _0x14a1e8=_0xb77256,_0x1942d7=declaredRunnerProfiles({'codexAvailable':_0x53c7e2[_0x14a1e8(0x1c7)][_0x14a1e8(0x1e9)],'claudeCodeAvailable':_0x53c7e2[_0x14a1e8(0x1f3)][_0x14a1e8(0x1e9)],'openCodeAvailable':_0x53c7e2[_0x14a1e8(0x1cd)]?.[_0x14a1e8(0x1e9)]===!![]})[_0x14a1e8(0x21b)](_0x35df36=>_0x35df36[_0x14a1e8(0x1ba)]===this[_0x14a1e8(0x1cc)]);return{..._0x1942d7,'models':[]};}async[_0xb77256(0x194)](_0x2239be,_0x548ba0,_0x787063={}){const _0x508511=_0xb77256;if(_0x2239be[_0x508511(0x1cd)]?.[_0x508511(0x1e9)]!==!![]||_0x548ba0===undefined)return this[_0x508511(0x1ed)](_0x2239be);const _0x20cc34=this[_0x508511(0x1e8)](_0x548ba0[_0x508511(0x20d)],_0x787063),_0x1fa36a=Date[_0x508511(0x1ec)]();for(const [_0x567602,_0x4abe16]of this[_0x508511(0x1c5)])if(_0x4abe16[_0x508511(0x239)]<=_0x1fa36a)this[_0x508511(0x1c5)][_0x508511(0x1c3)](_0x567602);const _0x71fc3=this[_0x508511(0x1c5)][_0x508511(0x1ae)](_0x20cc34);if(_0x71fc3!==undefined)return nodeLog(_0x508511(0x203),{'workspaceId':_0x548ba0['id'],'models':_0x71fc3[_0x508511(0x218)][_0x508511(0x1fe)],'remainingTtlMs':_0x71fc3[_0x508511(0x239)]-_0x1fa36a}),this[_0x508511(0x1f6)][_0x508511(0x1b2)](_0x548ba0[_0x508511(0x20d)],_0x71fc3[_0x508511(0x218)]),this[_0x508511(0x1bd)][_0x508511(0x1b2)](_0x548ba0[_0x508511(0x20d)],_0x71fc3[_0x508511(0x209)]),this[_0x508511(0x1a7)](_0x548ba0[_0x508511(0x20d)]),{...this[_0x508511(0x1ed)](_0x2239be),'models':_0x71fc3[_0x508511(0x218)]};const _0x178e72=this[_0x508511(0x1c6)][_0x508511(0x1ae)](_0x20cc34);if(_0x178e72!==undefined)return nodeLog(_0x508511(0x1da),{'workspaceId':_0x548ba0['id']}),_0x178e72;const _0x4928e0=this[_0x508511(0x21c)](_0x2239be,_0x548ba0,_0x787063,_0x20cc34)[_0x508511(0x20f)](()=>{const _0x12c288=_0x508511;if(this[_0x12c288(0x1c6)][_0x12c288(0x1ae)](_0x20cc34)===_0x4928e0)this[_0x12c288(0x1c6)][_0x12c288(0x1c3)](_0x20cc34);});return this[_0x508511(0x1c6)][_0x508511(0x1b2)](_0x20cc34,_0x4928e0),_0x4928e0;}async[_0xb77256(0x21c)](_0x517d18,_0x20efb0,_0x525d1f,_0x1e50d8){const _0x59a0f8=_0xb77256,_0x36eea0=this[_0x59a0f8(0x18d)](_0x525d1f),_0xf27e34=performance[_0x59a0f8(0x1ec)]();try{const _0x2fecb5=await _0x36eea0[_0x59a0f8(0x1cb)](_0x20efb0[_0x59a0f8(0x20d)]),_0x787a4b=openCodeProfileModels(_0x2fecb5),_0x29f234=openCodeContextLimits(_0x2fecb5);return this[_0x59a0f8(0x1f6)][_0x59a0f8(0x1b2)](_0x20efb0[_0x59a0f8(0x20d)],_0x787a4b),this[_0x59a0f8(0x1bd)][_0x59a0f8(0x1b2)](_0x20efb0[_0x59a0f8(0x20d)],_0x29f234),this[_0x59a0f8(0x1c5)][_0x59a0f8(0x1b2)](_0x1e50d8,{'expiresAt':Date[_0x59a0f8(0x1ec)]()+PROFILE_ENTRY_TTL_MS,'workspacePath':_0x20efb0[_0x59a0f8(0x20d)],'environmentFingerprint':this[_0x59a0f8(0x1db)](_0x525d1f),'models':_0x787a4b,'contextLimits':_0x29f234}),this[_0x59a0f8(0x1a7)](_0x20efb0[_0x59a0f8(0x20d)]),nodeLog(_0x59a0f8(0x1e0),{'workspaceId':_0x20efb0['id'],'models':_0x787a4b[_0x59a0f8(0x1fe)],'durationMs':Math[_0x59a0f8(0x20c)](performance[_0x59a0f8(0x1ec)]()-_0xf27e34)}),{...this[_0x59a0f8(0x1ed)](_0x517d18),'models':_0x787a4b};}catch{nodeLog(_0x59a0f8(0x1e2),{'workspaceId':_0x20efb0['id'],'durationMs':Math[_0x59a0f8(0x20c)](performance[_0x59a0f8(0x1ec)]()-_0xf27e34)});}finally{this[_0x59a0f8(0x1a8)](_0x36eea0);}return this[_0x59a0f8(0x1ed)](_0x517d18);}[_0xb77256(0x1e8)](_0x50c434,_0x1fe36e){const _0x1d88ef=_0xb77256;return createHash(_0x1d88ef(0x234))[_0x1d88ef(0x1f5)](JSON[_0x1d88ef(0x219)]({'workspacePath':_0x50c434,'environment':this[_0x1d88ef(0x1db)](_0x1fe36e)}))[_0x1d88ef(0x1aa)](_0x1d88ef(0x23b));}[_0xb77256(0x1db)](_0x4ca3a7){const _0x150d3b=_0xb77256,_0x105f49=Object[_0x150d3b(0x22f)](_0x4ca3a7)[_0x150d3b(0x196)](([_0x32b942],[_0x47f36b])=>_0x32b942[_0x150d3b(0x215)](_0x47f36b));return createHash(_0x150d3b(0x234))[_0x150d3b(0x1f5)](JSON[_0x150d3b(0x219)](_0x105f49))[_0x150d3b(0x1aa)](_0x150d3b(0x23b));}[_0xb77256(0x1e9)](_0x2d9ba5){const _0x42ef99=_0xb77256;return _0x2d9ba5[_0x42ef99(0x1cd)]?.[_0x42ef99(0x1e9)]===!![];}[_0xb77256(0x1d4)](){const _0x17c5f0=_0xb77256;return this[_0x17c5f0(0x1ed)]({'platform':_0x17c5f0(0x192),'architecture':_0x17c5f0(0x19d),'nodeAppVersion':_0x17c5f0(0x19d),'nodeVersion':_0x17c5f0(0x19d),'codex':{'available':![]},'claudeCode':{'available':![]},'openCode':{'available':!![]}});}[_0xb77256(0x19b)](_0x1911fc,_0x286690,_0x497c7f={}){const _0xbb3f51=_0xb77256;if(_0x1911fc[_0xbb3f51(0x1ba)]!==this[_0xbb3f51(0x1cc)])return![];const _0x2b55b3=this[_0xbb3f51(0x1ac)](_0x286690,_0x497c7f),_0x50f696=_0x2b55b3[_0xbb3f51(0x21b)](_0x15afad=>_0x15afad['id']===_0x1911fc[_0xbb3f51(0x202)]);return _0x50f696!==undefined&&(_0x50f696[_0xbb3f51(0x1c9)][_0xbb3f51(0x1fe)]===0x2694*0x1+0x1d74+-0xe*0x4dc||_0x50f696[_0xbb3f51(0x1c9)][_0xbb3f51(0x1f7)](_0x1911fc[_0xbb3f51(0x1b9)]))&&this[_0xbb3f51(0x1d4)]()[_0xbb3f51(0x1bf)][_0xbb3f51(0x1f4)](_0x55b507=>_0x55b507['id']===_0x1911fc[_0xbb3f51(0x228)]);}[_0xb77256(0x23a)](_0x332435,_0x4a5e98={}){const _0x204f5c=_0xb77256,_0x13f73e=this[_0x204f5c(0x1ac)](_0x332435,_0x4a5e98)[0xda*0x2d+-0x213*-0x2+-0x3*0xe28];return{'runner':this[_0x204f5c(0x1cc)],'model':_0x13f73e?.['id']??'','effort':_0x13f73e?.[_0x204f5c(0x1c9)][-0x2622+0x2457+0x1cb]??'','access':_0x204f5c(0x1df)};}[_0xb77256(0x1ac)](_0x341010,_0x39ab01){const _0x2fea21=_0xb77256,_0x56c051=this[_0x2fea21(0x1db)](_0x39ab01),_0x3344b6=Date[_0x2fea21(0x1ec)]();return[...this[_0x2fea21(0x1c5)][_0x2fea21(0x1fb)]()][_0x2fea21(0x220)](_0x734cca=>_0x734cca[_0x2fea21(0x239)]>_0x3344b6&&_0x734cca[_0x2fea21(0x1db)]===_0x56c051&&(_0x341010===undefined||_0x734cca[_0x2fea21(0x231)]===_0x341010[_0x2fea21(0x20d)]))[_0x2fea21(0x1be)](_0x4f4846=>_0x4f4846[_0x2fea21(0x218)]);}[_0xb77256(0x22e)](_0x2827a7,_0x7c927){const _0x4d9483=_0xb77256,_0x316257=super[_0x4d9483(0x22e)](_0x2827a7,_0x7c927);return Object[_0x4d9483(0x1a5)](_0x316257[_0x4d9483(0x227)](_0x14d99d=>[_0x14d99d[_0x4d9483(0x1cc)],_0x14d99d[_0x4d9483(0x1d0)]===_0x4d9483(0x21e)?{'type':_0x4d9483(0x1ef),'command':[_0x14d99d[_0x4d9483(0x1fc)],..._0x14d99d[_0x4d9483(0x1ff)]??[]],'environment':{..._0x14d99d[_0x4d9483(0x1b4)]??{}}}:{'type':_0x4d9483(0x1e4),'url':_0x14d99d[_0x4d9483(0x1de)],'headers':{..._0x14d99d[_0x4d9483(0x1f9)]??{}},'oauth':![]}]));}async[_0xb77256(0x1a2)](_0x4933c9,_0x3e20a6){const _0x2c9e23=_0xb77256,_0x5b373b=[];for(const _0x304201 of _0x3e20a6===undefined?_0x4933c9[_0x2c9e23(0x1c2)]:[_0x3e20a6]){let _0x4bc4ee;try{_0x4bc4ee=await this[_0x2c9e23(0x224)][_0x2c9e23(0x22a)](_0x304201[_0x2c9e23(0x20d)]);}catch{continue;}for(const _0x3be48e of _0x4bc4ee){const _0x15bfc3=openCodeSession(_0x3be48e);if(_0x15bfc3===undefined||_0x15bfc3[_0x2c9e23(0x1e5)]!==undefined||!isWithinWorkspace(_0x15bfc3[_0x2c9e23(0x197)],_0x304201[_0x2c9e23(0x20d)]))continue;_0x5b373b[_0x2c9e23(0x223)](_0x4933c9[_0x2c9e23(0x229)]({'workspace':_0x304201,'runner':this[_0x2c9e23(0x1cc)],'externalSessionId':_0x15bfc3['id'],'cwd':_0x15bfc3[_0x2c9e23(0x197)],'title':_0x15bfc3[_0x2c9e23(0x23c)],'titleOrigin':_0x2c9e23(0x1eb),'lastActivityAt':_0x15bfc3[_0x2c9e23(0x200)]}));}}return _0x5b373b;}async[_0xb77256(0x201)](_0x246100,_0x594ca6){const _0x2e09a2=_0xb77256;if(_0x246100[_0x2e09a2(0x1ba)]!==this[_0x2e09a2(0x1cc)]||_0x246100[_0x2e09a2(0x1fa)]===null||!_0x594ca6[_0x2e09a2(0x1e9)])return{'failureCode':_0x2e09a2(0x1e7)};const _0x1ae568=_0x594ca6[_0x2e09a2(0x1a3)](_0x246100),_0x5b3b59=_0x1ae568===undefined?_0x594ca6[_0x2e09a2(0x207)](_0x246100):_0x594ca6[_0x2e09a2(0x208)](_0x1ae568['id']);return _0x5b3b59===undefined?{'activity':_0x2e09a2(0x1e6),'failureCode':_0x2e09a2(0x18b)}:{'activity':_0x2e09a2(0x191),'session':_0x594ca6[_0x2e09a2(0x236)](_0x5b3b59)};}async[_0xb77256(0x1c1)](_0x2d0e0f,_0x5c9b94,_0x598712){const _0x4780f0=_0xb77256;if(_0x2d0e0f[_0x4780f0(0x1fa)]===null)return undefined;try{return openCodeConversationPage(_0x2d0e0f,await this[_0x4780f0(0x224)][_0x4780f0(0x18e)](_0x2d0e0f[_0x4780f0(0x1af)],_0x2d0e0f[_0x4780f0(0x1fa)],-0x444+-0x225b+-0x2893*-0x1),_0x5c9b94,_0x598712);}catch{return undefined;}}async[_0xb77256(0x213)](_0xf5c3fa){const _0x3fc709=_0xb77256,_0x4cbb14=await _0xf5c3fa[_0x3fc709(0x1fd)]();return _0x4cbb14===undefined?undefined:{..._0x4cbb14,'source':_0x3fc709(0x1fd)};}[_0xb77256(0x232)](_0x65a410){const _0x1c2f8b=_0xb77256;return this[_0x1c2f8b(0x210)][_0x1c2f8b(0x1ae)](_0x65a410);}[_0xb77256(0x204)](_0x4329ae,_0x552d6d,_0x249d65){const _0x2c6bbe=_0xb77256,_0xd124fd=_0x552d6d[_0x2c6bbe(0x1cd)]?.[_0x2c6bbe(0x1e9)]===!![],_0x362e89=_0x4329ae[_0x2c6bbe(0x1d7)]===_0x2c6bbe(0x1ce),_0x5e6deb=_0x249d65[_0x2c6bbe(0x198)]?_0x2c6bbe(0x1b6):_0x249d65[_0x2c6bbe(0x1ad)]??(_0xd124fd?_0x2c6bbe(0x191):_0x2c6bbe(0x1e6));if(!_0xd124fd)return{'activity':_0x2c6bbe(0x1e6),'control':{'level':_0x2c6bbe(0x1e6),'capabilities':[]},'runtime':{'level':_0x2c6bbe(0x1e6),'capabilities':[],'reasonCode':_0x2c6bbe(0x1e7)},'commandStates':_0x249d65[_0x2c6bbe(0x230)]};const _0x1d522b=[_0x2c6bbe(0x1d8),_0x2c6bbe(0x19e),_0x2c6bbe(0x1a4),_0x2c6bbe(0x1f0),_0x2c6bbe(0x233),_0x2c6bbe(0x205),_0x2c6bbe(0x19a),_0x2c6bbe(0x22c),_0x2c6bbe(0x1c8),_0x2c6bbe(0x1d6),_0x2c6bbe(0x1bc),..._0x4329ae[_0x2c6bbe(0x1fa)]===null?[]:[_0x2c6bbe(0x1b3)]];return{'activity':_0x5e6deb,'control':{'level':_0x362e89?_0x2c6bbe(0x1a0):_0x5e6deb===_0x2c6bbe(0x191)?_0x2c6bbe(0x1a6):_0x2c6bbe(0x1b8),'capabilities':_0x362e89||_0x5e6deb===_0x2c6bbe(0x191)?[_0x2c6bbe(0x1d8),_0x2c6bbe(0x19e),_0x2c6bbe(0x1a4),_0x2c6bbe(0x233)]:[_0x2c6bbe(0x1d8),_0x2c6bbe(0x19e)]},'runtime':{'level':_0x362e89?_0x2c6bbe(0x1a0):_0x5e6deb===_0x2c6bbe(0x191)?_0x2c6bbe(0x1a6):_0x2c6bbe(0x1b8),'capabilities':_0x1d522b,'reasonCode':_0x5e6deb===_0x2c6bbe(0x18f)?_0x2c6bbe(0x20b):null},'commandStates':_0x249d65[_0x2c6bbe(0x230)]};}async[_0xb77256(0x22d)](_0x12743a,_0xd59ffb,_0x5aeaa2){const _0x149ee7=_0xb77256;if(_0x12743a[_0x149ee7(0x1fa)]!==null&&_0xd59ffb[_0x149ee7(0x23c)]!==undefined)await this[_0x149ee7(0x224)][_0x149ee7(0x237)](_0x12743a[_0x149ee7(0x1af)],_0x12743a[_0x149ee7(0x1fa)],_0xd59ffb[_0x149ee7(0x23c)]??'');await super[_0x149ee7(0x22d)](_0x12743a,_0xd59ffb,_0x5aeaa2);}async[_0xb77256(0x22b)](_0x11f950,_0x13a09f){const _0xfadd4c=_0xb77256;return await this[_0xfadd4c(0x224)][_0xfadd4c(0x1ab)](_0x11f950[_0xfadd4c(0x1af)],_0x13a09f),!![];}async[_0xb77256(0x1bb)](_0x417cf3,_0xcac844,_0x3da434){const _0x27d9c7=_0xb77256;if(_0x417cf3[_0x27d9c7(0x1fa)]===null)throw new Error(_0x27d9c7(0x1a9));const _0x2dc026=_0xcac844===null?await this[_0x27d9c7(0x224)][_0x27d9c7(0x216)](_0x417cf3[_0x27d9c7(0x1af)],_0x3da434):await this[_0x27d9c7(0x224)][_0x27d9c7(0x1c0)](_0x417cf3[_0x27d9c7(0x1af)],_0x417cf3[_0x27d9c7(0x1fa)],_0xcac844),_0x4c0e4c=object(_0x2dc026);if(typeof _0x4c0e4c?.['id']!==_0x27d9c7(0x1ea))throw new Error(_0x27d9c7(0x1f1));if(_0xcac844!==null)await this[_0x27d9c7(0x224)][_0x27d9c7(0x237)](_0x417cf3[_0x27d9c7(0x1af)],_0x4c0e4c['id'],_0x3da434);return _0x4c0e4c['id'];}async[_0xb77256(0x238)](_0x5ac2f7,_0x292e61){const _0x41b0cb=_0xb77256;if(_0x5ac2f7[_0x41b0cb(0x1fa)]===null||_0x5ac2f7[_0x41b0cb(0x202)]===null)throw new Error(_0x41b0cb(0x20e));const _0x152590=this[_0x41b0cb(0x18d)](_0x292e61);try{return await _0x152590[_0x41b0cb(0x212)](_0x5ac2f7[_0x41b0cb(0x1af)],_0x5ac2f7[_0x41b0cb(0x1fa)],_0x5ac2f7[_0x41b0cb(0x202)]);}finally{this[_0x41b0cb(0x1a8)](_0x152590);}}async[_0xb77256(0x206)](_0x47ab0e){const _0x3d3375=_0xb77256;if(_0x47ab0e[_0x3d3375(0x1fa)]===null)return undefined;const _0x3301ad=await this[_0x3d3375(0x224)][_0x3d3375(0x18e)](_0x47ab0e[_0x3d3375(0x1af)],_0x47ab0e[_0x3d3375(0x1fa)],-0x637*-0x5+0x1887+0x3736*-0x1),_0x45eb1a=_0x3301ad[_0x3d3375(0x1be)](_0x5ad87d=>{const _0x3fb672=_0x3d3375,_0x2e8af0=object(_0x5ad87d),_0x1d6caa=object(_0x2e8af0?.[_0x3fb672(0x21d)]);return _0x1d6caa?.[_0x3fb672(0x211)]===_0x3fb672(0x18a)?[_0x1d6caa]:[];}),_0x3bbc75=_0x45eb1a['at'](-(-0x8b*-0x43+-0x1*-0x21d6+-0x13*0x3b2)),_0x7bed0e=typeof _0x3bbc75?.[_0x3d3375(0x199)]===_0x3d3375(0x1ea)?_0x3bbc75[_0x3d3375(0x199)]:undefined,_0x20e135=typeof _0x3bbc75?.[_0x3d3375(0x190)]===_0x3d3375(0x1ea)?_0x3bbc75[_0x3d3375(0x190)]:undefined,_0x47e835=object(_0x3bbc75?.[_0x3d3375(0x1d5)]),_0x1f1cc5=object(_0x47e835?.[_0x3d3375(0x1d2)]),_0x2eecdb=positiveNumber(_0x47e835?.[_0x3d3375(0x1e3)])+positiveNumber(_0x1f1cc5?.[_0x3d3375(0x222)]),_0x4c086f=_0x7bed0e!==undefined&&_0x20e135!==undefined?_0x7bed0e+'/'+_0x20e135:_0x47ab0e[_0x3d3375(0x202)],_0x1a0938=[...this[_0x3d3375(0x1bd)]][_0x3d3375(0x21b)](([_0x2cc164])=>isWithinWorkspace(_0x47ab0e[_0x3d3375(0x1af)],_0x2cc164))?.[0x5*-0x255+-0x1233+0x2b7*0xb],_0x45d63c=_0x4c086f===null?undefined:_0x1a0938?.[_0x3d3375(0x1ae)](_0x4c086f);return _0x45d63c===undefined||_0x2eecdb<=0xea*0x27+0x830+-0x2bd6?undefined:{'model':_0x4c086f,'usedTokens':_0x2eecdb,'maxTokens':_0x45d63c};}async[_0xb77256(0x217)](){const _0xfa26a8=_0xb77256;for(const _0x24cda6 of this[_0xfa26a8(0x20a)][_0xfa26a8(0x1fb)]())_0x24cda6[_0xfa26a8(0x214)][_0xfa26a8(0x214)]();this[_0xfa26a8(0x20a)][_0xfa26a8(0x225)](),this[_0xfa26a8(0x210)][_0xfa26a8(0x225)]();for(const _0x2a33aa of this[_0xfa26a8(0x1ee)][_0xfa26a8(0x1fb)]())clearTimeout(_0x2a33aa);this[_0xfa26a8(0x1ee)][_0xfa26a8(0x225)](),this[_0xfa26a8(0x1c5)][_0xfa26a8(0x225)](),this[_0xfa26a8(0x1c6)][_0xfa26a8(0x225)](),this[_0xfa26a8(0x1f6)][_0xfa26a8(0x225)](),this[_0xfa26a8(0x1bd)][_0xfa26a8(0x225)]();const _0x58065a=[this[_0xfa26a8(0x224)][_0xfa26a8(0x217)](),...[...this[_0xfa26a8(0x1e1)][_0xfa26a8(0x1fb)]()][_0xfa26a8(0x227)](({client:_0x32789d})=>_0x32789d[_0xfa26a8(0x217)]()),...this[_0xfa26a8(0x21f)]];this[_0xfa26a8(0x1e1)][_0xfa26a8(0x225)](),await Promise[_0xfa26a8(0x1b1)](_0x58065a),this[_0xfa26a8(0x21f)][_0xfa26a8(0x225)]();}[_0xb77256(0x1a7)](_0x390af1){const _0xef4157=_0xb77256;this[_0xef4157(0x1ca)](_0x390af1);const _0x2377ad=setTimeout(()=>{const _0x3e37cc=_0xef4157;this[_0x3e37cc(0x1ee)][_0x3e37cc(0x1c3)](_0x390af1),this[_0x3e37cc(0x1f6)][_0x3e37cc(0x1c3)](_0x390af1),this[_0x3e37cc(0x1bd)][_0x3e37cc(0x1c3)](_0x390af1);},PROFILE_ENTRY_TTL_MS);_0x2377ad[_0xef4157(0x1c4)](),this[_0xef4157(0x1ee)][_0xef4157(0x1b2)](_0x390af1,_0x2377ad);}[_0xb77256(0x1ca)](_0x4e76cc){const _0x88dfab=_0xb77256,_0x1a26a8=this[_0x88dfab(0x1ee)][_0x88dfab(0x1ae)](_0x4e76cc);if(_0x1a26a8!==undefined)clearTimeout(_0x1a26a8);this[_0x88dfab(0x1ee)][_0x88dfab(0x1c3)](_0x4e76cc);}[_0xb77256(0x18d)](_0x3eddaf,_0x5e9c87){const _0x413c25=_0xb77256,_0x1cc0ff=Object[_0x413c25(0x22f)](_0x3eddaf)[_0x413c25(0x196)](([_0x1886f6],[_0x427563])=>_0x1886f6[_0x413c25(0x215)](_0x427563));if(_0x1cc0ff[_0x413c25(0x1fe)]===-0x1*-0xfb6+0x2d*0x35+-0x1907&&_0x5e9c87===undefined)return this[_0x413c25(0x224)];const _0xe860ff=createHash(_0x413c25(0x234))[_0x413c25(0x1f5)](JSON[_0x413c25(0x219)]({'entries':_0x1cc0ff,'isolationKey':_0x5e9c87}))[_0x413c25(0x1aa)](_0x413c25(0x23b)),_0x5c9083=this[_0x413c25(0x1e1)][_0x413c25(0x1ae)](_0xe860ff);if(_0x5c9083!==undefined)return _0x5c9083[_0x413c25(0x1d3)]+=0xcbb*-0x3+-0x1aa*0x5+0x2e84,_0x5c9083[_0x413c25(0x224)];const _0x3948cb=this[_0x413c25(0x1cf)]();return _0x3948cb[_0x413c25(0x226)](_0x3eddaf),this[_0x413c25(0x1e1)][_0x413c25(0x1b2)](_0xe860ff,{'client':_0x3948cb,'leases':0x1}),_0x3948cb;}[_0xb77256(0x1a8)](_0x3fb842){const _0x5712b7=_0xb77256;if(_0x3fb842===this[_0x5712b7(0x224)])return;for(const [_0x2ec4c2,_0x41fa9c]of this[_0x5712b7(0x1e1)]){if(_0x41fa9c[_0x5712b7(0x224)]!==_0x3fb842)continue;_0x41fa9c[_0x5712b7(0x1d3)]-=0x1*-0x1f63+-0x4*0x36f+-0x2*-0x1690;if(_0x41fa9c[_0x5712b7(0x1d3)]<=0x2*0xc83+0x1a7d+-0x3383){const _0x26e8db=_0x41fa9c[_0x5712b7(0x224)][_0x5712b7(0x217)]();this[_0x5712b7(0x21f)][_0x5712b7(0x193)](_0x26e8db),void _0x26e8db[_0x5712b7(0x20f)](()=>this[_0x5712b7(0x21f)][_0x5712b7(0x1c3)](_0x26e8db)),this[_0x5712b7(0x1e1)][_0x5712b7(0x1c3)](_0x2ec4c2);}return;}}}function object(_0x48fbb0){const _0x276d60=_0xb77256;return typeof _0x48fbb0===_0x276d60(0x21a)&&_0x48fbb0!==null&&!Array[_0x276d60(0x1b5)](_0x48fbb0)?_0x48fbb0:undefined;}function positiveNumber(_0x39649c){const _0x2fb0a5=_0xb77256;return typeof _0x39649c===_0x2fb0a5(0x235)&&Number[_0x2fb0a5(0x1b0)](_0x39649c)&&_0x39649c>-0x1*0x22cb+-0x2dd*-0x4+0x1757?_0x39649c:-0x101+0x26f8+-0x25f7*0x1;}function openCodeSession(_0x32ad35){const _0x5cb3bb=_0xb77256;if(typeof _0x32ad35!==_0x5cb3bb(0x21a)||_0x32ad35===null)return undefined;const _0x159a58=_0x32ad35,_0x242f75=typeof _0x159a58[_0x5cb3bb(0x1d1)]===_0x5cb3bb(0x21a)&&_0x159a58[_0x5cb3bb(0x1d1)]!==null?_0x159a58[_0x5cb3bb(0x1d1)]:undefined;if(typeof _0x159a58['id']!==_0x5cb3bb(0x1ea)||typeof _0x159a58[_0x5cb3bb(0x197)]!==_0x5cb3bb(0x1ea)||typeof _0x159a58[_0x5cb3bb(0x23c)]!==_0x5cb3bb(0x1ea))return undefined;return{'id':_0x159a58['id'],'directory':_0x159a58[_0x5cb3bb(0x197)],'title':_0x159a58[_0x5cb3bb(0x23c)],'updatedAt':typeof _0x242f75?.[_0x5cb3bb(0x18c)]===_0x5cb3bb(0x235)?_0x242f75[_0x5cb3bb(0x18c)]:0x3*-0xac2+-0xf43*0x2+0x3ecc,...typeof _0x159a58[_0x5cb3bb(0x1d9)]===_0x5cb3bb(0x1ea)&&_0x159a58[_0x5cb3bb(0x1d9)][_0x5cb3bb(0x1fe)]>-0x15d1+-0x20c2+0x3693?{'parentId':_0x159a58[_0x5cb3bb(0x1d9)]}:{}};}
|
|
1
|
+
import { OpenCodeServerClient } from '../opencode-server.js';
|
|
2
|
+
import { openCodeContextLimits, openCodeProfileModels } from '../opencode-runtime.js';
|
|
3
|
+
import { declaredRunnerProfiles } from '../runner-profiles.js';
|
|
4
|
+
import { AbstractRunner } from './abstract-runner.js';
|
|
5
|
+
import { isWithinWorkspace } from './codex/conversation-parser.js';
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
import { openCodeConversationPage } from './opencode/conversation-parser.js';
|
|
8
|
+
import { nodeLog } from '../operational.js';
|
|
9
|
+
const PROFILE_ENTRY_TTL_MS = 30 * 60_000;
|
|
10
|
+
export class OpenCodeRunner extends AbstractRunner {
|
|
11
|
+
client;
|
|
12
|
+
clientFactory;
|
|
13
|
+
name = 'opencode';
|
|
14
|
+
discoveryScope = 'WORKSPACE_REQUIRED';
|
|
15
|
+
modelsByWorkspace = new Map();
|
|
16
|
+
contextLimitsByWorkspace = new Map();
|
|
17
|
+
profileTimersByWorkspace = new Map();
|
|
18
|
+
profileCache = new Map();
|
|
19
|
+
profileRefreshes = new Map();
|
|
20
|
+
execution = new Map();
|
|
21
|
+
managedTurns = new Map();
|
|
22
|
+
environmentClients = new Map();
|
|
23
|
+
stoppingClients = new Set();
|
|
24
|
+
constructor(client = new OpenCodeServerClient(), clientFactory = () => new OpenCodeServerClient()) {
|
|
25
|
+
super();
|
|
26
|
+
this.client = client;
|
|
27
|
+
this.clientFactory = clientFactory;
|
|
28
|
+
}
|
|
29
|
+
profile(capabilities) {
|
|
30
|
+
const base = declaredRunnerProfiles({
|
|
31
|
+
codexAvailable: capabilities.codex.available,
|
|
32
|
+
claudeCodeAvailable: capabilities.claudeCode.available,
|
|
33
|
+
openCodeAvailable: capabilities.openCode?.available === true
|
|
34
|
+
}).find((profile) => profile.runner === this.name);
|
|
35
|
+
return { ...base, models: [] };
|
|
36
|
+
}
|
|
37
|
+
async refreshProfile(capabilities, workspace, environment = {}) {
|
|
38
|
+
if (capabilities.openCode?.available !== true || workspace === undefined) {
|
|
39
|
+
return this.profile(capabilities);
|
|
40
|
+
}
|
|
41
|
+
const cacheKey = this.profileCacheKey(workspace.path, environment);
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
for (const [key, entry] of this.profileCache)
|
|
44
|
+
if (entry.expiresAt <= now)
|
|
45
|
+
this.profileCache.delete(key);
|
|
46
|
+
const cached = this.profileCache.get(cacheKey);
|
|
47
|
+
if (cached !== undefined) {
|
|
48
|
+
nodeLog('runner.opencode.profile.cache-hit', {
|
|
49
|
+
workspaceId: workspace.id,
|
|
50
|
+
models: cached.models.length,
|
|
51
|
+
remainingTtlMs: cached.expiresAt - now
|
|
52
|
+
});
|
|
53
|
+
this.modelsByWorkspace.set(workspace.path, cached.models);
|
|
54
|
+
this.contextLimitsByWorkspace.set(workspace.path, cached.contextLimits);
|
|
55
|
+
this.scheduleProfileExpiry(workspace.path);
|
|
56
|
+
return { ...this.profile(capabilities), models: cached.models };
|
|
57
|
+
}
|
|
58
|
+
const current = this.profileRefreshes.get(cacheKey);
|
|
59
|
+
if (current !== undefined) {
|
|
60
|
+
nodeLog('runner.opencode.profile.single-flight-joined', { workspaceId: workspace.id });
|
|
61
|
+
return current;
|
|
62
|
+
}
|
|
63
|
+
const refresh = this.fetchProfile(capabilities, workspace, environment, cacheKey).finally(() => {
|
|
64
|
+
if (this.profileRefreshes.get(cacheKey) === refresh)
|
|
65
|
+
this.profileRefreshes.delete(cacheKey);
|
|
66
|
+
});
|
|
67
|
+
this.profileRefreshes.set(cacheKey, refresh);
|
|
68
|
+
return refresh;
|
|
69
|
+
}
|
|
70
|
+
async fetchProfile(capabilities, workspace, environment, cacheKey) {
|
|
71
|
+
const client = this.managedClient(environment);
|
|
72
|
+
const startedAt = performance.now();
|
|
73
|
+
try {
|
|
74
|
+
const catalog = await client.providers(workspace.path);
|
|
75
|
+
const models = openCodeProfileModels(catalog);
|
|
76
|
+
const contextLimits = openCodeContextLimits(catalog);
|
|
77
|
+
this.modelsByWorkspace.set(workspace.path, models);
|
|
78
|
+
this.contextLimitsByWorkspace.set(workspace.path, contextLimits);
|
|
79
|
+
this.profileCache.set(cacheKey, {
|
|
80
|
+
expiresAt: Date.now() + PROFILE_ENTRY_TTL_MS,
|
|
81
|
+
workspacePath: workspace.path,
|
|
82
|
+
environmentFingerprint: this.environmentFingerprint(environment),
|
|
83
|
+
models,
|
|
84
|
+
contextLimits
|
|
85
|
+
});
|
|
86
|
+
this.scheduleProfileExpiry(workspace.path);
|
|
87
|
+
nodeLog('runner.opencode.profile.providers.completed', {
|
|
88
|
+
workspaceId: workspace.id,
|
|
89
|
+
models: models.length,
|
|
90
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
91
|
+
});
|
|
92
|
+
return { ...this.profile(capabilities), models };
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
nodeLog('runner.opencode.profile.providers.failed', {
|
|
96
|
+
workspaceId: workspace.id,
|
|
97
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
this.releaseManagedClient(client);
|
|
102
|
+
}
|
|
103
|
+
return this.profile(capabilities);
|
|
104
|
+
}
|
|
105
|
+
profileCacheKey(workspacePath, environment) {
|
|
106
|
+
return createHash('sha256')
|
|
107
|
+
.update(JSON.stringify({ workspacePath, environment: this.environmentFingerprint(environment) }))
|
|
108
|
+
.digest('hex');
|
|
109
|
+
}
|
|
110
|
+
environmentFingerprint(environment) {
|
|
111
|
+
const entries = Object.entries(environment).sort(([left], [right]) => left.localeCompare(right));
|
|
112
|
+
return createHash('sha256').update(JSON.stringify(entries)).digest('hex');
|
|
113
|
+
}
|
|
114
|
+
available(capabilities) {
|
|
115
|
+
return capabilities.openCode?.available === true;
|
|
116
|
+
}
|
|
117
|
+
profileForValidation() {
|
|
118
|
+
return this.profile({
|
|
119
|
+
platform: 'linux',
|
|
120
|
+
architecture: 'validation',
|
|
121
|
+
nodeAppVersion: 'validation',
|
|
122
|
+
nodeVersion: 'validation',
|
|
123
|
+
codex: { available: false },
|
|
124
|
+
claudeCode: { available: false },
|
|
125
|
+
openCode: { available: true }
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
supportsConfiguration(configuration, workspace, environment = {}) {
|
|
129
|
+
if (configuration.runner !== this.name)
|
|
130
|
+
return false;
|
|
131
|
+
const models = this.cachedModels(workspace, environment);
|
|
132
|
+
const model = models.find((candidate) => candidate.id === configuration.model);
|
|
133
|
+
return (model !== undefined &&
|
|
134
|
+
(model.supportedEfforts.length === 0 ||
|
|
135
|
+
model.supportedEfforts.includes(configuration.effort)) &&
|
|
136
|
+
this.profileForValidation().accessOptions.some((candidate) => candidate.id === configuration.access));
|
|
137
|
+
}
|
|
138
|
+
defaultConfiguration(workspace, environment = {}) {
|
|
139
|
+
const model = this.cachedModels(workspace, environment)[0];
|
|
140
|
+
return {
|
|
141
|
+
runner: this.name,
|
|
142
|
+
model: model?.id ?? '',
|
|
143
|
+
effort: model?.supportedEfforts[0] ?? '',
|
|
144
|
+
access: 'default'
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
cachedModels(workspace, environment) {
|
|
148
|
+
const fingerprint = this.environmentFingerprint(environment);
|
|
149
|
+
const now = Date.now();
|
|
150
|
+
return [...this.profileCache.values()]
|
|
151
|
+
.filter((entry) => entry.expiresAt > now &&
|
|
152
|
+
entry.environmentFingerprint === fingerprint &&
|
|
153
|
+
(workspace === undefined || entry.workspacePath === workspace.path))
|
|
154
|
+
.flatMap((entry) => entry.models);
|
|
155
|
+
}
|
|
156
|
+
mcpConfiguration(raw, secrets) {
|
|
157
|
+
const servers = super.mcpConfiguration(raw, secrets);
|
|
158
|
+
return Object.fromEntries(servers.map((server) => [
|
|
159
|
+
server.name,
|
|
160
|
+
server.transport === 'STDIO'
|
|
161
|
+
? {
|
|
162
|
+
type: 'local',
|
|
163
|
+
command: [server.command, ...(server.args ?? [])],
|
|
164
|
+
environment: { ...(server.environment ?? {}) }
|
|
165
|
+
}
|
|
166
|
+
: {
|
|
167
|
+
type: 'remote',
|
|
168
|
+
url: server.url,
|
|
169
|
+
headers: { ...(server.headers ?? {}) },
|
|
170
|
+
oauth: false
|
|
171
|
+
}
|
|
172
|
+
]));
|
|
173
|
+
}
|
|
174
|
+
async discoverSessions(context, workspace) {
|
|
175
|
+
const result = [];
|
|
176
|
+
for (const target of workspace === undefined ? context.workspaces : [workspace]) {
|
|
177
|
+
let sessions;
|
|
178
|
+
try {
|
|
179
|
+
sessions = await this.client.sessions(target.path);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
for (const value of sessions) {
|
|
185
|
+
const session = openCodeSession(value);
|
|
186
|
+
if (session === undefined ||
|
|
187
|
+
session.parentId !== undefined ||
|
|
188
|
+
!isWithinWorkspace(session.directory, target.path))
|
|
189
|
+
continue;
|
|
190
|
+
result.push(context.createProjection({
|
|
191
|
+
workspace: target,
|
|
192
|
+
runner: this.name,
|
|
193
|
+
externalSessionId: session.id,
|
|
194
|
+
cwd: session.directory,
|
|
195
|
+
title: session.title,
|
|
196
|
+
titleOrigin: 'OFFICIAL',
|
|
197
|
+
lastActivityAt: session.updatedAt
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
async resumeExternal(external, context) {
|
|
204
|
+
if (external.runner !== this.name || external.externalSessionId === null || !context.available)
|
|
205
|
+
return { failureCode: 'RUNNER_UNAVAILABLE' };
|
|
206
|
+
const projection = context.projectionFor(external);
|
|
207
|
+
const session = projection === undefined ? context.create(external) : context.promote(projection.id);
|
|
208
|
+
return session === undefined
|
|
209
|
+
? { activity: 'UNAVAILABLE', failureCode: 'RUNNER_RESUME_FAILED' }
|
|
210
|
+
: { activity: 'IDLE', session: context.ensureConfiguration(session) };
|
|
211
|
+
}
|
|
212
|
+
async readOfficialConversation(session, input, managedTurn) {
|
|
213
|
+
if (session.externalSessionId === null)
|
|
214
|
+
return undefined;
|
|
215
|
+
try {
|
|
216
|
+
return openCodeConversationPage(session, await this.client.messages(session.cwd, session.externalSessionId, 500), input, managedTurn);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async readConversationHistory(readers) {
|
|
223
|
+
const official = await readers.official();
|
|
224
|
+
return official === undefined ? undefined : { ...official, source: 'official' };
|
|
225
|
+
}
|
|
226
|
+
managedRunForNativeTurn(nativeTurnId) {
|
|
227
|
+
return this.managedTurns.get(nativeTurnId);
|
|
228
|
+
}
|
|
229
|
+
presentSession(session, capabilities, context) {
|
|
230
|
+
const available = capabilities.openCode?.available === true;
|
|
231
|
+
const managed = session.nativeControl === 'MAR_MANAGED';
|
|
232
|
+
const activity = context.managedActive
|
|
233
|
+
? 'MANAGED_ACTIVE'
|
|
234
|
+
: (context.externalActivity ?? (available ? 'IDLE' : 'UNAVAILABLE'));
|
|
235
|
+
if (!available)
|
|
236
|
+
return {
|
|
237
|
+
activity: 'UNAVAILABLE',
|
|
238
|
+
control: { level: 'UNAVAILABLE', capabilities: [] },
|
|
239
|
+
runtime: { level: 'UNAVAILABLE', capabilities: [], reasonCode: 'RUNNER_UNAVAILABLE' },
|
|
240
|
+
commandStates: context.commandStates
|
|
241
|
+
};
|
|
242
|
+
const runtimeCapabilities = [
|
|
243
|
+
'history.read',
|
|
244
|
+
'events.live',
|
|
245
|
+
'turn.start',
|
|
246
|
+
'turn.queue',
|
|
247
|
+
'turn.interrupt',
|
|
248
|
+
'run.cancel',
|
|
249
|
+
'approval.respond',
|
|
250
|
+
'user-input.respond',
|
|
251
|
+
'session.rename',
|
|
252
|
+
'session.remove',
|
|
253
|
+
'session.pin',
|
|
254
|
+
...(session.externalSessionId === null ? [] : ['session.rewind'])
|
|
255
|
+
];
|
|
256
|
+
return {
|
|
257
|
+
activity,
|
|
258
|
+
control: {
|
|
259
|
+
level: managed ? 'MANAGED' : activity === 'IDLE' ? 'RESUMABLE' : 'OBSERVE_ONLY',
|
|
260
|
+
capabilities: managed || activity === 'IDLE'
|
|
261
|
+
? ['history.read', 'events.live', 'turn.start', 'turn.interrupt']
|
|
262
|
+
: ['history.read', 'events.live']
|
|
263
|
+
},
|
|
264
|
+
runtime: {
|
|
265
|
+
level: managed ? 'MANAGED' : activity === 'IDLE' ? 'RESUMABLE' : 'OBSERVE_ONLY',
|
|
266
|
+
capabilities: runtimeCapabilities,
|
|
267
|
+
reasonCode: activity === 'EXTERNAL_ACTIVE' ? 'EXTERNAL_SESSION_OBSERVE_ONLY' : null
|
|
268
|
+
},
|
|
269
|
+
commandStates: context.commandStates
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
async renameNative(session, input, database) {
|
|
273
|
+
if (session.externalSessionId !== null && input.title !== undefined)
|
|
274
|
+
await this.client.updateSession(session.cwd, session.externalSessionId, input.title ?? '');
|
|
275
|
+
await super.renameNative(session, input, database);
|
|
276
|
+
}
|
|
277
|
+
async removeNative(session, nativeSessionId) {
|
|
278
|
+
await this.client.deleteSession(session.cwd, nativeSessionId);
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
async forkNative(session, boundary, title) {
|
|
282
|
+
if (session.externalSessionId === null)
|
|
283
|
+
throw new Error('SESSION_REWIND_UNAVAILABLE');
|
|
284
|
+
const result = boundary === null
|
|
285
|
+
? await this.client.createSession(session.cwd, title)
|
|
286
|
+
: await this.client.forkSession(session.cwd, session.externalSessionId, boundary);
|
|
287
|
+
const value = object(result);
|
|
288
|
+
if (typeof value?.id !== 'string')
|
|
289
|
+
throw new Error('SESSION_REWIND_FAILED');
|
|
290
|
+
if (boundary !== null)
|
|
291
|
+
await this.client.updateSession(session.cwd, value.id, title);
|
|
292
|
+
return value.id;
|
|
293
|
+
}
|
|
294
|
+
async executeCompact(session, environment) {
|
|
295
|
+
if (session.externalSessionId === null || session.model === null)
|
|
296
|
+
throw new Error('RUNNER_COMMAND_UNAVAILABLE');
|
|
297
|
+
const client = this.managedClient(environment);
|
|
298
|
+
try {
|
|
299
|
+
return await client.summarize(session.cwd, session.externalSessionId, session.model);
|
|
300
|
+
}
|
|
301
|
+
finally {
|
|
302
|
+
this.releaseManagedClient(client);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async readContextUsage(session) {
|
|
306
|
+
if (session.externalSessionId === null)
|
|
307
|
+
return undefined;
|
|
308
|
+
const messages = await this.client.messages(session.cwd, session.externalSessionId, 100);
|
|
309
|
+
const assistants = messages.flatMap((value) => {
|
|
310
|
+
const entry = object(value);
|
|
311
|
+
const info = object(entry?.info);
|
|
312
|
+
return info?.role === 'assistant' ? [info] : [];
|
|
313
|
+
});
|
|
314
|
+
const latest = assistants.at(-1);
|
|
315
|
+
const provider = typeof latest?.providerID === 'string' ? latest.providerID : undefined;
|
|
316
|
+
const model = typeof latest?.modelID === 'string' ? latest.modelID : undefined;
|
|
317
|
+
const tokens = object(latest?.tokens);
|
|
318
|
+
const cache = object(tokens?.cache);
|
|
319
|
+
const usedTokens = positiveNumber(tokens?.input) + positiveNumber(cache?.read);
|
|
320
|
+
const modelId = provider !== undefined && model !== undefined ? `${provider}/${model}` : session.model;
|
|
321
|
+
const limits = [...this.contextLimitsByWorkspace].find(([workspacePath]) => isWithinWorkspace(session.cwd, workspacePath))?.[1];
|
|
322
|
+
const maxTokens = modelId === null ? undefined : limits?.get(modelId);
|
|
323
|
+
return maxTokens === undefined || usedTokens <= 0
|
|
324
|
+
? undefined
|
|
325
|
+
: { model: modelId, usedTokens, maxTokens };
|
|
326
|
+
}
|
|
327
|
+
async stop() {
|
|
328
|
+
for (const execution of this.execution.values())
|
|
329
|
+
execution.abort.abort();
|
|
330
|
+
this.execution.clear();
|
|
331
|
+
this.managedTurns.clear();
|
|
332
|
+
for (const timer of this.profileTimersByWorkspace.values())
|
|
333
|
+
clearTimeout(timer);
|
|
334
|
+
this.profileTimersByWorkspace.clear();
|
|
335
|
+
this.profileCache.clear();
|
|
336
|
+
this.profileRefreshes.clear();
|
|
337
|
+
this.modelsByWorkspace.clear();
|
|
338
|
+
this.contextLimitsByWorkspace.clear();
|
|
339
|
+
const stopping = [
|
|
340
|
+
this.client.stop(),
|
|
341
|
+
...[...this.environmentClients.values()].map(({ client }) => client.stop()),
|
|
342
|
+
...this.stoppingClients
|
|
343
|
+
];
|
|
344
|
+
this.environmentClients.clear();
|
|
345
|
+
await Promise.allSettled(stopping);
|
|
346
|
+
this.stoppingClients.clear();
|
|
347
|
+
}
|
|
348
|
+
scheduleProfileExpiry(workspacePath) {
|
|
349
|
+
this.clearProfileTimer(workspacePath);
|
|
350
|
+
const timer = setTimeout(() => {
|
|
351
|
+
this.profileTimersByWorkspace.delete(workspacePath);
|
|
352
|
+
this.modelsByWorkspace.delete(workspacePath);
|
|
353
|
+
this.contextLimitsByWorkspace.delete(workspacePath);
|
|
354
|
+
}, PROFILE_ENTRY_TTL_MS);
|
|
355
|
+
timer.unref();
|
|
356
|
+
this.profileTimersByWorkspace.set(workspacePath, timer);
|
|
357
|
+
}
|
|
358
|
+
clearProfileTimer(workspacePath) {
|
|
359
|
+
const timer = this.profileTimersByWorkspace.get(workspacePath);
|
|
360
|
+
if (timer !== undefined)
|
|
361
|
+
clearTimeout(timer);
|
|
362
|
+
this.profileTimersByWorkspace.delete(workspacePath);
|
|
363
|
+
}
|
|
364
|
+
managedClient(environment, isolationKey) {
|
|
365
|
+
const entries = Object.entries(environment).sort(([left], [right]) => left.localeCompare(right));
|
|
366
|
+
if (entries.length === 0 && isolationKey === undefined)
|
|
367
|
+
return this.client;
|
|
368
|
+
const fingerprint = createHash('sha256')
|
|
369
|
+
.update(JSON.stringify({ entries, isolationKey }))
|
|
370
|
+
.digest('hex');
|
|
371
|
+
const existing = this.environmentClients.get(fingerprint);
|
|
372
|
+
if (existing !== undefined) {
|
|
373
|
+
existing.leases += 1;
|
|
374
|
+
return existing.client;
|
|
375
|
+
}
|
|
376
|
+
const client = this.clientFactory();
|
|
377
|
+
client.configureEnvironment(environment);
|
|
378
|
+
this.environmentClients.set(fingerprint, { client, leases: 1 });
|
|
379
|
+
return client;
|
|
380
|
+
}
|
|
381
|
+
releaseManagedClient(client) {
|
|
382
|
+
if (client === this.client)
|
|
383
|
+
return;
|
|
384
|
+
for (const [fingerprint, entry] of this.environmentClients) {
|
|
385
|
+
if (entry.client !== client)
|
|
386
|
+
continue;
|
|
387
|
+
entry.leases -= 1;
|
|
388
|
+
if (entry.leases <= 0) {
|
|
389
|
+
const stopping = entry.client.stop();
|
|
390
|
+
this.stoppingClients.add(stopping);
|
|
391
|
+
void stopping.finally(() => this.stoppingClients.delete(stopping));
|
|
392
|
+
this.environmentClients.delete(fingerprint);
|
|
393
|
+
}
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function object(value) {
|
|
399
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
400
|
+
? value
|
|
401
|
+
: undefined;
|
|
402
|
+
}
|
|
403
|
+
function positiveNumber(value) {
|
|
404
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0;
|
|
405
|
+
}
|
|
406
|
+
function openCodeSession(value) {
|
|
407
|
+
if (typeof value !== 'object' || value === null)
|
|
408
|
+
return undefined;
|
|
409
|
+
const record = value;
|
|
410
|
+
const time = typeof record.time === 'object' && record.time !== null
|
|
411
|
+
? record.time
|
|
412
|
+
: undefined;
|
|
413
|
+
if (typeof record.id !== 'string' ||
|
|
414
|
+
typeof record.directory !== 'string' ||
|
|
415
|
+
typeof record.title !== 'string')
|
|
416
|
+
return undefined;
|
|
417
|
+
return {
|
|
418
|
+
id: record.id,
|
|
419
|
+
directory: record.directory,
|
|
420
|
+
title: record.title,
|
|
421
|
+
updatedAt: typeof time?.updated === 'number' ? time.updated : 0,
|
|
422
|
+
...(typeof record.parentID === 'string' && record.parentID.length > 0
|
|
423
|
+
? { parentId: record.parentID }
|
|
424
|
+
: {})
|
|
425
|
+
};
|
|
426
|
+
}
|