@clinebot/core 0.0.36 → 0.0.37

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 (228) hide show
  1. package/dist/ClineCore.d.ts +312 -3
  2. package/dist/ClineCore.d.ts.map +1 -1
  3. package/dist/account/cline-account-service.d.ts.map +1 -1
  4. package/dist/cron/cron-event-ingress.d.ts +38 -0
  5. package/dist/cron/cron-event-ingress.d.ts.map +1 -0
  6. package/dist/cron/cron-materializer.d.ts +36 -0
  7. package/dist/cron/cron-materializer.d.ts.map +1 -0
  8. package/dist/cron/cron-reconciler.d.ts +62 -0
  9. package/dist/cron/cron-reconciler.d.ts.map +1 -0
  10. package/dist/cron/cron-report-writer.d.ts +41 -0
  11. package/dist/cron/cron-report-writer.d.ts.map +1 -0
  12. package/dist/cron/cron-runner.d.ts +43 -0
  13. package/dist/cron/cron-runner.d.ts.map +1 -0
  14. package/dist/cron/cron-schema.d.ts +3 -0
  15. package/dist/cron/cron-schema.d.ts.map +1 -0
  16. package/dist/cron/cron-service.d.ts +57 -0
  17. package/dist/cron/cron-service.d.ts.map +1 -0
  18. package/dist/cron/cron-spec-parser.d.ts +27 -0
  19. package/dist/cron/cron-spec-parser.d.ts.map +1 -0
  20. package/dist/cron/cron-watcher.d.ts +23 -0
  21. package/dist/cron/cron-watcher.d.ts.map +1 -0
  22. package/dist/cron/scheduler.d.ts +3 -1
  23. package/dist/cron/scheduler.d.ts.map +1 -1
  24. package/dist/cron/sqlite-cron-store.d.ts +230 -0
  25. package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
  26. package/dist/extensions/plugin/plugin-config-loader.d.ts +7 -1
  27. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  28. package/dist/extensions/plugin/plugin-loader.d.ts +10 -6
  29. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  30. package/dist/extensions/plugin/plugin-sandbox.d.ts +7 -1
  31. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  32. package/dist/extensions/plugin-sandbox-bootstrap.js +236 -275
  33. package/dist/extensions/tools/constants.d.ts +1 -0
  34. package/dist/extensions/tools/constants.d.ts.map +1 -1
  35. package/dist/extensions/tools/definitions.d.ts +2 -3
  36. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  37. package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
  38. package/dist/extensions/tools/helpers.d.ts +1 -0
  39. package/dist/extensions/tools/helpers.d.ts.map +1 -1
  40. package/dist/extensions/tools/index.d.ts +1 -2
  41. package/dist/extensions/tools/index.d.ts.map +1 -1
  42. package/dist/extensions/tools/presets.d.ts +1 -1
  43. package/dist/extensions/tools/schemas.d.ts +25 -3
  44. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  45. package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
  46. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
  47. package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
  48. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
  49. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  50. package/dist/extensions/tools/types.d.ts +0 -5
  51. package/dist/extensions/tools/types.d.ts.map +1 -1
  52. package/dist/hooks/hook-bridge.d.ts +118 -0
  53. package/dist/hooks/hook-bridge.d.ts.map +1 -0
  54. package/dist/hooks/hook-file-hooks.d.ts +2 -1
  55. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  56. package/dist/hooks/hook-registry.d.ts +16 -0
  57. package/dist/hooks/hook-registry.d.ts.map +1 -0
  58. package/dist/hub/browser-websocket.d.ts.map +1 -1
  59. package/dist/hub/client.d.ts +7 -1
  60. package/dist/hub/client.d.ts.map +1 -1
  61. package/dist/hub/daemon-entry.js +721 -461
  62. package/dist/hub/daemon.d.ts.map +1 -1
  63. package/dist/hub/defaults.d.ts +8 -4
  64. package/dist/hub/defaults.d.ts.map +1 -1
  65. package/dist/hub/index.js +665 -415
  66. package/dist/hub/runtime-handlers.d.ts.map +1 -1
  67. package/dist/hub/server.d.ts +18 -0
  68. package/dist/hub/server.d.ts.map +1 -1
  69. package/dist/hub/session-client.d.ts +3 -0
  70. package/dist/hub/session-client.d.ts.map +1 -1
  71. package/dist/hub/start-shared-server.d.ts.map +1 -1
  72. package/dist/hub/ui-client.d.ts +1 -0
  73. package/dist/hub/ui-client.d.ts.map +1 -1
  74. package/dist/index.d.ts +9 -7
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +756 -467
  77. package/dist/llms/cline-recommended-models.d.ts +20 -0
  78. package/dist/llms/cline-recommended-models.d.ts.map +1 -0
  79. package/dist/llms/handler-factory.d.ts +16 -0
  80. package/dist/llms/handler-factory.d.ts.map +1 -0
  81. package/dist/llms/provider-defaults.d.ts.map +1 -1
  82. package/dist/llms/provider-settings.d.ts +45 -2
  83. package/dist/llms/provider-settings.d.ts.map +1 -1
  84. package/dist/llms/runtime-registry.d.ts.map +1 -1
  85. package/dist/runtime/agent-config-adapter.d.ts +148 -0
  86. package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
  87. package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
  88. package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
  89. package/dist/runtime/history.d.ts +6 -0
  90. package/dist/runtime/history.d.ts.map +1 -1
  91. package/dist/runtime/host.d.ts.map +1 -1
  92. package/dist/runtime/loop-detection.d.ts +59 -0
  93. package/dist/runtime/loop-detection.d.ts.map +1 -0
  94. package/dist/runtime/mistake-tracker.d.ts +69 -0
  95. package/dist/runtime/mistake-tracker.d.ts.map +1 -0
  96. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  97. package/dist/runtime/runtime-event-adapter.d.ts +102 -0
  98. package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
  99. package/dist/runtime/runtime-host.d.ts +28 -3
  100. package/dist/runtime/runtime-host.d.ts.map +1 -1
  101. package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
  102. package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
  103. package/dist/runtime/session-runtime.d.ts +16 -3
  104. package/dist/runtime/session-runtime.d.ts.map +1 -1
  105. package/dist/runtime/user-input-builder.d.ts +24 -0
  106. package/dist/runtime/user-input-builder.d.ts.map +1 -0
  107. package/dist/services/index.js +28 -0
  108. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  109. package/dist/services/plugin-tools.d.ts.map +1 -1
  110. package/dist/services/providers/local-provider-registry.d.ts +197 -21
  111. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  112. package/dist/services/providers/local-provider-service.d.ts +3 -1
  113. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  114. package/dist/services/session-data.d.ts.map +1 -1
  115. package/dist/services/session-telemetry.d.ts +7 -2
  116. package/dist/services/session-telemetry.d.ts.map +1 -1
  117. package/dist/services/storage/file-team-store.d.ts.map +1 -1
  118. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  119. package/dist/services/storage/provider-settings-manager.d.ts +1 -0
  120. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
  121. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
  122. package/dist/session/conversation-store.d.ts +30 -0
  123. package/dist/session/conversation-store.d.ts.map +1 -0
  124. package/dist/session/message-builder.d.ts +65 -0
  125. package/dist/session/message-builder.d.ts.map +1 -0
  126. package/dist/session/session-manifest.d.ts +1 -1
  127. package/dist/transports/hub.d.ts +14 -3
  128. package/dist/transports/hub.d.ts.map +1 -1
  129. package/dist/transports/local.d.ts +14 -4
  130. package/dist/transports/local.d.ts.map +1 -1
  131. package/dist/transports/remote.d.ts.map +1 -1
  132. package/dist/types/chat-schema.d.ts +5 -5
  133. package/dist/types/config.d.ts +9 -0
  134. package/dist/types/config.d.ts.map +1 -1
  135. package/dist/types/events.d.ts +7 -6
  136. package/dist/types/events.d.ts.map +1 -1
  137. package/dist/types/provider-settings.d.ts +2 -2
  138. package/dist/types/provider-settings.d.ts.map +1 -1
  139. package/dist/types/session.d.ts +5 -2
  140. package/dist/types/session.d.ts.map +1 -1
  141. package/dist/types.d.ts +4 -4
  142. package/dist/types.d.ts.map +1 -1
  143. package/package.json +4 -4
  144. package/src/ClineCore.ts +691 -6
  145. package/src/account/cline-account-service.ts +44 -6
  146. package/src/cron/cron-event-ingress.ts +357 -0
  147. package/src/cron/cron-materializer.ts +97 -0
  148. package/src/cron/cron-reconciler.ts +241 -0
  149. package/src/cron/cron-report-writer.ts +153 -0
  150. package/src/cron/cron-runner.ts +495 -0
  151. package/src/cron/cron-schema.ts +127 -0
  152. package/src/cron/cron-service.ts +163 -0
  153. package/src/cron/cron-spec-parser.ts +489 -0
  154. package/src/cron/cron-watcher.ts +102 -0
  155. package/src/cron/index.ts +10 -0
  156. package/src/cron/scheduler.ts +141 -6
  157. package/src/cron/sqlite-cron-store.ts +1286 -0
  158. package/src/extensions/plugin/plugin-config-loader.ts +21 -1
  159. package/src/extensions/plugin/plugin-loader.ts +25 -9
  160. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +151 -1
  161. package/src/extensions/plugin/plugin-sandbox.ts +131 -7
  162. package/src/extensions/tools/constants.ts +2 -0
  163. package/src/extensions/tools/definitions.ts +31 -22
  164. package/src/extensions/tools/executors/editor.ts +4 -3
  165. package/src/extensions/tools/helpers.ts +24 -0
  166. package/src/extensions/tools/index.ts +1 -2
  167. package/src/extensions/tools/presets.ts +1 -1
  168. package/src/extensions/tools/schemas.ts +13 -18
  169. package/src/extensions/tools/team/delegated-agent.ts +8 -3
  170. package/src/extensions/tools/team/multi-agent.ts +135 -19
  171. package/src/extensions/tools/team/team-tools.ts +151 -91
  172. package/src/extensions/tools/types.ts +0 -6
  173. package/src/hooks/hook-bridge.ts +489 -0
  174. package/src/hooks/hook-file-hooks.ts +58 -3
  175. package/src/hooks/hook-registry.ts +257 -0
  176. package/src/hub/browser-websocket.ts +26 -4
  177. package/src/hub/client.ts +72 -13
  178. package/src/hub/daemon-entry.ts +35 -0
  179. package/src/hub/daemon.ts +117 -14
  180. package/src/hub/defaults.ts +39 -12
  181. package/src/hub/runtime-handlers.ts +4 -3
  182. package/src/hub/server.ts +506 -77
  183. package/src/hub/session-client.ts +43 -1
  184. package/src/hub/start-shared-server.ts +3 -0
  185. package/src/hub/ui-client.ts +4 -0
  186. package/src/index.ts +46 -1
  187. package/src/llms/cline-recommended-models.ts +167 -0
  188. package/src/llms/handler-factory.ts +56 -0
  189. package/src/llms/provider-defaults.ts +17 -1
  190. package/src/llms/provider-settings.ts +48 -1
  191. package/src/llms/runtime-registry.ts +1 -0
  192. package/src/runtime/agent-config-adapter.ts +636 -0
  193. package/src/runtime/agent-runtime-config-builder.ts +205 -0
  194. package/src/runtime/error-feedback.ts +142 -0
  195. package/src/runtime/history.ts +137 -0
  196. package/src/runtime/host.ts +22 -0
  197. package/src/runtime/loop-detection.ts +162 -0
  198. package/src/runtime/mistake-tracker.ts +221 -0
  199. package/src/runtime/runtime-builder.ts +61 -5
  200. package/src/runtime/runtime-event-adapter.ts +412 -0
  201. package/src/runtime/runtime-host.ts +45 -1
  202. package/src/runtime/session-runtime-orchestrator.ts +1253 -0
  203. package/src/runtime/session-runtime.ts +16 -2
  204. package/src/runtime/user-input-builder.ts +167 -0
  205. package/src/services/local-runtime-bootstrap.ts +128 -22
  206. package/src/services/plugin-tools.ts +1 -0
  207. package/src/services/providers/local-provider-registry.ts +273 -57
  208. package/src/services/providers/local-provider-service.ts +67 -7
  209. package/src/services/session-data.ts +16 -14
  210. package/src/services/session-telemetry.ts +6 -15
  211. package/src/services/storage/file-team-store.ts +1 -5
  212. package/src/services/storage/provider-settings-legacy-migration.ts +8 -47
  213. package/src/services/storage/provider-settings-manager.ts +16 -1
  214. package/src/services/storage/sqlite-team-store.ts +1 -5
  215. package/src/session/conversation-store.ts +77 -0
  216. package/src/session/message-builder.ts +941 -0
  217. package/src/transports/hub.ts +458 -33
  218. package/src/transports/local.ts +296 -65
  219. package/src/transports/remote.ts +1 -0
  220. package/src/types/config.ts +9 -0
  221. package/src/types/events.ts +8 -6
  222. package/src/types/index.ts +3 -0
  223. package/src/types/provider-settings.ts +8 -1
  224. package/src/types/session.ts +5 -2
  225. package/src/types.ts +15 -1
  226. package/dist/cron/index.d.ts +0 -6
  227. package/dist/cron/index.d.ts.map +0 -1
  228. package/dist/services/telemetry/index.js +0 -28
@@ -0,0 +1,412 @@
1
+ /**
2
+ * Adapter from the new `AgentRuntimeEvent` union (13 variants, defined
3
+ * in `@clinebot/shared/src/agent.ts`) to the legacy `AgentEvent` union
4
+ * (9 top-level types, defined in
5
+ * `@clinebot/shared/src/agents/types.ts`) consumed by today's
6
+ * `Agent.subscribeEvents` callback.
7
+ *
8
+ * @see PLAN.md §3.1 — new file introduced alongside the core runtime port.
9
+ * @see PLAN.md §3.3.2 — variant-by-variant OLD → NEW mapping.
10
+ * @see PLAN.md §3.2.4 — called from `Agent.subscribeEvents` inside the
11
+ * legacy-agent facade.
12
+ *
13
+ * --- IMPLEMENTATION NOTE — PLAN §3.3.2 text/reasoning-delta rows ----------
14
+ *
15
+ * PLAN.md §3.3.2 describes `assistant-text-delta` as "first delta →
16
+ * content_start, subsequent → content_update". The **actual** legacy
17
+ * shape forbids this: `AgentContentUpdateEvent.contentType` is
18
+ * hard-typed as `"tool"` in
19
+ * `packages/shared/src/agents/types.ts:87`, and the legacy
20
+ * turn-processor
21
+ * (`packages/agents/src/runtime/turn-processor.ts:82-87,113-118`)
22
+ * emits a `content_start` event for **every** text delta and for
23
+ * **every** reasoning delta — not just the first. This adapter
24
+ * preserves that observable behavior (what every legacy consumer
25
+ * relies on today) over the description in §3.3.2.
26
+ *
27
+ * text deltas → content_start { contentType:"text", text,
28
+ * accumulated } (per delta)
29
+ * reasoning deltas → content_start { contentType:"reasoning",
30
+ * reasoning, redacted } (per delta)
31
+ * assistant-message → one content_end { contentType:"text", text }
32
+ * if any text parts; one
33
+ * content_end { contentType:"reasoning", reasoning }
34
+ * if any reasoning parts
35
+ * (turn-processor.ts:157-170).
36
+ *
37
+ * --- STATEFUL BOOK-KEEPING ------------------------------------------------
38
+ *
39
+ * 1. Rolling usage totals. `usage-updated` carries the already-
40
+ * accumulated snapshot (agent-runtime.ts:668-683). Legacy
41
+ * `AgentUsageEvent` wants both per-turn delta and accumulated
42
+ * totals; the adapter subtracts the previous accumulated value
43
+ * from the incoming one to produce the delta.
44
+ * 2. Tool timing. `tool-finished` does not carry `durationMs`. The
45
+ * adapter records `Date.now()` on `tool-started` (keyed by
46
+ * `toolCallId`) and computes `durationMs` at `tool-finished`.
47
+ * Matches `tool-orchestrator.ts:112-131`.
48
+ *
49
+ * Both are scoped to a single adapter instance and cleared by
50
+ * `reset()`.
51
+ */
52
+
53
+ import type {
54
+ AgentEvent,
55
+ AgentFinishReason,
56
+ AgentMessage,
57
+ AgentReasoningPart,
58
+ AgentRuntimeEvent,
59
+ AgentTextPart,
60
+ AgentToolResultPart,
61
+ AgentUsage,
62
+ LegacyAgentUsage,
63
+ } from "@clinebot/shared";
64
+
65
+ // =============================================================================
66
+ // Helpers
67
+ // =============================================================================
68
+
69
+ function extractTextPart(message: AgentMessage): string | undefined {
70
+ const parts = message.content.filter(
71
+ (part): part is AgentTextPart => part.type === "text",
72
+ );
73
+ if (parts.length === 0) {
74
+ return undefined;
75
+ }
76
+ return parts.map((part) => part.text).join("");
77
+ }
78
+
79
+ function extractReasoningPart(
80
+ message: AgentMessage,
81
+ ): { reasoning: string; redacted: boolean } | undefined {
82
+ const parts = message.content.filter(
83
+ (part): part is AgentReasoningPart => part.type === "reasoning",
84
+ );
85
+ if (parts.length === 0) {
86
+ return undefined;
87
+ }
88
+ return {
89
+ reasoning: parts.map((part) => part.text).join(""),
90
+ redacted: parts.some((part) => part.redacted === true),
91
+ };
92
+ }
93
+
94
+ function extractToolResultPart(
95
+ message: AgentMessage,
96
+ ): AgentToolResultPart | undefined {
97
+ return message.content.find(
98
+ (part): part is AgentToolResultPart => part.type === "tool-result",
99
+ );
100
+ }
101
+
102
+ function textFromMessage(message: AgentMessage | undefined): string {
103
+ if (!message) {
104
+ return "";
105
+ }
106
+ return extractTextPart(message) ?? "";
107
+ }
108
+
109
+ function statusToLegacyFinishReason(
110
+ status: "completed" | "aborted" | "failed",
111
+ ): AgentFinishReason {
112
+ switch (status) {
113
+ case "completed":
114
+ return "completed";
115
+ case "aborted":
116
+ return "aborted";
117
+ case "failed":
118
+ return "error";
119
+ }
120
+ }
121
+
122
+ function deriveToolError(
123
+ result: AgentToolResultPart | undefined,
124
+ ): string | undefined {
125
+ if (!result || result.isError !== true) {
126
+ return undefined;
127
+ }
128
+ if (typeof result.output === "string") {
129
+ return result.output;
130
+ }
131
+ if (result.output instanceof Error) {
132
+ return result.output.message;
133
+ }
134
+ try {
135
+ return JSON.stringify(result.output);
136
+ } catch {
137
+ return String(result.output);
138
+ }
139
+ }
140
+
141
+ // =============================================================================
142
+ // Stateful adapter
143
+ // =============================================================================
144
+
145
+ /**
146
+ * Per-subscriber adapter instance. Constructed once per
147
+ * `Agent.subscribeEvents` registration (or per `SessionRuntime`),
148
+ * used for the lifetime of that subscription, and `reset()` at the
149
+ * start of every new run.
150
+ *
151
+ * `translate(event)` returns zero, one, or two `AgentEvent`s. An
152
+ * array is needed because a single `assistant-message` may yield both
153
+ * a text `content_end` and a reasoning `content_end`. Empty array
154
+ * means the event is intentionally suppressed (§3.3.2 rows
155
+ * `run-started`, `message-added`).
156
+ */
157
+ export class RuntimeEventAdapter {
158
+ private lastUsage: AgentUsage = {
159
+ inputTokens: 0,
160
+ outputTokens: 0,
161
+ cacheReadTokens: 0,
162
+ cacheWriteTokens: 0,
163
+ totalCost: 0,
164
+ };
165
+
166
+ private toolStartedAt = new Map<string, number>();
167
+
168
+ translate(event: AgentRuntimeEvent): AgentEvent[] {
169
+ switch (event.type) {
170
+ case "run-started":
171
+ return [];
172
+ case "message-added":
173
+ return [];
174
+ case "turn-started":
175
+ return [{ type: "iteration_start", iteration: event.iteration }];
176
+ case "turn-finished":
177
+ return [
178
+ {
179
+ type: "iteration_end",
180
+ iteration: event.iteration,
181
+ hadToolCalls: event.toolCallCount > 0,
182
+ toolCallCount: event.toolCallCount,
183
+ },
184
+ ];
185
+ case "assistant-text-delta":
186
+ return [
187
+ {
188
+ type: "content_start",
189
+ contentType: "text",
190
+ text: event.text,
191
+ accumulated: event.accumulatedText,
192
+ },
193
+ ];
194
+ case "assistant-reasoning-delta":
195
+ return [
196
+ {
197
+ type: "content_start",
198
+ contentType: "reasoning",
199
+ reasoning: event.text,
200
+ redacted: event.redacted === true,
201
+ },
202
+ ];
203
+ case "assistant-message":
204
+ return this.translateAssistantMessage(event.message);
205
+ case "tool-started":
206
+ return this.translateToolStarted(event);
207
+ case "tool-updated":
208
+ return [
209
+ {
210
+ type: "content_update",
211
+ contentType: "tool",
212
+ toolName: event.toolCall.toolName,
213
+ toolCallId: event.toolCall.toolCallId,
214
+ update: event.update,
215
+ },
216
+ ];
217
+ case "tool-finished":
218
+ return this.translateToolFinished(event);
219
+ case "usage-updated":
220
+ return this.translateUsage(event.usage);
221
+ case "run-finished":
222
+ return this.translateRunFinished(event.result);
223
+ case "run-failed":
224
+ return [
225
+ {
226
+ type: "error",
227
+ error: event.error,
228
+ recoverable: false,
229
+ iteration: event.snapshot.iteration,
230
+ },
231
+ ];
232
+ default: {
233
+ const _exhaustive: never = event;
234
+ return _exhaustive;
235
+ }
236
+ }
237
+ }
238
+
239
+ reset(): void {
240
+ this.lastUsage = {
241
+ inputTokens: 0,
242
+ outputTokens: 0,
243
+ cacheReadTokens: 0,
244
+ cacheWriteTokens: 0,
245
+ totalCost: 0,
246
+ };
247
+ this.toolStartedAt.clear();
248
+ }
249
+
250
+ // ------- per-variant translators ------------------------------------
251
+
252
+ private translateAssistantMessage(message: AgentMessage): AgentEvent[] {
253
+ const out: AgentEvent[] = [];
254
+ const text = extractTextPart(message);
255
+ if (text !== undefined) {
256
+ out.push({ type: "content_end", contentType: "text", text });
257
+ }
258
+ const reasoning = extractReasoningPart(message);
259
+ if (reasoning !== undefined) {
260
+ out.push({
261
+ type: "content_end",
262
+ contentType: "reasoning",
263
+ reasoning: reasoning.reasoning,
264
+ });
265
+ }
266
+ return out;
267
+ }
268
+
269
+ private translateToolStarted(event: {
270
+ toolCall: { toolCallId: string; toolName: string; input: unknown };
271
+ }): AgentEvent[] {
272
+ this.toolStartedAt.set(event.toolCall.toolCallId, Date.now());
273
+ return [
274
+ {
275
+ type: "content_start",
276
+ contentType: "tool",
277
+ toolName: event.toolCall.toolName,
278
+ toolCallId: event.toolCall.toolCallId,
279
+ input: event.toolCall.input,
280
+ },
281
+ ];
282
+ }
283
+
284
+ private translateToolFinished(event: {
285
+ toolCall: { toolCallId: string; toolName: string };
286
+ message: AgentMessage;
287
+ }): AgentEvent[] {
288
+ const startedAt = this.toolStartedAt.get(event.toolCall.toolCallId);
289
+ const durationMs =
290
+ startedAt === undefined ? undefined : Date.now() - startedAt;
291
+ this.toolStartedAt.delete(event.toolCall.toolCallId);
292
+ const result = extractToolResultPart(event.message);
293
+ const output = result?.output;
294
+ const error = deriveToolError(result);
295
+ return [
296
+ {
297
+ type: "content_end",
298
+ contentType: "tool",
299
+ toolName: event.toolCall.toolName,
300
+ toolCallId: event.toolCall.toolCallId,
301
+ output,
302
+ error,
303
+ durationMs,
304
+ },
305
+ ];
306
+ }
307
+
308
+ private translateUsage(next: AgentUsage): AgentEvent[] {
309
+ const deltaInput = next.inputTokens - this.lastUsage.inputTokens;
310
+ const deltaOutput = next.outputTokens - this.lastUsage.outputTokens;
311
+ const deltaCacheRead =
312
+ next.cacheReadTokens - this.lastUsage.cacheReadTokens;
313
+ const deltaCacheWrite =
314
+ next.cacheWriteTokens - this.lastUsage.cacheWriteTokens;
315
+ const prevCost = this.lastUsage.totalCost ?? 0;
316
+ const nextCost = next.totalCost ?? 0;
317
+ const deltaCost = nextCost - prevCost;
318
+ this.lastUsage = {
319
+ inputTokens: next.inputTokens,
320
+ outputTokens: next.outputTokens,
321
+ cacheReadTokens: next.cacheReadTokens,
322
+ cacheWriteTokens: next.cacheWriteTokens,
323
+ totalCost: next.totalCost,
324
+ };
325
+ return [
326
+ {
327
+ type: "usage",
328
+ inputTokens: Math.max(0, deltaInput),
329
+ outputTokens: Math.max(0, deltaOutput),
330
+ cacheReadTokens:
331
+ deltaCacheRead === 0 ? undefined : Math.max(0, deltaCacheRead),
332
+ cacheWriteTokens:
333
+ deltaCacheWrite === 0 ? undefined : Math.max(0, deltaCacheWrite),
334
+ cost: deltaCost === 0 ? undefined : deltaCost,
335
+ totalInputTokens: next.inputTokens,
336
+ totalOutputTokens: next.outputTokens,
337
+ totalCacheReadTokens:
338
+ next.cacheReadTokens === 0 ? undefined : next.cacheReadTokens,
339
+ totalCacheWriteTokens:
340
+ next.cacheWriteTokens === 0 ? undefined : next.cacheWriteTokens,
341
+ totalCost: next.totalCost,
342
+ },
343
+ ];
344
+ }
345
+
346
+ private translateRunFinished(result: {
347
+ status: "completed" | "aborted" | "failed";
348
+ outputText: string;
349
+ iterations: number;
350
+ usage: AgentUsage;
351
+ }): AgentEvent[] {
352
+ const usage: LegacyAgentUsage = {
353
+ inputTokens: result.usage.inputTokens,
354
+ outputTokens: result.usage.outputTokens,
355
+ cacheReadTokens:
356
+ result.usage.cacheReadTokens === 0
357
+ ? undefined
358
+ : result.usage.cacheReadTokens,
359
+ cacheWriteTokens:
360
+ result.usage.cacheWriteTokens === 0
361
+ ? undefined
362
+ : result.usage.cacheWriteTokens,
363
+ totalCost: result.usage.totalCost,
364
+ };
365
+ return [
366
+ {
367
+ type: "done",
368
+ reason: statusToLegacyFinishReason(result.status),
369
+ text: result.outputText,
370
+ iterations: result.iterations,
371
+ usage,
372
+ },
373
+ ];
374
+ }
375
+ }
376
+
377
+ // =============================================================================
378
+ // Stateless convenience export
379
+ // =============================================================================
380
+
381
+ /**
382
+ * Stateless translator. Works correctly for every variant except
383
+ * those that require bookkeeping:
384
+ *
385
+ * - `usage-updated` — deltas cannot be computed without a prior
386
+ * snapshot; this function treats the prior snapshot as zero (so
387
+ * delta == accumulated). Adequate for a single event, incorrect
388
+ * across multiple.
389
+ * - `tool-finished` — `durationMs` is reported as `undefined`
390
+ * because the corresponding `tool-started` was never observed by
391
+ * this one-shot adapter.
392
+ *
393
+ * Production code must use `RuntimeEventAdapter` for multi-event
394
+ * runs; this function exists for ad-hoc unit tests and one-shot
395
+ * translations where bookkeeping does not matter.
396
+ *
397
+ * Returns `undefined` when the event maps to zero legacy events
398
+ * (`run-started`, `message-added`, or an `assistant-message` that
399
+ * carries no text/reasoning parts). When an event produces multiple
400
+ * legacy events (e.g. `assistant-message` with both text and
401
+ * reasoning parts), only the first is returned; callers needing the
402
+ * full array must use `RuntimeEventAdapter.translate()`.
403
+ */
404
+ export function toLegacyAgentEvent(
405
+ event: AgentRuntimeEvent,
406
+ ): AgentEvent | undefined {
407
+ const adapter = new RuntimeEventAdapter();
408
+ const translated = adapter.translate(event);
409
+ return translated[0];
410
+ }
411
+
412
+ export { textFromMessage };
@@ -1,6 +1,7 @@
1
1
  import type * as LlmsProviders from "@clinebot/llms";
2
2
  import type {
3
3
  AgentResult,
4
+ RuntimeConfigExtensionKind,
4
5
  ToolApprovalRequest,
5
6
  ToolApprovalResult,
6
7
  } from "@clinebot/shared";
@@ -10,13 +11,14 @@ import type { ProviderSettings } from "../llms/provider-settings";
10
11
  import type { SessionManifest } from "../session/session-manifest";
11
12
  import type { SessionSource } from "../types/common";
12
13
  import type { CoreSessionConfig } from "../types/config";
13
- import type { CoreSessionEvent } from "../types/events";
14
+ import type { CoreSessionEvent, SessionPendingPrompt } from "../types/events";
14
15
  import type { SessionRecord } from "../types/sessions";
15
16
 
16
17
  type LocalOnlyCoreSessionConfigKeys =
17
18
  | "hooks"
18
19
  | "logger"
19
20
  | "telemetry"
21
+ | "extensionContext"
20
22
  | "extraTools"
21
23
  | "extensions"
22
24
  | "onTeamEvent"
@@ -50,6 +52,7 @@ export interface LocalRuntimeStartOptions {
50
52
  configOverrides?: Partial<LocalRuntimeConfigOverrides>;
51
53
  modelCatalogDefaults?: Partial<NonNullable<ProviderSettings["modelCatalog"]>>;
52
54
  userInstructionWatcher?: import("../extensions/config").UserInstructionConfigWatcher;
55
+ configExtensions?: RuntimeConfigExtensionKind[];
53
56
  onTeamRestored?: () => void;
54
57
  defaultToolExecutors?: Partial<ToolExecutors>;
55
58
  }
@@ -83,6 +86,7 @@ export function splitCoreSessionConfig(config: CoreSessionConfig): {
83
86
  hooks,
84
87
  logger,
85
88
  telemetry,
89
+ extensionContext,
86
90
  extraTools,
87
91
  extensions,
88
92
  onTeamEvent,
@@ -96,6 +100,8 @@ export function splitCoreSessionConfig(config: CoreSessionConfig): {
96
100
  if (hooks) localConfigOverrides.hooks = hooks;
97
101
  if (logger) localConfigOverrides.logger = logger;
98
102
  if (telemetry) localConfigOverrides.telemetry = telemetry;
103
+ if (extensionContext)
104
+ localConfigOverrides.extensionContext = extensionContext;
99
105
  if (extraTools) localConfigOverrides.extraTools = extraTools;
100
106
  if (extensions) localConfigOverrides.extensions = extensions;
101
107
  if (onTeamEvent) localConfigOverrides.onTeamEvent = onTeamEvent;
@@ -164,6 +170,32 @@ export interface SessionAccumulatedUsage {
164
170
  totalCost: number;
165
171
  }
166
172
 
173
+ export interface PendingPromptMutationResult {
174
+ sessionId: string;
175
+ prompts: SessionPendingPrompt[];
176
+ prompt?: SessionPendingPrompt;
177
+ updated?: boolean;
178
+ removed?: boolean;
179
+ }
180
+
181
+ export type PendingPromptsAction = "list" | "update" | "delete";
182
+
183
+ export interface PendingPromptsListInput {
184
+ sessionId: string;
185
+ }
186
+
187
+ export interface PendingPromptsUpdateInput {
188
+ sessionId: string;
189
+ promptId: string;
190
+ prompt?: string;
191
+ delivery?: "queue" | "steer";
192
+ }
193
+
194
+ export interface PendingPromptsDeleteInput {
195
+ sessionId: string;
196
+ promptId: string;
197
+ }
198
+
167
199
  export interface RuntimeHostSubscribeOptions {
168
200
  sessionId?: string;
169
201
  }
@@ -177,6 +209,18 @@ export interface RuntimeHost {
177
209
  readonly runtimeAddress?: string;
178
210
  start(input: StartSessionInput): Promise<StartSessionResult>;
179
211
  send(input: SendSessionInput): Promise<AgentResult | undefined>;
212
+ pendingPrompts(
213
+ action: "list",
214
+ input: PendingPromptsListInput,
215
+ ): Promise<SessionPendingPrompt[]>;
216
+ pendingPrompts(
217
+ action: "update",
218
+ input: PendingPromptsUpdateInput,
219
+ ): Promise<PendingPromptMutationResult>;
220
+ pendingPrompts(
221
+ action: "delete",
222
+ input: PendingPromptsDeleteInput,
223
+ ): Promise<PendingPromptMutationResult>;
180
224
  getAccumulatedUsage(
181
225
  sessionId: string,
182
226
  ): Promise<SessionAccumulatedUsage | undefined>;