@qwen-code/arena-agent 0.0.6 → 0.0.7-preview.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/.env.example +12 -19
- package/README.md +26 -133
- package/dist/agent.d.ts +3 -9
- package/dist/agent.js +108 -246
- package/dist/agent.js.map +1 -1
- package/dist/cli.js +12 -51
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -6
- package/dist/config.js +2 -28
- package/dist/config.js.map +1 -1
- package/dist/fetch-page.js +7 -18
- package/dist/fetch-page.js.map +1 -1
- package/dist/history.d.ts +3 -3
- package/dist/history.js +4 -4
- package/dist/history.js.map +1 -1
- package/dist/mock.js +9 -25
- package/dist/mock.js.map +1 -1
- package/dist/prompts.d.ts +4 -0
- package/dist/prompts.js +57 -0
- package/dist/prompts.js.map +1 -0
- package/dist/protocol.d.ts +2 -4
- package/dist/protocol.js +1 -17
- package/dist/protocol.js.map +1 -1
- package/dist/provider.d.ts +0 -4
- package/dist/provider.js +11 -169
- package/dist/provider.js.map +1 -1
- package/dist/repo.d.ts +4 -0
- package/dist/repo.js +84 -0
- package/dist/repo.js.map +1 -0
- package/dist/server.js +184 -26
- package/dist/server.js.map +1 -1
- package/dist/spec.d.ts +11 -6
- package/dist/spec.js +74 -123
- package/dist/spec.js.map +1 -1
- package/dist/tools.d.ts +2 -5
- package/dist/tools.js +237 -134
- package/dist/tools.js.map +1 -1
- package/dist/tui.js +18 -53
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +24 -25
- package/dist/web/app.js +3 -2
- package/dist/web/app.js.map +1 -1
- package/docs/SDK.md +521 -0
- package/package.json +5 -4
- package/spec/tools.json +418 -0
- package/dist/anthropic.d.ts +0 -16
- package/dist/anthropic.js +0 -391
- package/dist/anthropic.js.map +0 -1
- package/dist/attachments.d.ts +0 -29
- package/dist/attachments.js +0 -222
- package/dist/attachments.js.map +0 -1
- package/dist/canonical-data.d.ts +0 -2
- package/dist/canonical-data.js +0 -4
- package/dist/canonical-data.js.map +0 -1
- package/dist/compaction.d.ts +0 -16
- package/dist/compaction.js +0 -182
- package/dist/compaction.js.map +0 -1
package/dist/anthropic.js
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
const dataUriPattern = /^data:([^;,]+);base64,(.+)$/s;
|
|
2
|
-
function imageBlock(image) {
|
|
3
|
-
const match = dataUriPattern.exec(image);
|
|
4
|
-
if (match) {
|
|
5
|
-
return {
|
|
6
|
-
type: "image",
|
|
7
|
-
source: { type: "base64", media_type: match[1], data: match[2] },
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
return { type: "image", source: { type: "url", url: image } };
|
|
11
|
-
}
|
|
12
|
-
function parseToolInput(argumentsText) {
|
|
13
|
-
try {
|
|
14
|
-
const parsed = JSON.parse(argumentsText);
|
|
15
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
16
|
-
return parsed;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
// Malformed tool arguments become an empty input object.
|
|
21
|
-
}
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
export function anthropicMessages(messages, includeThinking) {
|
|
25
|
-
const systemParts = [];
|
|
26
|
-
const converted = [];
|
|
27
|
-
// The Messages API wants tool results and any follow-up user content in a
|
|
28
|
-
// single user turn, so consecutive same-role messages are merged.
|
|
29
|
-
const push = (role, blocks) => {
|
|
30
|
-
if (!blocks.length)
|
|
31
|
-
return;
|
|
32
|
-
const last = converted.at(-1);
|
|
33
|
-
if (last && last.role === role)
|
|
34
|
-
last.content.push(...blocks);
|
|
35
|
-
else
|
|
36
|
-
converted.push({ role, content: blocks });
|
|
37
|
-
};
|
|
38
|
-
for (const message of messages) {
|
|
39
|
-
if (message.role === "system") {
|
|
40
|
-
if (message.content)
|
|
41
|
-
systemParts.push(message.content);
|
|
42
|
-
}
|
|
43
|
-
else if (message.role === "user") {
|
|
44
|
-
if (typeof message.content === "string") {
|
|
45
|
-
push("user", message.content ? [{ type: "text", text: message.content }] : []);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
const blocks = [];
|
|
49
|
-
for (const part of message.content) {
|
|
50
|
-
if ("image" in part)
|
|
51
|
-
blocks.push(imageBlock(part.image));
|
|
52
|
-
else if (part.text)
|
|
53
|
-
blocks.push({ type: "text", text: part.text });
|
|
54
|
-
}
|
|
55
|
-
push("user", blocks);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
else if (message.role === "assistant") {
|
|
59
|
-
const blocks = [];
|
|
60
|
-
// Signed thinking/redacted_thinking blocks must be replayed ahead of
|
|
61
|
-
// the turn's other content for tool-use continuations to validate.
|
|
62
|
-
// With thinking disabled the API rejects thinking blocks instead of
|
|
63
|
-
// requiring them, so they are only included when it is enabled.
|
|
64
|
-
// Unsigned thinking blocks (gateways like DashScope's /apps/anthropic
|
|
65
|
-
// emit signature: "") are never required for continuation — and that
|
|
66
|
-
// same gateway hangs when they come back — so only signed blocks,
|
|
67
|
-
// which real Anthropic validates and requires, go back on the wire.
|
|
68
|
-
if (includeThinking && Array.isArray(message.reasoning_details)) {
|
|
69
|
-
for (const block of message.reasoning_details) {
|
|
70
|
-
if (block.type === "thinking" && !block.signature)
|
|
71
|
-
continue;
|
|
72
|
-
blocks.push(block);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (message.content)
|
|
76
|
-
blocks.push({ type: "text", text: message.content });
|
|
77
|
-
for (const call of message.tool_calls || []) {
|
|
78
|
-
blocks.push({
|
|
79
|
-
type: "tool_use",
|
|
80
|
-
id: call.id,
|
|
81
|
-
name: call.function.name,
|
|
82
|
-
input: parseToolInput(call.function.arguments),
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
push("assistant", blocks);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
push("user", [
|
|
89
|
-
{
|
|
90
|
-
type: "tool_result",
|
|
91
|
-
tool_use_id: message.tool_call_id,
|
|
92
|
-
content: message.content,
|
|
93
|
-
},
|
|
94
|
-
]);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
system: systemParts.length ? systemParts.join("\n\n") : undefined,
|
|
99
|
-
messages: converted,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
export function anthropicRequestBody(request, model) {
|
|
103
|
-
const { system, messages } = anthropicMessages(request.messages, request.enableThinking);
|
|
104
|
-
const body = {
|
|
105
|
-
model,
|
|
106
|
-
max_tokens: request.maxTokens,
|
|
107
|
-
messages,
|
|
108
|
-
stream: true,
|
|
109
|
-
};
|
|
110
|
-
if (system)
|
|
111
|
-
body.system = system;
|
|
112
|
-
if (request.tools.length) {
|
|
113
|
-
body.tools = request.tools.map((tool) => ({
|
|
114
|
-
name: tool.function.name,
|
|
115
|
-
...(tool.function.description
|
|
116
|
-
? { description: tool.function.description }
|
|
117
|
-
: {}),
|
|
118
|
-
input_schema: tool.function.parameters,
|
|
119
|
-
}));
|
|
120
|
-
let choice = request.toolChoice === "none" ? "none" : "auto";
|
|
121
|
-
if (!request.enableThinking &&
|
|
122
|
-
(request.toolChoice === "any" || request.toolChoice === "required")) {
|
|
123
|
-
// Forced tool use is not supported alongside extended thinking.
|
|
124
|
-
choice = "any";
|
|
125
|
-
}
|
|
126
|
-
body.tool_choice = { type: choice };
|
|
127
|
-
}
|
|
128
|
-
if (request.enableThinking) {
|
|
129
|
-
// Extended thinking rejects temperature adjustments, so the configured
|
|
130
|
-
// temperature is only sent when thinking is off.
|
|
131
|
-
body.thinking = { type: "enabled", budget_tokens: request.thinkingBudget };
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
body.temperature = request.temperature;
|
|
135
|
-
}
|
|
136
|
-
return body;
|
|
137
|
-
}
|
|
138
|
-
async function* sseJsonEvents(stream) {
|
|
139
|
-
const reader = stream.getReader();
|
|
140
|
-
const decoder = new TextDecoder();
|
|
141
|
-
let buffer = "";
|
|
142
|
-
const framePayload = (frame) => frame
|
|
143
|
-
.split("\n")
|
|
144
|
-
.filter((line) => line.startsWith("data:"))
|
|
145
|
-
.map((line) => line.slice(5).trimStart())
|
|
146
|
-
.join("\n");
|
|
147
|
-
while (true) {
|
|
148
|
-
const { done, value } = await reader.read();
|
|
149
|
-
buffer += decoder.decode(value, { stream: !done }).replace(/\r\n/g, "\n");
|
|
150
|
-
let boundary = buffer.indexOf("\n\n");
|
|
151
|
-
while (boundary !== -1) {
|
|
152
|
-
const payload = framePayload(buffer.slice(0, boundary));
|
|
153
|
-
buffer = buffer.slice(boundary + 2);
|
|
154
|
-
if (payload)
|
|
155
|
-
yield JSON.parse(payload);
|
|
156
|
-
boundary = buffer.indexOf("\n\n");
|
|
157
|
-
}
|
|
158
|
-
if (done)
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
const payload = framePayload(buffer);
|
|
162
|
-
if (payload)
|
|
163
|
-
yield JSON.parse(payload);
|
|
164
|
-
}
|
|
165
|
-
function record(value) {
|
|
166
|
-
return value && typeof value === "object"
|
|
167
|
-
? value
|
|
168
|
-
: {};
|
|
169
|
-
}
|
|
170
|
-
function anthropicUsage(totals) {
|
|
171
|
-
if (totals.inputTokens === undefined && !totals.outputTokens)
|
|
172
|
-
return undefined;
|
|
173
|
-
const input = totals.inputTokens ?? 0;
|
|
174
|
-
// Anthropic's input_tokens excludes cache writes/reads; prompt_tokens is
|
|
175
|
-
// the OpenAI-style total input so downstream accounting can sum one field.
|
|
176
|
-
const prompt = input + totals.cacheCreation + totals.cacheRead;
|
|
177
|
-
const usage = {
|
|
178
|
-
prompt_tokens: prompt,
|
|
179
|
-
completion_tokens: totals.outputTokens,
|
|
180
|
-
total_tokens: prompt + totals.outputTokens,
|
|
181
|
-
input_tokens: input,
|
|
182
|
-
output_tokens: totals.outputTokens,
|
|
183
|
-
};
|
|
184
|
-
if (totals.cacheCreation)
|
|
185
|
-
usage.cache_creation_input_tokens = totals.cacheCreation;
|
|
186
|
-
if (totals.cacheRead)
|
|
187
|
-
usage.cache_read_input_tokens = totals.cacheRead;
|
|
188
|
-
return usage;
|
|
189
|
-
}
|
|
190
|
-
export async function* anthropicChunks(stream) {
|
|
191
|
-
let nextToolIndex = 0;
|
|
192
|
-
const toolIndexByBlock = new Map();
|
|
193
|
-
const blockTypes = new Map();
|
|
194
|
-
const thinkingText = new Map();
|
|
195
|
-
const thinkingSignature = new Map();
|
|
196
|
-
const reasoningDetails = [];
|
|
197
|
-
const totals = { outputTokens: 0, cacheCreation: 0, cacheRead: 0 };
|
|
198
|
-
for await (const event of sseJsonEvents(stream)) {
|
|
199
|
-
const type = String(event.type || "");
|
|
200
|
-
if (type === "error") {
|
|
201
|
-
const detail = record(event.error);
|
|
202
|
-
throw new Error(`Anthropic stream error: ${String(detail.message || JSON.stringify(detail))}`);
|
|
203
|
-
}
|
|
204
|
-
if (type === "message_start") {
|
|
205
|
-
const usage = record(record(event.message).usage);
|
|
206
|
-
if (typeof usage.input_tokens === "number") {
|
|
207
|
-
totals.inputTokens = usage.input_tokens;
|
|
208
|
-
}
|
|
209
|
-
if (typeof usage.output_tokens === "number") {
|
|
210
|
-
totals.outputTokens = usage.output_tokens;
|
|
211
|
-
}
|
|
212
|
-
if (typeof usage.cache_creation_input_tokens === "number") {
|
|
213
|
-
totals.cacheCreation = usage.cache_creation_input_tokens;
|
|
214
|
-
}
|
|
215
|
-
if (typeof usage.cache_read_input_tokens === "number") {
|
|
216
|
-
totals.cacheRead = usage.cache_read_input_tokens;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
else if (type === "content_block_start") {
|
|
220
|
-
const index = Number(event.index);
|
|
221
|
-
const block = record(event.content_block);
|
|
222
|
-
const kind = String(block.type || "");
|
|
223
|
-
blockTypes.set(index, kind);
|
|
224
|
-
if (kind === "tool_use") {
|
|
225
|
-
const toolIndex = nextToolIndex++;
|
|
226
|
-
toolIndexByBlock.set(index, toolIndex);
|
|
227
|
-
yield {
|
|
228
|
-
choices: [
|
|
229
|
-
{
|
|
230
|
-
delta: {
|
|
231
|
-
tool_calls: [
|
|
232
|
-
{
|
|
233
|
-
index: toolIndex,
|
|
234
|
-
id: String(block.id || ""),
|
|
235
|
-
type: "function",
|
|
236
|
-
function: { name: String(block.name || ""), arguments: "" },
|
|
237
|
-
},
|
|
238
|
-
],
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
],
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
else if (kind === "thinking") {
|
|
245
|
-
thinkingText.set(index, String(block.thinking || ""));
|
|
246
|
-
}
|
|
247
|
-
else if (kind === "redacted_thinking") {
|
|
248
|
-
reasoningDetails.push({ type: "redacted_thinking", data: block.data });
|
|
249
|
-
}
|
|
250
|
-
else if (kind === "text" && block.text) {
|
|
251
|
-
yield { choices: [{ delta: { content: String(block.text) } }] };
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
else if (type === "content_block_delta") {
|
|
255
|
-
const index = Number(event.index);
|
|
256
|
-
const delta = record(event.delta);
|
|
257
|
-
const kind = String(delta.type || "");
|
|
258
|
-
if (kind === "text_delta" && delta.text) {
|
|
259
|
-
yield { choices: [{ delta: { content: String(delta.text) } }] };
|
|
260
|
-
}
|
|
261
|
-
else if (kind === "thinking_delta" && delta.thinking) {
|
|
262
|
-
const value = String(delta.thinking);
|
|
263
|
-
thinkingText.set(index, (thinkingText.get(index) || "") + value);
|
|
264
|
-
yield { choices: [{ delta: { reasoning_content: value } }] };
|
|
265
|
-
}
|
|
266
|
-
else if (kind === "signature_delta" && delta.signature) {
|
|
267
|
-
thinkingSignature.set(index, (thinkingSignature.get(index) || "") + String(delta.signature));
|
|
268
|
-
}
|
|
269
|
-
else if (kind === "input_json_delta" &&
|
|
270
|
-
typeof delta.partial_json === "string" &&
|
|
271
|
-
delta.partial_json) {
|
|
272
|
-
const toolIndex = toolIndexByBlock.get(index);
|
|
273
|
-
if (toolIndex !== undefined) {
|
|
274
|
-
yield {
|
|
275
|
-
choices: [
|
|
276
|
-
{
|
|
277
|
-
delta: {
|
|
278
|
-
tool_calls: [
|
|
279
|
-
{
|
|
280
|
-
index: toolIndex,
|
|
281
|
-
function: { arguments: delta.partial_json },
|
|
282
|
-
},
|
|
283
|
-
],
|
|
284
|
-
},
|
|
285
|
-
},
|
|
286
|
-
],
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
else if (type === "content_block_stop") {
|
|
292
|
-
const index = Number(event.index);
|
|
293
|
-
if (blockTypes.get(index) === "thinking") {
|
|
294
|
-
reasoningDetails.push({
|
|
295
|
-
type: "thinking",
|
|
296
|
-
thinking: thinkingText.get(index) || "",
|
|
297
|
-
signature: thinkingSignature.get(index) || "",
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
else if (type === "message_delta") {
|
|
302
|
-
const usage = record(event.usage);
|
|
303
|
-
if (typeof usage.output_tokens === "number") {
|
|
304
|
-
totals.outputTokens = usage.output_tokens;
|
|
305
|
-
}
|
|
306
|
-
// Anthropic itself reports input tokens on message_start, but some
|
|
307
|
-
// Anthropic-compatible gateways (e.g. DashScope's claude-code-proxy)
|
|
308
|
-
// only provide them in the final message_delta. Positive values win so
|
|
309
|
-
// zero placeholders never clobber real counts.
|
|
310
|
-
if (typeof usage.input_tokens === "number" && usage.input_tokens > 0) {
|
|
311
|
-
totals.inputTokens = usage.input_tokens;
|
|
312
|
-
}
|
|
313
|
-
if (typeof usage.cache_creation_input_tokens === "number" &&
|
|
314
|
-
usage.cache_creation_input_tokens > 0) {
|
|
315
|
-
totals.cacheCreation = usage.cache_creation_input_tokens;
|
|
316
|
-
}
|
|
317
|
-
if (typeof usage.cache_read_input_tokens === "number" &&
|
|
318
|
-
usage.cache_read_input_tokens > 0) {
|
|
319
|
-
totals.cacheRead = usage.cache_read_input_tokens;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
// message_stop and ping carry nothing the accumulator needs.
|
|
323
|
-
}
|
|
324
|
-
const usage = anthropicUsage(totals);
|
|
325
|
-
if (usage || reasoningDetails.length) {
|
|
326
|
-
const final = { choices: [] };
|
|
327
|
-
if (usage)
|
|
328
|
-
final.usage = usage;
|
|
329
|
-
if (reasoningDetails.length)
|
|
330
|
-
final.reasoning_details = reasoningDetails;
|
|
331
|
-
yield final;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
export function anthropicFallbackChunk(value) {
|
|
335
|
-
const blocks = (Array.isArray(value.content) ? value.content : []);
|
|
336
|
-
const textParts = [];
|
|
337
|
-
const reasoningParts = [];
|
|
338
|
-
const toolCalls = [];
|
|
339
|
-
const reasoningDetails = [];
|
|
340
|
-
for (const block of blocks) {
|
|
341
|
-
if (block.type === "text" && block.text) {
|
|
342
|
-
textParts.push(String(block.text));
|
|
343
|
-
}
|
|
344
|
-
else if (block.type === "thinking") {
|
|
345
|
-
reasoningParts.push(String(block.thinking || ""));
|
|
346
|
-
reasoningDetails.push(block);
|
|
347
|
-
}
|
|
348
|
-
else if (block.type === "redacted_thinking") {
|
|
349
|
-
reasoningDetails.push(block);
|
|
350
|
-
}
|
|
351
|
-
else if (block.type === "tool_use") {
|
|
352
|
-
toolCalls.push({
|
|
353
|
-
index: toolCalls.length,
|
|
354
|
-
id: String(block.id || ""),
|
|
355
|
-
type: "function",
|
|
356
|
-
function: {
|
|
357
|
-
name: String(block.name || ""),
|
|
358
|
-
arguments: JSON.stringify(block.input ?? {}),
|
|
359
|
-
},
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
const rawUsage = record(value.usage);
|
|
364
|
-
const usage = anthropicUsage({
|
|
365
|
-
inputTokens: typeof rawUsage.input_tokens === "number" ? rawUsage.input_tokens : undefined,
|
|
366
|
-
outputTokens: typeof rawUsage.output_tokens === "number" ? rawUsage.output_tokens : 0,
|
|
367
|
-
cacheCreation: typeof rawUsage.cache_creation_input_tokens === "number"
|
|
368
|
-
? rawUsage.cache_creation_input_tokens
|
|
369
|
-
: 0,
|
|
370
|
-
cacheRead: typeof rawUsage.cache_read_input_tokens === "number"
|
|
371
|
-
? rawUsage.cache_read_input_tokens
|
|
372
|
-
: 0,
|
|
373
|
-
});
|
|
374
|
-
const chunk = {
|
|
375
|
-
choices: [
|
|
376
|
-
{
|
|
377
|
-
delta: {
|
|
378
|
-
content: textParts.join(""),
|
|
379
|
-
reasoning_content: reasoningParts.join(""),
|
|
380
|
-
...(toolCalls.length ? { tool_calls: toolCalls } : {}),
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
],
|
|
384
|
-
};
|
|
385
|
-
if (usage)
|
|
386
|
-
chunk.usage = usage;
|
|
387
|
-
if (reasoningDetails.length)
|
|
388
|
-
chunk.reasoning_details = reasoningDetails;
|
|
389
|
-
return chunk;
|
|
390
|
-
}
|
|
391
|
-
//# sourceMappingURL=anthropic.js.map
|
package/dist/anthropic.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../src/anthropic.ts"],"names":[],"mappings":"AAmBA,MAAM,cAAc,GAAG,8BAA8B,CAAC;AAEtD,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE;SACjE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,cAAc,CAAC,aAAqB;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAY,CAAC;QACpD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,MAAiC,CAAC;QAC3C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAmB,EACnB,eAAwB;IAExB,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,SAAS,GAAkC,EAAE,CAAC;IAEpD,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,IAAI,GAAG,CAAC,IAA0B,EAAE,MAAe,EAAQ,EAAE;QACjE,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO;QAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;;YACxD,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,OAAO,CAAC,OAAO;gBAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACnC,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACxC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACjF,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAY,EAAE,CAAC;gBAC3B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACnC,IAAI,OAAO,IAAI,IAAI;wBAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;yBACpD,IAAI,IAAI,CAAC,IAAI;wBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACrE,CAAC;gBACD,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACxC,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,qEAAqE;YACrE,mEAAmE;YACnE,oEAAoE;YACpE,gEAAgE;YAChE,sEAAsE;YACtE,qEAAqE;YACrE,kEAAkE;YAClE,oEAAoE;YACpE,IAAI,eAAe,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAChE,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,iBAA4B,EAAE,CAAC;oBACzD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,KAAK,CAAC,SAAS;wBAAE,SAAS;oBAC5D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;YACD,IAAI,OAAO,CAAC,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1E,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,UAAU;oBAChB,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;oBACxB,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;iBAC/C,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,EAAE;gBACX;oBACE,IAAI,EAAE,aAAa;oBACnB,WAAW,EAAE,OAAO,CAAC,YAAY;oBACjC,OAAO,EAAE,OAAO,CAAC,OAAO;iBACzB;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QACjE,QAAQ,EAAE,SAAS;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,OAAqB,EACrB,KAAa;IAEb,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAC5C,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,cAAc,CACvB,CAAC;IACF,MAAM,IAAI,GAA4B;QACpC,KAAK;QACL,UAAU,EAAE,OAAO,CAAC,SAAS;QAC7B,QAAQ;QACR,MAAM,EAAE,IAAI;KACb,CAAC;IACF,IAAI,MAAM;QAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACjC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACxB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW;gBAC3B,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;gBAC5C,CAAC,CAAC,EAAE,CAAC;YACP,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU;SACvC,CAAC,CAAC,CAAC;QACJ,IAAI,MAAM,GAAG,OAAO,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7D,IACE,CAAC,OAAO,CAAC,cAAc;YACvB,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK,IAAI,OAAO,CAAC,UAAU,KAAK,UAAU,CAAC,EACnE,CAAC;YACD,gEAAgE;YAChE,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,uEAAuE;QACvE,iDAAiD;QACjD,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;IAC7E,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,aAAa,CAC3B,MAAkC;IAElC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAC7C,KAAK;SACF,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;SAC1C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;SACxC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEhB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1E,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;YACxD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YACpC,IAAI,OAAO;gBAAE,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;YAClE,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,IAAI;YAAE,MAAM;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,OAAO;QAAE,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;AACpE,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QACvC,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AASD,SAAS,cAAc,CAAC,MAAmB;IACzC,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,OAAO,SAAS,CAAC;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;IACtC,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC;IAC/D,MAAM,KAAK,GAAe;QACxB,aAAa,EAAE,MAAM;QACrB,iBAAiB,EAAE,MAAM,CAAC,YAAY;QACtC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,YAAY;QAC1C,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,MAAM,CAAC,YAAY;KACnC,CAAC;IACF,IAAI,MAAM,CAAC,aAAa;QAAE,KAAK,CAAC,2BAA2B,GAAG,MAAM,CAAC,aAAa,CAAC;IACnF,IAAI,MAAM,CAAC,SAAS;QAAE,KAAK,CAAC,uBAAuB,GAAG,MAAM,CAAC,SAAS,CAAC;IACvE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,eAAe,CACpC,MAAkC;IAElC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC/C,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpD,MAAM,gBAAgB,GAAmC,EAAE,CAAC;IAC5D,MAAM,MAAM,GAAgB,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAEhF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAEtC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,2BAA2B,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAC9E,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC3C,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC;YAC1C,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC5C,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;YAC5C,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,2BAA2B,KAAK,QAAQ,EAAE,CAAC;gBAC1D,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC,2BAA2B,CAAC;YAC3D,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,uBAAuB,KAAK,QAAQ,EAAE,CAAC;gBACtD,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,uBAAuB,CAAC;YACnD,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACtC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5B,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;gBAClC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBACvC,MAAM;oBACJ,OAAO,EAAE;wBACP;4BACE,KAAK,EAAE;gCACL,UAAU,EAAE;oCACV;wCACE,KAAK,EAAE,SAAS;wCAChB,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;wCAC1B,IAAI,EAAE,UAAU;wCAChB,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;qCAC5D;iCACF;6BACF;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;iBAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC/B,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;YACxD,CAAC;iBAAM,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;gBACxC,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACzE,CAAC;iBAAM,IAAI,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACzC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAClE,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACtC,IAAI,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAClE,CAAC;iBAAM,IAAI,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACrC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;gBACjE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;YAC/D,CAAC;iBAAM,IAAI,IAAI,KAAK,iBAAiB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACzD,iBAAiB,CAAC,GAAG,CACnB,KAAK,EACL,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAC/D,CAAC;YACJ,CAAC;iBAAM,IACL,IAAI,KAAK,kBAAkB;gBAC3B,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ;gBACtC,KAAK,CAAC,YAAY,EAClB,CAAC;gBACD,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;oBAC5B,MAAM;wBACJ,OAAO,EAAE;4BACP;gCACE,KAAK,EAAE;oCACL,UAAU,EAAE;wCACV;4CACE,KAAK,EAAE,SAAS;4CAChB,QAAQ,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE;yCAC5C;qCACF;iCACF;6BACF;yBACF;qBACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,UAAU,EAAE,CAAC;gBACzC,gBAAgB,CAAC,IAAI,CAAC;oBACpB,IAAI,EAAE,UAAU;oBAChB,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;oBACvC,SAAS,EAAE,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC5C,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;YAC5C,CAAC;YACD,mEAAmE;YACnE,qEAAqE;YACrE,uEAAuE;YACvE,+CAA+C;YAC/C,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;gBACrE,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC;YAC1C,CAAC;YACD,IACE,OAAO,KAAK,CAAC,2BAA2B,KAAK,QAAQ;gBACrD,KAAK,CAAC,2BAA2B,GAAG,CAAC,EACrC,CAAC;gBACD,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC,2BAA2B,CAAC;YAC3D,CAAC;YACD,IACE,OAAO,KAAK,CAAC,uBAAuB,KAAK,QAAQ;gBACjD,KAAK,CAAC,uBAAuB,GAAG,CAAC,EACjC,CAAC;gBACD,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,uBAAuB,CAAC;YACnD,CAAC;QACH,CAAC;QACD,6DAA6D;IAC/D,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,KAAK,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,KAAK,GAAe,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC1C,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/B,IAAI,gBAAgB,CAAC,MAAM;YAAE,KAAK,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QACxE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAA8B;IAE9B,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAY,CAAC;IAC9E,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,SAAS,GAAyB,EAAE,CAAC;IAC3C,MAAM,gBAAgB,GAAmC,EAAE,CAAC;IAE5D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;YAClD,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC9C,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACrC,SAAS,CAAC,IAAI,CAAC;gBACb,KAAK,EAAE,SAAS,CAAC,MAAM;gBACvB,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;gBAC1B,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE;oBACR,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC9B,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;iBAC7C;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,cAAc,CAAC;QAC3B,WAAW,EACT,OAAO,QAAQ,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;QAC/E,YAAY,EACV,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACzE,aAAa,EACX,OAAO,QAAQ,CAAC,2BAA2B,KAAK,QAAQ;YACtD,CAAC,CAAC,QAAQ,CAAC,2BAA2B;YACtC,CAAC,CAAC,CAAC;QACP,SAAS,EACP,OAAO,QAAQ,CAAC,uBAAuB,KAAK,QAAQ;YAClD,CAAC,CAAC,QAAQ,CAAC,uBAAuB;YAClC,CAAC,CAAC,CAAC;KACR,CAAC,CAAC;IAEH,MAAM,KAAK,GAAe;QACxB,OAAO,EAAE;YACP;gBACE,KAAK,EAAE;oBACL,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3B,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1C,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvD;aACF;SACF;KACF,CAAC;IACF,IAAI,KAAK;QAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IAC/B,IAAI,gBAAgB,CAAC,MAAM;QAAE,KAAK,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;IACxE,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/attachments.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { MultimodalUserMessage } from "./types.js";
|
|
2
|
-
export interface Attachment {
|
|
3
|
-
name: string;
|
|
4
|
-
path: string;
|
|
5
|
-
mimeType: string;
|
|
6
|
-
size: number;
|
|
7
|
-
imageMimeType?: string;
|
|
8
|
-
bytes?: Buffer;
|
|
9
|
-
sourceUrl?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface StageAttachmentOptions {
|
|
12
|
-
fetch?: typeof globalThis.fetch;
|
|
13
|
-
signal?: AbortSignal;
|
|
14
|
-
}
|
|
15
|
-
export declare const maxUploadBytes: number;
|
|
16
|
-
export declare const maxAttachmentsPerMessage = 10;
|
|
17
|
-
export declare const maxAttachmentBytesPerMessage: number;
|
|
18
|
-
export declare const mimeTypes: Record<string, string>;
|
|
19
|
-
export declare function sanitizeAttachmentName(value: string): string;
|
|
20
|
-
export declare function normalizedMediaType(value: string): string;
|
|
21
|
-
export declare function detectedImageMimeType(bytes: Buffer): string | undefined;
|
|
22
|
-
export declare function attachmentMimeType(name: string, bytes: Buffer, declaredType?: string): {
|
|
23
|
-
mimeType: string;
|
|
24
|
-
imageMimeType?: string;
|
|
25
|
-
};
|
|
26
|
-
export declare function uploadsDirectory(workspace: string, create: boolean): Promise<string>;
|
|
27
|
-
export declare function saveAttachment(workspace: string, requestedName: string, bytes: Buffer, declaredType?: string): Promise<Attachment>;
|
|
28
|
-
export declare function stageAttachment(workspace: string, source: string, options?: StageAttachmentOptions): Promise<Attachment>;
|
|
29
|
-
export declare function attachmentUserMessage(prompt: string, attachments: Attachment[]): MultimodalUserMessage;
|
package/dist/attachments.js
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { lstat, mkdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
export const maxUploadBytes = 20 * 1024 * 1024;
|
|
4
|
-
export const maxAttachmentsPerMessage = 10;
|
|
5
|
-
export const maxAttachmentBytesPerMessage = 50 * 1024 * 1024;
|
|
6
|
-
export const mimeTypes = {
|
|
7
|
-
".aac": "audio/aac",
|
|
8
|
-
".avi": "video/x-msvideo",
|
|
9
|
-
".bmp": "image/bmp",
|
|
10
|
-
".csv": "text/csv; charset=utf-8",
|
|
11
|
-
".css": "text/css; charset=utf-8",
|
|
12
|
-
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
13
|
-
".gif": "image/gif",
|
|
14
|
-
".html": "text/html; charset=utf-8",
|
|
15
|
-
".ico": "image/x-icon",
|
|
16
|
-
".jpeg": "image/jpeg",
|
|
17
|
-
".js": "text/javascript; charset=utf-8",
|
|
18
|
-
".jpg": "image/jpeg",
|
|
19
|
-
".json": "application/json; charset=utf-8",
|
|
20
|
-
".m4a": "audio/mp4",
|
|
21
|
-
".md": "text/markdown; charset=utf-8",
|
|
22
|
-
".mjs": "text/javascript; charset=utf-8",
|
|
23
|
-
".mov": "video/quicktime",
|
|
24
|
-
".mp3": "audio/mpeg",
|
|
25
|
-
".mp4": "video/mp4",
|
|
26
|
-
".ogg": "audio/ogg",
|
|
27
|
-
".ogv": "video/ogg",
|
|
28
|
-
".pdf": "application/pdf",
|
|
29
|
-
".png": "image/png",
|
|
30
|
-
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
31
|
-
".py": "text/plain; charset=utf-8",
|
|
32
|
-
".svg": "image/svg+xml",
|
|
33
|
-
".toml": "text/plain; charset=utf-8",
|
|
34
|
-
".ts": "text/plain; charset=utf-8",
|
|
35
|
-
".tsx": "text/plain; charset=utf-8",
|
|
36
|
-
".txt": "text/plain; charset=utf-8",
|
|
37
|
-
".wav": "audio/wav",
|
|
38
|
-
".webm": "video/webm",
|
|
39
|
-
".webp": "image/webp",
|
|
40
|
-
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
41
|
-
".xml": "application/xml; charset=utf-8",
|
|
42
|
-
".yaml": "text/plain; charset=utf-8",
|
|
43
|
-
".yml": "text/plain; charset=utf-8",
|
|
44
|
-
};
|
|
45
|
-
const imageExtensions = {
|
|
46
|
-
"image/bmp": ".bmp",
|
|
47
|
-
"image/gif": ".gif",
|
|
48
|
-
"image/jpeg": ".jpg",
|
|
49
|
-
"image/png": ".png",
|
|
50
|
-
"image/webp": ".webp",
|
|
51
|
-
};
|
|
52
|
-
export function sanitizeAttachmentName(value) {
|
|
53
|
-
const cleaned = value
|
|
54
|
-
.normalize("NFC")
|
|
55
|
-
.replace(/[\u0000-\u001f\u007f]+/g, " ")
|
|
56
|
-
.replaceAll("/", "_")
|
|
57
|
-
.replaceAll("\\", "_")
|
|
58
|
-
.replace(/[<>]/g, "_")
|
|
59
|
-
.replace(/\s+/g, " ")
|
|
60
|
-
.replace(/^\.+/, "")
|
|
61
|
-
.trim();
|
|
62
|
-
if (!cleaned || cleaned === "." || cleaned === "..") {
|
|
63
|
-
throw new Error("attachment filename is empty");
|
|
64
|
-
}
|
|
65
|
-
const extension = path.extname(cleaned);
|
|
66
|
-
const stem = cleaned.slice(0, cleaned.length - extension.length);
|
|
67
|
-
const maximumStemLength = Math.max(1, 180 - Array.from(extension).length);
|
|
68
|
-
return `${Array.from(stem).slice(0, maximumStemLength).join("")}${extension}`;
|
|
69
|
-
}
|
|
70
|
-
export function normalizedMediaType(value) {
|
|
71
|
-
const mediaType = value.split(";")[0]?.trim().toLowerCase() || "";
|
|
72
|
-
return /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(mediaType)
|
|
73
|
-
? mediaType
|
|
74
|
-
: "";
|
|
75
|
-
}
|
|
76
|
-
export function detectedImageMimeType(bytes) {
|
|
77
|
-
if (bytes.length >= 8 &&
|
|
78
|
-
bytes.subarray(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) {
|
|
79
|
-
return "image/png";
|
|
80
|
-
}
|
|
81
|
-
if (bytes.length >= 3 &&
|
|
82
|
-
bytes[0] === 0xff &&
|
|
83
|
-
bytes[1] === 0xd8 &&
|
|
84
|
-
bytes[2] === 0xff) {
|
|
85
|
-
return "image/jpeg";
|
|
86
|
-
}
|
|
87
|
-
const prefix = bytes.subarray(0, 12).toString("ascii");
|
|
88
|
-
if (prefix.startsWith("GIF87a") || prefix.startsWith("GIF89a")) {
|
|
89
|
-
return "image/gif";
|
|
90
|
-
}
|
|
91
|
-
if (prefix.startsWith("RIFF") && prefix.slice(8, 12) === "WEBP") {
|
|
92
|
-
return "image/webp";
|
|
93
|
-
}
|
|
94
|
-
if (bytes.length >= 2 && bytes[0] === 0x42 && bytes[1] === 0x4d) {
|
|
95
|
-
return "image/bmp";
|
|
96
|
-
}
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
|
-
export function attachmentMimeType(name, bytes, declaredType = "") {
|
|
100
|
-
const imageMimeType = detectedImageMimeType(bytes);
|
|
101
|
-
if (imageMimeType)
|
|
102
|
-
return { mimeType: imageMimeType, imageMimeType };
|
|
103
|
-
const extensionType = mimeTypes[path.extname(name).toLowerCase()]?.split(";")[0];
|
|
104
|
-
return {
|
|
105
|
-
mimeType: normalizedMediaType(extensionType || "") ||
|
|
106
|
-
normalizedMediaType(declaredType) ||
|
|
107
|
-
"application/octet-stream",
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
export async function uploadsDirectory(workspace, create) {
|
|
111
|
-
const uploads = path.join(workspace, "uploads");
|
|
112
|
-
if (create)
|
|
113
|
-
await mkdir(uploads, { recursive: true });
|
|
114
|
-
const [workspaceReal, uploadsReal, info] = await Promise.all([
|
|
115
|
-
realpath(workspace),
|
|
116
|
-
realpath(uploads),
|
|
117
|
-
lstat(uploads),
|
|
118
|
-
]);
|
|
119
|
-
const relative = path.relative(workspaceReal, uploadsReal);
|
|
120
|
-
if (!info.isDirectory() ||
|
|
121
|
-
info.isSymbolicLink() ||
|
|
122
|
-
relative.startsWith("..") ||
|
|
123
|
-
path.isAbsolute(relative)) {
|
|
124
|
-
throw new Error("/home/user/uploads/ is not a safe session directory");
|
|
125
|
-
}
|
|
126
|
-
return uploadsReal;
|
|
127
|
-
}
|
|
128
|
-
export async function saveAttachment(workspace, requestedName, bytes, declaredType = "") {
|
|
129
|
-
const uploads = await uploadsDirectory(workspace, true);
|
|
130
|
-
const originalName = sanitizeAttachmentName(requestedName);
|
|
131
|
-
const extension = path.extname(originalName);
|
|
132
|
-
const stem = originalName.slice(0, originalName.length - extension.length);
|
|
133
|
-
for (let suffix = 0; suffix < 10_000; suffix += 1) {
|
|
134
|
-
const name = suffix === 0 ? originalName : `${stem}-${suffix + 1}${extension}`;
|
|
135
|
-
const absolutePath = path.join(uploads, name);
|
|
136
|
-
try {
|
|
137
|
-
await writeFile(absolutePath, bytes, { flag: "wx" });
|
|
138
|
-
const type = attachmentMimeType(name, bytes, declaredType);
|
|
139
|
-
return {
|
|
140
|
-
name,
|
|
141
|
-
path: `uploads/${name}`,
|
|
142
|
-
size: bytes.length,
|
|
143
|
-
bytes,
|
|
144
|
-
...type,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
if (error.code !== "EEXIST")
|
|
149
|
-
throw error;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
throw new Error("could not allocate a unique attachment filename");
|
|
153
|
-
}
|
|
154
|
-
function withDetectedImageExtension(name, bytes) {
|
|
155
|
-
if (path.extname(name))
|
|
156
|
-
return name;
|
|
157
|
-
const extension = imageExtensions[detectedImageMimeType(bytes) || ""];
|
|
158
|
-
return extension ? `${name}${extension}` : name;
|
|
159
|
-
}
|
|
160
|
-
export async function stageAttachment(workspace, source, options = {}) {
|
|
161
|
-
if (/^https?:\/\//i.test(source)) {
|
|
162
|
-
const fetchImpl = options.fetch || globalThis.fetch.bind(globalThis);
|
|
163
|
-
let response;
|
|
164
|
-
try {
|
|
165
|
-
response = await fetchImpl(source, { signal: options.signal });
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
if (options.signal?.aborted)
|
|
169
|
-
throw error;
|
|
170
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
171
|
-
throw new Error(`attachment download failed (${detail}): ${source}`);
|
|
172
|
-
}
|
|
173
|
-
if (!response.ok) {
|
|
174
|
-
throw new Error(`attachment download failed (${response.status} ${response.statusText}): ${source}`);
|
|
175
|
-
}
|
|
176
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
177
|
-
if (bytes.length > maxUploadBytes) {
|
|
178
|
-
throw new Error(`attachment exceeds ${maxUploadBytes} bytes: ${source}`);
|
|
179
|
-
}
|
|
180
|
-
let name = path.posix.basename(new URL(source).pathname) || "attachment";
|
|
181
|
-
try {
|
|
182
|
-
name = decodeURIComponent(name);
|
|
183
|
-
}
|
|
184
|
-
catch {
|
|
185
|
-
// Keep the raw basename when it is not URI encoded.
|
|
186
|
-
}
|
|
187
|
-
const attachment = await saveAttachment(workspace, withDetectedImageExtension(name, bytes), bytes, response.headers.get("content-type") || "");
|
|
188
|
-
attachment.sourceUrl = source;
|
|
189
|
-
return attachment;
|
|
190
|
-
}
|
|
191
|
-
const absolute = path.resolve(source);
|
|
192
|
-
const bytes = await readFile(absolute);
|
|
193
|
-
if (bytes.length > maxUploadBytes) {
|
|
194
|
-
throw new Error(`attachment exceeds ${maxUploadBytes} bytes: ${source}`);
|
|
195
|
-
}
|
|
196
|
-
return saveAttachment(workspace, withDetectedImageExtension(path.basename(absolute), bytes), bytes);
|
|
197
|
-
}
|
|
198
|
-
export function attachmentUserMessage(prompt, attachments) {
|
|
199
|
-
const content = [];
|
|
200
|
-
for (const attachment of attachments) {
|
|
201
|
-
if (attachment.imageMimeType && attachment.bytes) {
|
|
202
|
-
// URL-sourced images keep the original URL, matching how baseline
|
|
203
|
-
// traces reference attachments; local files have no URL to cite and
|
|
204
|
-
// embed the bytes instead.
|
|
205
|
-
content.push({
|
|
206
|
-
image: attachment.sourceUrl ||
|
|
207
|
-
`data:${attachment.imageMimeType};base64,` +
|
|
208
|
-
attachment.bytes.toString("base64"),
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
if (prompt)
|
|
213
|
-
content.push({ text: prompt });
|
|
214
|
-
content.push({
|
|
215
|
-
text: "\n\n<arena-system-message>\n" +
|
|
216
|
-
"The user attached the following files (saved to /home/user/uploads/):\n" +
|
|
217
|
-
attachments.map((attachment) => attachment.name).join(",\n") +
|
|
218
|
-
"\n</arena-system-message>",
|
|
219
|
-
});
|
|
220
|
-
return { role: "user", content };
|
|
221
|
-
}
|
|
222
|
-
//# sourceMappingURL=attachments.js.map
|