@platless/axom-cli 0.5.9 → 0.6.36

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.
Files changed (163) hide show
  1. package/README.md +18 -5
  2. package/dist/axom-patch/cli/README.md +100 -12
  3. package/dist/axom-patch/cli/account-limits/generate.py +15 -12
  4. package/dist/axom-patch/cli/account-limits/kimi-proxy.mjs +20 -3
  5. package/dist/axom-patch/cli/claude-account-limits.json +9 -9
  6. package/dist/axom-patch/cli/codex-account-limits.json +11 -11
  7. package/dist/axom-patch/cli/codex-terminal-output.json +16 -0
  8. package/dist/axom-patch/cli/commandcode-account-limits.json +9 -9
  9. package/dist/axom-patch/cli/kimi-quota.mjs +12 -0
  10. package/dist/axom-patch/cli/kimi-subagents.mjs +173 -0
  11. package/dist/axom-patch/cli/nightly-task.md +55 -13
  12. package/dist/axom-patch/cli/probes/codex-terminal-output.mjs +33 -0
  13. package/dist/axom-patch/cli/probes/kimi-subagent-subwork.mjs +82 -0
  14. package/dist/axom-patch/cli/qoder/dist/axom-acp-compat.mjs +1591 -0
  15. package/dist/axom-patch/cli/qoder/releases/1.1.75.json +360 -0
  16. package/dist/axom-patch/cli/qoder-background-terminal.md +13 -6
  17. package/dist/axom-patch/cli/qoder-foreground-output.md +14 -8
  18. package/dist/axom-patch/cli/qoder-native-acp.json +227 -0
  19. package/dist/axom-patch/cli/qoder-steering.md +20 -25
  20. package/dist/axom-patch/cli/qoder-subagent-subwork.md +17 -68
  21. package/dist/axom-patch/cli/runtime.json +16 -18
  22. package/dist/axom-patch/cli/zcode-account-limits.json +10 -11
  23. package/dist/axom-patch/cli/zcode-models.json +1 -2
  24. package/dist/axom-patch/cli/zcode-subagent-subwork.json +9 -10
  25. package/dist/cli.js +4 -36
  26. package/dist/commands/knowledge.js +47 -0
  27. package/dist/commands/update.js +65 -3
  28. package/dist/commands/workstation.js +73 -7
  29. package/dist/install/claude/commands.js +13 -13
  30. package/dist/mcp.js +1 -1
  31. package/dist/native/darwin-arm64/axom-quic +0 -0
  32. package/dist/workstation/acp/acpAgents.js +102 -98
  33. package/dist/workstation/acp/acpClient.js +26 -0
  34. package/dist/workstation/acp/builds/install/npm.js +99 -10
  35. package/dist/workstation/acp/initializeResponse.js +6 -1
  36. package/dist/workstation/acp/managedPatches.js +189 -25
  37. package/dist/workstation/acp/managedRuntime.js +314 -0
  38. package/dist/workstation/acp/patchAssets.js +40 -0
  39. package/dist/workstation/acp/processor/checkpoint.js +25 -34
  40. package/dist/workstation/acp/processor/control.js +5 -78
  41. package/dist/workstation/acp/processor/runtime.js +5 -81
  42. package/dist/workstation/acp/processor/session.js +51 -80
  43. package/dist/workstation/acp/processor/state.js +6 -13
  44. package/dist/workstation/acp/processor/step.js +3 -20
  45. package/dist/workstation/acp/processor/test/fixtureLog.js +9 -16
  46. package/dist/workstation/acp/processor/updates.js +131 -105
  47. package/dist/workstation/acp/processorSession.js +8 -172
  48. package/dist/workstation/acp/registry/catalog.js +65 -39
  49. package/dist/workstation/acp/registry/launch.js +16 -1
  50. package/dist/workstation/acp/switching.js +0 -3
  51. package/dist/workstation/acp/test/fakeAgent.js +13 -0
  52. package/dist/workstation/acp/test/keeperWorld.js +28 -0
  53. package/dist/workstation/acp/test/raw/sources.js +16 -130
  54. package/dist/workstation/acp/test/realAdapter.js +1 -47
  55. package/dist/workstation/acp/test/scriptAgent.js +11 -3
  56. package/dist/workstation/agentFlow.js +1 -1
  57. package/dist/workstation/agentSessions.js +38 -143
  58. package/dist/workstation/channels/management.js +95 -11
  59. package/dist/workstation/channels/url.js +1 -1
  60. package/dist/workstation/config.js +16 -4
  61. package/dist/workstation/connection/encryptedChannel.js +4 -1
  62. package/dist/workstation/control/bindingStore.js +200 -0
  63. package/dist/workstation/control/commands.js +124 -0
  64. package/dist/workstation/control/daemonIdentity.js +53 -0
  65. package/dist/workstation/control/enrollment.js +106 -0
  66. package/dist/workstation/control/inspect.js +71 -0
  67. package/dist/workstation/control/locks.js +63 -0
  68. package/dist/workstation/control/protocol.js +40 -0
  69. package/dist/workstation/control/restartGuard.js +46 -0
  70. package/dist/workstation/control/runtimeClient.js +97 -0
  71. package/dist/workstation/control/runtimeHost.js +148 -0
  72. package/dist/workstation/control/serverIdentity.js +35 -0
  73. package/dist/workstation/daemon.js +106 -6
  74. package/dist/workstation/daemonctl.js +77 -14
  75. package/dist/workstation/desktopControl/audio.js +99 -0
  76. package/dist/workstation/desktopControl/capabilities.js +92 -0
  77. package/dist/workstation/desktopControl/captureModes.js +9 -0
  78. package/dist/workstation/desktopControl/captureTargetLabel.js +9 -0
  79. package/dist/workstation/desktopControl/deviceSockets.js +246 -0
  80. package/dist/workstation/desktopControl/helperProcess.js +353 -0
  81. package/dist/workstation/desktopControl/lobby.js +129 -0
  82. package/dist/workstation/desktopControl/macProvider.js +155 -0
  83. package/dist/workstation/desktopControl/media.js +331 -0
  84. package/dist/workstation/desktopControl/nativeProvider.js +1018 -0
  85. package/dist/workstation/desktopControl/networkEvidence.js +43 -0
  86. package/dist/workstation/desktopControl/overview.js +58 -0
  87. package/dist/workstation/desktopControl/protocol.js +302 -0
  88. package/dist/workstation/desktopControl/quicMedia.js +240 -0
  89. package/dist/workstation/desktopControl/rateController.js +226 -0
  90. package/dist/workstation/desktopControl/supervisor.js +1681 -0
  91. package/dist/workstation/desktopControl/transport.js +27 -0
  92. package/dist/workstation/desktopControl/wallpaper.js +78 -0
  93. package/dist/workstation/files/credentials.js +142 -0
  94. package/dist/workstation/files/text.js +42 -8
  95. package/dist/workstation/keepers/kit/bundle.js +21 -17
  96. package/dist/workstation/keepers/kit/launcher.js +47 -7
  97. package/dist/workstation/keepers/kit/paths.js +2 -1
  98. package/dist/workstation/managedInstall.js +57 -0
  99. package/dist/workstation/protocol/agent.js +2 -15
  100. package/dist/workstation/protocol/management.js +93 -4
  101. package/dist/workstation/protocol/runtimeDiagnostics.js +15 -0
  102. package/dist/workstation/rd/artifact.js +119 -0
  103. package/dist/workstation/rd/control.js +119 -0
  104. package/dist/workstation/rd/display.js +29 -0
  105. package/dist/workstation/rd/provider.js +222 -0
  106. package/dist/workstation/rd/sessions.js +391 -0
  107. package/dist/workstation/rd/state.js +45 -0
  108. package/dist/workstation/rd/update.js +171 -0
  109. package/dist/workstation/rd/upkeep.js +38 -0
  110. package/dist/workstation/register.js +27 -37
  111. package/dist/workstation/service/installer.js +104 -13
  112. package/dist/workstation/service/launchd.js +1 -0
  113. package/dist/workstation/storageMetrics.js +118 -0
  114. package/dist/workstation/systemMetrics.js +44 -92
  115. package/dist/workstation/toolchain.js +94 -0
  116. package/dist/workstation/tools/browser.js +28 -4
  117. package/dist/workstation/update/artifact.js +2 -1
  118. package/dist/workstation/update/globalInstall.js +116 -0
  119. package/dist/workstation/update/npmInstaller.js +49 -23
  120. package/dist/workstation/update/rdRollback.js +145 -0
  121. package/dist/workstation/update/runUpdate.js +3 -2
  122. package/dist/workstation/update/watchdog.js +16790 -334
  123. package/package.json +5 -5
  124. package/skills/axom/SKILL.md +11 -11
  125. package/skills/axom-definition/SKILL.md +3 -3
  126. package/skills/axom-platform/SKILL.md +3 -3
  127. package/dist/axom-patch/cli/probes/qoder-steering.mjs +0 -89
  128. package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +0 -61
  129. package/dist/axom-patch/cli/qoder-steering.json +0 -52
  130. package/dist/axom-patch/cli/qoder-subagent-origin.json +0 -73
  131. package/dist/commands/guide.js +0 -38
  132. package/dist/runtime-deps/qoder-sdk/package-lock.json +0 -1189
  133. package/dist/runtime-deps/qoder-sdk/package.json +0 -8
  134. package/dist/workstation/acp/delegationMcp.js +0 -24
  135. package/dist/workstation/acp/processor/sideChannel.js +0 -80
  136. package/dist/workstation/acp/qoderStartup.js +0 -45
  137. package/dist/workstation/acp/test/raw/qoderCaptures.js +0 -125
  138. package/dist/workstation/qoderAdapter/backgroundProcess.js +0 -118
  139. package/dist/workstation/qoderAdapter/backgroundTerminal.js +0 -193
  140. package/dist/workstation/qoderAdapter/backgroundTerminalFold.js +0 -372
  141. package/dist/workstation/qoderAdapter/callbackContext.js +0 -76
  142. package/dist/workstation/qoderAdapter/completedContinuation.js +0 -139
  143. package/dist/workstation/qoderAdapter/contract.js +0 -78
  144. package/dist/workstation/qoderAdapter/foregroundOutput.js +0 -36
  145. package/dist/workstation/qoderAdapter/history.js +0 -85
  146. package/dist/workstation/qoderAdapter/identityIndex.js +0 -191
  147. package/dist/workstation/qoderAdapter/inputQueue.js +0 -42
  148. package/dist/workstation/qoderAdapter/main.js +0 -95
  149. package/dist/workstation/qoderAdapter/mapper.js +0 -117
  150. package/dist/workstation/qoderAdapter/observerPlugin.js +0 -245
  151. package/dist/workstation/qoderAdapter/observerReceiver.js +0 -187
  152. package/dist/workstation/qoderAdapter/permissions.js +0 -61
  153. package/dist/workstation/qoderAdapter/profile.js +0 -93
  154. package/dist/workstation/qoderAdapter/sdkDriver.js +0 -48
  155. package/dist/workstation/qoderAdapter/sdkRuntime.js +0 -93
  156. package/dist/workstation/qoderAdapter/sdkRuntimeInstall.js +0 -145
  157. package/dist/workstation/qoderAdapter/session.js +0 -319
  158. package/dist/workstation/qoderAdapter/subagentMeta.js +0 -28
  159. package/dist/workstation/qoderAdapter/subwork.js +0 -85
  160. package/dist/workstation/qoderAdapter/taskControl.js +0 -38
  161. package/dist/workstation/qoderAdapter/taskLedger.js +0 -163
  162. package/dist/workstation/qoderAdapter/usage.js +0 -37
  163. /package/dist/workstation/{qoderAdapter/types.js → desktopControl/provider.js} +0 -0
@@ -1,36 +0,0 @@
1
- export function certifiedRuntime(identity) {
2
- return identity?.name === 'qoder-cli' && identity.version === '1.1.61';
3
- }
4
- function record(value) {
5
- return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
6
- }
7
- export function newForegroundOutputData() {
8
- return { pending: {} };
9
- }
10
- export class ForegroundOutputBoundary {
11
- nativeSessionId;
12
- data;
13
- constructor(nativeSessionId, data = newForegroundOutputData()) {
14
- this.nativeSessionId = nativeSessionId;
15
- this.data = data;
16
- }
17
- accept(event) {
18
- if (event.acpSessionId && event.acpSessionId !== this.nativeSessionId)
19
- return true;
20
- const p = event.payload, input = record(p.rawInput), pending = this.data.pending;
21
- if (event.eventName === 'tool_call' && p.kind === 'think' && record(record(p._meta).qoder).toolName === 'Agent' &&
22
- typeof p.toolCallId === 'string' && typeof input.prompt === 'string' &&
23
- (input.run_in_background === undefined || input.run_in_background === false)) {
24
- Object.defineProperty(pending, p.toolCallId, { value: true, enumerable: true, writable: true, configurable: true });
25
- }
26
- if (event.eventName === 'tool_call_update' && typeof p.toolCallId === 'string' &&
27
- ['completed', 'failed', 'cancelled'].includes(String(p.status)) && Object.hasOwn(pending, p.toolCallId))
28
- delete pending[p.toolCallId];
29
- // Identified/draft child streams and controls keep their existing handling. Never assign an
30
- // unaddressed chunk to whichever child happens to finish first.
31
- return Object.keys(pending).length === 0 || !['agent_message_chunk', 'agent_thought_chunk'].includes(event.eventName) ||
32
- typeof p.messageId === 'string' || p._meta != null;
33
- }
34
- endTurn() { for (const id of Object.keys(this.data.pending))
35
- delete this.data.pending[id]; }
36
- }
@@ -1,85 +0,0 @@
1
- const DEFAULT_LIMIT = 50;
2
- const MAX_LIMIT = 200;
3
- const MAX_OFFSET = 100_000;
4
- const MAX_IDS = 4096;
5
- const DEFAULT_TIMEOUT_MS = 5_000;
6
- const MAX_TIMEOUT_MS = 30_000;
7
- const DEFAULT_MAX_BYTES = 4 * 1024 * 1024;
8
- const MAX_BYTES = 8 * 1024 * 1024;
9
- const safeIdentity = (value) => typeof value === 'string' &&
10
- value.length > 0 && value.length <= 256 && !/[\x00-\x1f\x7f\\/]/.test(value) &&
11
- /^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(value);
12
- function validDirectory(value) {
13
- return typeof value === 'string' && value.length > 0 && value.length <= 4096 &&
14
- value.startsWith('/') && !/[\x00-\x1f\x7f]/.test(value) &&
15
- !value.replaceAll('\\', '/').split('/').includes('..');
16
- }
17
- function unknownResult(rootSessionId, agentId, offset = 0, limit = DEFAULT_LIMIT, reason = 'sdk-error') {
18
- return { status: 'unknown', entries: [], rootSessionId, agentId, offset, limit,
19
- hasMore: false, snapshotStable: false, reason };
20
- }
21
- async function bounded(operation, timeoutMs) {
22
- return await new Promise((resolve, reject) => {
23
- const timer = setTimeout(() => reject(new Error('history read timed out')), timeoutMs);
24
- operation.then(resolve, reject).finally(() => clearTimeout(timer));
25
- });
26
- }
27
- function normalizeMessage(rootSessionId, agentId, message) {
28
- const kind = message.type === 'user' || message.type === 'assistant' || message.type === 'system'
29
- ? message.type : 'unknown';
30
- const parent = safeIdentity(message.parent_agent_id) ? message.parent_agent_id : undefined;
31
- return {
32
- kind, id: safeIdentity(message.uuid) ? message.uuid : 'unknown', rootSessionId, agentId,
33
- source: 'qoder-sdk', readOnly: true, actions: [], message: message.message,
34
- ...(typeof message.timestamp === 'string' ? { timestamp: message.timestamp } : {}),
35
- ...(parent ? { parentAgentId: parent } : {}),
36
- parentAgentIdStatus: parent ? 'verified' : 'unknown',
37
- };
38
- }
39
- /**
40
- * Reads a bounded, read-only child transcript using only Qoder's public SDK APIs.
41
- * `offset` is a page offset, never a durable tail cursor. The SDK may read the full
42
- * transcript before applying it; maxBytes bounds returned data, not bytes read on disk.
43
- */
44
- export async function readChildHistory(rootSessionId, agentId, page, reader) {
45
- const offset = page?.offset ?? 0;
46
- const limit = page?.limit ?? DEFAULT_LIMIT;
47
- const timeoutMs = page?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
48
- const maxBytes = page?.maxBytes ?? DEFAULT_MAX_BYTES;
49
- if (!safeIdentity(rootSessionId) || !safeIdentity(agentId))
50
- return unknownResult(rootSessionId, agentId, 0, DEFAULT_LIMIT, 'invalid-identity');
51
- if (!validDirectory(page?.dir) || !Number.isSafeInteger(offset) || offset < 0 || offset > MAX_OFFSET ||
52
- !Number.isSafeInteger(limit) || limit < 1 || limit > MAX_LIMIT ||
53
- !Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > MAX_TIMEOUT_MS ||
54
- !Number.isSafeInteger(maxBytes) || maxBytes < 1024 || maxBytes > MAX_BYTES)
55
- return unknownResult(rootSessionId, agentId, Number.isSafeInteger(offset) && offset >= 0 ? offset : 0, Number.isSafeInteger(limit) && limit > 0 ? limit : DEFAULT_LIMIT, 'invalid-page');
56
- const rosterOptions = { dir: page.dir };
57
- const messageOptions = { dir: page.dir, offset, limit };
58
- try {
59
- const listed = await bounded(reader.listSubagents(rootSessionId, rosterOptions), timeoutMs);
60
- if (!Array.isArray(listed) || listed.length > MAX_IDS ||
61
- listed.some((id) => !safeIdentity(id)))
62
- return unknownResult(rootSessionId, agentId, offset, limit, 'malformed-result');
63
- if (!listed.includes(agentId))
64
- return unknownResult(rootSessionId, agentId, offset, limit, 'child-not-listed');
65
- const messages = await bounded(reader.getSubagentMessages(rootSessionId, agentId, messageOptions), timeoutMs);
66
- if (!Array.isArray(messages) || messages.length > limit || messages.length > MAX_IDS)
67
- return unknownResult(rootSessionId, agentId, offset, limit, 'malformed-result');
68
- if (messages.some((message) => !message || typeof message !== 'object' ||
69
- message.session_id !== rootSessionId || !safeIdentity(message.uuid)))
70
- return unknownResult(rootSessionId, agentId, offset, limit, 'malformed-result');
71
- const entries = messages.map((message) => normalizeMessage(rootSessionId, agentId, message));
72
- const serialized = JSON.stringify(entries);
73
- if (serialized === undefined || Buffer.byteLength(serialized, 'utf8') > maxBytes)
74
- return unknownResult(rootSessionId, agentId, offset, limit, 'oversized-result');
75
- // Recheck membership after the read so a changing child roster cannot be presented as stable.
76
- const after = await bounded(reader.listSubagents(rootSessionId, rosterOptions), timeoutMs);
77
- if (!Array.isArray(after) || !after.includes(agentId))
78
- return unknownResult(rootSessionId, agentId, offset, limit, 'snapshot-changed');
79
- return { status: 'verified', entries, rootSessionId, agentId, offset, limit,
80
- hasMore: messages.length === limit, snapshotStable: true };
81
- }
82
- catch {
83
- return unknownResult(rootSessionId, agentId, offset, limit, 'sdk-error');
84
- }
85
- }
@@ -1,191 +0,0 @@
1
- const identifier = (value) => typeof value === 'string' &&
2
- value.length > 0 && value.length <= 256 && !/[\x00-\x1f\x7f]/.test(value);
3
- const copySource = (source) => ({
4
- rootSessionId: source.rootSessionId, runtimeGeneration: source.runtimeGeneration,
5
- toolUseId: source.toolUseId, sourceId: source.sourceId, runId: source.runId,
6
- ...(source.parentToolUseId ? { parentToolUseId: source.parentToolUseId } : {}),
7
- });
8
- const copyOrigin = (origin) => ({
9
- rootSessionId: origin.rootSessionId,
10
- ...(origin.runtimeGeneration !== undefined ? { runtimeGeneration: origin.runtimeGeneration } : {}),
11
- ...(origin.agentId !== undefined ? { agentId: origin.agentId } : {}),
12
- ...(origin.taskId !== undefined ? { taskId: origin.taskId } : {}),
13
- ...(origin.toolUseId !== undefined ? { toolUseId: origin.toolUseId } : {}),
14
- ...(origin.launchingToolUseId !== undefined ? { launchingToolUseId: origin.launchingToolUseId } : {}),
15
- });
16
- export class IdentityIndex {
17
- options;
18
- binding;
19
- entries = new Map();
20
- launches = new Map();
21
- agents = new Map();
22
- closed = false;
23
- maximum;
24
- constructor(binding, options = {}) {
25
- this.options = options;
26
- if (!identifier(binding.rootSessionId) || !identifier(binding.runtimeGeneration))
27
- throw new Error('Invalid observer binding');
28
- this.binding = { rootSessionId: binding.rootSessionId, runtimeGeneration: binding.runtimeGeneration };
29
- const maximum = options.maxBindings ?? 4096;
30
- if (!Number.isSafeInteger(maximum) || maximum < 1)
31
- throw new Error('Invalid observer capacity');
32
- this.maximum = Math.min(4096, maximum);
33
- }
34
- accepts(origin) {
35
- return !this.closed && origin.rootSessionId === this.binding.rootSessionId &&
36
- origin.runtimeGeneration === this.binding.runtimeGeneration;
37
- }
38
- entry(id) {
39
- if (!identifier(id))
40
- return undefined;
41
- let entry = this.entries.get(id);
42
- if (!entry) {
43
- if (this.entries.size >= this.maximum) {
44
- this.options.onDegraded?.('capacity');
45
- return undefined;
46
- }
47
- entry = {};
48
- this.entries.set(id, entry);
49
- }
50
- return entry;
51
- }
52
- publish(entry) {
53
- if (!entry.source || (!entry.origin && !entry.revoked))
54
- return;
55
- const origin = entry.revoked ? null : copyOrigin(entry.origin);
56
- const key = JSON.stringify([origin, entry.revoked]);
57
- if (entry.emitted === key)
58
- return;
59
- entry.emitted = key;
60
- this.options.onCorrection?.({ binding: copySource(entry.source), origin,
61
- ...(entry.revoked ? { reason: entry.revoked } : {}) });
62
- }
63
- revoke(entry, reason) {
64
- if (!entry.revoked) {
65
- entry.revoked = reason;
66
- this.options.onDegraded?.(reason);
67
- }
68
- this.publish(entry);
69
- }
70
- registerTool(source) {
71
- if (!this.accepts(source) || !identifier(source.sourceId) || !identifier(source.runId))
72
- return;
73
- const entry = this.entry(source.toolUseId);
74
- if (!entry)
75
- return;
76
- if (entry.source && (entry.source.sourceId !== source.sourceId || entry.source.runId !== source.runId)) {
77
- this.revoke(entry, 'source-conflict');
78
- return;
79
- }
80
- entry.source ??= copySource(source);
81
- this.publish(entry);
82
- }
83
- joinLaunch(agentId, launchingToolUseId) {
84
- const prior = this.agents.get(agentId);
85
- const priorAgent = this.launches.get(launchingToolUseId);
86
- if ((!this.agents.has(agentId) && this.agents.size >= this.maximum) ||
87
- (!this.launches.has(launchingToolUseId) && this.launches.size >= this.maximum)) {
88
- this.options.onDegraded?.('capacity');
89
- this.observeConflict({ ...this.binding, agentId, launchingToolUseId });
90
- return false;
91
- }
92
- if ((prior !== undefined && prior !== launchingToolUseId) ||
93
- (priorAgent !== undefined && priorAgent !== agentId)) {
94
- this.observeConflict({ ...this.binding, agentId, launchingToolUseId });
95
- if (prior)
96
- this.observeConflict({ ...this.binding, launchingToolUseId: prior });
97
- return false;
98
- }
99
- this.launches.set(launchingToolUseId, agentId);
100
- this.agents.set(agentId, launchingToolUseId);
101
- return true;
102
- }
103
- observe(origin) {
104
- if (!this.accepts(origin) || !identifier(origin.agentId))
105
- return;
106
- if (!origin.toolUseId && identifier(origin.launchingToolUseId)) {
107
- if (!this.joinLaunch(origin.agentId, origin.launchingToolUseId))
108
- return;
109
- for (const entry of this.entries.values()) {
110
- if (!entry.origin?.agentId || !this.agents.has(entry.origin.agentId))
111
- continue;
112
- const launch = this.agents.get(entry.origin.agentId);
113
- if (launch === null)
114
- this.revoke(entry, 'identity-conflict');
115
- else {
116
- entry.origin = { ...entry.origin, launchingToolUseId: launch };
117
- this.publish(entry);
118
- }
119
- }
120
- return;
121
- }
122
- if (!identifier(origin.toolUseId))
123
- return;
124
- const entry = this.entry(origin.toolUseId);
125
- if (!entry || entry.revoked)
126
- return;
127
- if (origin.launchingToolUseId !== undefined &&
128
- (!identifier(origin.launchingToolUseId) || !this.joinLaunch(origin.agentId, origin.launchingToolUseId))) {
129
- this.revoke(entry, 'identity-conflict');
130
- return;
131
- }
132
- const launch = this.agents.get(origin.agentId);
133
- if (launch === null || (entry.origin && entry.origin.agentId !== origin.agentId) ||
134
- (entry.origin?.launchingToolUseId && launch && entry.origin.launchingToolUseId !== launch)) {
135
- this.revoke(entry, 'identity-conflict');
136
- return;
137
- }
138
- if (origin.launchingToolUseId !== undefined && (!identifier(origin.launchingToolUseId) ||
139
- this.launches.get(origin.launchingToolUseId) === null ||
140
- (entry.origin?.launchingToolUseId !== undefined && entry.origin.launchingToolUseId !== origin.launchingToolUseId) ||
141
- (launch !== undefined && launch !== origin.launchingToolUseId))) {
142
- this.revoke(entry, 'identity-conflict');
143
- return;
144
- }
145
- const launchingToolUseId = launch ?? origin.launchingToolUseId ?? entry.origin?.launchingToolUseId;
146
- entry.origin = { ...this.binding, toolUseId: origin.toolUseId, agentId: origin.agentId,
147
- ...(launchingToolUseId ? { launchingToolUseId } : {}) };
148
- this.publish(entry);
149
- }
150
- observeConflict(origin) {
151
- if (!this.accepts(origin))
152
- return;
153
- if (identifier(origin.toolUseId)) {
154
- const entry = this.entry(origin.toolUseId);
155
- if (entry)
156
- this.revoke(entry, 'identity-conflict');
157
- }
158
- if (identifier(origin.agentId)) {
159
- if (this.agents.has(origin.agentId) || this.agents.size < this.maximum)
160
- this.agents.set(origin.agentId, null);
161
- for (const entry of this.entries.values()) {
162
- if (entry.origin?.agentId === origin.agentId)
163
- this.revoke(entry, 'identity-conflict');
164
- }
165
- }
166
- if (!identifier(origin.launchingToolUseId))
167
- return;
168
- const agent = this.launches.get(origin.launchingToolUseId);
169
- if (!this.launches.has(origin.launchingToolUseId) && this.launches.size >= this.maximum) {
170
- this.options.onDegraded?.('capacity');
171
- return;
172
- }
173
- if (this.launches.get(origin.launchingToolUseId) !== null)
174
- this.options.onDegraded?.('identity-conflict');
175
- this.launches.set(origin.launchingToolUseId, null);
176
- if (agent)
177
- this.agents.set(agent, null);
178
- for (const entry of this.entries.values()) {
179
- if ((agent && entry.origin?.agentId === agent) || entry.origin?.launchingToolUseId === origin.launchingToolUseId) {
180
- this.revoke(entry, 'identity-conflict');
181
- }
182
- }
183
- }
184
- resolveTool(rootSessionId, toolUseId) {
185
- if (this.closed || rootSessionId !== this.binding.rootSessionId)
186
- return undefined;
187
- const entry = this.entries.get(toolUseId);
188
- return entry?.origin && !entry.revoked ? copyOrigin(entry.origin) : undefined;
189
- }
190
- dispose() { this.closed = true; this.entries.clear(); this.launches.clear(); this.agents.clear(); }
191
- }
@@ -1,42 +0,0 @@
1
- export class InputQueue {
2
- capacity;
3
- values = [];
4
- waiting;
5
- closed = false;
6
- constructor(capacity = 32) {
7
- this.capacity = capacity;
8
- if (!Number.isSafeInteger(capacity) || capacity < 1 || capacity > 1024)
9
- throw new Error('Invalid input capacity');
10
- }
11
- push(value) {
12
- if (this.closed)
13
- throw new Error('Input queue closed');
14
- if (this.waiting) {
15
- const waiting = this.waiting;
16
- this.waiting = undefined;
17
- waiting({ done: false, value });
18
- }
19
- else {
20
- if (this.values.length >= this.capacity)
21
- throw new Error('Input queue capacity exceeded');
22
- this.values.push(value);
23
- }
24
- }
25
- close() {
26
- this.closed = true;
27
- this.values = [];
28
- this.waiting?.({ done: true, value: undefined });
29
- this.waiting = undefined;
30
- }
31
- next() {
32
- if (this.closed)
33
- return Promise.resolve({ done: true, value: undefined });
34
- if (this.values.length)
35
- return Promise.resolve({ done: false, value: this.values.shift() });
36
- if (this.waiting)
37
- return Promise.reject(new Error('Input queue already has a reader'));
38
- return new Promise((resolve) => { this.waiting = resolve; });
39
- }
40
- return() { this.close(); return this.next(); }
41
- [Symbol.asyncIterator]() { return this; }
42
- }
@@ -1,95 +0,0 @@
1
- import { agent, methods, PROTOCOL_VERSION, RequestError, ndJsonStream } from '@agentclientprotocol/sdk';
2
- import { Readable, Writable } from 'node:stream';
3
- import { mkdtemp, rm } from 'node:fs/promises';
4
- import { tmpdir } from 'node:os';
5
- import { join } from 'node:path';
6
- import { loadSdkDriver } from './sdkDriver.js';
7
- import { loadPreparedSdkRuntime } from './sdkRuntime.js';
8
- import { QoderAdapterSession } from './session.js';
9
- import { supportsQoderSdkSteering } from './sdkDriver.js';
10
- const stopRequest = (value) => {
11
- if (!value || typeof value !== 'object' || Array.isArray(value) ||
12
- ['sessionId', 'taskId', 'requestId'].some((key) => typeof value[key] !== 'string'))
13
- throw RequestError.invalidParams('Invalid provider task stop request');
14
- return value;
15
- };
16
- const steeringRequest = (value) => {
17
- if (!value || typeof value !== 'object' || Array.isArray(value))
18
- throw RequestError.invalidParams('Invalid Qoder steering request');
19
- const input = value;
20
- if (typeof input.sessionId !== 'string' || !input.sessionId.trim() || !Array.isArray(input.prompt) || input.prompt.length === 0)
21
- throw RequestError.invalidParams('Invalid Qoder steering request');
22
- const meta = input._meta;
23
- const steering = meta && typeof meta === 'object' && !Array.isArray(meta) ? meta.steering : undefined;
24
- const priority = steering && typeof steering === 'object' && !Array.isArray(steering) ? steering.priority : undefined;
25
- if (priority !== undefined && priority !== 'now')
26
- throw RequestError.invalidParams('Qoder steering only supports priority now');
27
- return { sessionId: input.sessionId, prompt: input.prompt, priority: priority };
28
- };
29
- export function createQoderAgent(options) {
30
- let connection;
31
- let opened = false;
32
- let profileRevision = 0;
33
- const session = new QoderAdapterSession({ ...options,
34
- update: (value) => connection.client.notify(methods.client.session.update, value),
35
- profile: (value) => connection?.signal.aborted ? Promise.resolve() :
36
- connection.client.notify('_axom/qoder/profile', { sessionId: value.rootSessionId,
37
- revision: ++profileRevision, profile: value }),
38
- permission: (request, signal) => connection.client.request(methods.client.session.requestPermission, request, { cancellationSignal: signal }),
39
- taskObservation: (value) => connection.client.notify('_qoder/task_event', value) });
40
- const close = () => session.close();
41
- const app = agent({ name: 'axom-qoder-sdk' })
42
- .onConnect((value) => {
43
- if (connection) {
44
- if (connection.signal !== value.signal)
45
- value.close(new Error('Adapter permits one connection'));
46
- return;
47
- }
48
- connection = value;
49
- value.signal.addEventListener('abort', () => { void close().catch(() => { }); }, { once: true });
50
- })
51
- .onRequest(methods.agent.initialize, () => ({ protocolVersion: PROTOCOL_VERSION,
52
- agentInfo: { name: 'axom-qoder-sdk', version: '1.0.50' },
53
- agentCapabilities: { loadSession: false, promptCapabilities: { image: false, audio: false, embeddedContext: false } },
54
- authMethods: [], _meta: { qoderProfile: {
55
- cliVersion: options.driver.cliVersion, sdkVersion: options.driver.sdkVersion, mode: 'sdk-adapter',
56
- executable: options.driver.executable, persistent: true, transport: 'process', capabilities: [],
57
- agentMessaging: false, observerHealthy: false, initialized: false, rootConfirmed: false,
58
- completedContinuationEnabled: false, sendMessageExposed: false, platform: process.platform,
59
- runtimeSource: 'explicit-local'
60
- },
61
- ...(supportsQoderSdkSteering(options.driver.cliVersion) ? { steering: { supported: true, timings: ['now'] } } : {}) } }))
62
- .onRequest(methods.agent.session.new, async (ctx) => {
63
- if (opened)
64
- throw RequestError.invalidParams('Adapter permits one session');
65
- opened = true;
66
- return session.newSession(ctx.params);
67
- })
68
- .onRequest(methods.agent.session.prompt, (ctx) => session.prompt(ctx.params))
69
- .onRequest('_session/steering', steeringRequest, (ctx) => {
70
- if (ctx.params.sessionId !== session.currentProfile?.rootSessionId)
71
- return { outcome: 'promptRequired' };
72
- return session.steer(ctx.params.prompt, ctx.params.priority).then((outcome) => ({ outcome }));
73
- })
74
- .onRequest('_axom/task/stop', stopRequest, (ctx) => session.stopTask(ctx.params))
75
- .onNotification(methods.agent.session.cancel, async (ctx) => {
76
- if (ctx.params.sessionId !== session.currentProfile?.rootSessionId)
77
- return;
78
- await session.cancel();
79
- });
80
- return { app, close };
81
- }
82
- export async function runQoderAdapter(executable) {
83
- const { sdk } = await loadPreparedSdkRuntime();
84
- const driver = await loadSdkDriver(executable, sdk);
85
- const runDir = await mkdtemp(join(tmpdir(), 'axom-qoder-acp-'));
86
- const server = createQoderAgent({ driver, runDir, historyReader: sdk });
87
- try {
88
- const connection = server.app.connect(ndJsonStream(Writable.toWeb(process.stdout), Readable.toWeb(process.stdin)));
89
- await connection.closed;
90
- }
91
- finally {
92
- await server.close();
93
- await rm(runDir, { recursive: true, force: true });
94
- }
95
- }
@@ -1,117 +0,0 @@
1
- import { IdentityIndex } from './identityIndex.js';
2
- import { qoderChildMeta, qoderCorrectionMeta, qoderSpawnMeta } from './subagentMeta.js';
3
- const id = (value) => typeof value === 'string' && value.length > 0 &&
4
- value.length <= 256 && !/[\x00-\x1f\x7f]/.test(value);
5
- export class QoderMessageMapper {
6
- options;
7
- binding;
8
- sources = new Map();
9
- conflictedTools = new Set();
10
- messages = new Set();
11
- index;
12
- collecting;
13
- closed = false;
14
- constructor(binding, options = {}) {
15
- this.options = options;
16
- this.binding = { rootSessionId: binding.rootSessionId, runtimeGeneration: binding.runtimeGeneration };
17
- this.index = new IdentityIndex(this.binding, { onDegraded: options.degraded, onCorrection: ({ binding: source, origin }) => {
18
- const update = { sessionUpdate: 'tool_call_update', toolCallId: source.toolUseId,
19
- _meta: { qoderSdk: { version: 1, source, origin, originCleared: origin === null },
20
- ...qoderCorrectionMeta(source, origin) } };
21
- if (this.collecting)
22
- this.collecting.push(update);
23
- else
24
- options.correction?.(update);
25
- } });
26
- }
27
- map(message, runId) {
28
- if (this.closed || message.session_id !== this.binding.rootSessionId ||
29
- (message.type === 'user' && 'isReplay' in message && message.isReplay))
30
- return [];
31
- if (message.type !== 'assistant' && message.type !== 'user')
32
- return [];
33
- if (!id(message.uuid)) {
34
- this.options.degraded?.('message-identity');
35
- return [];
36
- }
37
- if (this.messages.has(message.uuid))
38
- return [];
39
- if (this.messages.size >= 4096) {
40
- this.options.degraded?.('mapper-capacity');
41
- return [];
42
- }
43
- this.messages.add(message.uuid);
44
- const updates = [];
45
- this.collecting = updates;
46
- try {
47
- const blocks = message.message.content;
48
- if (!Array.isArray(blocks))
49
- return [];
50
- for (const block of blocks) {
51
- if (message.type === 'assistant' && (block.type === 'text' || block.type === 'thinking')) {
52
- const text = block.type === 'thinking' ? block.thinking : block.text;
53
- const parentToolUseId = message.parent_tool_use_id;
54
- if (typeof text === 'string' && Buffer.byteLength(text) <= 131072) {
55
- if (parentToolUseId !== null && (!id(parentToolUseId) || this.conflictedTools.has(parentToolUseId))) {
56
- this.options.degraded?.('child-message-unscoped');
57
- continue;
58
- }
59
- updates.push({ sessionUpdate: block.type === 'text' ? 'agent_message_chunk' : 'agent_thought_chunk',
60
- content: { type: 'text', text },
61
- ...(parentToolUseId ? { _meta: qoderChildMeta(parentToolUseId, this.index.resolveTool(this.binding.rootSessionId, parentToolUseId), { source: 'sdk' }) } : {}) });
62
- }
63
- }
64
- else if (message.type === 'assistant' && block.type === 'tool_use' && id(block.id) && id(block.name)) {
65
- const parentToolUseId = message.parent_tool_use_id;
66
- const ownerRun = parentToolUseId && !this.conflictedTools.has(parentToolUseId)
67
- ? this.sources.get(parentToolUseId)?.runId : parentToolUseId ? undefined : runId;
68
- if (!id(ownerRun)) {
69
- this.options.degraded?.('tool-run-unbound');
70
- continue;
71
- }
72
- const source = { ...this.binding, toolUseId: block.id, sourceId: message.uuid, runId: ownerRun,
73
- ...(parentToolUseId ? { parentToolUseId } : {}) };
74
- const existing = this.sources.get(block.id);
75
- if (existing) {
76
- this.conflictedTools.add(block.id);
77
- this.index.registerTool(source);
78
- this.options.degraded?.('tool-id-reused');
79
- continue;
80
- }
81
- if (this.sources.size >= 4096) {
82
- this.options.degraded?.('mapper-capacity');
83
- continue;
84
- }
85
- this.sources.set(block.id, source);
86
- const qoder = parentToolUseId && !this.conflictedTools.has(parentToolUseId)
87
- ? qoderChildMeta(parentToolUseId, this.index.resolveTool(this.binding.rootSessionId, block.id), { source: 'sdk', toolUseId: block.id, toolName: block.name })
88
- : !parentToolUseId && block.name === 'Agent' ? qoderSpawnMeta(block.id) : undefined;
89
- updates.push({ sessionUpdate: 'tool_call', toolCallId: block.id, name: block.name, title: block.name,
90
- kind: block.name === 'Agent' ? 'think' : block.name === 'Read' ? 'read' : block.name === 'Edit' ? 'edit' : block.name === 'Bash' ? 'execute' : 'other',
91
- status: 'in_progress', rawInput: block.input,
92
- _meta: { qoderSdk: { version: 1, source, toolName: block.name }, ...(qoder ?? {}) } });
93
- this.index.registerTool(source);
94
- }
95
- else if (message.type === 'user' && block.type === 'tool_result' && id(block.tool_use_id) &&
96
- this.sources.has(block.tool_use_id) && !this.conflictedTools.has(block.tool_use_id)) {
97
- const source = this.sources.get(block.tool_use_id);
98
- const qoder = source.parentToolUseId
99
- ? qoderChildMeta(source.parentToolUseId, this.index.resolveTool(this.binding.rootSessionId, block.tool_use_id), { source: 'sdk', toolUseId: block.tool_use_id })
100
- : undefined;
101
- updates.push({ sessionUpdate: 'tool_call_update', toolCallId: block.tool_use_id,
102
- status: block.is_error ? 'failed' : 'completed', rawOutput: block.content,
103
- _meta: { qoderSdk: { version: 1, source }, ...(qoder ?? {}) } });
104
- }
105
- }
106
- return updates;
107
- }
108
- finally {
109
- this.collecting = undefined;
110
- }
111
- }
112
- observe(origin) { if (!this.closed)
113
- this.index.observe(origin); }
114
- conflict(origin) { if (!this.closed)
115
- this.index.observeConflict(origin); }
116
- dispose() { this.closed = true; this.index.dispose(); this.sources.clear(); this.conflictedTools.clear(); this.messages.clear(); }
117
- }