@a-dray/aglib 0.1.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.
- package/LICENSE +21 -0
- package/README.md +172 -0
- package/dist/agent.d.ts +158 -0
- package/dist/agent.js +2 -0
- package/dist/agent.js.map +1 -0
- package/dist/content.d.ts +45 -0
- package/dist/content.js +11 -0
- package/dist/content.js.map +1 -0
- package/dist/harness/adapters/acp/index.d.ts +92 -0
- package/dist/harness/adapters/acp/index.js +479 -0
- package/dist/harness/adapters/acp/index.js.map +1 -0
- package/dist/harness/adapters/acp/rpc.d.ts +23 -0
- package/dist/harness/adapters/acp/rpc.js +103 -0
- package/dist/harness/adapters/acp/rpc.js.map +1 -0
- package/dist/harness/adapters/native/compaction.d.ts +16 -0
- package/dist/harness/adapters/native/compaction.js +55 -0
- package/dist/harness/adapters/native/compaction.js.map +1 -0
- package/dist/harness/adapters/native/index.d.ts +2 -0
- package/dist/harness/adapters/native/index.js +2 -0
- package/dist/harness/adapters/native/index.js.map +1 -0
- package/dist/harness/adapters/native/loop.d.ts +25 -0
- package/dist/harness/adapters/native/loop.js +153 -0
- package/dist/harness/adapters/native/loop.js.map +1 -0
- package/dist/harness/harness.d.ts +129 -0
- package/dist/harness/harness.js +2 -0
- package/dist/harness/harness.js.map +1 -0
- package/dist/harness/index.d.ts +3 -0
- package/dist/harness/index.js +2 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +4 -0
- package/dist/json.js +2 -0
- package/dist/json.js.map +1 -0
- package/dist/model/adapters/anthropic/index.d.ts +34 -0
- package/dist/model/adapters/anthropic/index.js +271 -0
- package/dist/model/adapters/anthropic/index.js.map +1 -0
- package/dist/model/adapters/fake/index.d.ts +27 -0
- package/dist/model/adapters/fake/index.js +37 -0
- package/dist/model/adapters/fake/index.js.map +1 -0
- package/dist/model/adapters/openai-compatible/index.d.ts +29 -0
- package/dist/model/adapters/openai-compatible/index.js +226 -0
- package/dist/model/adapters/openai-compatible/index.js.map +1 -0
- package/dist/model/conformance.d.ts +210 -0
- package/dist/model/conformance.js +427 -0
- package/dist/model/conformance.js.map +1 -0
- package/dist/model/index.d.ts +2 -0
- package/dist/model/index.js +2 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/model.d.ts +85 -0
- package/dist/model/model.js +8 -0
- package/dist/model/model.js.map +1 -0
- package/dist/result.d.ts +23 -0
- package/dist/result.js +3 -0
- package/dist/result.js.map +1 -0
- package/dist/run.d.ts +10 -0
- package/dist/run.js +477 -0
- package/dist/run.js.map +1 -0
- package/dist/sandbox/adapters/docker.d.ts +22 -0
- package/dist/sandbox/adapters/docker.js +443 -0
- package/dist/sandbox/adapters/docker.js.map +1 -0
- package/dist/sandbox/adapters/local.d.ts +11 -0
- package/dist/sandbox/adapters/local.js +284 -0
- package/dist/sandbox/adapters/local.js.map +1 -0
- package/dist/sandbox/conformance.d.ts +73 -0
- package/dist/sandbox/conformance.js +309 -0
- package/dist/sandbox/conformance.js.map +1 -0
- package/dist/sandbox/index.d.ts +1 -0
- package/dist/sandbox/index.js +2 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/sandbox.d.ts +172 -0
- package/dist/sandbox/sandbox.js +2 -0
- package/dist/sandbox/sandbox.js.map +1 -0
- package/dist/session/entry.d.ts +196 -0
- package/dist/session/entry.js +2 -0
- package/dist/session/entry.js.map +1 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/log.d.ts +20 -0
- package/dist/session/log.js +24 -0
- package/dist/session/log.js.map +1 -0
- package/dist/session/messages.d.ts +42 -0
- package/dist/session/messages.js +99 -0
- package/dist/session/messages.js.map +1 -0
- package/dist/store/adapters/sqlite.d.ts +20 -0
- package/dist/store/adapters/sqlite.js +365 -0
- package/dist/store/adapters/sqlite.js.map +1 -0
- package/dist/store/conformance.d.ts +66 -0
- package/dist/store/conformance.js +580 -0
- package/dist/store/conformance.js.map +1 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.js +2 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/store.d.ts +244 -0
- package/dist/store/store.js +2 -0
- package/dist/store/store.js.map +1 -0
- package/dist/tools/execute.d.ts +24 -0
- package/dist/tools/execute.js +105 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/tool.d.ts +106 -0
- package/dist/tools/tool.js +34 -0
- package/dist/tools/tool.js.map +1 -0
- package/package.json +119 -0
package/dist/json.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"","sourcesContent":["/** Anything that survives a round-trip through storage or a provider wire. */\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | readonly JsonValue[]\n | { readonly [key: string]: JsonValue };\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Model } from "../../model.js";
|
|
2
|
+
export interface AnthropicOptions {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
model: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
fetch?: typeof fetch;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The Anthropic Messages wire.
|
|
11
|
+
*
|
|
12
|
+
* A genuinely different shape from OpenAI's — the leading system prompt hoisted
|
|
13
|
+
* out of the message list, tool results carried as user content blocks, cache
|
|
14
|
+
* breakpoints marked inline — which is the point of it being here: a port
|
|
15
|
+
* proved against one wire format has not been proved.
|
|
16
|
+
*
|
|
17
|
+
* Three things this wire will refuse, and what we send instead:
|
|
18
|
+
*
|
|
19
|
+
* - **Thinking budgets.** `thinking: { type: "enabled", budget_tokens }` is
|
|
20
|
+
* removed on the current models and returns 400. Depth is `output_config.effort`
|
|
21
|
+
* over adaptive thinking, so `effort` maps there and nothing computes a budget.
|
|
22
|
+
* - **Sampling controls.** `temperature`, `top_p` and `top_k` are removed on the
|
|
23
|
+
* same models. `ModelRequest.temperature` is therefore dropped here rather
|
|
24
|
+
* than forwarded into a request the provider rejects.
|
|
25
|
+
* - **A system message in the middle of a turn.** Only the *leading* run of
|
|
26
|
+
* system messages becomes the `system` field. One arriving after the
|
|
27
|
+
* conversation has started is turn-scoped context, which the projection
|
|
28
|
+
* deliberately places after the cache boundary, so it stays in `messages` as
|
|
29
|
+
* a mid-conversation system message. Hoisting it would put the one thing that
|
|
30
|
+
* changes every turn at the front of the prefix that must not change.
|
|
31
|
+
* Supported on Opus 5, Opus 4.8 and Fable 5; a model without it fails the
|
|
32
|
+
* request rather than silently having its cache invalidated every turn.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createAnthropicModel(options: AnthropicOptions): Model;
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { err, ok } from "../../../result.js";
|
|
2
|
+
import { textOf } from "../../../content.js";
|
|
3
|
+
/**
|
|
4
|
+
* The Anthropic Messages wire.
|
|
5
|
+
*
|
|
6
|
+
* A genuinely different shape from OpenAI's — the leading system prompt hoisted
|
|
7
|
+
* out of the message list, tool results carried as user content blocks, cache
|
|
8
|
+
* breakpoints marked inline — which is the point of it being here: a port
|
|
9
|
+
* proved against one wire format has not been proved.
|
|
10
|
+
*
|
|
11
|
+
* Three things this wire will refuse, and what we send instead:
|
|
12
|
+
*
|
|
13
|
+
* - **Thinking budgets.** `thinking: { type: "enabled", budget_tokens }` is
|
|
14
|
+
* removed on the current models and returns 400. Depth is `output_config.effort`
|
|
15
|
+
* over adaptive thinking, so `effort` maps there and nothing computes a budget.
|
|
16
|
+
* - **Sampling controls.** `temperature`, `top_p` and `top_k` are removed on the
|
|
17
|
+
* same models. `ModelRequest.temperature` is therefore dropped here rather
|
|
18
|
+
* than forwarded into a request the provider rejects.
|
|
19
|
+
* - **A system message in the middle of a turn.** Only the *leading* run of
|
|
20
|
+
* system messages becomes the `system` field. One arriving after the
|
|
21
|
+
* conversation has started is turn-scoped context, which the projection
|
|
22
|
+
* deliberately places after the cache boundary, so it stays in `messages` as
|
|
23
|
+
* a mid-conversation system message. Hoisting it would put the one thing that
|
|
24
|
+
* changes every turn at the front of the prefix that must not change.
|
|
25
|
+
* Supported on Opus 5, Opus 4.8 and Fable 5; a model without it fails the
|
|
26
|
+
* request rather than silently having its cache invalidated every turn.
|
|
27
|
+
*/
|
|
28
|
+
export function createAnthropicModel(options) {
|
|
29
|
+
const call = options.fetch ?? fetch;
|
|
30
|
+
const baseUrl = options.baseUrl ?? "https://api.anthropic.com/v1";
|
|
31
|
+
return {
|
|
32
|
+
id: `anthropic:${options.model}`,
|
|
33
|
+
async *generate(request) {
|
|
34
|
+
// Only the leading run of system messages is the system prompt. Anything
|
|
35
|
+
// after it belongs where the projection put it — see the header.
|
|
36
|
+
let lead = 0;
|
|
37
|
+
while (lead < request.messages.length && request.messages[lead].role === "system")
|
|
38
|
+
lead += 1;
|
|
39
|
+
const system = request.messages.slice(0, lead).map((message) => textOf(message.content));
|
|
40
|
+
const conversation = request.messages.slice(lead);
|
|
41
|
+
// The prefix ends where the caller says it does. In practice that is the
|
|
42
|
+
// end of the system prompt, which is the one span fixed for the whole
|
|
43
|
+
// run; a mark past it is honoured too rather than quietly ignored.
|
|
44
|
+
const boundary = request.cacheAfter;
|
|
45
|
+
const cacheSystem = boundary !== undefined && boundary >= lead && system.length > 0;
|
|
46
|
+
const cacheAt = boundary !== undefined && boundary > lead ? boundary - lead - 1 : -1;
|
|
47
|
+
const maxOutputTokens = request.maxOutputTokens ?? 32_000;
|
|
48
|
+
let response;
|
|
49
|
+
try {
|
|
50
|
+
response = await call(`${baseUrl}/messages`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
"content-type": "application/json",
|
|
54
|
+
"x-api-key": options.apiKey,
|
|
55
|
+
"anthropic-version": options.version ?? "2023-06-01",
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
model: options.model,
|
|
59
|
+
max_tokens: maxOutputTokens,
|
|
60
|
+
...(system.length ? { system: encodeSystem(system, cacheSystem) } : {}),
|
|
61
|
+
messages: encodeConversation(conversation, cacheAt),
|
|
62
|
+
...(request.tools?.length ? { tools: request.tools.map(encodeTool) } : {}),
|
|
63
|
+
...(request.effort
|
|
64
|
+
? { thinking: { type: "adaptive" }, output_config: { effort: request.effort } }
|
|
65
|
+
: {}),
|
|
66
|
+
stream: true,
|
|
67
|
+
}),
|
|
68
|
+
...(request.signal ? { signal: request.signal } : {}),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return err(transportError(error, request.signal));
|
|
73
|
+
}
|
|
74
|
+
if (!response.ok)
|
|
75
|
+
return err(await httpError(response));
|
|
76
|
+
if (!response.body)
|
|
77
|
+
return err({ code: "provider", message: "No response body", retryable: true });
|
|
78
|
+
const text = [];
|
|
79
|
+
const calls = [];
|
|
80
|
+
let partial = "";
|
|
81
|
+
let stop;
|
|
82
|
+
let usage = {};
|
|
83
|
+
let model;
|
|
84
|
+
// A stream that dies mid-body — cancelled, dropped, truncated — must come
|
|
85
|
+
// back as a typed failure like any other. Without this the generator throws,
|
|
86
|
+
// `run.result` rejects instead of resolving `cancelled`, no `run.finished`
|
|
87
|
+
// is ever committed, and the activation stays open until its claim expires.
|
|
88
|
+
try {
|
|
89
|
+
for await (const event of sseData(response.body)) {
|
|
90
|
+
let frame;
|
|
91
|
+
try {
|
|
92
|
+
frame = JSON.parse(event);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (frame.type === "message_start" && frame.message) {
|
|
98
|
+
model = frame.message.model;
|
|
99
|
+
usage = { ...usage, ...decodeUsage(frame.message.usage) };
|
|
100
|
+
}
|
|
101
|
+
if (frame.type === "content_block_start" && frame.content_block?.type === "tool_use") {
|
|
102
|
+
calls.push({ callId: frame.content_block.id, name: frame.content_block.name, arguments: "" });
|
|
103
|
+
partial = "";
|
|
104
|
+
}
|
|
105
|
+
if (frame.type === "content_block_delta") {
|
|
106
|
+
const delta = frame.delta;
|
|
107
|
+
if (delta.type === "text_delta" && delta.text) {
|
|
108
|
+
text.push(delta.text);
|
|
109
|
+
yield { type: "text.delta", text: delta.text };
|
|
110
|
+
}
|
|
111
|
+
if (delta.type === "thinking_delta" && delta.thinking)
|
|
112
|
+
yield { type: "reasoning.delta", text: delta.thinking };
|
|
113
|
+
if (delta.type === "input_json_delta" && delta.partial_json !== undefined) {
|
|
114
|
+
partial += delta.partial_json;
|
|
115
|
+
const current = calls.at(-1);
|
|
116
|
+
if (current)
|
|
117
|
+
yield { type: "tool-call.delta", callId: current.callId, arguments: delta.partial_json };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (frame.type === "content_block_stop" && calls.length) {
|
|
121
|
+
const current = calls.at(-1);
|
|
122
|
+
if (!current.arguments)
|
|
123
|
+
current.arguments = partial || "{}";
|
|
124
|
+
}
|
|
125
|
+
if (frame.type === "message_delta") {
|
|
126
|
+
stop = frame.delta?.stop_reason ?? stop;
|
|
127
|
+
usage = { ...usage, ...decodeUsage(frame.usage) };
|
|
128
|
+
}
|
|
129
|
+
if (frame.type === "error") {
|
|
130
|
+
return err({ code: "provider", message: frame.error?.message ?? "Provider error", retryable: true });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
return err(transportError(error, request.signal));
|
|
136
|
+
}
|
|
137
|
+
return ok({
|
|
138
|
+
message: { content: text.join(""), ...(calls.length ? { calls } : {}) },
|
|
139
|
+
finishReason: stop === "max_tokens" ? "length" : stop === "refusal" ? "refusal" : calls.length ? "tool-calls" : "stop",
|
|
140
|
+
usage,
|
|
141
|
+
...(model ? { model } : {}),
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Text blocks rather than one joined string, so the end of the prefix can carry
|
|
148
|
+
* a breakpoint. Only the last block is marked: a breakpoint caches everything
|
|
149
|
+
* before it, so marking each one would buy nothing and spend the budget of four.
|
|
150
|
+
*/
|
|
151
|
+
function encodeSystem(blocks, cache) {
|
|
152
|
+
return blocks.map((text, index) => ({
|
|
153
|
+
type: "text",
|
|
154
|
+
text,
|
|
155
|
+
...(cache && index === blocks.length - 1 ? { cache_control: { type: "ephemeral" } } : {}),
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Tool results are user-role content blocks here, not a role of their own.
|
|
160
|
+
*
|
|
161
|
+
* `cacheAt` is an index into `messages`; the breakpoint lands on the last
|
|
162
|
+
* content block that message produced. Tool results merge into a preceding user
|
|
163
|
+
* block, so the mapping from message to block is not one to one and the mark is
|
|
164
|
+
* placed as each message is encoded rather than computed afterwards.
|
|
165
|
+
*/
|
|
166
|
+
function encodeConversation(messages, cacheAt = -1) {
|
|
167
|
+
const out = [];
|
|
168
|
+
let mark;
|
|
169
|
+
messages.forEach((message, index) => {
|
|
170
|
+
if (message.role === "tool") {
|
|
171
|
+
const block = {
|
|
172
|
+
type: "tool_result", tool_use_id: message.callId, content: textOf(message.content),
|
|
173
|
+
...(message.isError ? { is_error: true } : {}),
|
|
174
|
+
};
|
|
175
|
+
const last = out.at(-1);
|
|
176
|
+
if (last?.role === "user")
|
|
177
|
+
last.content.push(block);
|
|
178
|
+
else
|
|
179
|
+
out.push({ role: "user", content: [block] });
|
|
180
|
+
}
|
|
181
|
+
else if (message.role === "assistant") {
|
|
182
|
+
const content = [];
|
|
183
|
+
const spoken = textOf(message.content);
|
|
184
|
+
if (spoken)
|
|
185
|
+
content.push({ type: "text", text: spoken });
|
|
186
|
+
for (const call of message.calls ?? []) {
|
|
187
|
+
content.push({ type: "tool_use", id: call.callId, name: call.name, input: safeJson(call.arguments) });
|
|
188
|
+
}
|
|
189
|
+
out.push({ role: "assistant", content });
|
|
190
|
+
}
|
|
191
|
+
else if (message.role === "system") {
|
|
192
|
+
// Turn-scoped context, kept where the projection put it: an operator
|
|
193
|
+
// instruction inside the conversation leaves the cached prefix intact,
|
|
194
|
+
// where rewriting the front of it would invalidate every following turn.
|
|
195
|
+
out.push({ role: "system", content: encodeContent(message.content) });
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
out.push({ role: "user", content: encodeContent(message.content) });
|
|
199
|
+
}
|
|
200
|
+
if (index === cacheAt)
|
|
201
|
+
mark = out.at(-1)?.content;
|
|
202
|
+
});
|
|
203
|
+
const block = mark?.at(-1);
|
|
204
|
+
if (block)
|
|
205
|
+
block["cache_control"] = { type: "ephemeral" };
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
208
|
+
function encodeContent(content) {
|
|
209
|
+
if (typeof content === "string")
|
|
210
|
+
return [{ type: "text", text: content }];
|
|
211
|
+
const parts = [];
|
|
212
|
+
for (const part of content) {
|
|
213
|
+
if (part.type === "text")
|
|
214
|
+
parts.push({ type: "text", text: part.text });
|
|
215
|
+
if (part.type === "image") {
|
|
216
|
+
parts.push(part.source.kind === "url"
|
|
217
|
+
? { type: "image", source: { type: "url", url: part.source.url } }
|
|
218
|
+
: { type: "image", source: { type: "base64", media_type: part.mediaType, data: part.source.data } });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return parts;
|
|
222
|
+
}
|
|
223
|
+
const encodeTool = (tool) => ({
|
|
224
|
+
name: tool.name, description: tool.description, input_schema: tool.parameters,
|
|
225
|
+
});
|
|
226
|
+
const safeJson = (raw) => { try {
|
|
227
|
+
return JSON.parse(raw);
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return {};
|
|
231
|
+
} };
|
|
232
|
+
const decodeUsage = (usage) => usage ? {
|
|
233
|
+
...(usage.input_tokens !== undefined ? { inputTokens: usage.input_tokens } : {}),
|
|
234
|
+
...(usage.output_tokens !== undefined ? { outputTokens: usage.output_tokens } : {}),
|
|
235
|
+
...(usage.cache_read_input_tokens !== undefined ? { cacheReadTokens: usage.cache_read_input_tokens } : {}),
|
|
236
|
+
...(usage.cache_creation_input_tokens !== undefined ? { cacheWriteTokens: usage.cache_creation_input_tokens } : {}),
|
|
237
|
+
} : {};
|
|
238
|
+
async function httpError(response) {
|
|
239
|
+
const body = await response.text().catch(() => "");
|
|
240
|
+
const code = response.status === 401 || response.status === 403 ? "auth"
|
|
241
|
+
: response.status === 429 ? "rate-limit"
|
|
242
|
+
: response.status === 400 && /prompt is too long|context/i.test(body) ? "context-length"
|
|
243
|
+
: response.status >= 500 ? "provider"
|
|
244
|
+
: "failed";
|
|
245
|
+
return {
|
|
246
|
+
code,
|
|
247
|
+
message: `${response.status} ${response.statusText}${body ? `: ${body.slice(0, 400)}` : ""}`,
|
|
248
|
+
retryable: code === "rate-limit" || code === "provider",
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function transportError(error, signal) {
|
|
252
|
+
if (signal?.aborted)
|
|
253
|
+
return { code: "cancelled", message: "Generation cancelled", retryable: false };
|
|
254
|
+
return { code: "provider", message: error instanceof Error ? error.message : String(error), retryable: true };
|
|
255
|
+
}
|
|
256
|
+
async function* sseData(body) {
|
|
257
|
+
const decoder = new TextDecoder();
|
|
258
|
+
let buffer = "";
|
|
259
|
+
for await (const chunk of body) {
|
|
260
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
261
|
+
let newline = buffer.indexOf("\n");
|
|
262
|
+
while (newline >= 0) {
|
|
263
|
+
const line = buffer.slice(0, newline).trim();
|
|
264
|
+
buffer = buffer.slice(newline + 1);
|
|
265
|
+
if (line.startsWith("data:"))
|
|
266
|
+
yield line.slice(5).trim();
|
|
267
|
+
newline = buffer.indexOf("\n");
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/model/adapters/anthropic/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAU7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAyB;IAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,8BAA8B,CAAC;IAElE,OAAO;QACL,EAAE,EAAE,aAAa,OAAO,CAAC,KAAK,EAAE;QAEhC,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAqB;YACnC,yEAAyE;YACzE,iEAAiE;YACjE,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,OAAO,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAE,CAAC,IAAI,KAAK,QAAQ;gBAAE,IAAI,IAAI,CAAC,CAAC;YAC9F,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YACzF,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAElD,yEAAyE;YACzE,sEAAsE;YACtE,mEAAmE;YACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;YACpC,MAAM,WAAW,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YACpF,MAAM,OAAO,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAErF,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,MAAM,CAAC;YAE1D,IAAI,QAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,OAAO,WAAW,EAAE;oBAC3C,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,WAAW,EAAE,OAAO,CAAC,MAAM;wBAC3B,mBAAmB,EAAE,OAAO,CAAC,OAAO,IAAI,YAAY;qBACrD;oBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,UAAU,EAAE,eAAe;wBAC3B,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACvE,QAAQ,EAAE,kBAAkB,CAAC,YAAY,EAAE,OAAO,CAAC;wBACnD,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC1E,GAAG,CAAC,OAAO,CAAC,MAAM;4BAChB,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE;4BAC/E,CAAC,CAAC,EAAE,CAAC;wBACP,MAAM,EAAE,IAAI;qBACb,CAAC;oBACF,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACtD,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,OAAO,GAAG,CAAC,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEnG,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAe,EAAE,CAAC;YAC7B,IAAI,OAAO,GAAG,EAAE,CAAC;YACjB,IAAI,IAAwB,CAAC;YAC7B,IAAI,KAAK,GAAU,EAAE,CAAC;YACtB,IAAI,KAAyB,CAAC;YAE9B,0EAA0E;YAC1E,6EAA6E;YAC7E,2EAA2E;YAC3E,4EAA4E;YAC5E,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjD,IAAI,KAAqB,CAAC;oBAC1B,IAAI,CAAC;wBAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAmB,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC;wBAAC,SAAS;oBAAC,CAAC;oBAExE,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;wBACpD,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;wBAC5B,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC5D,CAAC;oBACD,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,IAAI,KAAK,CAAC,aAAa,EAAE,IAAI,KAAK,UAAU,EAAE,CAAC;wBACrF,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,EAAG,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,IAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;wBAChG,OAAO,GAAG,EAAE,CAAC;oBACf,CAAC;oBACD,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;wBACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAM,CAAC;wBAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;4BAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAAC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;wBAAC,CAAC;wBACzH,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,QAAQ;4BAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;wBAC/G,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;4BAC1E,OAAO,IAAI,KAAK,CAAC,YAAY,CAAC;4BAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC7B,IAAI,OAAO;gCAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC;wBACxG,CAAC;oBACH,CAAC;oBACD,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;wBACxD,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC;wBAC9B,IAAI,CAAC,OAAO,CAAC,SAAS;4BAAE,OAAO,CAAC,SAAS,GAAG,OAAO,IAAI,IAAI,CAAC;oBAC9D,CAAC;oBACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;wBACnC,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,WAAW,IAAI,IAAI,CAAC;wBACxC,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBACpD,CAAC;oBACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;wBAC3B,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBACvG,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,OAAO,EAAE,CAAC;gBACR,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;gBACvE,YAAY,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM;gBACtH,KAAK;gBACL,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5B,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,MAAyB,EAAE,KAAc;IAC7D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,GAAG,CAAC,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1F,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAAC,QAA4B,EAAE,OAAO,GAAG,CAAC,CAAC;IACpE,MAAM,GAAG,GAA2C,EAAE,CAAC;IACvD,IAAI,IAA2B,CAAC;IAEhC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QAClC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG;gBACZ,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBAClF,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/C,CAAC;YACF,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,IAAI,EAAE,IAAI,KAAK,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;gBAC/C,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACxC,MAAM,OAAO,GAAc,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACzD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBACvC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACxG,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,qEAAqE;YACrE,uEAAuE;YACvE,yEAAyE;YACzE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,KAAK,KAAK,OAAO;YAAE,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAwC,CAAC;IAClE,IAAI,KAAK;QAAE,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,OAA2B;IAChD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,OAAiC,EAAE,CAAC;QACrD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK;gBACnC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE;gBAClE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU;CAC9E,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAW,EAAE,GAAG,IAAI,CAAC;IAAC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAAC,CAAC;AAAC,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC;AAAC,CAAC,CAAC,CAAC,CAAC;AAEpG,MAAM,WAAW,GAAG,CAAC,KAAiC,EAAS,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,GAAG,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,GAAG,CAAC,KAAK,CAAC,uBAAuB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,GAAG,CAAC,KAAK,CAAC,2BAA2B,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CACpH,CAAC,CAAC,CAAC,EAAE,CAAC;AAEP,KAAK,UAAU,SAAS,CAAC,QAAkB;IACzC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,IAAI,GACR,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM;QAC3D,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY;YACxC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB;gBACxF,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU;oBACrC,CAAC,CAAC,QAAQ,CAAC;IACb,OAAO;QACL,IAAI;QACJ,OAAO,EAAE,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5F,SAAS,EAAE,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,UAAU;KACxD,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAc,EAAE,MAAoB;IAC1D,IAAI,MAAM,EAAE,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACrG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAChH,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,IAAgC;IACtD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAA4C,EAAE,CAAC;QACvE,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,OAAO,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACzD,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type {\n ContentPart, Message, Model, ModelDelta, ModelError, ModelRequest, ModelResponse, ToolCall, ToolSpec, Usage,\n} from \"../../model.js\";\nimport { err, ok, type Result } from \"../../../result.js\";\nimport { textOf } from \"../../../content.js\";\n\nexport interface AnthropicOptions {\n apiKey: string;\n model: string;\n baseUrl?: string;\n version?: string;\n fetch?: typeof fetch;\n}\n\n/**\n * The Anthropic Messages wire.\n *\n * A genuinely different shape from OpenAI's — the leading system prompt hoisted\n * out of the message list, tool results carried as user content blocks, cache\n * breakpoints marked inline — which is the point of it being here: a port\n * proved against one wire format has not been proved.\n *\n * Three things this wire will refuse, and what we send instead:\n *\n * - **Thinking budgets.** `thinking: { type: \"enabled\", budget_tokens }` is\n * removed on the current models and returns 400. Depth is `output_config.effort`\n * over adaptive thinking, so `effort` maps there and nothing computes a budget.\n * - **Sampling controls.** `temperature`, `top_p` and `top_k` are removed on the\n * same models. `ModelRequest.temperature` is therefore dropped here rather\n * than forwarded into a request the provider rejects.\n * - **A system message in the middle of a turn.** Only the *leading* run of\n * system messages becomes the `system` field. One arriving after the\n * conversation has started is turn-scoped context, which the projection\n * deliberately places after the cache boundary, so it stays in `messages` as\n * a mid-conversation system message. Hoisting it would put the one thing that\n * changes every turn at the front of the prefix that must not change.\n * Supported on Opus 5, Opus 4.8 and Fable 5; a model without it fails the\n * request rather than silently having its cache invalidated every turn.\n */\nexport function createAnthropicModel(options: AnthropicOptions): Model {\n const call = options.fetch ?? fetch;\n const baseUrl = options.baseUrl ?? \"https://api.anthropic.com/v1\";\n\n return {\n id: `anthropic:${options.model}`,\n\n async *generate(request: ModelRequest): AsyncGenerator<ModelDelta, Result<ModelResponse, ModelError>> {\n // Only the leading run of system messages is the system prompt. Anything\n // after it belongs where the projection put it — see the header.\n let lead = 0;\n while (lead < request.messages.length && request.messages[lead]!.role === \"system\") lead += 1;\n const system = request.messages.slice(0, lead).map((message) => textOf(message.content));\n const conversation = request.messages.slice(lead);\n\n // The prefix ends where the caller says it does. In practice that is the\n // end of the system prompt, which is the one span fixed for the whole\n // run; a mark past it is honoured too rather than quietly ignored.\n const boundary = request.cacheAfter;\n const cacheSystem = boundary !== undefined && boundary >= lead && system.length > 0;\n const cacheAt = boundary !== undefined && boundary > lead ? boundary - lead - 1 : -1;\n\n const maxOutputTokens = request.maxOutputTokens ?? 32_000;\n\n let response: Response;\n try {\n response = await call(`${baseUrl}/messages`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": options.apiKey,\n \"anthropic-version\": options.version ?? \"2023-06-01\",\n },\n body: JSON.stringify({\n model: options.model,\n max_tokens: maxOutputTokens,\n ...(system.length ? { system: encodeSystem(system, cacheSystem) } : {}),\n messages: encodeConversation(conversation, cacheAt),\n ...(request.tools?.length ? { tools: request.tools.map(encodeTool) } : {}),\n ...(request.effort\n ? { thinking: { type: \"adaptive\" }, output_config: { effort: request.effort } }\n : {}),\n stream: true,\n }),\n ...(request.signal ? { signal: request.signal } : {}),\n });\n } catch (error) {\n return err(transportError(error, request.signal));\n }\n if (!response.ok) return err(await httpError(response));\n if (!response.body) return err({ code: \"provider\", message: \"No response body\", retryable: true });\n\n const text: string[] = [];\n const calls: ToolCall[] = [];\n let partial = \"\";\n let stop: string | undefined;\n let usage: Usage = {};\n let model: string | undefined;\n\n // A stream that dies mid-body — cancelled, dropped, truncated — must come\n // back as a typed failure like any other. Without this the generator throws,\n // `run.result` rejects instead of resolving `cancelled`, no `run.finished`\n // is ever committed, and the activation stays open until its claim expires.\n try {\n for await (const event of sseData(response.body)) {\n let frame: AnthropicFrame;\n try { frame = JSON.parse(event) as AnthropicFrame; } catch { continue; }\n\n if (frame.type === \"message_start\" && frame.message) {\n model = frame.message.model;\n usage = { ...usage, ...decodeUsage(frame.message.usage) };\n }\n if (frame.type === \"content_block_start\" && frame.content_block?.type === \"tool_use\") {\n calls.push({ callId: frame.content_block.id!, name: frame.content_block.name!, arguments: \"\" });\n partial = \"\";\n }\n if (frame.type === \"content_block_delta\") {\n const delta = frame.delta!;\n if (delta.type === \"text_delta\" && delta.text) { text.push(delta.text); yield { type: \"text.delta\", text: delta.text }; }\n if (delta.type === \"thinking_delta\" && delta.thinking) yield { type: \"reasoning.delta\", text: delta.thinking };\n if (delta.type === \"input_json_delta\" && delta.partial_json !== undefined) {\n partial += delta.partial_json;\n const current = calls.at(-1);\n if (current) yield { type: \"tool-call.delta\", callId: current.callId, arguments: delta.partial_json };\n }\n }\n if (frame.type === \"content_block_stop\" && calls.length) {\n const current = calls.at(-1)!;\n if (!current.arguments) current.arguments = partial || \"{}\";\n }\n if (frame.type === \"message_delta\") {\n stop = frame.delta?.stop_reason ?? stop;\n usage = { ...usage, ...decodeUsage(frame.usage) };\n }\n if (frame.type === \"error\") {\n return err({ code: \"provider\", message: frame.error?.message ?? \"Provider error\", retryable: true });\n }\n }\n } catch (error) {\n return err(transportError(error, request.signal));\n }\n\n return ok({\n message: { content: text.join(\"\"), ...(calls.length ? { calls } : {}) },\n finishReason: stop === \"max_tokens\" ? \"length\" : stop === \"refusal\" ? \"refusal\" : calls.length ? \"tool-calls\" : \"stop\",\n usage,\n ...(model ? { model } : {}),\n });\n },\n };\n}\n\n/**\n * Text blocks rather than one joined string, so the end of the prefix can carry\n * a breakpoint. Only the last block is marked: a breakpoint caches everything\n * before it, so marking each one would buy nothing and spend the budget of four.\n */\nfunction encodeSystem(blocks: readonly string[], cache: boolean): unknown[] {\n return blocks.map((text, index) => ({\n type: \"text\",\n text,\n ...(cache && index === blocks.length - 1 ? { cache_control: { type: \"ephemeral\" } } : {}),\n }));\n}\n\n/**\n * Tool results are user-role content blocks here, not a role of their own.\n *\n * `cacheAt` is an index into `messages`; the breakpoint lands on the last\n * content block that message produced. Tool results merge into a preceding user\n * block, so the mapping from message to block is not one to one and the mark is\n * placed as each message is encoded rather than computed afterwards.\n */\nfunction encodeConversation(messages: readonly Message[], cacheAt = -1): unknown[] {\n const out: { role: string; content: unknown[] }[] = [];\n let mark: unknown[] | undefined;\n\n messages.forEach((message, index) => {\n if (message.role === \"tool\") {\n const block = {\n type: \"tool_result\", tool_use_id: message.callId, content: textOf(message.content),\n ...(message.isError ? { is_error: true } : {}),\n };\n const last = out.at(-1);\n if (last?.role === \"user\") last.content.push(block);\n else out.push({ role: \"user\", content: [block] });\n } else if (message.role === \"assistant\") {\n const content: unknown[] = [];\n const spoken = textOf(message.content);\n if (spoken) content.push({ type: \"text\", text: spoken });\n for (const call of message.calls ?? []) {\n content.push({ type: \"tool_use\", id: call.callId, name: call.name, input: safeJson(call.arguments) });\n }\n out.push({ role: \"assistant\", content });\n } else if (message.role === \"system\") {\n // Turn-scoped context, kept where the projection put it: an operator\n // instruction inside the conversation leaves the cached prefix intact,\n // where rewriting the front of it would invalidate every following turn.\n out.push({ role: \"system\", content: encodeContent(message.content) });\n } else {\n out.push({ role: \"user\", content: encodeContent(message.content) });\n }\n if (index === cacheAt) mark = out.at(-1)?.content;\n });\n\n const block = mark?.at(-1) as Record<string, unknown> | undefined;\n if (block) block[\"cache_control\"] = { type: \"ephemeral\" };\n return out;\n}\n\nfunction encodeContent(content: Message[\"content\"]): unknown[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n const parts: unknown[] = [];\n for (const part of content as readonly ContentPart[]) {\n if (part.type === \"text\") parts.push({ type: \"text\", text: part.text });\n if (part.type === \"image\") {\n parts.push(part.source.kind === \"url\"\n ? { type: \"image\", source: { type: \"url\", url: part.source.url } }\n : { type: \"image\", source: { type: \"base64\", media_type: part.mediaType, data: part.source.data } });\n }\n }\n return parts;\n}\n\nconst encodeTool = (tool: ToolSpec) => ({\n name: tool.name, description: tool.description, input_schema: tool.parameters,\n});\n\nconst safeJson = (raw: string): unknown => { try { return JSON.parse(raw); } catch { return {}; } };\n\nconst decodeUsage = (usage: AnthropicUsage | undefined): Usage => usage ? {\n ...(usage.input_tokens !== undefined ? { inputTokens: usage.input_tokens } : {}),\n ...(usage.output_tokens !== undefined ? { outputTokens: usage.output_tokens } : {}),\n ...(usage.cache_read_input_tokens !== undefined ? { cacheReadTokens: usage.cache_read_input_tokens } : {}),\n ...(usage.cache_creation_input_tokens !== undefined ? { cacheWriteTokens: usage.cache_creation_input_tokens } : {}),\n} : {};\n\nasync function httpError(response: Response): Promise<ModelError> {\n const body = await response.text().catch(() => \"\");\n const code: ModelError[\"code\"] =\n response.status === 401 || response.status === 403 ? \"auth\"\n : response.status === 429 ? \"rate-limit\"\n : response.status === 400 && /prompt is too long|context/i.test(body) ? \"context-length\"\n : response.status >= 500 ? \"provider\"\n : \"failed\";\n return {\n code,\n message: `${response.status} ${response.statusText}${body ? `: ${body.slice(0, 400)}` : \"\"}`,\n retryable: code === \"rate-limit\" || code === \"provider\",\n };\n}\n\nfunction transportError(error: unknown, signal?: AbortSignal): ModelError {\n if (signal?.aborted) return { code: \"cancelled\", message: \"Generation cancelled\", retryable: false };\n return { code: \"provider\", message: error instanceof Error ? error.message : String(error), retryable: true };\n}\n\nasync function* sseData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n for await (const chunk of body as unknown as AsyncIterable<Uint8Array>) {\n buffer += decoder.decode(chunk, { stream: true });\n let newline = buffer.indexOf(\"\\n\");\n while (newline >= 0) {\n const line = buffer.slice(0, newline).trim();\n buffer = buffer.slice(newline + 1);\n if (line.startsWith(\"data:\")) yield line.slice(5).trim();\n newline = buffer.indexOf(\"\\n\");\n }\n }\n}\n\ninterface AnthropicUsage {\n input_tokens?: number; output_tokens?: number;\n cache_read_input_tokens?: number; cache_creation_input_tokens?: number;\n}\ninterface AnthropicFrame {\n type: string;\n message?: { model?: string; usage?: AnthropicUsage };\n content_block?: { type: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; thinking?: string; partial_json?: string; stop_reason?: string };\n usage?: AnthropicUsage;\n error?: { message?: string };\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Model, ToolCall, Usage } from "../../model.js";
|
|
2
|
+
export interface FakeResponse {
|
|
3
|
+
text?: string;
|
|
4
|
+
calls?: readonly ToolCall[];
|
|
5
|
+
usage?: Usage;
|
|
6
|
+
/** Which model the provider says answered. Absent, like a provider that does not say. */
|
|
7
|
+
model?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Why the turn ended, where the response's own shape cannot say.
|
|
10
|
+
*
|
|
11
|
+
* Only these two: `stop` and `tool-calls` are already determined by whether
|
|
12
|
+
* there are calls, and a second way to say them would be a second answer to
|
|
13
|
+
* one question. Being cut off at the ceiling or declined by the provider is a
|
|
14
|
+
* fact nothing else here expresses — and without it the loop's two branches
|
|
15
|
+
* for exactly those endings are unreachable from any test.
|
|
16
|
+
*/
|
|
17
|
+
finishReason?: "length" | "refusal";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns the given responses in order.
|
|
21
|
+
*
|
|
22
|
+
* Deliberately dumb. It is a real implementation of the port — so it runs the
|
|
23
|
+
* same conformance the providers do — and it has exactly one way to express
|
|
24
|
+
* each fact. Running out of responses is an error, never a repeat: a fake more
|
|
25
|
+
* forgiving than reality quietly makes tests pass that should not.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createFakeModel(responses: readonly FakeResponse[]): Model;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { err, ok } from "../../../result.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the given responses in order.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately dumb. It is a real implementation of the port — so it runs the
|
|
6
|
+
* same conformance the providers do — and it has exactly one way to express
|
|
7
|
+
* each fact. Running out of responses is an error, never a repeat: a fake more
|
|
8
|
+
* forgiving than reality quietly makes tests pass that should not.
|
|
9
|
+
*/
|
|
10
|
+
export function createFakeModel(responses) {
|
|
11
|
+
let cursor = 0;
|
|
12
|
+
return {
|
|
13
|
+
id: "fake",
|
|
14
|
+
async *generate({ signal }) {
|
|
15
|
+
if (signal?.aborted)
|
|
16
|
+
return err({ code: "cancelled", message: "Generation cancelled", retryable: false });
|
|
17
|
+
const response = responses[cursor];
|
|
18
|
+
cursor += 1;
|
|
19
|
+
if (!response) {
|
|
20
|
+
return err({
|
|
21
|
+
code: "provider",
|
|
22
|
+
message: `Fake model has no response for call ${cursor}; it was given ${responses.length}`,
|
|
23
|
+
retryable: false,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (response.text)
|
|
27
|
+
yield { type: "text.delta", text: response.text };
|
|
28
|
+
return ok({
|
|
29
|
+
message: { content: response.text ?? "", ...(response.calls?.length ? { calls: response.calls } : {}) },
|
|
30
|
+
finishReason: response.finishReason ?? (response.calls?.length ? "tool-calls" : "stop"),
|
|
31
|
+
usage: response.usage ?? {},
|
|
32
|
+
...(response.model ? { model: response.model } : {}),
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/model/adapters/fake/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,oBAAoB,CAAC;AAoB1D;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,SAAkC;IAChE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO;QACL,EAAE,EAAE,MAAM;QACV,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE;YACxB,IAAI,MAAM,EAAE,OAAO;gBAAE,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1G,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,CAAC;YACZ,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,GAAG,CAAC;oBACT,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,uCAAuC,MAAM,kBAAkB,SAAS,CAAC,MAAM,EAAE;oBAC1F,SAAS,EAAE,KAAK;iBACjB,CAAC,CAAC;YACL,CAAC;YACD,IAAI,QAAQ,CAAC,IAAI;gBAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrE,OAAO,EAAE,CAAC;gBACR,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;gBACvG,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;gBACvF,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE;gBAC3B,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Model, ModelDelta, ModelError, ModelResponse, ToolCall, Usage } from \"../../model.js\";\nimport { err, ok, type Result } from \"../../../result.js\";\n\nexport interface FakeResponse {\n text?: string;\n calls?: readonly ToolCall[];\n usage?: Usage;\n /** Which model the provider says answered. Absent, like a provider that does not say. */\n model?: string;\n /**\n * Why the turn ended, where the response's own shape cannot say.\n *\n * Only these two: `stop` and `tool-calls` are already determined by whether\n * there are calls, and a second way to say them would be a second answer to\n * one question. Being cut off at the ceiling or declined by the provider is a\n * fact nothing else here expresses — and without it the loop's two branches\n * for exactly those endings are unreachable from any test.\n */\n finishReason?: \"length\" | \"refusal\";\n}\n\n/**\n * Returns the given responses in order.\n *\n * Deliberately dumb. It is a real implementation of the port — so it runs the\n * same conformance the providers do — and it has exactly one way to express\n * each fact. Running out of responses is an error, never a repeat: a fake more\n * forgiving than reality quietly makes tests pass that should not.\n */\nexport function createFakeModel(responses: readonly FakeResponse[]): Model {\n let cursor = 0;\n return {\n id: \"fake\",\n async *generate({ signal }): AsyncGenerator<ModelDelta, Result<ModelResponse, ModelError>> {\n if (signal?.aborted) return err({ code: \"cancelled\", message: \"Generation cancelled\", retryable: false });\n const response = responses[cursor];\n cursor += 1;\n if (!response) {\n return err({\n code: \"provider\",\n message: `Fake model has no response for call ${cursor}; it was given ${responses.length}`,\n retryable: false,\n });\n }\n if (response.text) yield { type: \"text.delta\", text: response.text };\n return ok({\n message: { content: response.text ?? \"\", ...(response.calls?.length ? { calls: response.calls } : {}) },\n finishReason: response.finishReason ?? (response.calls?.length ? \"tool-calls\" : \"stop\"),\n usage: response.usage ?? {},\n ...(response.model ? { model: response.model } : {}),\n });\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Model } from "../../model.js";
|
|
2
|
+
export interface OpenAiCompatibleOptions {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
model: string;
|
|
6
|
+
headers?: Readonly<Record<string, string>>;
|
|
7
|
+
/**
|
|
8
|
+
* How this endpoint spells reasoning effort. OpenAI takes `reasoning_effort`;
|
|
9
|
+
* OpenRouter takes `reasoning: { effort }` and forwards it to whoever is
|
|
10
|
+
* serving the model. Sending both is not compatibility — OpenAI rejects the
|
|
11
|
+
* request outright — so the dialect is declared rather than guessed.
|
|
12
|
+
*/
|
|
13
|
+
effortParameter?: "reasoning_effort" | "reasoning" | "none";
|
|
14
|
+
/** Injectable for tests; defaults to global fetch. */
|
|
15
|
+
fetch?: typeof fetch;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The OpenAI chat-completions wire, which almost every provider now speaks —
|
|
19
|
+
* OpenRouter, Together, Groq, vLLM, Ollama. One adapter, one base URL.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createOpenAiCompatibleModel(options: OpenAiCompatibleOptions): Model;
|
|
22
|
+
/** OpenRouter is this wire with a fixed base URL and attribution headers. */
|
|
23
|
+
export declare function createOpenRouterModel(input: {
|
|
24
|
+
apiKey: string;
|
|
25
|
+
model: string;
|
|
26
|
+
appUrl?: string;
|
|
27
|
+
appName?: string;
|
|
28
|
+
fetch?: typeof fetch;
|
|
29
|
+
}): Model;
|