lark-remote 0.1.6 → 0.1.8

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 (216) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.en.md +9 -1
  3. package/README.md +14 -2
  4. package/dist/bridge/approval-coordinator.d.ts +71 -34
  5. package/dist/bridge/approval-coordinator.js +225 -41
  6. package/dist/bridge/inbound-media.d.ts +62 -0
  7. package/dist/bridge/inbound-media.js +282 -0
  8. package/dist/bridge/index.d.ts +97 -13
  9. package/dist/bridge/index.js +227 -87
  10. package/dist/bridge/queue-manager.d.ts +2 -1
  11. package/dist/bridge/queue-manager.js +1 -0
  12. package/dist/card/approval-render.js +294 -36
  13. package/dist/card/bash-card-session.d.ts +2 -24
  14. package/dist/card/bash-card-session.js +6 -73
  15. package/dist/card/bash-renderer.js +2 -3
  16. package/dist/card/card-budget.js +29 -75
  17. package/dist/card/card-session.d.ts +48 -0
  18. package/dist/card/card-session.js +86 -0
  19. package/dist/card/card-shared.d.ts +7 -16
  20. package/dist/card/card-shared.js +7 -30
  21. package/dist/card/run-card-session.d.ts +2 -55
  22. package/dist/card/run-card-session.js +6 -104
  23. package/dist/card/run-renderer.d.ts +7 -0
  24. package/dist/card/run-renderer.js +116 -238
  25. package/dist/card/run-state.d.ts +13 -0
  26. package/dist/card/run-state.js +25 -16
  27. package/dist/card/text-truncate.d.ts +13 -12
  28. package/dist/card/text-truncate.js +13 -63
  29. package/dist/common/fs.d.ts +8 -0
  30. package/dist/common/fs.js +17 -0
  31. package/dist/common/guards.d.ts +0 -20
  32. package/dist/common/guards.js +0 -43
  33. package/dist/common/sleep.d.ts +2 -0
  34. package/dist/common/sleep.js +5 -0
  35. package/dist/common/truncate.d.ts +39 -0
  36. package/dist/common/truncate.js +92 -0
  37. package/dist/config/codex-config.d.ts +1 -1
  38. package/dist/config/codex-config.js +1 -1
  39. package/dist/config/index.d.ts +112 -24
  40. package/dist/config/index.js +139 -37
  41. package/dist/connector/index.d.ts +69 -2
  42. package/dist/connector/index.js +107 -1
  43. package/dist/index.js +150 -118
  44. package/dist/instance-lock.js +4 -12
  45. package/dist/order/alias-resolve.d.ts +13 -0
  46. package/dist/order/alias-resolve.js +22 -0
  47. package/dist/order/alias-store.d.ts +38 -0
  48. package/dist/order/alias-store.js +106 -0
  49. package/dist/persistence/atomic-write.d.ts +8 -2
  50. package/dist/persistence/atomic-write.js +23 -7
  51. package/dist/restart.js +2 -1
  52. package/dist/router/card-action-payload.d.ts +30 -0
  53. package/dist/router/card-action-payload.js +39 -0
  54. package/dist/router/card-helpers.d.ts +63 -0
  55. package/dist/router/card-helpers.js +146 -0
  56. package/dist/router/config/claude.js +30 -1
  57. package/dist/router/config/codex.js +29 -50
  58. package/dist/router/config/common/model-patch.d.ts +22 -0
  59. package/dist/router/config/common/model-patch.js +26 -0
  60. package/dist/router/config/common/render.js +5 -4
  61. package/dist/router/config/dsh.d.ts +51 -0
  62. package/dist/router/config/dsh.js +179 -0
  63. package/dist/router/config/index.d.ts +12 -0
  64. package/dist/router/config/index.js +28 -1
  65. package/dist/router/config/kimi.d.ts +4 -1
  66. package/dist/router/config/kimi.js +27 -0
  67. package/dist/router/config/opencode.js +18 -5
  68. package/dist/router/config/pi.js +4 -5
  69. package/dist/router/config/types.d.ts +17 -2
  70. package/dist/router/index.d.ts +76 -22
  71. package/dist/router/index.js +479 -548
  72. package/dist/router/utils.d.ts +2 -0
  73. package/dist/router/utils.js +16 -2
  74. package/dist/runner/agent-choices-common.d.ts +16 -0
  75. package/dist/runner/agent-choices-common.js +34 -0
  76. package/dist/runner/claude/runner.d.ts +47 -10
  77. package/dist/runner/claude/runner.js +117 -46
  78. package/dist/runner/claude/session.d.ts +166 -0
  79. package/dist/runner/claude/session.js +768 -0
  80. package/dist/runner/codex/app-server/protocol-types.d.ts +66 -39
  81. package/dist/runner/codex/app-server/protocol-types.js +2 -13
  82. package/dist/runner/codex/app-server/runner.d.ts +52 -59
  83. package/dist/runner/codex/app-server/runner.js +216 -338
  84. package/dist/runner/codex/app-server/translator.d.ts +8 -21
  85. package/dist/runner/codex/app-server/translator.js +45 -18
  86. package/dist/runner/codex/index.d.ts +0 -2
  87. package/dist/runner/codex/index.js +0 -2
  88. package/dist/runner/common/acp/protocol-helpers.d.ts +14 -0
  89. package/dist/runner/common/acp/protocol-helpers.js +21 -0
  90. package/dist/runner/common/acp/protocol-types.d.ts +271 -0
  91. package/dist/runner/common/acp/protocol-types.js +77 -0
  92. package/dist/runner/common/connection-based-runner.d.ts +111 -0
  93. package/dist/runner/common/connection-based-runner.js +261 -0
  94. package/dist/runner/{codex/app-server → common/jsonrpc}/client.d.ts +14 -7
  95. package/dist/runner/{codex/app-server → common/jsonrpc}/client.js +27 -18
  96. package/dist/runner/common/jsonrpc/connection-manager.d.ts +125 -0
  97. package/dist/runner/{codex/app-server → common/jsonrpc}/connection-manager.js +63 -28
  98. package/dist/runner/{codex/app-server → common/jsonrpc}/transport.d.ts +5 -4
  99. package/dist/runner/{codex/app-server → common/jsonrpc}/transport.js +18 -19
  100. package/dist/runner/common/jsonrpc/types.d.ts +32 -0
  101. package/dist/runner/common/jsonrpc/types.js +9 -0
  102. package/dist/runner/common/process-stopper.d.ts +2 -1
  103. package/dist/runner/common/process-stopper.js +1 -0
  104. package/dist/runner/common/runner-utils.d.ts +6 -13
  105. package/dist/runner/common/runner-utils.js +6 -47
  106. package/dist/runner/common/spawning-runner.d.ts +24 -70
  107. package/dist/runner/common/spawning-runner.js +98 -152
  108. package/dist/runner/dsh/client.d.ts +95 -0
  109. package/dist/runner/dsh/client.js +418 -0
  110. package/dist/runner/dsh/fake-dsh-server.d.ts +60 -0
  111. package/dist/runner/dsh/fake-dsh-server.js +156 -0
  112. package/dist/runner/dsh/index.d.ts +3 -0
  113. package/dist/runner/dsh/index.js +4 -0
  114. package/dist/runner/dsh/runner.d.ts +57 -0
  115. package/dist/runner/dsh/runner.js +191 -0
  116. package/dist/runner/dsh/translator.d.ts +28 -0
  117. package/dist/runner/dsh/translator.js +98 -0
  118. package/dist/runner/dsh/types.d.ts +155 -0
  119. package/dist/runner/dsh/types.js +14 -0
  120. package/dist/runner/index.d.ts +5 -4
  121. package/dist/runner/index.js +5 -4
  122. package/dist/runner/kimi/acp/runner.d.ts +106 -0
  123. package/dist/runner/kimi/acp/runner.js +516 -0
  124. package/dist/runner/kimi/acp/translator.d.ts +138 -0
  125. package/dist/runner/kimi/acp/translator.js +441 -0
  126. package/dist/runner/kimi/index.d.ts +1 -1
  127. package/dist/runner/kimi/index.js +1 -1
  128. package/dist/runner/opencode/acp/index.d.ts +1 -0
  129. package/dist/runner/opencode/acp/index.js +2 -0
  130. package/dist/runner/opencode/acp/runner.d.ts +121 -0
  131. package/dist/runner/opencode/acp/runner.js +429 -0
  132. package/dist/runner/opencode/acp/translator.d.ts +119 -0
  133. package/dist/runner/opencode/acp/translator.js +345 -0
  134. package/dist/runner/opencode/index.d.ts +1 -1
  135. package/dist/runner/opencode/index.js +1 -1
  136. package/dist/runner/pi/index.d.ts +1 -1
  137. package/dist/runner/pi/index.js +1 -1
  138. package/dist/runner/pi/rpc/client.d.ts +52 -0
  139. package/dist/runner/pi/rpc/client.js +114 -0
  140. package/dist/runner/pi/rpc/index.d.ts +4 -0
  141. package/dist/runner/pi/rpc/index.js +4 -0
  142. package/dist/runner/pi/rpc/protocol-types.d.ts +127 -0
  143. package/dist/runner/pi/rpc/protocol-types.js +21 -0
  144. package/dist/runner/pi/rpc/runner.d.ts +74 -0
  145. package/dist/runner/pi/rpc/runner.js +190 -0
  146. package/dist/runner/pi/rpc/translator.d.ts +55 -0
  147. package/dist/runner/pi/rpc/translator.js +258 -0
  148. package/dist/runner/probe.js +6 -1
  149. package/dist/runner/question-common.d.ts +26 -0
  150. package/dist/runner/question-common.js +42 -0
  151. package/dist/runner/registry.d.ts +7 -8
  152. package/dist/runner/registry.js +3 -4
  153. package/dist/runner/resolve-agent-choices.js +18 -59
  154. package/dist/runner/sync-agent-choices.js +16 -67
  155. package/dist/runner/types.d.ts +97 -14
  156. package/dist/session/claude/session-index.js +2 -3
  157. package/dist/session/claude/session-reader.js +3 -6
  158. package/dist/session/claude/sessions.js +43 -28
  159. package/dist/session/codex/rollout-reader.d.ts +2 -2
  160. package/dist/session/codex/rollout-reader.js +14 -17
  161. package/dist/session/codex/sessions.d.ts +1 -1
  162. package/dist/session/codex/sessions.js +2 -2
  163. package/dist/session/common/content-blocks.d.ts +7 -0
  164. package/dist/session/common/content-blocks.js +13 -9
  165. package/dist/session/common/jsonl.d.ts +8 -25
  166. package/dist/session/common/jsonl.js +126 -261
  167. package/dist/session/common/pagination.d.ts +28 -0
  168. package/dist/session/common/pagination.js +33 -0
  169. package/dist/session/dsh/index.d.ts +1 -0
  170. package/dist/session/dsh/index.js +2 -0
  171. package/dist/session/dsh/sessions.d.ts +39 -0
  172. package/dist/session/dsh/sessions.js +237 -0
  173. package/dist/session/index.d.ts +1 -0
  174. package/dist/session/index.js +1 -0
  175. package/dist/session/kimi/sessions.d.ts +34 -1
  176. package/dist/session/kimi/sessions.js +208 -98
  177. package/dist/session/opencode/sessions.d.ts +17 -3
  178. package/dist/session/opencode/sessions.js +29 -29
  179. package/dist/session/pi/sessions.d.ts +5 -1
  180. package/dist/session/pi/sessions.js +12 -16
  181. package/dist/session/session-store.d.ts +11 -1
  182. package/dist/session/session-store.js +75 -178
  183. package/dist/update/index.d.ts +2 -2
  184. package/dist/update/index.js +2 -2
  185. package/dist/update/install.d.ts +20 -2
  186. package/dist/update/install.js +51 -7
  187. package/dist/workspace/index.d.ts +4 -0
  188. package/dist/workspace/index.js +8 -1
  189. package/package.json +2 -1
  190. package/dist/runner/codex/app-server/connection-manager.d.ts +0 -56
  191. package/dist/runner/codex/argv.d.ts +0 -33
  192. package/dist/runner/codex/argv.js +0 -40
  193. package/dist/runner/codex/factory.d.ts +0 -29
  194. package/dist/runner/codex/factory.js +0 -39
  195. package/dist/runner/codex/jsonl.d.ts +0 -37
  196. package/dist/runner/codex/jsonl.js +0 -221
  197. package/dist/runner/codex/runner.d.ts +0 -66
  198. package/dist/runner/codex/runner.js +0 -129
  199. package/dist/runner/common/exec-translator.d.ts +0 -73
  200. package/dist/runner/common/exec-translator.js +0 -105
  201. package/dist/runner/kimi/jsonl.d.ts +0 -28
  202. package/dist/runner/kimi/jsonl.js +0 -143
  203. package/dist/runner/kimi/runner.d.ts +0 -49
  204. package/dist/runner/kimi/runner.js +0 -105
  205. package/dist/runner/opencode/argv.d.ts +0 -32
  206. package/dist/runner/opencode/argv.js +0 -35
  207. package/dist/runner/opencode/jsonl.d.ts +0 -68
  208. package/dist/runner/opencode/jsonl.js +0 -295
  209. package/dist/runner/opencode/runner.d.ts +0 -61
  210. package/dist/runner/opencode/runner.js +0 -93
  211. package/dist/runner/pi/jsonl.d.ts +0 -128
  212. package/dist/runner/pi/jsonl.js +0 -249
  213. package/dist/runner/pi/runner.d.ts +0 -36
  214. package/dist/runner/pi/runner.js +0 -76
  215. package/dist/session/common/catch-up.d.ts +0 -12
  216. package/dist/session/common/catch-up.js +0 -31
@@ -1,105 +0,0 @@
1
- /**
2
- * Abstract base class for exec-stream translators (codex, opencode, pi, kimi).
3
- *
4
- * Encapsulates the shared state machine and guard logic that was duplicated
5
- * across every concrete translator:
6
- * - Terminal-state tracking (idempotent `finish()`)
7
- * - `translate()` guard (terminal → []; non-record / non-string-type → anomaly)
8
- * - `recordUnknownEvent()` helper (warn-logs unknown event types)
9
- * - Session / usage / error getters
10
- *
11
- * Subclasses provide:
12
- * - `logTag` — prefix for warn logs
13
- * - `streamEndedMessage()` — agent-specific "stream ended early" message
14
- * - `translateEvent(raw)` — agent-specific event dispatch
15
- *
16
- * @see SpawningRunner for the runner that consumes translators
17
- */
18
- import { getLogger } from '../../logger/index.js';
19
- import { isRecord } from '../../common/guards.js';
20
- // ---------------------------------------------------------------------------
21
- // Abstract base class
22
- // ---------------------------------------------------------------------------
23
- export class ExecTranslator {
24
- // --- Shared state ---
25
- terminal = false;
26
- lastError;
27
- lastUsage;
28
- terminalErrorMessage;
29
- terminalErrorFromAgent = false;
30
- sessionId;
31
- startedTools = new Set();
32
- // --- translate() guard (shared) ---
33
- /** Translate a single parsed ndjson line into zero or more `AgentEvent`s.
34
- * P3-3: filter paths (terminal / non-record / non-string-type) return `null`
35
- * instead of `[]` to avoid a throwaway array allocation per non-emitting
36
- * event on codex/opencode hot paths. The consumer (SpawningRunner) already
37
- * handles `null` via `Array.isArray` + null guards. */
38
- translate(raw) {
39
- if (this.terminal)
40
- return null;
41
- if (!isRecord(raw) || typeof raw.type !== 'string') {
42
- return null;
43
- }
44
- return this.translateEvent(raw);
45
- }
46
- // --- recordUnknownEvent helper ---
47
- /** Warn-log an unknown event type and return `null` (P3-3: no throwaway []). */
48
- recordUnknownEvent(type) {
49
- getLogger().warn(`${this.logTag} unknown event type: ${type}`);
50
- return null;
51
- }
52
- // --- finish() (shared, idempotent) ---
53
- /**
54
- * Called when the stream ends without a natural terminal event.
55
- *
56
- * - Marks the translator terminal (idempotent — second call returns `[]`).
57
- * - For `reason='failed'`, stores `terminalErrorMessage` so the runner can
58
- * surface it via `buildResultEvent({translatorError})`.
59
- * - Returns `[]` — the runner is responsible for emitting the result event.
60
- */
61
- finish(reason = 'failed') {
62
- if (this.terminal)
63
- return [];
64
- this.terminal = true;
65
- if (reason === 'failed') {
66
- const detail = this.lastError ? `: ${this.lastError}` : '';
67
- this.terminalErrorMessage = `${this.streamEndedMessage()}${detail}`;
68
- }
69
- // interrupted / timeout: no terminalErrorMessage — the runner's
70
- // stoppedByUser flag (set by base class stop()) drives the result subtype.
71
- return [];
72
- }
73
- // --- Getters (shared) ---
74
- /** Whether a terminal event has already been seen. */
75
- isTerminal() {
76
- return this.terminal;
77
- }
78
- /** Session ID captured from the agent stream (for the result event). */
79
- getSessionId() {
80
- return this.sessionId;
81
- }
82
- /** Token usage captured from the terminal event (for the success result event). */
83
- getLastUsage() {
84
- return this.lastUsage;
85
- }
86
- /**
87
- * Terminal error message captured from an agent-reported error or
88
- * `finish('failed')`. Returns `undefined` if no terminal error occurred.
89
- */
90
- getTerminalError() {
91
- return this.terminalErrorMessage;
92
- }
93
- /**
94
- * True iff `getTerminalError()` was populated by an agent-reported terminal
95
- * error (e.g. codex `turn.failed`). The runner uses this to pick the correct
96
- * root cause for `buildResultEvent`: agent errors override signal/non-zero-code
97
- * (the agent error is the root cause), but stream-ended-early errors
98
- * (`finish('failed')`) yield to signal/non-zero-code (the signal is the root
99
- * cause and the early stream-end is a symptom).
100
- */
101
- hasAgentTerminalError() {
102
- return this.terminalErrorFromAgent;
103
- }
104
- }
105
- //# sourceMappingURL=exec-translator.js.map
@@ -1,28 +0,0 @@
1
- import type { RunnerTranslator } from '../common/spawning-runner.js';
2
- import type { AgentEvent } from '../types.js';
3
- /**
4
- * Translates kimi `--output-format stream-json` ndjson into lark-remote
5
- * AgentEvents. Stateful: captures sessionId from the first meta event so
6
- * the synthesized SystemInitEvent carries the correct session_id.
7
- *
8
- * Implements RunnerTranslator so the base SpawningRunner can drive it
9
- * uniformly. kimi has no agent-reported terminal error (no equivalent of
10
- * codex `turn.failed`), so isTerminal/finish/getTerminalError/
11
- * hasAgentTerminalError are no-ops — kimi relies entirely on the base
12
- * class's signal/code-based result event classification.
13
- */
14
- export declare class KimiTranslator implements RunnerTranslator {
15
- private readonly cwd;
16
- private readonly model;
17
- private sessionId;
18
- constructor(opts: {
19
- cwd: string;
20
- model: string;
21
- });
22
- translate(raw: unknown): AgentEvent | AgentEvent[] | null;
23
- isTerminal(): boolean;
24
- finish(_reason: 'failed' | 'interrupted' | 'timeout'): void;
25
- getTerminalError(): string | undefined;
26
- hasAgentTerminalError(): boolean;
27
- getSessionId(): string | undefined;
28
- }
@@ -1,143 +0,0 @@
1
- // --- Tool name normalization (Kimi uses lowercase) ---
2
- const TOOL_NAME_MAP = {
3
- read: 'Read',
4
- write: 'Write',
5
- edit: 'Edit',
6
- grep: 'Grep',
7
- glob: 'Glob',
8
- bash: 'Bash',
9
- websearch: 'WebSearch',
10
- fetchurl: 'FetchURL',
11
- skill: 'Skill',
12
- tasklist: 'TaskList',
13
- taskoutput: 'TaskOutput',
14
- taskstop: 'TaskStop',
15
- todolist: 'TodoList',
16
- croncreate: 'CronCreate',
17
- crondelete: 'CronDelete',
18
- cronlist: 'CronList',
19
- enterplanmode: 'EnterPlanMode',
20
- exitplanmode: 'ExitPlanMode',
21
- getgoal: 'GetGoal',
22
- setgoalbudget: 'SetGoalBudget',
23
- updategoal: 'UpdateGoal',
24
- readmediafile: 'ReadMediaFile',
25
- };
26
- function normalizeToolName(name) {
27
- return TOOL_NAME_MAP[name] || name.charAt(0).toUpperCase() + name.slice(1);
28
- }
29
- // --- KimiTranslator ---
30
- /**
31
- * Translates kimi `--output-format stream-json` ndjson into lark-remote
32
- * AgentEvents. Stateful: captures sessionId from the first meta event so
33
- * the synthesized SystemInitEvent carries the correct session_id.
34
- *
35
- * Implements RunnerTranslator so the base SpawningRunner can drive it
36
- * uniformly. kimi has no agent-reported terminal error (no equivalent of
37
- * codex `turn.failed`), so isTerminal/finish/getTerminalError/
38
- * hasAgentTerminalError are no-ops — kimi relies entirely on the base
39
- * class's signal/code-based result event classification.
40
- */
41
- export class KimiTranslator {
42
- cwd;
43
- model;
44
- sessionId;
45
- constructor(opts) {
46
- this.cwd = opts.cwd;
47
- this.model = opts.model;
48
- }
49
- translate(raw) {
50
- const rawEvent = raw;
51
- // Handle meta events (session.resume_hint) — emit system.init so the
52
- // bridge can sync sessionStore with the new sessionId. Without this,
53
- // the bridge never learns the sessionId and auto-resume silently fails.
54
- if (rawEvent.role === 'meta' && rawEvent.type === 'session.resume_hint') {
55
- const metaEvent = rawEvent;
56
- this.sessionId = metaEvent.session_id;
57
- return {
58
- type: 'system',
59
- subtype: 'init',
60
- session_id: metaEvent.session_id,
61
- cwd: this.cwd,
62
- model: this.model,
63
- timestamp: new Date().toISOString(),
64
- };
65
- }
66
- if (rawEvent.role === 'assistant') {
67
- const assistantEvent = rawEvent;
68
- const events = [];
69
- // Text content - yield immediately (Kimi sends complete content per message)
70
- if (assistantEvent.content) {
71
- events.push({
72
- type: 'assistant',
73
- message: { content: [{ type: 'text', text: assistantEvent.content }] },
74
- timestamp: new Date().toISOString(),
75
- });
76
- }
77
- // Tool calls - emit as separate events
78
- if (assistantEvent.tool_calls && assistantEvent.tool_calls.length > 0) {
79
- for (const tc of assistantEvent.tool_calls) {
80
- let argsObj = {};
81
- try {
82
- argsObj = JSON.parse(tc.function.arguments);
83
- }
84
- catch {
85
- // Use empty object if parse fails
86
- }
87
- events.push({
88
- type: 'assistant',
89
- message: {
90
- content: [
91
- {
92
- type: 'tool_use',
93
- id: tc.id,
94
- name: normalizeToolName(tc.function.name),
95
- input: argsObj,
96
- },
97
- ],
98
- },
99
- timestamp: new Date().toISOString(),
100
- });
101
- }
102
- }
103
- return events.length > 0 ? events : null;
104
- }
105
- if (rawEvent.role === 'tool') {
106
- const toolEvent = rawEvent;
107
- return {
108
- type: 'user',
109
- message: {
110
- content: [
111
- {
112
- type: 'tool_result',
113
- tool_use_id: toolEvent.tool_call_id,
114
- content: toolEvent.content,
115
- is_error: false,
116
- },
117
- ],
118
- },
119
- timestamp: new Date().toISOString(),
120
- };
121
- }
122
- return null;
123
- }
124
- isTerminal() {
125
- // kimi has no terminal event — the base class's result event is the terminal.
126
- return false;
127
- }
128
- finish(_reason) {
129
- // No-op: kimi has no stream-ended-early terminal error to record.
130
- }
131
- getTerminalError() {
132
- // Always undefined — kimi has no agent-reported terminal error.
133
- return undefined;
134
- }
135
- hasAgentTerminalError() {
136
- // Always false — kimi has no agent-reported terminal error.
137
- return false;
138
- }
139
- getSessionId() {
140
- return this.sessionId;
141
- }
142
- }
143
- //# sourceMappingURL=jsonl.js.map
@@ -1,49 +0,0 @@
1
- import type { ChildProcess } from 'node:child_process';
2
- import { SpawningRunner, type RunnerTranslator } from '../common/spawning-runner.js';
3
- import type { AgentRunner, AgentSessionReader, SpawnOptions, AgentStatusInfo } from '../types.js';
4
- interface KimiRunnerConfig {
5
- model?: string;
6
- thinkingEffort?: string;
7
- stopGraceMs?: number;
8
- pidDir?: string;
9
- workspace: string;
10
- spawnHeartbeatMs?: number;
11
- sessionReader?: AgentSessionReader;
12
- /** Completion timeout (ms). Default: 5000. Injectable for testing. */
13
- completionTimeoutMs?: number;
14
- }
15
- /**
16
- * KimiRunner: spawn-per-message runner using `kimi -p <prompt> --output-format stream-json`.
17
- *
18
- * Inherits the spawn + completion + cleanup orchestration from SpawningRunner.
19
- * This subclass overrides only:
20
- * - buildArgv(opts) → kimi-specific flags (-p/--output-format/thinkingEffort)
21
- * - createTranslator(opts) → new KimiTranslator({ cwd: opts.cwd, model })
22
- * - awaitCompletion(proc, p) → 5s timeout race + SIGKILL fallback (kimi hangs after
23
- * stdout closes)
24
- *
25
- * The spawn-error 5s race lives in the base class (awaitSpawnError), shared by all
26
- * 5 runners — kimi no longer overrides it. The completion 5s race MUST remain here
27
- * (pinned by source-grep anchor tests/anchor/kimi/kimi-runner-stream-error.test.ts
28
- * which checks for `Promise.race` and `timeout` strings in this file).
29
- */
30
- export declare class KimiRunner extends SpawningRunner implements AgentRunner {
31
- readonly kind: "kimi";
32
- readonly sessionReader: AgentSessionReader;
33
- private defaultModel;
34
- private thinkingEffort;
35
- private readonly completionTimeoutMs;
36
- constructor(opts: KimiRunnerConfig);
37
- get pid(): number | undefined;
38
- getStatusInfo(): AgentStatusInfo;
39
- protected buildArgv(opts: SpawnOptions): string[];
40
- protected createTranslator(opts: SpawnOptions): RunnerTranslator;
41
- protected awaitCompletion(proc: ChildProcess, completion: Promise<{
42
- code: number | null;
43
- signal: NodeJS.Signals | null;
44
- }>): Promise<{
45
- code: number | null;
46
- signal: NodeJS.Signals | null;
47
- }>;
48
- }
49
- export {};
@@ -1,105 +0,0 @@
1
- import { getLogger } from '../../logger/index.js';
2
- import { SpawningRunner } from '../common/spawning-runner.js';
3
- import { KimiTranslator } from './jsonl.js';
4
- /**
5
- * Timeout (ms) for kimi's spawn-error race and completion race. Kimi's CLI
6
- * sometimes hangs after stdout closes or fails silently without an 'error'
7
- * event; both hooks race against this timeout to avoid blocking the runner
8
- * forever. Same value for both because they protect the same failure mode
9
- * (silent hang). Clean Code P3-1 (G25 Magic Numbers).
10
- */
11
- const KIMI_TIMEOUT_MS = 5000;
12
- /**
13
- * KimiRunner: spawn-per-message runner using `kimi -p <prompt> --output-format stream-json`.
14
- *
15
- * Inherits the spawn + completion + cleanup orchestration from SpawningRunner.
16
- * This subclass overrides only:
17
- * - buildArgv(opts) → kimi-specific flags (-p/--output-format/thinkingEffort)
18
- * - createTranslator(opts) → new KimiTranslator({ cwd: opts.cwd, model })
19
- * - awaitCompletion(proc, p) → 5s timeout race + SIGKILL fallback (kimi hangs after
20
- * stdout closes)
21
- *
22
- * The spawn-error 5s race lives in the base class (awaitSpawnError), shared by all
23
- * 5 runners — kimi no longer overrides it. The completion 5s race MUST remain here
24
- * (pinned by source-grep anchor tests/anchor/kimi/kimi-runner-stream-error.test.ts
25
- * which checks for `Promise.race` and `timeout` strings in this file).
26
- */
27
- export class KimiRunner extends SpawningRunner {
28
- kind = 'kimi';
29
- sessionReader;
30
- defaultModel;
31
- thinkingEffort;
32
- completionTimeoutMs;
33
- constructor(opts) {
34
- super({
35
- pidDir: opts.pidDir,
36
- workspace: opts.workspace,
37
- stopGraceMs: opts.stopGraceMs,
38
- spawnHeartbeatMs: opts.spawnHeartbeatMs,
39
- pidFilePrefix: 'kimi',
40
- logTag: 'kimi-runner',
41
- });
42
- this.binary = 'kimi';
43
- this.defaultModel = opts.model ?? 'kimi-code/k3';
44
- this.thinkingEffort = opts.thinkingEffort ?? 'max';
45
- this.completionTimeoutMs = opts.completionTimeoutMs ?? KIMI_TIMEOUT_MS;
46
- this.sessionReader = opts.sessionReader ?? {
47
- listSessions: () => ({ sessions: [], total: 0 }),
48
- getNewestSession: () => null,
49
- readSessionContent: () => ({ events: [] }),
50
- isSessionActive: () => false,
51
- };
52
- }
53
- get pid() {
54
- return this.currentProcess?.pid;
55
- }
56
- getStatusInfo() {
57
- return {
58
- kind: 'kimi',
59
- model: this.defaultModel,
60
- reasoning: this.thinkingEffort,
61
- };
62
- }
63
- buildArgv(opts) {
64
- // kimi 0.26+ 的 -p 非交互模式与 --auto/--yolo 互斥,不能传权限 flag。
65
- const args = ['-p', this.currentMessage, '--output-format', 'stream-json'];
66
- if (opts.sessionId)
67
- args.push('-r', opts.sessionId);
68
- if (this.defaultModel)
69
- args.push('-m', this.defaultModel);
70
- return args;
71
- }
72
- // --- Hooks ---
73
- createTranslator(opts) {
74
- // Fresh translator per run. Pass opts.cwd and defaultModel so the
75
- // synthesized SystemInitEvent carries the session's real directory
76
- // and model name (the bridge persists these into last-session.json).
77
- return new KimiTranslator({ cwd: opts.cwd, model: this.defaultModel });
78
- }
79
- async awaitCompletion(proc, completion) {
80
- // kimi sometimes hangs after stdout closes — race completion against a
81
- // 5s timeout, then force SIGKILL if still running. Pinned by source-grep
82
- // anchor (tests/anchor/kimi/kimi-runner-stream-error.test.ts).
83
- if (proc.exitCode !== null || proc.signalCode !== null) {
84
- return { code: proc.exitCode, signal: proc.signalCode };
85
- }
86
- const result = await Promise.race([
87
- completion,
88
- new Promise((resolve) => setTimeout(() => resolve({ timeout: true }), this.completionTimeoutMs)),
89
- ]);
90
- if ('timeout' in result) {
91
- getLogger().warn(`[kimi-runner] completion timeout, force stopping`);
92
- // P1-12: 只杀组长会让组内子进程 reparent 成孤儿。复用 ProcessStopper 的
93
- // immediate 组杀(与 exit/cleanup/killOrphan 语义一致)。
94
- try {
95
- await this.stopper.stop(proc, { immediate: true });
96
- }
97
- catch {
98
- // Process may have already exited
99
- }
100
- return { code: null, signal: 'SIGKILL' };
101
- }
102
- return result;
103
- }
104
- }
105
- //# sourceMappingURL=runner.js.map
@@ -1,32 +0,0 @@
1
- /**
2
- * Builds `opencode run` command-line arguments.
3
- *
4
- * Design:
5
- * - `--auto` eliminates approval handshake (root cause ①).
6
- * - `--format json` outputs ndjson event stream.
7
- * - Prompt goes via stdin (verified: opencode reads from stdin).
8
- * - cwd is set via spawn `cwd` option (not a flag).
9
- * - Model format: `provider/model` (e.g. 'anthropic/claude-sonnet-4-20250514').
10
- */
11
- interface BuildOpencodeRunArgsInput {
12
- /** Model in provider/model format (maps to -m). Omitted → opencode config default. */
13
- model?: string;
14
- /** Session ID for resumption (maps to -s). */
15
- sessionId?: string;
16
- }
17
- /**
18
- * Construct argv for `opencode run --format json --auto`.
19
- *
20
- * New session:
21
- * opencode run --format json --auto -m <provider/model>
22
- * (prompt via stdin)
23
- *
24
- * Resume session:
25
- * opencode run --format json --auto -s <sessionID>
26
- * (prompt via stdin)
27
- *
28
- * Note: prompt is sent via stdin, NOT argv position parameter.
29
- * The `--` separator is NOT needed because prompt goes via stdin.
30
- */
31
- export declare function buildOpencodeRunArgs(input: BuildOpencodeRunArgsInput): string[];
32
- export {};
@@ -1,35 +0,0 @@
1
- /**
2
- * Builds `opencode run` command-line arguments.
3
- *
4
- * Design:
5
- * - `--auto` eliminates approval handshake (root cause ①).
6
- * - `--format json` outputs ndjson event stream.
7
- * - Prompt goes via stdin (verified: opencode reads from stdin).
8
- * - cwd is set via spawn `cwd` option (not a flag).
9
- * - Model format: `provider/model` (e.g. 'anthropic/claude-sonnet-4-20250514').
10
- */
11
- /**
12
- * Construct argv for `opencode run --format json --auto`.
13
- *
14
- * New session:
15
- * opencode run --format json --auto -m <provider/model>
16
- * (prompt via stdin)
17
- *
18
- * Resume session:
19
- * opencode run --format json --auto -s <sessionID>
20
- * (prompt via stdin)
21
- *
22
- * Note: prompt is sent via stdin, NOT argv position parameter.
23
- * The `--` separator is NOT needed because prompt goes via stdin.
24
- */
25
- export function buildOpencodeRunArgs(input) {
26
- const args = ['run', '--format', 'json', '--auto'];
27
- if (input.model) {
28
- args.push('-m', input.model);
29
- }
30
- if (input.sessionId) {
31
- args.push('-s', input.sessionId);
32
- }
33
- return args;
34
- }
35
- //# sourceMappingURL=argv.js.map
@@ -1,68 +0,0 @@
1
- /**
2
- * Translates opencode `run --format json` ndjson output into lark-remote `AgentEvent`s.
3
- *
4
- * Key design decisions:
5
- * - opencode uses step-level events (step_start/step_finish), not turn-level like codex.
6
- * - Tool is a single-part state machine: state.status evolves pending→running→completed/error,
7
- * input and output are in the same part.
8
- * - Fail-fast: unknown types and missing fields return [] (no event emitted),
9
- * never throw, never write back to opencode (root cause ② tolerance).
10
- * - Stream ending before a terminal event records a terminal error via `finish()`
11
- * (root cause ③ fail-fast); the runner's `buildResultEvent` emits the result.
12
- * - Each `run()` must create a new translator instance (stateful: sessionId/terminal/startedTools).
13
- *
14
- * Terminal state (sessionId, lastUsage, terminalErrorMessage) is stored on
15
- * the instance and exposed via getters; `OpencodeExecRunner.run()` folds
16
- * this state into `SpawningRunner.buildResultEvent(...)` so result-event
17
- * semantics are uniform across all 5 agents.
18
- *
19
- * Event mapping:
20
- * | opencode ndjson | lark-remote AgentEvent |
21
- * |--------------------------|------------------------------------------------------|
22
- * | step_start | SystemInitEvent (first event only) |
23
- * | text | AssistantEvent(text) |
24
- * | reasoning | AssistantEvent(thinking) |
25
- * | tool/tool_use (first) | AssistantEvent(tool_use) |
26
- * | tool (status=completed) | UserEvent(tool_result, is_error=false) |
27
- * | tool (status=error) | UserEvent(tool_result, is_error=true) |
28
- * | patch | FileChangeEvent |
29
- * | step_finish(reason=stop) | [] (terminal — usage stashed for runner) |
30
- * | step_finish(reason=*) | [] (non-terminal, continues) |
31
- * | error | [] (terminal - error message stashed for runner) |
32
- * | unknown type | [] (no event) |
33
- */
34
- import type { AgentEvent, ResultEvent } from '../types.js';
35
- import { ExecTranslator } from '../common/exec-translator.js';
36
- type ResultUsage = NonNullable<ResultEvent['usage']>;
37
- export declare class OpencodeExecTranslator extends ExecTranslator {
38
- private readonly cwd;
39
- /** Accumulate usage across all steps (not just terminal step). */
40
- private accumulatedUsage;
41
- /** Track which tool results have already been emitted (idempotency). */
42
- private readonly emittedResults;
43
- protected readonly logTag = "[opencode-exec-translator]";
44
- protected streamEndedMessage(): string;
45
- /**
46
- * @param opts.cwd The session's real directory. Emitted on the synthesized
47
- * SystemInitEvent so the bridge persists the correct cwd (was hardcoded '').
48
- * Post-PWD-sync-fix this equals the runner's opts.cwd == opencode's directory.
49
- */
50
- constructor(opts?: {
51
- cwd?: string;
52
- });
53
- /** Token usage captured from `step_finish(reason=stop)` (for the success result event). */
54
- getLastUsage: () => ResultUsage | undefined;
55
- /** Get accumulated usage across all steps (for diagnostics). */
56
- getAccumulatedUsage(): Readonly<typeof this.accumulatedUsage>;
57
- protected translateEvent(raw: Record<string, unknown>): AgentEvent[] | null;
58
- /** SystemInitEvent: synthesize from first event with sessionId. */
59
- private synthesizeInit;
60
- private onStepStart;
61
- private onText;
62
- private onReasoning;
63
- private onTool;
64
- private onPatch;
65
- private onStepFinish;
66
- private onError;
67
- }
68
- export {};