@jini-ai/daemon 0.3.7 → 0.5.0

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 (159) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +50 -8
  3. package/dist/agent-executor/contracts.d.ts +736 -0
  4. package/dist/agent-executor/contracts.js +28 -0
  5. package/dist/agent-executor/event-translation.d.ts +87 -0
  6. package/dist/agent-executor/event-translation.js +230 -0
  7. package/dist/agent-executor/events.d.ts +190 -0
  8. package/dist/agent-executor/events.js +848 -0
  9. package/dist/agent-executor/handoff.d.ts +18 -0
  10. package/dist/agent-executor/handoff.js +16 -0
  11. package/dist/agent-executor/index.d.ts +98 -0
  12. package/dist/agent-executor/index.js +98 -0
  13. package/dist/agent-executor/launch.d.ts +375 -0
  14. package/dist/agent-executor/launch.js +1001 -0
  15. package/dist/agent-executor/mcp-bridge.d.ts +338 -0
  16. package/dist/agent-executor/mcp-bridge.js +835 -0
  17. package/dist/agent-executor/values.d.ts +5 -0
  18. package/dist/agent-executor/values.js +13 -0
  19. package/dist/agent-executor.d.ts +382 -177
  20. package/dist/agent-executor.js +408 -344
  21. package/dist/close-status.d.ts +11 -8
  22. package/dist/close-status.js +31 -19
  23. package/dist/continuation/continuation-transport.d.ts +3 -1
  24. package/dist/continuation/continuation-transport.js +1 -1
  25. package/dist/continuation/journal.d.ts +12 -5
  26. package/dist/continuation/journal.js +4 -4
  27. package/dist/continuation/run-scoped-context-store.d.ts +13 -4
  28. package/dist/continuation/run-scoped-context-store.js +6 -6
  29. package/dist/continuation/run-start-handler.d.ts +1 -1
  30. package/dist/continuation/run-start-handler.js +3 -16
  31. package/dist/delegated-tool-bridge.d.ts +7 -3
  32. package/dist/delegated-tool-bridge.js +32 -31
  33. package/dist/event-log.d.ts +7 -5
  34. package/dist/event-log.js +12 -11
  35. package/dist/frontend-capability-tools.d.ts +1 -1
  36. package/dist/frontend-capability-tools.js +3 -2
  37. package/dist/frontend-session-registry.d.ts +32 -9
  38. package/dist/frontend-session-registry.js +12 -11
  39. package/dist/http/active-context.d.ts +105 -0
  40. package/dist/http/active-context.js +67 -0
  41. package/dist/http/agents.d.ts +68 -0
  42. package/dist/http/agents.js +12 -0
  43. package/dist/http/attachments.d.ts +618 -0
  44. package/dist/http/attachments.js +1034 -0
  45. package/dist/http/cancel-owned-runs.d.ts +49 -0
  46. package/dist/http/cancel-owned-runs.js +35 -0
  47. package/dist/http/component-catalog.d.ts +84 -0
  48. package/dist/http/component-catalog.js +64 -0
  49. package/dist/http/connectors.d.ts +209 -0
  50. package/dist/http/connectors.js +409 -0
  51. package/dist/http/daemon-status.d.ts +76 -0
  52. package/dist/http/daemon-status.js +55 -0
  53. package/dist/http/db-ops.d.ts +123 -0
  54. package/dist/http/db-ops.js +189 -0
  55. package/dist/http/delegated-tools.d.ts +113 -0
  56. package/dist/http/delegated-tools.js +230 -0
  57. package/dist/http/frontend-control.d.ts +136 -0
  58. package/dist/http/frontend-control.js +79 -0
  59. package/dist/http/frontend-sessions.d.ts +110 -0
  60. package/dist/http/frontend-sessions.js +180 -0
  61. package/dist/http/health.d.ts +95 -0
  62. package/dist/http/health.js +40 -0
  63. package/dist/http/host-tools.d.ts +214 -0
  64. package/dist/http/host-tools.js +329 -0
  65. package/dist/http/index.d.ts +52 -0
  66. package/dist/http/index.js +27 -0
  67. package/dist/http/media.d.ts +146 -0
  68. package/dist/http/media.js +346 -0
  69. package/dist/http/memory.d.ts +265 -0
  70. package/dist/http/memory.js +328 -0
  71. package/dist/http/model-proxy.d.ts +49 -0
  72. package/dist/http/model-proxy.js +642 -0
  73. package/dist/http/remote-run-events.d.ts +70 -0
  74. package/dist/http/remote-run-events.js +224 -0
  75. package/dist/http/research.d.ts +48 -0
  76. package/dist/http/research.js +315 -0
  77. package/dist/http/route-manifest.d.ts +35 -0
  78. package/dist/http/route-manifest.js +103 -0
  79. package/dist/http/routines.d.ts +120 -0
  80. package/dist/http/routines.js +298 -0
  81. package/dist/http/run-credentials.d.ts +73 -0
  82. package/dist/http/run-credentials.js +71 -0
  83. package/dist/http/runs.d.ts +91 -0
  84. package/dist/http/runs.js +221 -0
  85. package/dist/http/terminals.d.ts +138 -0
  86. package/dist/http/terminals.js +325 -0
  87. package/dist/http/tool-catalog.d.ts +78 -0
  88. package/dist/http/tool-catalog.js +66 -0
  89. package/dist/http/workspace-root.d.ts +77 -0
  90. package/dist/http/workspace-root.js +63 -0
  91. package/dist/http/xai.d.ts +90 -0
  92. package/dist/http/xai.js +655 -0
  93. package/dist/image-prompt-delivery.d.ts +13 -3
  94. package/dist/image-prompt-delivery.js +5 -5
  95. package/dist/index.d.ts +556 -4
  96. package/dist/index.js +556 -4
  97. package/dist/legacy-data-migration.d.ts +59 -8
  98. package/dist/legacy-data-migration.js +38 -33
  99. package/dist/read-only-tools.d.ts +130 -0
  100. package/dist/read-only-tools.js +115 -0
  101. package/dist/remote-tool-bridge.d.ts +11 -5
  102. package/dist/remote-tool-bridge.js +15 -15
  103. package/dist/routines/index.d.ts +1 -1
  104. package/dist/routines/index.js +1 -1
  105. package/dist/routines/routine-store.d.ts +34 -12
  106. package/dist/routines/routine-store.js +21 -20
  107. package/dist/routines/schedule.d.ts +48 -10
  108. package/dist/routines/schedule.js +21 -21
  109. package/dist/routines/scheduler.d.ts +32 -11
  110. package/dist/routines/scheduler.js +61 -57
  111. package/dist/routines/types.d.ts +10 -3
  112. package/dist/run/core/result.d.ts +6 -2
  113. package/dist/run/core/result.js +3 -3
  114. package/dist/run/core/retry.d.ts +17 -4
  115. package/dist/run/core/retry.js +7 -11
  116. package/dist/run/diagnostics/diagnostics.d.ts +14 -4
  117. package/dist/run/diagnostics/diagnostics.js +7 -7
  118. package/dist/run/index.d.ts +1 -1
  119. package/dist/run/index.js +1 -1
  120. package/dist/run-credentials.d.ts +138 -0
  121. package/dist/run-credentials.js +152 -0
  122. package/dist/run-lifecycle.d.ts +92 -33
  123. package/dist/run-lifecycle.js +86 -73
  124. package/dist/scheduler.d.ts +8 -0
  125. package/dist/scheduler.js +2 -0
  126. package/dist/session-coordination.d.ts +115 -0
  127. package/dist/session-coordination.js +111 -0
  128. package/dist/store/agent-sessions/errors.d.ts +8 -0
  129. package/dist/store/agent-sessions/errors.js +10 -0
  130. package/dist/store/agent-sessions/index.d.ts +12 -0
  131. package/dist/store/agent-sessions/index.js +19 -0
  132. package/dist/store/agent-sessions/pglite.d.ts +12 -0
  133. package/dist/store/agent-sessions/pglite.js +7 -0
  134. package/dist/store/agent-sessions/ports.d.ts +24 -0
  135. package/dist/store/agent-sessions/ports.js +2 -0
  136. package/dist/store/agent-sessions/postgres.d.ts +12 -0
  137. package/dist/store/agent-sessions/postgres.js +7 -0
  138. package/dist/store/agent-sessions/schema.d.ts +3 -0
  139. package/dist/store/agent-sessions/schema.js +23 -0
  140. package/dist/store/agent-sessions/sql.d.ts +35 -0
  141. package/dist/store/agent-sessions/sql.js +59 -0
  142. package/dist/store/agent-sessions/sqlite.d.ts +117 -0
  143. package/dist/store/agent-sessions/sqlite.js +128 -0
  144. package/dist/store/event-log/sqlite.d.ts +75 -0
  145. package/dist/store/event-log/sqlite.js +230 -0
  146. package/dist/surface-exchanges.d.ts +97 -0
  147. package/dist/surface-exchanges.js +153 -0
  148. package/dist/terminal-session.d.ts +43 -11
  149. package/dist/terminal-session.js +22 -20
  150. package/dist/tokens.js +4 -4
  151. package/dist/tool-audit.d.ts +114 -0
  152. package/dist/tool-audit.js +95 -0
  153. package/dist/tool-executor.d.ts +22 -7
  154. package/dist/tool-executor.js +16 -16
  155. package/dist/tool-result-media.d.ts +3 -1
  156. package/dist/tool-result-media.js +1 -1
  157. package/dist/tool-result-surfaces.d.ts +3 -1
  158. package/dist/tool-result-surfaces.js +1 -1
  159. package/package.json +127 -9
@@ -0,0 +1,28 @@
1
+ import {} from 'node:child_process';
2
+ import {} from '@jini-ai/core';
3
+ import {} from '@jini-ai/protocol';
4
+ import {} from '@jini-ai/agent-runtime';
5
+ import {} from '@jini-ai/platform';
6
+ import {} from '../continuation/journal.js';
7
+ import {} from '../run/core/index.js';
8
+ import {} from '../tool-executor.js';
9
+ import {} from '../run-lifecycle.js';
10
+ export const SUPPORTED_STREAM_FORMATS = [
11
+ 'claude-stream-json',
12
+ 'json-event-stream',
13
+ 'copilot-stream-json',
14
+ 'qoder-stream-json',
15
+ 'acp-json-rpc',
16
+ 'pi-rpc',
17
+ 'plain',
18
+ ];
19
+ /** Thrown by `AgentExecutor.run()` on every failure path — never a bare `Error`, so callers can branch on `.code` instead of parsing `.message`. */
20
+ export class AgentExecutorError extends Error {
21
+ code;
22
+ constructor({ code, message }) {
23
+ super(message);
24
+ this.name = 'AgentExecutorError';
25
+ this.code = code;
26
+ }
27
+ }
28
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1,87 @@
1
+ import { type RunAgentPayload, type RunErrorPayload } from '@jini-ai/protocol';
2
+ import { type AgentRuntimeEventTranslation } from './contracts.js';
3
+ /**
4
+ * Narrows a parsed `usage` event's `usage` sub-object (`{input_tokens?, output_tokens?}`) — the one
5
+ * piece of {@link translateUsagePayload} with real nested branching (an optional container holding
6
+ * two optional numeric fields), extracted so that function reads as a flat field-by-field mapping.
7
+ * @param rawUsage - `rawEvent.usage` once already narrowed to a record, or `undefined` when absent/malformed.
8
+ * @returns `undefined` when neither token count is present — matching `translateUsagePayload`'s
9
+ * original "omit the whole `usage` field rather than emit an empty object" behavior.
10
+ * @complexity O(1).
11
+ */
12
+ export declare function extractUsageTokens({ rawUsage }: {
13
+ readonly rawUsage: Record<string, unknown> | undefined;
14
+ }): {
15
+ input_tokens?: number;
16
+ output_tokens?: number;
17
+ } | undefined;
18
+ export declare function translateStatusEvent({ rawEvent }: {
19
+ readonly rawEvent: Record<string, unknown>;
20
+ }): AgentRuntimeEventTranslation;
21
+ export declare function translateToolResultEvent({ rawEvent }: {
22
+ readonly rawEvent: Record<string, unknown>;
23
+ }): AgentRuntimeEventTranslation;
24
+ export declare function translateErrorEvent({ rawEvent }: {
25
+ readonly rawEvent: Record<string, unknown>;
26
+ }): AgentRuntimeEventTranslation;
27
+ export declare function translateTurnEndEvent({ rawEvent }: {
28
+ readonly rawEvent: Record<string, unknown>;
29
+ }): AgentRuntimeEventTranslation;
30
+ /**
31
+ * Narrows one parser-emitted `{type, ...}` record into this engine's
32
+ * `RunAgentPayload` union (or the `error`/`turn-end`/`ignored` routing
33
+ * `run()` special-cases). Pure — no I/O, no closure state — so every
34
+ * variant each of the 4 supported parsers can produce is directly
35
+ * assertable in isolation.
36
+ *
37
+ * Defensive by construction: several real parser emissions carry fields
38
+ * looser than `RunAgentPayload`'s types promise (e.g. copilot's
39
+ * `tool.execution_start` emits `id: data.toolCallId ?? null` — a literal
40
+ * `null`, not the `string` `RunAgentPayload['tool_use']['id']` demands).
41
+ * Every field read here is defensively coerced (`asString`/
42
+ * `asOptionalString`/`asOptionalNumber`) rather than trusted, so a
43
+ * malformed or null field degrades to a safe default instead of
44
+ * propagating `null`/`undefined` into a field typed as required, or
45
+ * throwing.
46
+ *
47
+ * @param rawEvent - One event as delivered to a stream parser's `onEvent` callback.
48
+ * @returns The routing + payload this event maps to.
49
+ * @complexity O(1) — one table lookup, no iteration.
50
+ * @overallScore 100/100
51
+ */
52
+ export declare function translateAgentRuntimeEvent({ rawEvent }: {
53
+ readonly rawEvent: unknown;
54
+ }): AgentRuntimeEventTranslation;
55
+ /**
56
+ * Maps an ACP session's transport error into the canonical run-error shape.
57
+ * ACP adapters may add a structured `error` member, but a daemon driver must
58
+ * never make one vendor's error shape part of the run protocol.
59
+ */
60
+ export declare function translateAcpError(payload: unknown): RunErrorPayload;
61
+ /** The side-effect signals {@link applyAgentTranslationSideEffects} reports through, one callback per signal so a caller only wires the ones it actually tracks. */
62
+ interface AgentTranslationSideEffectSink {
63
+ readonly onSessionId: (args: {
64
+ readonly sessionId: string;
65
+ }) => void;
66
+ readonly onToolCall: () => void;
67
+ readonly onUserVisibleOutput: () => void;
68
+ }
69
+ /**
70
+ * Applies one already-translated `'agent'`-kind event's side-effect signals — a captured session id
71
+ * (gap 5), and the `toolCallSeen`/`userVisibleOutputSeen` pair every `wire*Lifecycle` driver tracks
72
+ * for `FailureClassificationContext.sideEffects` — through `sink`. Extracted from `wireAcpLifecycle`'s
73
+ * `send()`, where this exact three-level-deep nesting (session-id check, then tool_use/else-if
74
+ * delta-length check) was that function's largest single cognitive-complexity contributor. Pure
75
+ * except for calling the injected `sink` callbacks.
76
+ * @param payload - The translated event's `RunAgentPayload`.
77
+ * @param sessionId - The translation's optional captured session id, or `undefined`.
78
+ * @param sink - The driver-specific effects to apply.
79
+ * @complexity O(1).
80
+ */
81
+ export declare function applyAgentTranslationSideEffects({ payload, sessionId, sink }: {
82
+ readonly payload: RunAgentPayload;
83
+ readonly sessionId: string | undefined;
84
+ readonly sink: AgentTranslationSideEffectSink;
85
+ }): void;
86
+ export {};
87
+ //# sourceMappingURL=event-translation.d.ts.map
@@ -0,0 +1,230 @@
1
+ import {} from '@jini-ai/protocol';
2
+ import {} from './contracts.js';
3
+ import { isRecord, asString, asOptionalString, } from './values.js';
4
+ function asOptionalNumber(value) {
5
+ return typeof value === 'number' ? value : undefined;
6
+ }
7
+ /**
8
+ * Narrows a parsed `usage` event's `usage` sub-object (`{input_tokens?, output_tokens?}`) — the one
9
+ * piece of {@link translateUsagePayload} with real nested branching (an optional container holding
10
+ * two optional numeric fields), extracted so that function reads as a flat field-by-field mapping.
11
+ * @param rawUsage - `rawEvent.usage` once already narrowed to a record, or `undefined` when absent/malformed.
12
+ * @returns `undefined` when neither token count is present — matching `translateUsagePayload`'s
13
+ * original "omit the whole `usage` field rather than emit an empty object" behavior.
14
+ * @complexity O(1).
15
+ */
16
+ export function extractUsageTokens({ rawUsage }) {
17
+ if (!rawUsage)
18
+ return undefined;
19
+ const inputTokens = asOptionalNumber(rawUsage.input_tokens);
20
+ const outputTokens = asOptionalNumber(rawUsage.output_tokens);
21
+ if (inputTokens === undefined && outputTokens === undefined)
22
+ return undefined;
23
+ return {
24
+ ...(inputTokens !== undefined ? { input_tokens: inputTokens } : {}),
25
+ ...(outputTokens !== undefined ? { output_tokens: outputTokens } : {}),
26
+ };
27
+ }
28
+ /**
29
+ * Narrows one parsed `usage` event's loosely-typed fields into
30
+ * `RunAgentPayload`'s `usage` variant. The 4 source parsers attach extra
31
+ * fields this narrow payload has no room for — `thought_tokens`,
32
+ * `cached_read_tokens`/`cached_write_tokens` (opencode/gemini/codex),
33
+ * `modelUsage`/`stopReason`/`isError` (qoder), a top-level `stopReason`
34
+ * (claude/copilot) — all intentionally dropped here, not carried through.
35
+ * @param rawEvent - The raw `{type:'usage', ...}` record from a stream parser.
36
+ * @returns The narrowed `RunAgentPayload` `usage` variant.
37
+ * @complexity O(1).
38
+ * @overallScore 100/100
39
+ */
40
+ function translateUsagePayload(rawEvent) {
41
+ const rawUsage = isRecord(rawEvent.usage) ? rawEvent.usage : undefined;
42
+ const usage = extractUsageTokens({ rawUsage: rawUsage });
43
+ const costUsd = asOptionalNumber(rawEvent.costUsd);
44
+ const durationMs = asOptionalNumber(rawEvent.durationMs);
45
+ return {
46
+ type: 'usage',
47
+ ...(usage !== undefined ? { usage } : {}),
48
+ ...(costUsd !== undefined ? { costUsd } : {}),
49
+ ...(durationMs !== undefined ? { durationMs } : {}),
50
+ };
51
+ }
52
+ export function translateStatusEvent({ rawEvent }) {
53
+ const model = asOptionalString(rawEvent.model);
54
+ const ttftMs = asOptionalNumber(rawEvent.ttftMs);
55
+ const detail = asOptionalString(rawEvent.detail);
56
+ const sessionId = asOptionalString(rawEvent.sessionId);
57
+ return {
58
+ kind: 'agent',
59
+ payload: {
60
+ type: 'status',
61
+ label: asString(rawEvent.label, 'unknown'),
62
+ ...(model !== undefined ? { model } : {}),
63
+ ...(ttftMs !== undefined ? { ttftMs } : {}),
64
+ ...(detail !== undefined ? { detail } : {}),
65
+ },
66
+ ...(sessionId !== undefined ? { sessionId } : {}),
67
+ };
68
+ }
69
+ function translateTextDeltaEvent(rawEvent) {
70
+ return { kind: 'agent', payload: { type: 'text_delta', delta: asString(rawEvent.delta) } };
71
+ }
72
+ function translateThinkingStartEvent() {
73
+ return { kind: 'agent', payload: { type: 'thinking_start' } };
74
+ }
75
+ function translateThinkingDeltaEvent(rawEvent) {
76
+ return { kind: 'agent', payload: { type: 'thinking_delta', delta: asString(rawEvent.delta) } };
77
+ }
78
+ function translateToolUseEvent(rawEvent) {
79
+ return {
80
+ kind: 'agent',
81
+ payload: {
82
+ type: 'tool_use',
83
+ id: asString(rawEvent.id),
84
+ name: asString(rawEvent.name),
85
+ input: rawEvent.input ?? null,
86
+ },
87
+ };
88
+ }
89
+ function translateToolInputDeltaEvent(rawEvent) {
90
+ return {
91
+ kind: 'agent',
92
+ payload: {
93
+ type: 'tool_input_delta',
94
+ id: asString(rawEvent.id),
95
+ name: asString(rawEvent.name),
96
+ delta: asString(rawEvent.delta),
97
+ },
98
+ };
99
+ }
100
+ export function translateToolResultEvent({ rawEvent }) {
101
+ const isError = typeof rawEvent.isError === 'boolean' ? rawEvent.isError : undefined;
102
+ return {
103
+ kind: 'agent',
104
+ payload: {
105
+ type: 'tool_result',
106
+ toolUseId: asString(rawEvent.toolUseId),
107
+ content: asString(rawEvent.content),
108
+ ...(isError !== undefined ? { isError } : {}),
109
+ },
110
+ };
111
+ }
112
+ function translateUsageEvent(rawEvent) {
113
+ return { kind: 'agent', payload: translateUsagePayload(rawEvent) };
114
+ }
115
+ function translateRawEvent(rawEvent) {
116
+ return { kind: 'agent', payload: { type: 'raw', line: asString(rawEvent.line) } };
117
+ }
118
+ export function translateErrorEvent({ rawEvent }) {
119
+ const code = asOptionalString(rawEvent.code);
120
+ const message = asString(rawEvent.message, 'Unknown agent error');
121
+ return {
122
+ kind: 'error',
123
+ payload: { message, ...(code !== undefined ? { error: { code, message } } : {}) },
124
+ };
125
+ }
126
+ export function translateTurnEndEvent({ rawEvent }) {
127
+ // Claude-specific per-turn boundary. Not forwarded as an 'agent'
128
+ // event (no RunAgentPayload variant represents it) — run() reacts to
129
+ // it directly to close stdin (or, for gap 3, decide whether to inject
130
+ // a tool result and keep it open instead). See module doc.
131
+ const stopReason = asOptionalString(rawEvent.stopReason);
132
+ return { kind: 'turn-end', ...(stopReason !== undefined ? { stopReason } : {}) };
133
+ }
134
+ /**
135
+ * One entry per `rawEvent.type` this driver understands, each producing the same
136
+ * {@link AgentRuntimeEventTranslation} `translateAgentRuntimeEvent` used to return from an inline
137
+ * `switch` — replaced with this table (refactor-patterns' preferred fix for a long switch over an
138
+ * event-kind discriminant) so each case's own mapping is independently readable and testable, and so
139
+ * `translateAgentRuntimeEvent` itself is just a lookup plus the two upfront guards.
140
+ */
141
+ const EVENT_TYPE_TRANSLATORS = {
142
+ status: rawEvent => translateStatusEvent({ rawEvent }),
143
+ text_delta: translateTextDeltaEvent,
144
+ thinking_start: translateThinkingStartEvent,
145
+ thinking_delta: translateThinkingDeltaEvent,
146
+ tool_use: translateToolUseEvent,
147
+ tool_input_delta: translateToolInputDeltaEvent,
148
+ tool_result: rawEvent => translateToolResultEvent({ rawEvent }),
149
+ usage: translateUsageEvent,
150
+ raw: translateRawEvent,
151
+ error: rawEvent => translateErrorEvent({ rawEvent }),
152
+ turn_end: rawEvent => translateTurnEndEvent({ rawEvent }),
153
+ };
154
+ /**
155
+ * Narrows one parser-emitted `{type, ...}` record into this engine's
156
+ * `RunAgentPayload` union (or the `error`/`turn-end`/`ignored` routing
157
+ * `run()` special-cases). Pure — no I/O, no closure state — so every
158
+ * variant each of the 4 supported parsers can produce is directly
159
+ * assertable in isolation.
160
+ *
161
+ * Defensive by construction: several real parser emissions carry fields
162
+ * looser than `RunAgentPayload`'s types promise (e.g. copilot's
163
+ * `tool.execution_start` emits `id: data.toolCallId ?? null` — a literal
164
+ * `null`, not the `string` `RunAgentPayload['tool_use']['id']` demands).
165
+ * Every field read here is defensively coerced (`asString`/
166
+ * `asOptionalString`/`asOptionalNumber`) rather than trusted, so a
167
+ * malformed or null field degrades to a safe default instead of
168
+ * propagating `null`/`undefined` into a field typed as required, or
169
+ * throwing.
170
+ *
171
+ * @param rawEvent - One event as delivered to a stream parser's `onEvent` callback.
172
+ * @returns The routing + payload this event maps to.
173
+ * @complexity O(1) — one table lookup, no iteration.
174
+ * @overallScore 100/100
175
+ */
176
+ export function translateAgentRuntimeEvent({ rawEvent }) {
177
+ if (!isRecord(rawEvent) || typeof rawEvent.type !== 'string') {
178
+ return { kind: 'ignored' };
179
+ }
180
+ const translator = EVENT_TYPE_TRANSLATORS[rawEvent.type];
181
+ return translator ? translator(rawEvent) : { kind: 'ignored' };
182
+ }
183
+ /**
184
+ * Maps an ACP session's transport error into the canonical run-error shape.
185
+ * ACP adapters may add a structured `error` member, but a daemon driver must
186
+ * never make one vendor's error shape part of the run protocol.
187
+ */
188
+ export function translateAcpError(payload) {
189
+ if (!isRecord(payload))
190
+ return { message: asString(payload, 'ACP agent failed') };
191
+ const message = asString(payload.message, 'ACP agent failed');
192
+ const error = isRecord(payload.error) ? payload.error : null;
193
+ const code = error ? asOptionalString(error.code) : undefined;
194
+ const retryable = error && typeof error.retryable === 'boolean' ? error.retryable : undefined;
195
+ return {
196
+ message,
197
+ ...(code !== undefined
198
+ ? {
199
+ error: {
200
+ code,
201
+ message: asString(error?.message, message),
202
+ ...(retryable !== undefined ? { retryable } : {}),
203
+ },
204
+ }
205
+ : {}),
206
+ };
207
+ }
208
+ /**
209
+ * Applies one already-translated `'agent'`-kind event's side-effect signals — a captured session id
210
+ * (gap 5), and the `toolCallSeen`/`userVisibleOutputSeen` pair every `wire*Lifecycle` driver tracks
211
+ * for `FailureClassificationContext.sideEffects` — through `sink`. Extracted from `wireAcpLifecycle`'s
212
+ * `send()`, where this exact three-level-deep nesting (session-id check, then tool_use/else-if
213
+ * delta-length check) was that function's largest single cognitive-complexity contributor. Pure
214
+ * except for calling the injected `sink` callbacks.
215
+ * @param payload - The translated event's `RunAgentPayload`.
216
+ * @param sessionId - The translation's optional captured session id, or `undefined`.
217
+ * @param sink - The driver-specific effects to apply.
218
+ * @complexity O(1).
219
+ */
220
+ export function applyAgentTranslationSideEffects({ payload, sessionId, sink }) {
221
+ if (sessionId !== undefined)
222
+ sink.onSessionId({ sessionId });
223
+ if (payload.type === 'tool_use') {
224
+ sink.onToolCall();
225
+ }
226
+ else if ((payload.type === 'text_delta' || payload.type === 'thinking_delta') && payload.delta.length > 0) {
227
+ sink.onUserVisibleOutput();
228
+ }
229
+ }
230
+ //# sourceMappingURL=event-translation.js.map
@@ -0,0 +1,190 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ import { attachAcpSession, attachPiRpcSession, type AcpPermissionHandler, type RuntimeAgentDef } from '@jini-ai/agent-runtime';
3
+ import { type RunByteJournal } from '../continuation/journal.js';
4
+ import { type RunLifecycle } from '../run-lifecycle.js';
5
+ import { type ChildDrivenStreamFormat, type TerminateChildTreeDeps, type AgentCleanupFailureContext, type StdinCloseHandle, type ContinuationOptions, type McpBridgeDelivery, type ClassifyFailure, type FailBeforeSpawn } from './contracts.js';
6
+ /** Default sink when a host does not supply `onCleanupFailure`: still observable, never silent. Redacted per SEC-007 (a spawn/permission error can embed paths/host detail). */
7
+ export declare function defaultCleanupFailureSink(context: AgentCleanupFailureContext): void;
8
+ /**
9
+ * Default ceiling on the `'until-close'` stdout accumulator (see `RuntimeStdoutPolicy` in
10
+ * `@jini-ai/agent-runtime`), in bytes of received UTF-8.
11
+ *
12
+ * A buffered def holds its child's entire stdout in one in-memory string until the process closes,
13
+ * which is exactly what makes the accumulator a denial-of-service surface: the child is a
14
+ * prompt-influenced agent CLI this driver already treats as potentially adversarial (SEC-001), and
15
+ * nothing obliges it to ever close or to stop emitting. Without a ceiling one run could exhaust the
16
+ * daemon's heap and take every unrelated run in the process down with it.
17
+ *
18
+ * 8 MiB is chosen to sit far above any real buffered-agent transcript (antigravity's print-mode
19
+ * output — the only `'until-close'` def — is a few KiB of auth prompt and result text) while staying
20
+ * small enough that a hostile child cannot meaningfully pressure the heap. A host that genuinely
21
+ * needs more passes `CreateAgentExecutorOptions.bufferedStdoutMaxBytes`.
22
+ */
23
+ export declare const DEFAULT_BUFFERED_STDOUT_MAX_BYTES: number;
24
+ interface WireChildLifecycleContext extends TerminateChildTreeDeps {
25
+ readonly runId: string;
26
+ readonly def: RuntimeAgentDef;
27
+ readonly streamFormat: ChildDrivenStreamFormat;
28
+ readonly child: ChildProcess;
29
+ readonly lifecycle: RunLifecycle;
30
+ readonly onCleanupFailure: (context: AgentCleanupFailureContext) => void;
31
+ /**
32
+ * Removes every temp file `run()` staged for this run — a `promptViaFile`
33
+ * def's prompt file (grok-build) and a `needsAgentLogFile` def's log file
34
+ * (antigravity) — after the child exits. Deliberately one composed closure
35
+ * rather than one field per file: the two are staged at the same point and
36
+ * must be released on the same set of paths, and a second parallel field
37
+ * is exactly how one of them ends up forgotten on a path the other covers.
38
+ * A no-op default when neither was staged — see `run()`'s
39
+ * `preparePromptFileForAgent`/`prepareAgentLogFile` call sites.
40
+ */
41
+ readonly cleanupStagedFiles: () => Promise<void>;
42
+ /** Gap 1's byte-journal (see `continuation/journal.ts`). `undefined` when a caller configured none — every journal call site below is then a no-op. */
43
+ readonly journal: RunByteJournal | undefined;
44
+ /** Gap 3's stdin-tool-result injection config. `undefined` means every `turn_end` closes stdin unconditionally — see `ContinuationOptions`'s own doc. */
45
+ readonly continuation: ContinuationOptions | undefined;
46
+ /** Gap 4's failure classifier. `undefined` means every `'failed'` outcome stays `resumable: false` — byte-identical to pre-gap-4 behavior. See `ClassifyFailure`'s own doc. */
47
+ readonly classifyFailure: ClassifyFailure | undefined;
48
+ /** Ceiling on the `'until-close'` stdout accumulator — see {@link DEFAULT_BUFFERED_STDOUT_MAX_BYTES}. Always resolved by `run()`, never left to this function to default. */
49
+ readonly bufferedStdoutMaxBytes: number;
50
+ /**
51
+ * True when this run's CLI was handed the `jini` bridge (`'claude-mcp-json'` delivery). The first
52
+ * init frame's MCP report is then checked, and a bridge that is not connected stops the run with
53
+ * {@link MCP_BRIDGE_UNAVAILABLE} instead of letting it continue without the host's tools.
54
+ */
55
+ readonly expectsJiniBridge: boolean;
56
+ }
57
+ /**
58
+ * Wires one spawned child's full observable lifecycle: raw stdout/stderr
59
+ * forwarding, structured stream-parser dispatch (translated via
60
+ * {@link translateAgentRuntimeEvent}), cancellation (subscribes
61
+ * `lifecycle.onCancelRequested` and escalates via `stopProcesses` on the
62
+ * child's full descendant tree), and the terminal `close` → `finish()`
63
+ * transition. Registered *before* the caller awaits spawn confirmation so
64
+ * no early `'error'`/`'close'` event is ever missed.
65
+ *
66
+ * Every `lifecycle.emit()` call is funneled through a per-run FIFO queue
67
+ * (`enqueueEmit`) rather than fired independently: a single stdout `data`
68
+ * chunk can synchronously produce several parsed events (a JSON line's
69
+ * `feed()` call may invoke `onEvent` more than once), and successive
70
+ * `data` events must not have their derived `emit()` calls race each
71
+ * other out of order. The queue also absorbs an individual `emit()`
72
+ * rejection (e.g. a race against an already-terminal run) without losing
73
+ * subsequently queued events, and the `close` handler awaits it fully
74
+ * drained before computing the terminal outcome — so `finish()`'s `'end'`
75
+ * event is always durably last, never interleaved with a still-in-flight
76
+ * `'agent'`/`'stdout'`/`'stderr'` append.
77
+ *
78
+ * `streamFormat: 'plain'` gets no `createStreamHandlerForDef` parser at
79
+ * all (Option B — see index.ts module doc and
80
+ * `ADS-memory/reports/proposals/PROP-plain-format-agent-driving-2026-07-21.md`
81
+ * §3): every raw stdout chunk is forwarded verbatim as a `text_delta`
82
+ * `'agent'` event, through the same `enqueueEmit` FIFO queue every other
83
+ * emit already goes through — no new parser state machine.
84
+ * **Deliberately un-hygiened for v1**: no ANSI/terminal-control-sequence
85
+ * stripping is applied (there is no Jini equivalent of OD's
86
+ * `TerminalControlSequenceStripper` yet) — a documented decision, not an
87
+ * oversight; see `packages/daemon/archived provenance ledger`'s 2026-07-21 addition for
88
+ * the reasoning.
89
+ *
90
+ * *When* those chunks leave is the def's call, via `def.stdoutPolicy`:
91
+ *
92
+ * - `'live'` (the default, and every def but antigravity) — emit per
93
+ * chunk, as it arrives.
94
+ * - `'until-close'` — accumulate, and emit the whole thing exactly once
95
+ * from the `close` handler, after `def.stdoutPolicy.sanitize`. For an
96
+ * adapter that can print a secret to stdout and still exit 0, no
97
+ * per-chunk decision is safe: the pattern to redact can straddle two
98
+ * `'data'` events.
99
+ *
100
+ * The buffered path holds back the raw `'stdout'` echo too, not just the
101
+ * `'agent'`/`text_delta`, and sanitizes both. Emitting an unsanitized raw
102
+ * echo while withholding the chat copy would leak the exact string the
103
+ * sanitizer exists to remove to any client subscribed to the run's events —
104
+ * the raw channel is a different *purpose*, not a different audience.
105
+ * `journal` is the one thing still recorded per-chunk and verbatim: it is
106
+ * the host's own byte record, deliberately kept in a **separate** `EventLog`
107
+ * instance that is never replayed to run-event subscribers (see
108
+ * `continuation/journal.ts`'s module doc), and "every byte received" is its
109
+ * whole contract.
110
+ *
111
+ * @param ctx - Run/def/child/lifecycle plus the cancellation-escalation ports.
112
+ * @returns A handle exposing `closeStdinOnce` for the initial prompt write to share.
113
+ * @complexity Registration is O(1); steady-state per-chunk cost is the
114
+ * chosen stream parser's own `feed()` cost plus O(1) queue bookkeeping.
115
+ * @overallScore 100/100
116
+ */
117
+ export declare function wireChildLifecycle(ctx: WireChildLifecycleContext): StdinCloseHandle;
118
+ /**
119
+ * Writes the initial user turn to the child's stdin per `def.promptInputFormat`
120
+ * (both branches only run for `promptViaStdin: true` defs — the only shape
121
+ * `run()` supports in v1, see index.ts module doc):
122
+ * - `'text'` (default): the raw prompt buffer, then stdin is closed —
123
+ * matches `RuntimeAgentDef.promptInputFormat`'s own doc.
124
+ * - `'stream-json'`: one JSONL line wrapping the prompt as an Anthropic
125
+ * user message; stdin is deliberately left open (a real multi-turn
126
+ * caller would inject further messages) — v1 has no such caller, so
127
+ * {@link wireChildLifecycle}'s `turn_end` handling closes it once the
128
+ * agent's own stream reports the turn ended.
129
+ * @param def - The resolved agent def (only `.promptInputFormat` is read).
130
+ * @param child - The spawned child (no-ops if `.stdin` is unexpectedly absent).
131
+ * @param prompt - The composed user turn.
132
+ * @param handle - Shared stdin-close guard so a `'text'` write's immediate close and a later `turn_end` close never race into a double-`end()`; also carries gap 1's byte-journal recorder (see `StdinCloseHandle.recordSentBytes`).
133
+ * @complexity O(1) plus the underlying stream write's own cost.
134
+ * @overallScore 100/100
135
+ */
136
+ export declare function writePromptToStdin(def: RuntimeAgentDef, child: ChildProcess, prompt: string, handle: StdinCloseHandle): void;
137
+ interface RunAcpDispatchInput {
138
+ readonly runId: string;
139
+ readonly agentId: string;
140
+ readonly child: ChildProcess;
141
+ readonly prompt: string;
142
+ readonly cwd: string;
143
+ readonly model: string | undefined;
144
+ readonly imagePaths: readonly string[];
145
+ readonly envFormat: 'array' | 'map' | undefined;
146
+ readonly mcpBridge: McpBridgeDelivery | null;
147
+ }
148
+ interface RunAcpDispatchDeps extends TerminateChildTreeDeps {
149
+ readonly lifecycle: RunLifecycle;
150
+ readonly attachAcpSession: typeof attachAcpSession;
151
+ readonly onPermissionRequest: AcpPermissionHandler | undefined;
152
+ readonly onCleanupFailure: (context: AgentCleanupFailureContext) => void;
153
+ readonly cleanupStagedFiles: () => Promise<void>;
154
+ readonly journal: RunByteJournal | undefined;
155
+ readonly classifyFailure: ClassifyFailure | undefined;
156
+ readonly releaseStagedResources: () => Promise<void>;
157
+ readonly failBeforeSpawn: FailBeforeSpawn;
158
+ }
159
+ /** Phase 15 (ACP branch): attaches the ACP session, escalating process-tree teardown and failing the run through `failBeforeSpawn` on an attach-time throw. */
160
+ export declare function runAcpDispatch({ input, deps }: {
161
+ readonly input: RunAcpDispatchInput;
162
+ readonly deps: RunAcpDispatchDeps;
163
+ }): Promise<void>;
164
+ interface RunPiRpcDispatchInput {
165
+ readonly runId: string;
166
+ readonly agentId: string;
167
+ readonly child: ChildProcess;
168
+ readonly prompt: string;
169
+ readonly cwd: string;
170
+ readonly model: string | undefined;
171
+ readonly imagePaths: readonly string[];
172
+ readonly uploadRoot: string | undefined;
173
+ }
174
+ interface RunPiRpcDispatchDeps extends TerminateChildTreeDeps {
175
+ readonly lifecycle: RunLifecycle;
176
+ readonly attachPiRpcSession: typeof attachPiRpcSession;
177
+ readonly onCleanupFailure: (context: AgentCleanupFailureContext) => void;
178
+ readonly cleanupStagedFiles: () => Promise<void>;
179
+ readonly journal: RunByteJournal | undefined;
180
+ readonly classifyFailure: ClassifyFailure | undefined;
181
+ readonly releaseStagedResources: () => Promise<void>;
182
+ readonly failBeforeSpawn: FailBeforeSpawn;
183
+ }
184
+ /** Phase 15 (pi-rpc branch): same discipline as {@link runAcpDispatch}, for the one `'pi-rpc'` def. */
185
+ export declare function runPiRpcDispatch({ input, deps }: {
186
+ readonly input: RunPiRpcDispatchInput;
187
+ readonly deps: RunPiRpcDispatchDeps;
188
+ }): Promise<void>;
189
+ export {};
190
+ //# sourceMappingURL=events.d.ts.map