@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.
- package/dist/ClineCore.d.ts +312 -3
- package/dist/ClineCore.d.ts.map +1 -1
- package/dist/account/cline-account-service.d.ts.map +1 -1
- package/dist/cron/cron-event-ingress.d.ts +38 -0
- package/dist/cron/cron-event-ingress.d.ts.map +1 -0
- package/dist/cron/cron-materializer.d.ts +36 -0
- package/dist/cron/cron-materializer.d.ts.map +1 -0
- package/dist/cron/cron-reconciler.d.ts +62 -0
- package/dist/cron/cron-reconciler.d.ts.map +1 -0
- package/dist/cron/cron-report-writer.d.ts +41 -0
- package/dist/cron/cron-report-writer.d.ts.map +1 -0
- package/dist/cron/cron-runner.d.ts +43 -0
- package/dist/cron/cron-runner.d.ts.map +1 -0
- package/dist/cron/cron-schema.d.ts +3 -0
- package/dist/cron/cron-schema.d.ts.map +1 -0
- package/dist/cron/cron-service.d.ts +57 -0
- package/dist/cron/cron-service.d.ts.map +1 -0
- package/dist/cron/cron-spec-parser.d.ts +27 -0
- package/dist/cron/cron-spec-parser.d.ts.map +1 -0
- package/dist/cron/cron-watcher.d.ts +23 -0
- package/dist/cron/cron-watcher.d.ts.map +1 -0
- package/dist/cron/scheduler.d.ts +3 -1
- package/dist/cron/scheduler.d.ts.map +1 -1
- package/dist/cron/sqlite-cron-store.d.ts +230 -0
- package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
- package/dist/extensions/plugin/plugin-config-loader.d.ts +7 -1
- package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-loader.d.ts +10 -6
- package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts +7 -1
- package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
- package/dist/extensions/plugin-sandbox-bootstrap.js +236 -275
- package/dist/extensions/tools/constants.d.ts +1 -0
- package/dist/extensions/tools/constants.d.ts.map +1 -1
- package/dist/extensions/tools/definitions.d.ts +2 -3
- package/dist/extensions/tools/definitions.d.ts.map +1 -1
- package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
- package/dist/extensions/tools/helpers.d.ts +1 -0
- package/dist/extensions/tools/helpers.d.ts.map +1 -1
- package/dist/extensions/tools/index.d.ts +1 -2
- package/dist/extensions/tools/index.d.ts.map +1 -1
- package/dist/extensions/tools/presets.d.ts +1 -1
- package/dist/extensions/tools/schemas.d.ts +25 -3
- package/dist/extensions/tools/schemas.d.ts.map +1 -1
- package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
- package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
- package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
- package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
- package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
- package/dist/extensions/tools/types.d.ts +0 -5
- package/dist/extensions/tools/types.d.ts.map +1 -1
- package/dist/hooks/hook-bridge.d.ts +118 -0
- package/dist/hooks/hook-bridge.d.ts.map +1 -0
- package/dist/hooks/hook-file-hooks.d.ts +2 -1
- package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
- package/dist/hooks/hook-registry.d.ts +16 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hub/browser-websocket.d.ts.map +1 -1
- package/dist/hub/client.d.ts +7 -1
- package/dist/hub/client.d.ts.map +1 -1
- package/dist/hub/daemon-entry.js +721 -461
- package/dist/hub/daemon.d.ts.map +1 -1
- package/dist/hub/defaults.d.ts +8 -4
- package/dist/hub/defaults.d.ts.map +1 -1
- package/dist/hub/index.js +665 -415
- package/dist/hub/runtime-handlers.d.ts.map +1 -1
- package/dist/hub/server.d.ts +18 -0
- package/dist/hub/server.d.ts.map +1 -1
- package/dist/hub/session-client.d.ts +3 -0
- package/dist/hub/session-client.d.ts.map +1 -1
- package/dist/hub/start-shared-server.d.ts.map +1 -1
- package/dist/hub/ui-client.d.ts +1 -0
- package/dist/hub/ui-client.d.ts.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +756 -467
- package/dist/llms/cline-recommended-models.d.ts +20 -0
- package/dist/llms/cline-recommended-models.d.ts.map +1 -0
- package/dist/llms/handler-factory.d.ts +16 -0
- package/dist/llms/handler-factory.d.ts.map +1 -0
- package/dist/llms/provider-defaults.d.ts.map +1 -1
- package/dist/llms/provider-settings.d.ts +45 -2
- package/dist/llms/provider-settings.d.ts.map +1 -1
- package/dist/llms/runtime-registry.d.ts.map +1 -1
- package/dist/runtime/agent-config-adapter.d.ts +148 -0
- package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
- package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
- package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
- package/dist/runtime/history.d.ts +6 -0
- package/dist/runtime/history.d.ts.map +1 -1
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/loop-detection.d.ts +59 -0
- package/dist/runtime/loop-detection.d.ts.map +1 -0
- package/dist/runtime/mistake-tracker.d.ts +69 -0
- package/dist/runtime/mistake-tracker.d.ts.map +1 -0
- package/dist/runtime/runtime-builder.d.ts.map +1 -1
- package/dist/runtime/runtime-event-adapter.d.ts +102 -0
- package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
- package/dist/runtime/runtime-host.d.ts +28 -3
- package/dist/runtime/runtime-host.d.ts.map +1 -1
- package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
- package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
- package/dist/runtime/session-runtime.d.ts +16 -3
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/runtime/user-input-builder.d.ts +24 -0
- package/dist/runtime/user-input-builder.d.ts.map +1 -0
- package/dist/services/index.js +28 -0
- package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
- package/dist/services/plugin-tools.d.ts.map +1 -1
- package/dist/services/providers/local-provider-registry.d.ts +197 -21
- package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
- package/dist/services/providers/local-provider-service.d.ts +3 -1
- package/dist/services/providers/local-provider-service.d.ts.map +1 -1
- package/dist/services/session-data.d.ts.map +1 -1
- package/dist/services/session-telemetry.d.ts +7 -2
- package/dist/services/session-telemetry.d.ts.map +1 -1
- package/dist/services/storage/file-team-store.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
- package/dist/services/storage/provider-settings-manager.d.ts +1 -0
- package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
- package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
- package/dist/session/conversation-store.d.ts +30 -0
- package/dist/session/conversation-store.d.ts.map +1 -0
- package/dist/session/message-builder.d.ts +65 -0
- package/dist/session/message-builder.d.ts.map +1 -0
- package/dist/session/session-manifest.d.ts +1 -1
- package/dist/transports/hub.d.ts +14 -3
- package/dist/transports/hub.d.ts.map +1 -1
- package/dist/transports/local.d.ts +14 -4
- package/dist/transports/local.d.ts.map +1 -1
- package/dist/transports/remote.d.ts.map +1 -1
- package/dist/types/chat-schema.d.ts +5 -5
- package/dist/types/config.d.ts +9 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/events.d.ts +7 -6
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/provider-settings.d.ts +2 -2
- package/dist/types/provider-settings.d.ts.map +1 -1
- package/dist/types/session.d.ts +5 -2
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ClineCore.ts +691 -6
- package/src/account/cline-account-service.ts +44 -6
- package/src/cron/cron-event-ingress.ts +357 -0
- package/src/cron/cron-materializer.ts +97 -0
- package/src/cron/cron-reconciler.ts +241 -0
- package/src/cron/cron-report-writer.ts +153 -0
- package/src/cron/cron-runner.ts +495 -0
- package/src/cron/cron-schema.ts +127 -0
- package/src/cron/cron-service.ts +163 -0
- package/src/cron/cron-spec-parser.ts +489 -0
- package/src/cron/cron-watcher.ts +102 -0
- package/src/cron/index.ts +10 -0
- package/src/cron/scheduler.ts +141 -6
- package/src/cron/sqlite-cron-store.ts +1286 -0
- package/src/extensions/plugin/plugin-config-loader.ts +21 -1
- package/src/extensions/plugin/plugin-loader.ts +25 -9
- package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +151 -1
- package/src/extensions/plugin/plugin-sandbox.ts +131 -7
- package/src/extensions/tools/constants.ts +2 -0
- package/src/extensions/tools/definitions.ts +31 -22
- package/src/extensions/tools/executors/editor.ts +4 -3
- package/src/extensions/tools/helpers.ts +24 -0
- package/src/extensions/tools/index.ts +1 -2
- package/src/extensions/tools/presets.ts +1 -1
- package/src/extensions/tools/schemas.ts +13 -18
- package/src/extensions/tools/team/delegated-agent.ts +8 -3
- package/src/extensions/tools/team/multi-agent.ts +135 -19
- package/src/extensions/tools/team/team-tools.ts +151 -91
- package/src/extensions/tools/types.ts +0 -6
- package/src/hooks/hook-bridge.ts +489 -0
- package/src/hooks/hook-file-hooks.ts +58 -3
- package/src/hooks/hook-registry.ts +257 -0
- package/src/hub/browser-websocket.ts +26 -4
- package/src/hub/client.ts +72 -13
- package/src/hub/daemon-entry.ts +35 -0
- package/src/hub/daemon.ts +117 -14
- package/src/hub/defaults.ts +39 -12
- package/src/hub/runtime-handlers.ts +4 -3
- package/src/hub/server.ts +506 -77
- package/src/hub/session-client.ts +43 -1
- package/src/hub/start-shared-server.ts +3 -0
- package/src/hub/ui-client.ts +4 -0
- package/src/index.ts +46 -1
- package/src/llms/cline-recommended-models.ts +167 -0
- package/src/llms/handler-factory.ts +56 -0
- package/src/llms/provider-defaults.ts +17 -1
- package/src/llms/provider-settings.ts +48 -1
- package/src/llms/runtime-registry.ts +1 -0
- package/src/runtime/agent-config-adapter.ts +636 -0
- package/src/runtime/agent-runtime-config-builder.ts +205 -0
- package/src/runtime/error-feedback.ts +142 -0
- package/src/runtime/history.ts +137 -0
- package/src/runtime/host.ts +22 -0
- package/src/runtime/loop-detection.ts +162 -0
- package/src/runtime/mistake-tracker.ts +221 -0
- package/src/runtime/runtime-builder.ts +61 -5
- package/src/runtime/runtime-event-adapter.ts +412 -0
- package/src/runtime/runtime-host.ts +45 -1
- package/src/runtime/session-runtime-orchestrator.ts +1253 -0
- package/src/runtime/session-runtime.ts +16 -2
- package/src/runtime/user-input-builder.ts +167 -0
- package/src/services/local-runtime-bootstrap.ts +128 -22
- package/src/services/plugin-tools.ts +1 -0
- package/src/services/providers/local-provider-registry.ts +273 -57
- package/src/services/providers/local-provider-service.ts +67 -7
- package/src/services/session-data.ts +16 -14
- package/src/services/session-telemetry.ts +6 -15
- package/src/services/storage/file-team-store.ts +1 -5
- package/src/services/storage/provider-settings-legacy-migration.ts +8 -47
- package/src/services/storage/provider-settings-manager.ts +16 -1
- package/src/services/storage/sqlite-team-store.ts +1 -5
- package/src/session/conversation-store.ts +77 -0
- package/src/session/message-builder.ts +941 -0
- package/src/transports/hub.ts +458 -33
- package/src/transports/local.ts +296 -65
- package/src/transports/remote.ts +1 -0
- package/src/types/config.ts +9 -0
- package/src/types/events.ts +8 -6
- package/src/types/index.ts +3 -0
- package/src/types/provider-settings.ts +8 -1
- package/src/types/session.ts +5 -2
- package/src/types.ts +15 -1
- package/dist/cron/index.d.ts +0 -6
- package/dist/cron/index.d.ts.map +0 -1
- package/dist/services/telemetry/index.js +0 -28
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-shape adapters between the **legacy host API** types
|
|
3
|
+
* (`ApiHandler`, `Tool`, `MessageWithMetadata`) and the **new
|
|
4
|
+
* runtime contract** types (`AgentModel`, `AgentTool`,
|
|
5
|
+
* `AgentMessage`) consumed by `AgentRuntime`.
|
|
6
|
+
*
|
|
7
|
+
* @see PLAN.md §3.1 — pure adapters; introduced alongside the core
|
|
8
|
+
* runtime port.
|
|
9
|
+
* @see PLAN.md §3.2.1 — consumed by `createAgentRuntimeConfig` to
|
|
10
|
+
* populate the `model`, `tools`, and
|
|
11
|
+
* `initialMessages` fields.
|
|
12
|
+
*
|
|
13
|
+
* These functions are intentionally **pure** (stateless adapters —
|
|
14
|
+
* they allocate fresh closures / arrays on every call and hold no
|
|
15
|
+
* internal state). Any state a consumer needs (e.g. an `AbortSignal`
|
|
16
|
+
* or a conversation id for `ToolContext.conversationId`) is injected
|
|
17
|
+
* per-call via the second-arg options object.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type {
|
|
21
|
+
ApiHandler,
|
|
22
|
+
ApiStreamChunk,
|
|
23
|
+
ToolDefinition,
|
|
24
|
+
} from "@clinebot/llms";
|
|
25
|
+
import type {
|
|
26
|
+
AgentMessage,
|
|
27
|
+
AgentMessagePart,
|
|
28
|
+
AgentModel,
|
|
29
|
+
AgentModelEvent,
|
|
30
|
+
AgentModelRequest,
|
|
31
|
+
AgentTextPart,
|
|
32
|
+
AgentTool,
|
|
33
|
+
AgentToolContext,
|
|
34
|
+
AgentToolResult,
|
|
35
|
+
ContentBlock,
|
|
36
|
+
FileContent,
|
|
37
|
+
ImageContent,
|
|
38
|
+
Message,
|
|
39
|
+
MessageWithMetadata,
|
|
40
|
+
RedactedThinkingContent,
|
|
41
|
+
TextContent,
|
|
42
|
+
ThinkingContent,
|
|
43
|
+
Tool,
|
|
44
|
+
ToolContext,
|
|
45
|
+
ToolResultContent,
|
|
46
|
+
ToolUseContent,
|
|
47
|
+
} from "@clinebot/shared";
|
|
48
|
+
|
|
49
|
+
// =============================================================================
|
|
50
|
+
// ApiHandler → AgentModel
|
|
51
|
+
// =============================================================================
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Context describing the model the `ApiHandler` talks to. This is
|
|
55
|
+
* used to populate `AgentMessage.modelInfo` on assistant messages
|
|
56
|
+
* emitted by the runtime. Matches PLAN.md §3.2.1 —
|
|
57
|
+
* `messageModelInfo = { id: modelId, provider: providerId, family:
|
|
58
|
+
* providerConfig?.family }`.
|
|
59
|
+
*/
|
|
60
|
+
export interface ApiHandlerAgentModelOptions {
|
|
61
|
+
/** Optional provider-family hint (e.g. `"claude-3.5"`). Attached as metadata. */
|
|
62
|
+
readonly family?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Optional abort-signal factory. When provided, the returned
|
|
65
|
+
* `AgentModel.stream()` installs the signal on the handler via
|
|
66
|
+
* `handler.setAbortSignal()` before each call, and threads
|
|
67
|
+
* `request.signal` through for per-turn abort semantics.
|
|
68
|
+
*/
|
|
69
|
+
readonly getAbortSignal?: () => AbortSignal | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Last-mile message preparation before the legacy handler builds a provider
|
|
72
|
+
* request. SessionRuntime uses this to apply API-safe normalization,
|
|
73
|
+
* tool-result truncation, and stale read-result rewriting with its
|
|
74
|
+
* session-owned MessageBuilder.
|
|
75
|
+
*/
|
|
76
|
+
readonly prepareMessages?: (
|
|
77
|
+
messages: Message[],
|
|
78
|
+
) => Message[] | Promise<Message[]>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Build an `AgentModel` adapter around an existing `ApiHandler`.
|
|
83
|
+
*
|
|
84
|
+
* The returned adapter:
|
|
85
|
+
*
|
|
86
|
+
* 1. Converts `AgentModelRequest.messages` (`AgentMessage[]`) back
|
|
87
|
+
* into `LlmsProviders.Message[]` via
|
|
88
|
+
* {@link agentMessagesToMessages}.
|
|
89
|
+
* 2. Converts `AgentModelRequest.tools`
|
|
90
|
+
* (`AgentToolDefinition[]`) to `LlmsProviders.ToolDefinition[]`.
|
|
91
|
+
* 3. Invokes `handler.createMessage(systemPrompt, messages, tools)`.
|
|
92
|
+
* 4. Iterates the returned `ApiStream` and yields
|
|
93
|
+
* `AgentModelEvent`s produced by {@link apiStreamChunkToAgentModelEvent}.
|
|
94
|
+
*/
|
|
95
|
+
export function apiHandlerToAgentModel(
|
|
96
|
+
handler: ApiHandler,
|
|
97
|
+
options: ApiHandlerAgentModelOptions = {},
|
|
98
|
+
): AgentModel {
|
|
99
|
+
return {
|
|
100
|
+
async stream(
|
|
101
|
+
request: AgentModelRequest,
|
|
102
|
+
): Promise<AsyncIterable<AgentModelEvent>> {
|
|
103
|
+
const signal = options.getAbortSignal?.() ?? request.signal;
|
|
104
|
+
handler.setAbortSignal?.(signal);
|
|
105
|
+
const systemPrompt = request.systemPrompt ?? "";
|
|
106
|
+
const messages = options.prepareMessages
|
|
107
|
+
? await options.prepareMessages(
|
|
108
|
+
agentMessagesToMessages(request.messages),
|
|
109
|
+
)
|
|
110
|
+
: agentMessagesToMessages(request.messages);
|
|
111
|
+
const tools = agentToolDefinitionsToToolDefinitions(request.tools);
|
|
112
|
+
const stream = handler.createMessage(systemPrompt, messages, tools);
|
|
113
|
+
return translateApiStream(stream);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Translate an `ApiStream` (async generator of `ApiStreamChunk`)
|
|
120
|
+
* into an async iterable of `AgentModelEvent`. Exposed for tests;
|
|
121
|
+
* production callers go through {@link apiHandlerToAgentModel}.
|
|
122
|
+
*/
|
|
123
|
+
export async function* translateApiStream(
|
|
124
|
+
stream: AsyncIterable<ApiStreamChunk>,
|
|
125
|
+
): AsyncIterable<AgentModelEvent> {
|
|
126
|
+
let sawFinish = false;
|
|
127
|
+
try {
|
|
128
|
+
for await (const chunk of stream) {
|
|
129
|
+
const event = apiStreamChunkToAgentModelEvent(chunk);
|
|
130
|
+
if (event) {
|
|
131
|
+
yield event;
|
|
132
|
+
}
|
|
133
|
+
if (chunk.type === "done") {
|
|
134
|
+
sawFinish = true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
yield {
|
|
139
|
+
type: "finish",
|
|
140
|
+
reason: "error",
|
|
141
|
+
error: error instanceof Error ? error.message : String(error),
|
|
142
|
+
};
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (!sawFinish) {
|
|
146
|
+
yield { type: "finish", reason: "stop" };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Map a single `ApiStreamChunk` to the corresponding
|
|
152
|
+
* `AgentModelEvent`. Returns `undefined` for chunks that carry no
|
|
153
|
+
* runtime-observable payload (currently none — but the hook exists
|
|
154
|
+
* so we can silently drop future additions without type breakage).
|
|
155
|
+
*/
|
|
156
|
+
export function apiStreamChunkToAgentModelEvent(
|
|
157
|
+
chunk: ApiStreamChunk,
|
|
158
|
+
): AgentModelEvent | undefined {
|
|
159
|
+
switch (chunk.type) {
|
|
160
|
+
case "text":
|
|
161
|
+
return { type: "text-delta", text: chunk.text };
|
|
162
|
+
case "reasoning": {
|
|
163
|
+
const metadata: Record<string, unknown> = {};
|
|
164
|
+
if (chunk.signature !== undefined) {
|
|
165
|
+
metadata.signature = chunk.signature;
|
|
166
|
+
}
|
|
167
|
+
if (chunk.details !== undefined) {
|
|
168
|
+
metadata.details = chunk.details;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
type: "reasoning-delta",
|
|
172
|
+
text: chunk.reasoning,
|
|
173
|
+
redacted: chunk.redacted_data !== undefined,
|
|
174
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
case "tool_calls": {
|
|
178
|
+
const fn = chunk.tool_call.function;
|
|
179
|
+
const args = fn.arguments;
|
|
180
|
+
const inputText = typeof args === "string" ? args : undefined;
|
|
181
|
+
const input =
|
|
182
|
+
args && typeof args === "object" ? (args as unknown) : undefined;
|
|
183
|
+
const metadata: Record<string, unknown> = {};
|
|
184
|
+
if (chunk.signature !== undefined) {
|
|
185
|
+
metadata.thoughtSignature = chunk.signature;
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
type: "tool-call-delta",
|
|
189
|
+
toolCallId: fn.id ?? chunk.tool_call.call_id,
|
|
190
|
+
toolName: fn.name,
|
|
191
|
+
inputText,
|
|
192
|
+
input,
|
|
193
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
case "usage":
|
|
197
|
+
return {
|
|
198
|
+
type: "usage",
|
|
199
|
+
usage: {
|
|
200
|
+
inputTokens: chunk.inputTokens,
|
|
201
|
+
outputTokens: chunk.outputTokens,
|
|
202
|
+
cacheReadTokens: chunk.cacheReadTokens,
|
|
203
|
+
cacheWriteTokens: chunk.cacheWriteTokens,
|
|
204
|
+
totalCost: chunk.totalCost,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
case "done":
|
|
208
|
+
if (chunk.success === false) {
|
|
209
|
+
return { type: "finish", reason: "error", error: chunk.error };
|
|
210
|
+
}
|
|
211
|
+
if (chunk.incompleteReason === "max_tokens") {
|
|
212
|
+
return { type: "finish", reason: "max-tokens" };
|
|
213
|
+
}
|
|
214
|
+
return { type: "finish", reason: "stop" };
|
|
215
|
+
default: {
|
|
216
|
+
const _exhaustive: never = chunk;
|
|
217
|
+
return _exhaustive;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// =============================================================================
|
|
223
|
+
// Tool[] → AgentTool[]
|
|
224
|
+
// =============================================================================
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Options threaded into every adapted tool's `ToolContext`.
|
|
228
|
+
*/
|
|
229
|
+
export interface ToolAdapterOptions {
|
|
230
|
+
/**
|
|
231
|
+
* Conversation id bound to every `ToolContext.conversationId`
|
|
232
|
+
* the tool's `execute()` receives. The new runtime scopes tools
|
|
233
|
+
* by `AgentToolContext.agentId`/`.runId`; the legacy `ToolContext`
|
|
234
|
+
* requires `conversationId` separately, so the caller
|
|
235
|
+
* (`SessionRuntime`) supplies it once at adapter-construction
|
|
236
|
+
* time.
|
|
237
|
+
*/
|
|
238
|
+
readonly conversationId: string;
|
|
239
|
+
/**
|
|
240
|
+
* Optional metadata merged into every tool execution
|
|
241
|
+
* (`AgentConfig.toolContextMetadata` equivalent).
|
|
242
|
+
*/
|
|
243
|
+
readonly metadata?: Record<string, unknown>;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Adapt a legacy `Tool<TInput, TOutput>` to the new
|
|
248
|
+
* `AgentTool<TInput, TOutput>`.
|
|
249
|
+
*
|
|
250
|
+
* - name/description/inputSchema flow through verbatim;
|
|
251
|
+
* - `execute(input, AgentToolContext)` is wrapped so the legacy
|
|
252
|
+
* signature `execute(input, ToolContext, onChange)` receives the
|
|
253
|
+
* correct fields and the return value is boxed into an
|
|
254
|
+
* `AgentToolResult`.
|
|
255
|
+
*/
|
|
256
|
+
export function toolToAgentTool<TInput, TOutput>(
|
|
257
|
+
tool: Tool<TInput, TOutput>,
|
|
258
|
+
options: ToolAdapterOptions,
|
|
259
|
+
): AgentTool<TInput, TOutput> {
|
|
260
|
+
return {
|
|
261
|
+
name: tool.name,
|
|
262
|
+
description: tool.description,
|
|
263
|
+
inputSchema: tool.inputSchema,
|
|
264
|
+
async execute(
|
|
265
|
+
input: TInput,
|
|
266
|
+
context: AgentToolContext,
|
|
267
|
+
): Promise<AgentToolResult<TOutput>> {
|
|
268
|
+
const legacyContext: ToolContext = {
|
|
269
|
+
agentId: context.agentId,
|
|
270
|
+
conversationId: options.conversationId,
|
|
271
|
+
iteration: context.iteration,
|
|
272
|
+
abortSignal: context.signal,
|
|
273
|
+
metadata: options.metadata,
|
|
274
|
+
};
|
|
275
|
+
try {
|
|
276
|
+
const output = await tool.execute(
|
|
277
|
+
input,
|
|
278
|
+
legacyContext,
|
|
279
|
+
context.emitUpdate,
|
|
280
|
+
);
|
|
281
|
+
return { output };
|
|
282
|
+
} catch (error) {
|
|
283
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
284
|
+
return {
|
|
285
|
+
output: message as unknown as TOutput,
|
|
286
|
+
isError: true,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Convenience bulk-adapter for `AgentConfig.tools`.
|
|
295
|
+
*/
|
|
296
|
+
export function toolsToAgentTools(
|
|
297
|
+
tools: readonly Tool[],
|
|
298
|
+
options: ToolAdapterOptions,
|
|
299
|
+
): AgentTool[] {
|
|
300
|
+
return tools.map((tool) => toolToAgentTool(tool, options));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// =============================================================================
|
|
304
|
+
// MessageWithMetadata[] ↔ AgentMessage[]
|
|
305
|
+
// =============================================================================
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Normalize a single `MessageWithMetadata` into an `AgentMessage`.
|
|
309
|
+
*
|
|
310
|
+
* Role mapping: the legacy `MessageRole` is `"user" | "assistant"`.
|
|
311
|
+
* `tool_result` content blocks on user messages are hoisted into a
|
|
312
|
+
* dedicated `AgentMessage` with role `"tool"` — matching how the new
|
|
313
|
+
* runtime's tool executor emits tool messages
|
|
314
|
+
* (`packages/agents/src/agent-runtime.ts` tool-finished path).
|
|
315
|
+
*/
|
|
316
|
+
export function messageToAgentMessages(
|
|
317
|
+
message: MessageWithMetadata,
|
|
318
|
+
): AgentMessage[] {
|
|
319
|
+
const blocks = normalizeContentBlocks(message.content);
|
|
320
|
+
const toolResults = blocks.filter(
|
|
321
|
+
(block): block is ToolResultContent => block.type === "tool_result",
|
|
322
|
+
);
|
|
323
|
+
const nonToolResults = blocks.filter((block) => block.type !== "tool_result");
|
|
324
|
+
|
|
325
|
+
const out: AgentMessage[] = [];
|
|
326
|
+
|
|
327
|
+
if (nonToolResults.length > 0 || toolResults.length === 0) {
|
|
328
|
+
out.push({
|
|
329
|
+
id: message.id ?? generateMessageId(),
|
|
330
|
+
role: message.role,
|
|
331
|
+
content: nonToolResults.map(contentBlockToAgentPart),
|
|
332
|
+
createdAt: message.ts ?? Date.now(),
|
|
333
|
+
metadata: message.metadata,
|
|
334
|
+
modelInfo: message.modelInfo,
|
|
335
|
+
metrics: metricsToAgentMetrics(message.metrics),
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
for (const toolResult of toolResults) {
|
|
340
|
+
out.push({
|
|
341
|
+
id: `${message.id ?? generateMessageId()}_tool_${toolResult.tool_use_id}`,
|
|
342
|
+
role: "tool",
|
|
343
|
+
content: [toolResultContentToAgentPart(toolResult)],
|
|
344
|
+
createdAt: message.ts ?? Date.now(),
|
|
345
|
+
metadata: message.metadata,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return out;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Bulk-adapter: `MessageWithMetadata[]` → `AgentMessage[]`. A single
|
|
354
|
+
* legacy message with both text and tool-result blocks may expand
|
|
355
|
+
* into multiple agent messages (see {@link messageToAgentMessages}).
|
|
356
|
+
*/
|
|
357
|
+
export function messagesToAgentMessages(
|
|
358
|
+
messages: readonly MessageWithMetadata[],
|
|
359
|
+
): AgentMessage[] {
|
|
360
|
+
const out: AgentMessage[] = [];
|
|
361
|
+
for (const message of messages) {
|
|
362
|
+
out.push(...messageToAgentMessages(message));
|
|
363
|
+
}
|
|
364
|
+
return out;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Reverse adapter: `AgentMessage` → `MessageWithMetadata`. Best-effort
|
|
369
|
+
* preservation of id/metadata/modelInfo/metrics; tool-message
|
|
370
|
+
* tool-result parts are rendered as `tool_result` content blocks on
|
|
371
|
+
* a user message (matching legacy storage conventions).
|
|
372
|
+
*/
|
|
373
|
+
export function agentMessageToMessageWithMetadata(
|
|
374
|
+
message: AgentMessage,
|
|
375
|
+
): MessageWithMetadata {
|
|
376
|
+
const content = message.content
|
|
377
|
+
.map(agentPartToContentBlock)
|
|
378
|
+
.filter((block): block is ContentBlock => block !== undefined);
|
|
379
|
+
return {
|
|
380
|
+
id: message.id,
|
|
381
|
+
role: message.role === "tool" ? "user" : message.role,
|
|
382
|
+
content,
|
|
383
|
+
ts: message.createdAt,
|
|
384
|
+
metadata: message.metadata,
|
|
385
|
+
modelInfo: message.modelInfo,
|
|
386
|
+
metrics: agentMetricsToMetrics(message.metrics),
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Bulk-adapter for the reverse direction.
|
|
392
|
+
*/
|
|
393
|
+
export function agentMessagesToMessagesWithMetadata(
|
|
394
|
+
messages: readonly AgentMessage[],
|
|
395
|
+
): MessageWithMetadata[] {
|
|
396
|
+
return messages.map(agentMessageToMessageWithMetadata);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Lossy but adequate: `AgentMessage[]` → `LlmsProviders.Message[]`.
|
|
401
|
+
* Used to feed the legacy `ApiHandler.createMessage()` in
|
|
402
|
+
* {@link apiHandlerToAgentModel}. Drops fields that the handler
|
|
403
|
+
* does not consume (id, ts, metrics, modelInfo).
|
|
404
|
+
*/
|
|
405
|
+
export function agentMessagesToMessages(
|
|
406
|
+
messages: readonly AgentMessage[],
|
|
407
|
+
): Message[] {
|
|
408
|
+
const out: Message[] = [];
|
|
409
|
+
for (const message of messages) {
|
|
410
|
+
const content = message.content
|
|
411
|
+
.map(agentPartToContentBlock)
|
|
412
|
+
.filter((block): block is ContentBlock => block !== undefined);
|
|
413
|
+
const role = message.role === "tool" ? "user" : message.role;
|
|
414
|
+
|
|
415
|
+
// AI SDK validates that assistant tool calls are followed by a single
|
|
416
|
+
// tool-result message containing results for every call in that turn.
|
|
417
|
+
// The AgentRuntime stores each executed tool as its own role:"tool"
|
|
418
|
+
// message; merge adjacent tool messages back into one legacy user
|
|
419
|
+
// message so multi-tool turns round-trip correctly.
|
|
420
|
+
const previous = out[out.length - 1];
|
|
421
|
+
if (
|
|
422
|
+
role === "user" &&
|
|
423
|
+
content.length > 0 &&
|
|
424
|
+
content.every((block) => block.type === "tool_result") &&
|
|
425
|
+
previous?.role === "user" &&
|
|
426
|
+
Array.isArray(previous.content) &&
|
|
427
|
+
previous.content.every((block) => block.type === "tool_result")
|
|
428
|
+
) {
|
|
429
|
+
previous.content.push(...content);
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
out.push({ role, content });
|
|
434
|
+
}
|
|
435
|
+
return out;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Map runtime `AgentToolDefinition[]` to legacy
|
|
440
|
+
* `LlmsProviders.ToolDefinition[]`. Structurally identical today —
|
|
441
|
+
* but typing them separately keeps the adapter explicit.
|
|
442
|
+
*/
|
|
443
|
+
export function agentToolDefinitionsToToolDefinitions(
|
|
444
|
+
tools: AgentModelRequest["tools"],
|
|
445
|
+
): ToolDefinition[] {
|
|
446
|
+
return tools.map((tool) => ({
|
|
447
|
+
name: tool.name,
|
|
448
|
+
description: tool.description,
|
|
449
|
+
inputSchema: tool.inputSchema,
|
|
450
|
+
}));
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// =============================================================================
|
|
454
|
+
// Content-block / part translation
|
|
455
|
+
// =============================================================================
|
|
456
|
+
|
|
457
|
+
function normalizeContentBlocks(content: Message["content"]): ContentBlock[] {
|
|
458
|
+
if (typeof content === "string") {
|
|
459
|
+
return content.length > 0
|
|
460
|
+
? [{ type: "text", text: content } as TextContent]
|
|
461
|
+
: [];
|
|
462
|
+
}
|
|
463
|
+
return [...content];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function contentBlockToAgentPart(block: ContentBlock): AgentMessagePart {
|
|
467
|
+
switch (block.type) {
|
|
468
|
+
case "text":
|
|
469
|
+
return { type: "text", text: block.text };
|
|
470
|
+
case "thinking":
|
|
471
|
+
return {
|
|
472
|
+
type: "reasoning",
|
|
473
|
+
text: block.thinking,
|
|
474
|
+
metadata: block.signature
|
|
475
|
+
? { signature: block.signature, details: block.details }
|
|
476
|
+
: block.details
|
|
477
|
+
? { details: block.details }
|
|
478
|
+
: undefined,
|
|
479
|
+
};
|
|
480
|
+
case "redacted_thinking":
|
|
481
|
+
return {
|
|
482
|
+
type: "reasoning",
|
|
483
|
+
text: "",
|
|
484
|
+
redacted: true,
|
|
485
|
+
metadata: { data: block.data },
|
|
486
|
+
};
|
|
487
|
+
case "image":
|
|
488
|
+
return {
|
|
489
|
+
type: "image",
|
|
490
|
+
image: block.data,
|
|
491
|
+
mediaType: block.mediaType,
|
|
492
|
+
};
|
|
493
|
+
case "file":
|
|
494
|
+
return {
|
|
495
|
+
type: "file",
|
|
496
|
+
path: block.path,
|
|
497
|
+
content: block.content,
|
|
498
|
+
};
|
|
499
|
+
case "tool_use":
|
|
500
|
+
return {
|
|
501
|
+
type: "tool-call",
|
|
502
|
+
toolCallId: block.id,
|
|
503
|
+
toolName: block.name,
|
|
504
|
+
input: block.input,
|
|
505
|
+
metadata: block.signature ? { signature: block.signature } : undefined,
|
|
506
|
+
};
|
|
507
|
+
case "tool_result":
|
|
508
|
+
return toolResultContentToAgentPart(block);
|
|
509
|
+
default: {
|
|
510
|
+
const _exhaustive: never = block;
|
|
511
|
+
return _exhaustive;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function toolResultContentToAgentPart(
|
|
517
|
+
block: ToolResultContent,
|
|
518
|
+
): AgentMessagePart {
|
|
519
|
+
return {
|
|
520
|
+
type: "tool-result",
|
|
521
|
+
toolCallId: block.tool_use_id,
|
|
522
|
+
toolName: "",
|
|
523
|
+
output: block.content,
|
|
524
|
+
isError: block.is_error,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function agentPartToContentBlock(
|
|
529
|
+
part: AgentMessagePart,
|
|
530
|
+
): ContentBlock | undefined {
|
|
531
|
+
switch (part.type) {
|
|
532
|
+
case "text":
|
|
533
|
+
return { type: "text", text: (part as AgentTextPart).text };
|
|
534
|
+
case "reasoning": {
|
|
535
|
+
if (part.redacted === true) {
|
|
536
|
+
const data =
|
|
537
|
+
(part.metadata as { data?: string } | undefined)?.data ?? "";
|
|
538
|
+
return {
|
|
539
|
+
type: "redacted_thinking",
|
|
540
|
+
data,
|
|
541
|
+
} satisfies RedactedThinkingContent;
|
|
542
|
+
}
|
|
543
|
+
const metadata = part.metadata as
|
|
544
|
+
| { signature?: string; details?: unknown[] }
|
|
545
|
+
| undefined;
|
|
546
|
+
return {
|
|
547
|
+
type: "thinking",
|
|
548
|
+
thinking: part.text,
|
|
549
|
+
signature: metadata?.signature,
|
|
550
|
+
details: metadata?.details,
|
|
551
|
+
} satisfies ThinkingContent;
|
|
552
|
+
}
|
|
553
|
+
case "image": {
|
|
554
|
+
if (typeof part.image !== "string") {
|
|
555
|
+
// Binary images are not round-trippable through the legacy
|
|
556
|
+
// `ImageContent.data: string` field; drop them.
|
|
557
|
+
return undefined;
|
|
558
|
+
}
|
|
559
|
+
return {
|
|
560
|
+
type: "image",
|
|
561
|
+
data: part.image,
|
|
562
|
+
mediaType: part.mediaType ?? "image/png",
|
|
563
|
+
} satisfies ImageContent;
|
|
564
|
+
}
|
|
565
|
+
case "file":
|
|
566
|
+
return {
|
|
567
|
+
type: "file",
|
|
568
|
+
path: part.path,
|
|
569
|
+
content: part.content,
|
|
570
|
+
} satisfies FileContent;
|
|
571
|
+
case "tool-call":
|
|
572
|
+
return {
|
|
573
|
+
type: "tool_use",
|
|
574
|
+
id: part.toolCallId,
|
|
575
|
+
name: part.toolName,
|
|
576
|
+
input: (part.input as Record<string, unknown>) ?? {},
|
|
577
|
+
signature: (part.metadata as { signature?: string } | undefined)
|
|
578
|
+
?.signature,
|
|
579
|
+
} satisfies ToolUseContent;
|
|
580
|
+
case "tool-result": {
|
|
581
|
+
const output = part.output;
|
|
582
|
+
const content =
|
|
583
|
+
typeof output === "string"
|
|
584
|
+
? output
|
|
585
|
+
: Array.isArray(output)
|
|
586
|
+
? (output as ToolResultContent["content"])
|
|
587
|
+
: JSON.stringify(output);
|
|
588
|
+
return {
|
|
589
|
+
type: "tool_result",
|
|
590
|
+
tool_use_id: part.toolCallId,
|
|
591
|
+
content,
|
|
592
|
+
is_error: part.isError,
|
|
593
|
+
} satisfies ToolResultContent;
|
|
594
|
+
}
|
|
595
|
+
default: {
|
|
596
|
+
const _exhaustive: never = part;
|
|
597
|
+
return _exhaustive;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function metricsToAgentMetrics(
|
|
603
|
+
metrics: MessageWithMetadata["metrics"],
|
|
604
|
+
): AgentMessage["metrics"] {
|
|
605
|
+
if (!metrics) {
|
|
606
|
+
return undefined;
|
|
607
|
+
}
|
|
608
|
+
return {
|
|
609
|
+
inputTokens: metrics.inputTokens ?? 0,
|
|
610
|
+
outputTokens: metrics.outputTokens ?? 0,
|
|
611
|
+
cacheReadTokens: metrics.cacheReadTokens ?? 0,
|
|
612
|
+
cacheWriteTokens: metrics.cacheWriteTokens ?? 0,
|
|
613
|
+
cost: metrics.cost,
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
function agentMetricsToMetrics(
|
|
618
|
+
metrics: AgentMessage["metrics"],
|
|
619
|
+
): MessageWithMetadata["metrics"] {
|
|
620
|
+
if (!metrics) {
|
|
621
|
+
return undefined;
|
|
622
|
+
}
|
|
623
|
+
return {
|
|
624
|
+
inputTokens: metrics.inputTokens,
|
|
625
|
+
outputTokens: metrics.outputTokens,
|
|
626
|
+
cacheReadTokens: metrics.cacheReadTokens,
|
|
627
|
+
cacheWriteTokens: metrics.cacheWriteTokens,
|
|
628
|
+
cost: metrics.cost,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
let _msgSeq = 0;
|
|
633
|
+
function generateMessageId(): string {
|
|
634
|
+
_msgSeq += 1;
|
|
635
|
+
return `msg_${Date.now().toString(36)}_${_msgSeq.toString(36)}`;
|
|
636
|
+
}
|