@myagentroam/node 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/capabilities.d.ts +2 -0
- package/dist/capabilities.js +15 -4
- package/dist/claude-agent-sdk.d.ts +3 -1
- package/dist/claude-agent-sdk.js +9 -2
- package/dist/claude-channel.js +0 -1
- package/dist/codex-app-server.d.ts +1 -0
- package/dist/codex-app-server.js +8 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.js +18 -2
- package/dist/connector/node-connector-options.d.ts +3 -0
- package/dist/connector/node-connector-options.js +0 -1
- package/dist/connector/node-operation-router.js +0 -1
- package/dist/connector.d.ts +3 -0
- package/dist/connector.js +109 -7
- package/dist/control-outbound-scheduler.js +0 -1
- package/dist/database.d.ts +4 -0
- package/dist/database.js +14 -9
- package/dist/event-buffer.js +0 -1
- package/dist/fake-runner.js +0 -1
- package/dist/health.js +0 -1
- package/dist/main.js +6 -1
- package/dist/migrations/v001.js +0 -1
- package/dist/migrations/v002.js +0 -1
- package/dist/migrations/v003.d.ts +4 -0
- package/dist/migrations/v003.js +44 -0
- package/dist/native-jsonl-reader.js +0 -1
- package/dist/native-session-history.d.ts +19 -1
- package/dist/native-session-history.js +65 -3
- package/dist/opencode-runtime.d.ts +33 -0
- package/dist/opencode-runtime.js +80 -0
- package/dist/opencode-server.d.ts +47 -0
- package/dist/opencode-server.js +250 -0
- package/dist/operational.js +10 -3
- package/dist/process-tree.js +0 -1
- package/dist/runner/abstract-runner.d.ts +7 -2
- package/dist/runner/abstract-runner.js +17 -2
- package/dist/runner/claude/managed-run-controller.js +20 -1
- package/dist/runner/claude-code-runner.d.ts +3 -1
- package/dist/runner/claude-code-runner.js +26 -8
- package/dist/runner/codex/conversation-parser.d.ts +1 -3
- package/dist/runner/codex/conversation-parser.js +174 -34
- package/dist/runner/codex/managed-run-controller.d.ts +2 -1
- package/dist/runner/codex/managed-run-controller.js +13 -4
- package/dist/runner/codex-runner.d.ts +4 -0
- package/dist/runner/codex-runner.js +27 -4
- package/dist/runner/fake-test-runner.js +0 -1
- package/dist/runner/opencode/conversation-parser.d.ts +27 -0
- package/dist/runner/opencode/conversation-parser.js +217 -0
- package/dist/runner/opencode/managed-run-controller.d.ts +76 -0
- package/dist/runner/opencode/managed-run-controller.js +451 -0
- package/dist/runner/opencode-runner.d.ts +60 -0
- package/dist/runner/opencode-runner.js +330 -0
- package/dist/runner/runner-registry.d.ts +3 -1
- package/dist/runner/runner-registry.js +12 -3
- package/dist/runner-command-engine.js +0 -1
- package/dist/runner-profiles.d.ts +4 -0
- package/dist/runner-profiles.js +76 -3
- package/dist/runner-usage.js +0 -1
- package/dist/runtime-state.js +20 -9
- package/dist/service/attachment-domain-state.js +0 -1
- package/dist/service/conversation-history-service.js +0 -1
- package/dist/service/external-session-resume-service.js +0 -1
- package/dist/service/fake-managed-run-service.js +0 -1
- package/dist/service/managed-runner-session-service.d.ts +3 -1
- package/dist/service/managed-runner-session-service.js +8 -4
- package/dist/service/native-session-projection-service.d.ts +2 -1
- package/dist/service/native-session-projection-service.js +8 -5
- package/dist/service/native-session-watch-service.js +0 -1
- package/dist/service/node-connection-lifecycle-service.js +3 -2
- package/dist/service/node-control-channel.d.ts +1 -1
- package/dist/service/node-control-channel.js +5 -4
- package/dist/service/node-control-message-service.js +0 -1
- package/dist/service/node-request-service.js +0 -1
- package/dist/service/node-run-event-bridge.d.ts +2 -0
- package/dist/service/node-run-event-bridge.js +4 -1
- package/dist/service/node-terminal-channel.js +16 -10
- package/dist/service/node-upgrade-coordinator.d.ts +29 -0
- package/dist/service/node-upgrade-coordinator.js +137 -0
- package/dist/service/node-workspace-coordinator.js +0 -1
- package/dist/service/run-attachment-service.js +0 -1
- package/dist/service/run-domain-state.js +0 -1
- package/dist/service/run-event-service.js +0 -1
- package/dist/service/run-workbench-service.js +0 -1
- package/dist/service/runner-channel-message-service.js +0 -1
- package/dist/service/runner-interaction-service.js +2 -1
- package/dist/service/runner-service.d.ts +5 -4
- package/dist/service/runner-service.js +19 -6
- package/dist/service/session-catalog-service.d.ts +16 -1
- package/dist/service/session-catalog-service.js +82 -3
- package/dist/service/session-command-service.js +0 -1
- package/dist/service/session-context-service.js +0 -1
- package/dist/service/session-domain-state.js +0 -1
- package/dist/service/session-identity-service.js +0 -1
- package/dist/service/session-lifecycle-service.js +13 -7
- package/dist/service/session-message-service.js +0 -1
- package/dist/service/session-presentation-service.js +0 -1
- package/dist/service/session-query-service.js +0 -1
- package/dist/service/terminal-relay-state.js +0 -1
- package/dist/service/terminal-service.js +0 -1
- package/dist/service/workbench-event-service.js +0 -1
- package/dist/service/workbench-manifest-service.d.ts +5 -4
- package/dist/service/workbench-manifest-service.js +3 -2
- package/dist/service/workspace-change-service.js +2 -2
- package/dist/service/workspace-content-search-service.d.ts +14 -0
- package/dist/service/workspace-content-search-service.js +477 -0
- package/dist/service/workspace-domain-state.js +0 -1
- package/dist/service/workspace-file-service.d.ts +3 -0
- package/dist/service/workspace-file-service.js +35 -3
- package/dist/service/workspace-queue-workbench-service.js +0 -1
- package/dist/service/workspace-service.js +23 -10
- package/dist/service/workspace-session-service.js +0 -1
- package/dist/service/workspace-upload-service.js +0 -1
- package/dist/service/workspace-watch-service.js +0 -1
- package/dist/service/workspace-workbench-service.d.ts +9 -0
- package/dist/service/workspace-workbench-service.js +69 -2
- package/dist/service.js +2 -3
- package/dist/storage.js +0 -1
- package/dist/supervisor.d.ts +1 -0
- package/dist/supervisor.js +154 -0
- package/dist/terminal.js +0 -1
- package/dist/util/node-operation-parsers.d.ts +1 -0
- package/dist/util/node-operation-parsers.js +3 -1
- package/dist/util/runner-native-session-parsers.js +117 -73
- package/dist/util/secret-environment.js +0 -1
- package/dist/workspace.d.ts +62 -2
- package/dist/workspace.js +539 -57
- package/package.json +3 -2
- package/dist/capabilities.js.map +0 -1
- package/dist/claude-agent-sdk.js.map +0 -1
- package/dist/claude-channel.js.map +0 -1
- package/dist/codex-app-server.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/connector/node-connector-options.js.map +0 -1
- package/dist/connector/node-operation-router.js.map +0 -1
- package/dist/connector.js.map +0 -1
- package/dist/control-outbound-scheduler.js.map +0 -1
- package/dist/database.js.map +0 -1
- package/dist/event-buffer.js.map +0 -1
- package/dist/fake-runner.js.map +0 -1
- package/dist/health.js.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/migrations/v001.js.map +0 -1
- package/dist/migrations/v002.js.map +0 -1
- package/dist/native-jsonl-reader.js.map +0 -1
- package/dist/native-session-history.js.map +0 -1
- package/dist/operational.js.map +0 -1
- package/dist/process-tree.js.map +0 -1
- package/dist/runner/abstract-runner.js.map +0 -1
- package/dist/runner/claude/managed-run-controller.js.map +0 -1
- package/dist/runner/claude-code-runner.js.map +0 -1
- package/dist/runner/codex/conversation-parser.js.map +0 -1
- package/dist/runner/codex/managed-run-controller.js.map +0 -1
- package/dist/runner/codex-runner.js.map +0 -1
- package/dist/runner/fake-test-runner.js.map +0 -1
- package/dist/runner/runner-registry.js.map +0 -1
- package/dist/runner-command-engine.js.map +0 -1
- package/dist/runner-profiles.js.map +0 -1
- package/dist/runner-usage.js.map +0 -1
- package/dist/runtime-state.js.map +0 -1
- package/dist/service/attachment-domain-state.js.map +0 -1
- package/dist/service/conversation-history-service.js.map +0 -1
- package/dist/service/external-session-resume-service.js.map +0 -1
- package/dist/service/fake-managed-run-service.js.map +0 -1
- package/dist/service/managed-runner-session-service.js.map +0 -1
- package/dist/service/native-session-projection-service.js.map +0 -1
- package/dist/service/native-session-watch-service.js.map +0 -1
- package/dist/service/node-connection-lifecycle-service.js.map +0 -1
- package/dist/service/node-control-channel.js.map +0 -1
- package/dist/service/node-control-message-service.js.map +0 -1
- package/dist/service/node-request-service.js.map +0 -1
- package/dist/service/node-run-event-bridge.js.map +0 -1
- package/dist/service/node-terminal-channel.js.map +0 -1
- package/dist/service/node-workspace-coordinator.js.map +0 -1
- package/dist/service/run-attachment-service.js.map +0 -1
- package/dist/service/run-domain-state.js.map +0 -1
- package/dist/service/run-event-service.js.map +0 -1
- package/dist/service/run-workbench-service.js.map +0 -1
- package/dist/service/runner-channel-message-service.js.map +0 -1
- package/dist/service/runner-interaction-service.js.map +0 -1
- package/dist/service/runner-service.js.map +0 -1
- package/dist/service/session-catalog-service.js.map +0 -1
- package/dist/service/session-command-service.js.map +0 -1
- package/dist/service/session-context-service.js.map +0 -1
- package/dist/service/session-domain-state.js.map +0 -1
- package/dist/service/session-identity-service.js.map +0 -1
- package/dist/service/session-lifecycle-service.js.map +0 -1
- package/dist/service/session-message-service.js.map +0 -1
- package/dist/service/session-presentation-service.js.map +0 -1
- package/dist/service/session-query-service.js.map +0 -1
- package/dist/service/terminal-relay-state.js.map +0 -1
- package/dist/service/terminal-service.js.map +0 -1
- package/dist/service/workbench-event-service.js.map +0 -1
- package/dist/service/workbench-manifest-service.js.map +0 -1
- package/dist/service/workspace-change-service.js.map +0 -1
- package/dist/service/workspace-domain-state.js.map +0 -1
- package/dist/service/workspace-file-service.js.map +0 -1
- package/dist/service/workspace-queue-workbench-service.js.map +0 -1
- package/dist/service/workspace-service.js.map +0 -1
- package/dist/service/workspace-session-service.js.map +0 -1
- package/dist/service/workspace-upload-service.js.map +0 -1
- package/dist/service/workspace-watch-service.js.map +0 -1
- package/dist/service/workspace-workbench-service.js.map +0 -1
- package/dist/service.js.map +0 -1
- package/dist/storage.js.map +0 -1
- package/dist/terminal.js.map +0 -1
- package/dist/util/node-operation-parsers.js.map +0 -1
- package/dist/util/runner-native-session-parsers.js.map +0 -1
- package/dist/util/secret-environment.js.map +0 -1
- package/dist/workspace.js.map +0 -1
|
@@ -8,6 +8,7 @@ import { discoverAllNativeSessions } from '../native-session-history.js';
|
|
|
8
8
|
import { readCodexNativeContextUsage } from '../native-session-history.js';
|
|
9
9
|
import { codexActiveTurnId, codexOfficialConversationPage, codexThreadCwd, codexThreadActivity, deduplicateDirectSessions, externalResumeFailureDetail, extractCodexThreads, isWithinWorkspace, latestNativeActivity } from './codex/conversation-parser.js';
|
|
10
10
|
import { codexSessionControl } from '../codex-app-server.js';
|
|
11
|
+
import { extractId } from '../util/runner-native-session-parsers.js';
|
|
11
12
|
export class CodexRunner extends AbstractRunner {
|
|
12
13
|
client;
|
|
13
14
|
name = 'codex';
|
|
@@ -23,7 +24,8 @@ export class CodexRunner extends AbstractRunner {
|
|
|
23
24
|
profile(capabilities) {
|
|
24
25
|
return declaredRunnerProfiles({
|
|
25
26
|
codexAvailable: capabilities.codex.available,
|
|
26
|
-
claudeCodeAvailable: capabilities.claudeCode.available
|
|
27
|
+
claudeCodeAvailable: capabilities.claudeCode.available,
|
|
28
|
+
openCodeAvailable: capabilities.openCode?.available === true
|
|
27
29
|
}).find((profile) => profile.runner === this.name);
|
|
28
30
|
}
|
|
29
31
|
available(capabilities) {
|
|
@@ -105,6 +107,11 @@ export class CodexRunner extends AbstractRunner {
|
|
|
105
107
|
acceptsTruncatedNativeHistory() {
|
|
106
108
|
return false;
|
|
107
109
|
}
|
|
110
|
+
async readManagedRunnerTitle(session, nativeSessionId) {
|
|
111
|
+
void session;
|
|
112
|
+
await this.start();
|
|
113
|
+
return extractCodexThreads(await this.listThreads()).find((thread) => thread.id === nativeSessionId)?.title;
|
|
114
|
+
}
|
|
108
115
|
nativeImageRoot(session) {
|
|
109
116
|
return session.externalSessionId === null
|
|
110
117
|
? undefined
|
|
@@ -120,7 +127,8 @@ export class CodexRunner extends AbstractRunner {
|
|
|
120
127
|
nodeAppVersion: 'validation',
|
|
121
128
|
nodeVersion: 'validation',
|
|
122
129
|
codex: { available: true },
|
|
123
|
-
claudeCode: { available: false }
|
|
130
|
+
claudeCode: { available: false },
|
|
131
|
+
openCode: { available: false }
|
|
124
132
|
});
|
|
125
133
|
}
|
|
126
134
|
defaultConfiguration() {
|
|
@@ -256,7 +264,8 @@ export class CodexRunner extends AbstractRunner {
|
|
|
256
264
|
...(control.level === 'MANAGED' ? ['turn.queue', 'run.cancel', 'approval.respond'] : []),
|
|
257
265
|
'session.rename',
|
|
258
266
|
'session.remove',
|
|
259
|
-
'session.pin'
|
|
267
|
+
'session.pin',
|
|
268
|
+
...(session.externalSessionId === null ? [] : ['session.rewind'])
|
|
260
269
|
],
|
|
261
270
|
reasonCode: control.level === 'UNAVAILABLE' ? 'RUNNER_UNAVAILABLE' : null
|
|
262
271
|
}
|
|
@@ -317,6 +326,21 @@ export class CodexRunner extends AbstractRunner {
|
|
|
317
326
|
startThread(cwd, configuration) {
|
|
318
327
|
return this.client.startThread(cwd, configuration);
|
|
319
328
|
}
|
|
329
|
+
forkThread(threadId, cwd, lastTurnId, configuration) {
|
|
330
|
+
return this.client.forkThread(threadId, cwd, lastTurnId, configuration);
|
|
331
|
+
}
|
|
332
|
+
async forkNative(session, boundary, title) {
|
|
333
|
+
if (session.externalSessionId === null)
|
|
334
|
+
throw new Error('SESSION_REWIND_UNAVAILABLE');
|
|
335
|
+
await this.start();
|
|
336
|
+
const configuration = { model: session.model, effort: session.effort, access: session.access };
|
|
337
|
+
const result = boundary === null
|
|
338
|
+
? await this.startThread(session.cwd, configuration)
|
|
339
|
+
: await this.forkThread(session.externalSessionId, session.cwd, boundary, configuration);
|
|
340
|
+
const threadId = extractId(result, 'thread');
|
|
341
|
+
await this.setThreadName(threadId, title);
|
|
342
|
+
return threadId;
|
|
343
|
+
}
|
|
320
344
|
resumeThread(threadId, cwd, configuration) {
|
|
321
345
|
return this.client.resumeThread(threadId, cwd, configuration);
|
|
322
346
|
}
|
|
@@ -339,4 +363,3 @@ export class CodexExecutionState {
|
|
|
339
363
|
approvals = new Map();
|
|
340
364
|
userInputs = new Map();
|
|
341
365
|
}
|
|
342
|
-
//# sourceMappingURL=codex-runner.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { NodeAgentSession, NodeConversationTurn } from '../../database.js';
|
|
2
|
+
export declare function openCodeConversationPage(session: NodeAgentSession, messages: readonly unknown[], input: {
|
|
3
|
+
readonly cursor?: string;
|
|
4
|
+
readonly limit?: number;
|
|
5
|
+
}, managedTurn: (nativeTurnId: string) => NodeConversationTurn | undefined): {
|
|
6
|
+
readonly turns: readonly NodeConversationTurn[];
|
|
7
|
+
readonly nextCursor: string | null;
|
|
8
|
+
} | undefined;
|
|
9
|
+
export declare function openCodeQuestions(value: unknown): {
|
|
10
|
+
id: string;
|
|
11
|
+
prompt: string;
|
|
12
|
+
input: string;
|
|
13
|
+
options: {
|
|
14
|
+
value: string;
|
|
15
|
+
label: string;
|
|
16
|
+
description: string | null;
|
|
17
|
+
}[];
|
|
18
|
+
allowOther: boolean;
|
|
19
|
+
multiSelect: boolean;
|
|
20
|
+
}[];
|
|
21
|
+
export declare function openCodePatchChanges(value: unknown): {
|
|
22
|
+
path: string;
|
|
23
|
+
change: string;
|
|
24
|
+
additions: null;
|
|
25
|
+
deletions: null;
|
|
26
|
+
diffAvailable: boolean;
|
|
27
|
+
}[];
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { boundedConversationItemId, compactRunnerText, compactRunnerValue } from '../codex/conversation-parser.js';
|
|
3
|
+
export function openCodeConversationPage(session, messages, input, managedTurn) {
|
|
4
|
+
const records = messages.flatMap((value) => {
|
|
5
|
+
const entry = record(value);
|
|
6
|
+
const info = record(entry?.info);
|
|
7
|
+
return info === undefined || typeof info.id !== 'string'
|
|
8
|
+
? []
|
|
9
|
+
: [{ info, parts: array(entry?.parts) }];
|
|
10
|
+
});
|
|
11
|
+
const parsedTurns = records
|
|
12
|
+
.filter(({ info }) => info.role === 'user')
|
|
13
|
+
.flatMap(({ info, parts }, sequence) => {
|
|
14
|
+
const assistants = records.filter((candidate) => candidate.info.role === 'assistant' && candidate.info.parentID === info.id);
|
|
15
|
+
const existing = managedTurn(info.id);
|
|
16
|
+
const turn = openCodeTurn(session, info, parts, assistants, sequence, existing);
|
|
17
|
+
const after = assistants.at(-1)?.info.id ?? info.id;
|
|
18
|
+
return turn === undefined || typeof after !== 'string' ? [] : [{ after, turn }];
|
|
19
|
+
});
|
|
20
|
+
const turns = parsedTurns.map(({ after, turn }, index) => ({
|
|
21
|
+
...turn,
|
|
22
|
+
rewind: { before: parsedTurns[index - 1]?.after ?? null, after }
|
|
23
|
+
}));
|
|
24
|
+
if (turns.length === 0)
|
|
25
|
+
return undefined;
|
|
26
|
+
const limit = Math.min(Math.max(input.limit ?? 30, 1), 500);
|
|
27
|
+
const end = pageEnd(input.cursor, session.id, turns.length);
|
|
28
|
+
const start = Math.max(0, end - limit);
|
|
29
|
+
return {
|
|
30
|
+
turns: turns.slice(start, end),
|
|
31
|
+
nextCursor: start === 0
|
|
32
|
+
? null
|
|
33
|
+
: Buffer.from(JSON.stringify({ sessionId: session.id, end: start })).toString('base64url')
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function openCodeTurn(session, user, userParts, assistants, sequence, managed) {
|
|
37
|
+
const nativeTurnId = user.id;
|
|
38
|
+
const startedAt = number(record(user.time)?.created);
|
|
39
|
+
const items = [];
|
|
40
|
+
const userText = userParts
|
|
41
|
+
.flatMap((part) => {
|
|
42
|
+
const value = record(part);
|
|
43
|
+
return value?.type === 'text' && typeof value.text === 'string' ? [value.text] : [];
|
|
44
|
+
})
|
|
45
|
+
.join('\n');
|
|
46
|
+
const localUser = managed?.items.find((item) => item.kind === 'user_message');
|
|
47
|
+
if (localUser !== undefined)
|
|
48
|
+
items.push({ ...localUser, turnId: managed.id });
|
|
49
|
+
else if (userText.length > 0)
|
|
50
|
+
items.push(item(session, nativeTurnId, `user-${nativeTurnId}`, 'user_message', 'COMPLETED', {
|
|
51
|
+
text: compactRunnerText(userText, 20_000),
|
|
52
|
+
attachments: []
|
|
53
|
+
}, startedAt, startedAt, sequence));
|
|
54
|
+
for (const assistant of assistants) {
|
|
55
|
+
const completedAt = number(record(assistant.info.time)?.completed);
|
|
56
|
+
for (const part of assistant.parts) {
|
|
57
|
+
const projected = partItem(session, nativeTurnId, part, assistant.info.mode === 'plan', startedAt, completedAt, sequence);
|
|
58
|
+
if (projected !== undefined)
|
|
59
|
+
items.push(projected);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (items.length === 0)
|
|
63
|
+
return undefined;
|
|
64
|
+
const completedAt = Math.max(startedAt ?? 0, ...assistants.map(({ info }) => number(record(info.time)?.completed) ?? 0)) || startedAt;
|
|
65
|
+
const id = managed?.id ?? `${session.id}:official:${nativeTurnId}`;
|
|
66
|
+
const runId = managed?.runId ?? null;
|
|
67
|
+
return {
|
|
68
|
+
id,
|
|
69
|
+
sessionId: session.id,
|
|
70
|
+
runId,
|
|
71
|
+
userItemId: items.find((value) => value.kind === 'user_message')?.id ?? null,
|
|
72
|
+
status: assistants.some(({ info }) => info.error !== undefined) ? 'FAILED' : 'SUCCEEDED',
|
|
73
|
+
model: assistants.find(({ info }) => typeof info.modelID === 'string')?.info.modelID ?? null,
|
|
74
|
+
effort: managed?.effort ?? null,
|
|
75
|
+
access: managed?.access ?? null,
|
|
76
|
+
items: items.map((value) => ({ ...value, turnId: id, runId })),
|
|
77
|
+
startedAt,
|
|
78
|
+
completedAt
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function partItem(session, turnId, raw, planMode, startedAt, completedAt, sequence) {
|
|
82
|
+
const part = record(raw);
|
|
83
|
+
if (typeof part?.id !== 'string' || typeof part.type !== 'string')
|
|
84
|
+
return undefined;
|
|
85
|
+
if ((part.type === 'text' || part.type === 'reasoning') && typeof part.text === 'string')
|
|
86
|
+
return item(session, turnId, part.id, part.type === 'text' ? (planMode ? 'plan' : 'assistant_message') : 'reasoning_summary', completedAt === null ? 'IN_PROGRESS' : 'COMPLETED', part.type === 'text'
|
|
87
|
+
? planMode
|
|
88
|
+
? { explanation: compactRunnerText(part.text, 20_000), steps: [] }
|
|
89
|
+
: { text: compactRunnerText(part.text, 20_000), format: 'markdown', model: null }
|
|
90
|
+
: { sections: [{ index: 0, text: compactRunnerText(part.text, 10_000) }] }, startedAt, completedAt, sequence);
|
|
91
|
+
if (part.type === 'tool' && typeof part.tool === 'string') {
|
|
92
|
+
const state = record(part.state);
|
|
93
|
+
if (part.tool === 'question' && typeof part.callID === 'string') {
|
|
94
|
+
const questions = openCodeQuestions(record(state?.input)?.questions);
|
|
95
|
+
if (questions.length > 0)
|
|
96
|
+
return item(session, turnId, part.id, 'user_input_request', 'COMPLETED', { requestId: `native:${part.callID}`, questions }, startedAt, completedAt, sequence);
|
|
97
|
+
}
|
|
98
|
+
const status = state?.status === 'completed'
|
|
99
|
+
? 'COMPLETED'
|
|
100
|
+
: state?.status === 'error'
|
|
101
|
+
? 'FAILED'
|
|
102
|
+
: 'IN_PROGRESS';
|
|
103
|
+
return item(session, turnId, part.id, 'tool_call', status, {
|
|
104
|
+
namespace: 'opencode',
|
|
105
|
+
toolName: compactRunnerText(part.tool, 128),
|
|
106
|
+
title: compactRunnerText(typeof state?.title === 'string' ? state.title : part.tool, 500),
|
|
107
|
+
inputSummary: compactRunnerValue(state?.input, 10_000).text || null,
|
|
108
|
+
outputSummary: typeof state?.output === 'string' ? compactRunnerText(state.output, 10_000) : null,
|
|
109
|
+
progressLabel: null,
|
|
110
|
+
errorCode: status === 'FAILED' ? 'OPENCODE_TOOL_FAILED' : null,
|
|
111
|
+
truncated: false
|
|
112
|
+
}, startedAt, completedAt, sequence);
|
|
113
|
+
}
|
|
114
|
+
if (part.type === 'compaction')
|
|
115
|
+
return item(session, turnId, part.id, 'context_compaction', 'COMPLETED', {
|
|
116
|
+
phase: 'COMPLETED',
|
|
117
|
+
summary: '上下文已整理'
|
|
118
|
+
}, startedAt, completedAt, sequence);
|
|
119
|
+
if (part.type === 'patch')
|
|
120
|
+
return item(session, turnId, part.id, 'file_change', 'COMPLETED', { changes: openCodePatchChanges(part.files) }, startedAt, completedAt, sequence);
|
|
121
|
+
if (part.type === 'step-start' || part.type === 'step-finish')
|
|
122
|
+
return undefined;
|
|
123
|
+
if (part.type === 'text' || part.type === 'reasoning')
|
|
124
|
+
return undefined;
|
|
125
|
+
return item(session, turnId, part.id, 'unknown', completedAt === null ? 'IN_PROGRESS' : 'COMPLETED', {
|
|
126
|
+
sourceEventType: `opencode:${part.type}`,
|
|
127
|
+
label: `OpenCode ${compactRunnerText(part.type, 128)}`
|
|
128
|
+
}, startedAt, completedAt, sequence);
|
|
129
|
+
}
|
|
130
|
+
export function openCodeQuestions(value) {
|
|
131
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > 4)
|
|
132
|
+
return [];
|
|
133
|
+
return value.flatMap((value, index) => {
|
|
134
|
+
const question = record(value);
|
|
135
|
+
if (typeof question?.question !== 'string')
|
|
136
|
+
return [];
|
|
137
|
+
const options = (Array.isArray(question.options) ? question.options : []).flatMap((value) => {
|
|
138
|
+
const option = record(value);
|
|
139
|
+
const label = typeof option?.label === 'string' ? compactRunnerText(option.label, 500) : '';
|
|
140
|
+
return label.length === 0
|
|
141
|
+
? []
|
|
142
|
+
: [
|
|
143
|
+
{
|
|
144
|
+
value: label,
|
|
145
|
+
label,
|
|
146
|
+
description: typeof option?.description === 'string'
|
|
147
|
+
? compactRunnerText(option.description, 1_000)
|
|
148
|
+
: null
|
|
149
|
+
}
|
|
150
|
+
];
|
|
151
|
+
});
|
|
152
|
+
const multiSelect = question.multiple === true;
|
|
153
|
+
return [
|
|
154
|
+
{
|
|
155
|
+
id: `question-${index + 1}`,
|
|
156
|
+
prompt: compactRunnerText(question.question, 5_000),
|
|
157
|
+
input: options.length === 0 ? 'SHORT_TEXT' : multiSelect ? 'MULTI_SELECT' : 'SINGLE_SELECT',
|
|
158
|
+
options,
|
|
159
|
+
allowOther: true,
|
|
160
|
+
multiSelect
|
|
161
|
+
}
|
|
162
|
+
];
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
export function openCodePatchChanges(value) {
|
|
166
|
+
return (Array.isArray(value) ? value : []).flatMap((path) => typeof path === 'string' && path.length > 0
|
|
167
|
+
? [
|
|
168
|
+
{
|
|
169
|
+
path: basename(path),
|
|
170
|
+
change: 'MODIFIED',
|
|
171
|
+
additions: null,
|
|
172
|
+
deletions: null,
|
|
173
|
+
diffAvailable: false
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
: []);
|
|
177
|
+
}
|
|
178
|
+
function item(session, turnId, nativeId, kind, status, payload, startedAt, completedAt, sequence) {
|
|
179
|
+
return {
|
|
180
|
+
id: boundedConversationItemId(`${session.id}:official:${turnId}`, nativeId),
|
|
181
|
+
sessionId: session.id,
|
|
182
|
+
turnId: `${session.id}:official:${turnId}`,
|
|
183
|
+
runId: null,
|
|
184
|
+
parentItemId: null,
|
|
185
|
+
sourceSequence: sequence,
|
|
186
|
+
revision: 1,
|
|
187
|
+
kind,
|
|
188
|
+
status,
|
|
189
|
+
payload,
|
|
190
|
+
startedAt,
|
|
191
|
+
completedAt
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function pageEnd(cursor, sessionId, fallback) {
|
|
195
|
+
if (cursor === undefined)
|
|
196
|
+
return fallback;
|
|
197
|
+
try {
|
|
198
|
+
const parsed = record(JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8')));
|
|
199
|
+
return parsed?.sessionId === sessionId && Number.isInteger(parsed.end)
|
|
200
|
+
? Math.min(Math.max(Number(parsed.end), 0), fallback)
|
|
201
|
+
: fallback;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return fallback;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function record(value) {
|
|
208
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
209
|
+
? value
|
|
210
|
+
: undefined;
|
|
211
|
+
}
|
|
212
|
+
function array(value) {
|
|
213
|
+
return Array.isArray(value) ? value : [];
|
|
214
|
+
}
|
|
215
|
+
function number(value) {
|
|
216
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
217
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { NodeEnvelope, RunnerCommandDescriptor, RunnerCommandState } from '@myagentroam/protocol';
|
|
2
|
+
import type { NodeAgentSession } from '../../database.js';
|
|
3
|
+
import type { FakeRunnerStatus } from '../../fake-runner.js';
|
|
4
|
+
import type { RunnerImageAttachment } from '../../service/run-attachment-service.js';
|
|
5
|
+
import { OpenCodeRunner } from '../opencode-runner.js';
|
|
6
|
+
interface OpenCodeManagedRunHost {
|
|
7
|
+
intercepted(): boolean;
|
|
8
|
+
readonly active: Set<string>;
|
|
9
|
+
parseAttachments(value: unknown): readonly RunnerImageAttachment[];
|
|
10
|
+
emit(runId: string, eventType: string, payload: unknown, status?: FakeRunnerStatus): void;
|
|
11
|
+
emitItem(runId: string, item: OpenCodePublicItem): void;
|
|
12
|
+
adopt(input: {
|
|
13
|
+
runId: string;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
runner: 'opencode';
|
|
16
|
+
cwd: string;
|
|
17
|
+
externalSessionId?: string;
|
|
18
|
+
}): void;
|
|
19
|
+
promote(sessionId: string, nativeSessionId: string): void;
|
|
20
|
+
rememberNative(nativeSessionId: string, sessionId: string): void;
|
|
21
|
+
send(type: string, payload: unknown): void;
|
|
22
|
+
captureSnapshot(runId: string, cwd: string): Promise<void>;
|
|
23
|
+
createApproval(input: {
|
|
24
|
+
readonly runId: string;
|
|
25
|
+
readonly approvalId: string;
|
|
26
|
+
readonly payload: unknown;
|
|
27
|
+
readonly expiresAt: number;
|
|
28
|
+
}): void;
|
|
29
|
+
publishApproval(input: {
|
|
30
|
+
readonly runId: string;
|
|
31
|
+
readonly approvalId: string;
|
|
32
|
+
readonly payload: unknown;
|
|
33
|
+
readonly expiresAt: number;
|
|
34
|
+
}): void;
|
|
35
|
+
expireApproval(approvalId: string): void;
|
|
36
|
+
commandState(sessionId: string, commandId: string): RunnerCommandState | undefined;
|
|
37
|
+
setCommandState(sessionId: string, state: RunnerCommandState): void;
|
|
38
|
+
clearCommandState(sessionId: string, commandId: string): void;
|
|
39
|
+
commandStates(sessionId: string): readonly RunnerCommandState[];
|
|
40
|
+
}
|
|
41
|
+
type OpenCodePublicItem = {
|
|
42
|
+
readonly itemId: string;
|
|
43
|
+
readonly kind: 'assistant_message' | 'plan' | 'reasoning_summary' | 'tool_call' | 'user_input_request' | 'context_compaction' | 'file_change' | 'unknown';
|
|
44
|
+
readonly status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';
|
|
45
|
+
readonly payload: Record<string, unknown>;
|
|
46
|
+
readonly merge?: boolean;
|
|
47
|
+
};
|
|
48
|
+
export declare class OpenCodeManagedRunController {
|
|
49
|
+
private readonly runner;
|
|
50
|
+
private readonly host;
|
|
51
|
+
private readonly interactionTimeoutMs;
|
|
52
|
+
private readonly permissions;
|
|
53
|
+
private readonly questions;
|
|
54
|
+
private readonly startingCwds;
|
|
55
|
+
private readonly promptAdmitted;
|
|
56
|
+
private readonly pendingIdle;
|
|
57
|
+
private readonly startingClients;
|
|
58
|
+
constructor(runner: OpenCodeRunner, host: OpenCodeManagedRunHost, interactionTimeoutMs?: number);
|
|
59
|
+
executeCommand(session: NodeAgentSession, command: RunnerCommandDescriptor, context: {
|
|
60
|
+
readonly secretEnvironment: Readonly<Record<string, string>>;
|
|
61
|
+
}): Promise<unknown>;
|
|
62
|
+
start(envelope: NodeEnvelope): void;
|
|
63
|
+
cancel(runId: string, intent: 'CANCEL' | 'INTERRUPT'): boolean;
|
|
64
|
+
decideApproval(input: {
|
|
65
|
+
readonly runId: string;
|
|
66
|
+
readonly approvalId: string;
|
|
67
|
+
readonly decision: 'APPROVED' | 'REJECTED';
|
|
68
|
+
}): boolean;
|
|
69
|
+
respondUserInput(runId: string, requestId: string, answers: Record<string, unknown>): boolean;
|
|
70
|
+
private run;
|
|
71
|
+
private event;
|
|
72
|
+
private requestPermission;
|
|
73
|
+
private requestQuestion;
|
|
74
|
+
private finish;
|
|
75
|
+
}
|
|
76
|
+
export {};
|