@qwen-code/arena-agent 0.0.10-dev.15 → 0.0.10-dev.17
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 +30 -7
- package/CHANGELOG.md +56 -1
- package/README.md +98 -38
- package/dist/agent.d.ts +5 -1
- package/dist/agent.js +130 -37
- package/dist/agent.js.map +1 -1
- package/dist/anthropic.js +33 -49
- package/dist/anthropic.js.map +1 -1
- package/dist/arena-history.d.ts +12 -0
- package/dist/arena-history.js +119 -0
- package/dist/arena-history.js.map +1 -0
- package/dist/attachment-limits.d.ts +4 -0
- package/dist/attachment-limits.js +10 -0
- package/dist/attachment-limits.js.map +1 -0
- package/dist/attachments.d.ts +4 -2
- package/dist/attachments.js +9 -11
- package/dist/attachments.js.map +1 -1
- package/dist/brave-search.js +11 -7
- package/dist/brave-search.js.map +1 -1
- package/dist/canonical-data.d.ts +7 -0
- package/dist/canonical-data.js +10 -3
- package/dist/canonical-data.js.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/code-cli.js +0 -0
- package/dist/code-tools.js +2 -4
- package/dist/code-tools.js.map +1 -1
- package/dist/compaction-threshold.d.ts +3 -0
- package/dist/compaction-threshold.js +6 -0
- package/dist/compaction-threshold.js.map +1 -0
- package/dist/compaction.d.ts +6 -3
- package/dist/compaction.js +76 -39
- package/dist/compaction.js.map +1 -1
- package/dist/config.d.ts +4 -2
- package/dist/config.js +12 -10
- package/dist/config.js.map +1 -1
- package/dist/connector-errors.d.ts +16 -0
- package/dist/connector-errors.js +69 -0
- package/dist/connector-errors.js.map +1 -0
- package/dist/connector-files.d.ts +31 -0
- package/dist/connector-files.js +249 -0
- package/dist/connector-files.js.map +1 -0
- package/dist/connector-input.d.ts +10 -0
- package/dist/connector-input.js +79 -0
- package/dist/connector-input.js.map +1 -0
- package/dist/connector-mcp.d.ts +15 -2
- package/dist/connector-mcp.js +201 -41
- package/dist/connector-mcp.js.map +1 -1
- package/dist/connectors.d.ts +7 -2
- package/dist/connectors.js +42 -30
- package/dist/connectors.js.map +1 -1
- package/dist/fetch-page.js +2 -2
- package/dist/fetch-page.js.map +1 -1
- package/dist/history.d.ts +4 -2
- package/dist/history.js +6 -2
- package/dist/history.js.map +1 -1
- package/dist/image-choice.d.ts +23 -0
- package/dist/image-choice.js +190 -0
- package/dist/image-choice.js.map +1 -0
- package/dist/image-input-fallback.js +5 -0
- package/dist/image-input-fallback.js.map +1 -1
- package/dist/image-model.d.ts +6 -0
- package/dist/image-model.js +32 -0
- package/dist/image-model.js.map +1 -0
- package/dist/mode.js +1 -1
- package/dist/mode.js.map +1 -1
- package/dist/model-router-media.js +5 -3
- package/dist/model-router-media.js.map +1 -1
- package/dist/model-stream.d.ts +16 -0
- package/dist/model-stream.js +129 -0
- package/dist/model-stream.js.map +1 -0
- package/dist/openai-responses.d.ts +1 -0
- package/dist/openai-responses.js +79 -85
- package/dist/openai-responses.js.map +1 -1
- package/dist/process-manager.js +9 -9
- package/dist/process-manager.js.map +1 -1
- package/dist/prompts.d.ts +0 -1
- package/dist/prompts.js +3 -27
- package/dist/prompts.js.map +1 -1
- package/dist/provider.js +42 -33
- package/dist/provider.js.map +1 -1
- package/dist/repo.d.ts +1 -1
- package/dist/repo.js +26 -4
- package/dist/repo.js.map +1 -1
- package/dist/routify-web-fetch.js +2 -2
- package/dist/routify-web-fetch.js.map +1 -1
- package/dist/server.js +40 -23
- package/dist/server.js.map +1 -1
- package/dist/session-memory-prompts.d.ts +3 -1
- package/dist/session-memory-prompts.js +4 -2
- package/dist/session-memory-prompts.js.map +1 -1
- package/dist/side-query.js +5 -0
- package/dist/side-query.js.map +1 -1
- package/dist/spec.d.ts +4 -4
- package/dist/spec.js +25 -12
- package/dist/spec.js.map +1 -1
- package/dist/startup-config.js +2 -1
- package/dist/startup-config.js.map +1 -1
- package/dist/startup-main-config.d.ts +1 -0
- package/dist/startup-main-config.js +1 -0
- package/dist/startup-main-config.js.map +1 -1
- package/dist/startup-tool-config.js +12 -2
- package/dist/startup-tool-config.js.map +1 -1
- package/dist/summary-compaction.js +5 -0
- package/dist/summary-compaction.js.map +1 -1
- package/dist/tools.d.ts +2 -0
- package/dist/tools.js +133 -49
- package/dist/tools.js.map +1 -1
- package/dist/tui.js +18 -2
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/web/app.js +30 -5
- package/dist/web/app.js.map +1 -1
- package/docs/BINARY_DISTRIBUTION.md +36 -4
- package/docs/MODES_AND_RELEASES.md +7 -2
- package/package.json +1 -1
- package/web/styles.css +22 -0
- package/dist/code-arena-output.d.ts +0 -15
- package/dist/code-arena-output.js +0 -41
- package/dist/code-arena-output.js.map +0 -1
- package/dist/legacy-compaction.d.ts +0 -20
- package/dist/legacy-compaction.js +0 -209
- package/dist/legacy-compaction.js.map +0 -1
- package/dist/web/app.d.ts +0 -1
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { mkdir, open, rename, rm } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import mime from "mime/lite";
|
|
6
|
+
import { connectorRepeatGuidance } from "./connector-errors.js";
|
|
7
|
+
export const connectorFileLimit = 104_857_600;
|
|
8
|
+
export const connectorUploadTools = new Set(["google_drive__upload_file", "dropbox__upload_file", "gmail__create_draft"]);
|
|
9
|
+
export const connectorDownloadTools = new Set(["google_drive__download_file", "google_drive__export_file", "dropbox__get_file_content", "gmail__get_attachment"]);
|
|
10
|
+
export class ConnectorFileError extends Error {
|
|
11
|
+
cacheFailure;
|
|
12
|
+
constructor(message, cacheFailure = false) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.cacheFailure = cacheFailure;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function oversizedConnectorDownload(size) {
|
|
18
|
+
return new ConnectorFileError(`Arena did not send this download. File metadata reports ${size} bytes, more than the 100 MiB (104857600 byte) workspace file limit. Tell the user that the file is too large. Share its Drive link if available.`, true);
|
|
19
|
+
}
|
|
20
|
+
export function connectorApiBase(config) {
|
|
21
|
+
const url = new URL(config.apiBase || "https://ah-api.merge.dev");
|
|
22
|
+
const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
23
|
+
if ((url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) ||
|
|
24
|
+
url.username || url.password || url.search || url.hash) {
|
|
25
|
+
throw new Error("ARENA_MERGE_API_BASE must be an HTTPS origin (HTTP loopback is allowed for testing)");
|
|
26
|
+
}
|
|
27
|
+
return url;
|
|
28
|
+
}
|
|
29
|
+
export function connectorResultObjects(result) {
|
|
30
|
+
return result.content.flatMap(part => {
|
|
31
|
+
if (part.type !== "text")
|
|
32
|
+
return [];
|
|
33
|
+
try {
|
|
34
|
+
const value = JSON.parse(part.text);
|
|
35
|
+
return value && typeof value === "object" && !Array.isArray(value) ? [value] : [];
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/** File bytes go through Merge's files API, never through the model context. */
|
|
43
|
+
export class ConnectorFiles {
|
|
44
|
+
config;
|
|
45
|
+
options;
|
|
46
|
+
signal;
|
|
47
|
+
uploadBlocked;
|
|
48
|
+
constructor(config, options, signal) {
|
|
49
|
+
this.config = config;
|
|
50
|
+
this.options = options;
|
|
51
|
+
this.signal = signal;
|
|
52
|
+
}
|
|
53
|
+
reset() { this.uploadBlocked = undefined; }
|
|
54
|
+
restoreFailure(message) {
|
|
55
|
+
if (message.startsWith("Merge is rate-limiting file uploads."))
|
|
56
|
+
this.uploadBlocked = message;
|
|
57
|
+
}
|
|
58
|
+
requestSignal() {
|
|
59
|
+
const timeout = AbortSignal.timeout(this.config.timeoutMs ?? 60_000);
|
|
60
|
+
return this.signal ? AbortSignal.any([this.signal, timeout]) : timeout;
|
|
61
|
+
}
|
|
62
|
+
fileUrl(raw, action) {
|
|
63
|
+
const base = connectorApiBase(this.config), url = new URL(raw);
|
|
64
|
+
const prefix = `${base.pathname.replace(/\/$/, "")}/api/v1/files/`;
|
|
65
|
+
// The files service returns authenticated same-origin URLs. Never forward
|
|
66
|
+
// the access key to a connector-supplied host or through a redirect.
|
|
67
|
+
if (url.origin !== base.origin || !url.pathname.startsWith(prefix) || !url.pathname.endsWith(`/${action}/`)
|
|
68
|
+
|| url.username || url.password || url.search || url.hash)
|
|
69
|
+
throw new ConnectorFileError("The connector returned an invalid file-transfer URL.");
|
|
70
|
+
return url;
|
|
71
|
+
}
|
|
72
|
+
async uploadFailure(response, rawPath) {
|
|
73
|
+
if (response.status === 429) {
|
|
74
|
+
const seconds = Math.max(1, Number(response.headers.get("retry-after")) || 15);
|
|
75
|
+
this.uploadBlocked = `Merge is rate-limiting file uploads. Arena did not send this file to the app. Do not upload more files in this reply. Tell the user that the upload limit was reached, and that they can try again in at least ${seconds} seconds.`;
|
|
76
|
+
throw new ConnectorFileError(this.uploadBlocked);
|
|
77
|
+
}
|
|
78
|
+
const text = await response.text();
|
|
79
|
+
if (/security.{0,30}(?:filter|block)|content.{0,30}block|guardrail/i.test(text)) {
|
|
80
|
+
throw new ConnectorFileError(`A security filter at the connector provider blocked the file at ${JSON.stringify(rawPath)} because of its content. The file was not sent. Do not send this content again, and do not change it to get past the filter. Tell the user that the connector provider blocked it.`, true);
|
|
81
|
+
}
|
|
82
|
+
throw new ConnectorFileError(`Arena could not upload the workspace file (HTTP ${response.status}), so it did not send the file to the app. ${connectorRepeatGuidance}`);
|
|
83
|
+
}
|
|
84
|
+
async upload(name, args) {
|
|
85
|
+
const input = args.input;
|
|
86
|
+
if (!connectorUploadTools.has(name) || !input || typeof input.file_path !== "string")
|
|
87
|
+
return args;
|
|
88
|
+
if (this.uploadBlocked)
|
|
89
|
+
throw new ConnectorFileError(this.uploadBlocked);
|
|
90
|
+
const rawPath = input.file_path;
|
|
91
|
+
let handle;
|
|
92
|
+
let phase = "read";
|
|
93
|
+
try {
|
|
94
|
+
if (!this.options.resolvePath)
|
|
95
|
+
throw new Error("No workspace resolver");
|
|
96
|
+
const target = await this.options.resolvePath(rawPath);
|
|
97
|
+
handle = await open(target, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
98
|
+
const metadata = await handle.stat();
|
|
99
|
+
if (!metadata.isFile())
|
|
100
|
+
throw new Error("Not a regular file");
|
|
101
|
+
if (!metadata.size)
|
|
102
|
+
throw new ConnectorFileError(`The file at ${JSON.stringify(rawPath)} is empty. The app rejects an empty file.`);
|
|
103
|
+
if (metadata.size > connectorFileLimit)
|
|
104
|
+
throw new ConnectorFileError(`The file at ${JSON.stringify(rawPath)} is larger than the 100 MiB (104857600 byte) workspace file limit. Arena did not send it to the app. Compress or split the file, or tell the user that it is too large.`);
|
|
105
|
+
const filename = path.basename(target), contentType = input.content_mime_type || mime.getType(filename) || "application/octet-stream";
|
|
106
|
+
const base = connectorApiBase(this.config);
|
|
107
|
+
base.pathname = `${base.pathname.replace(/\/$/, "")}/api/v1/files/`;
|
|
108
|
+
const headers = { Authorization: `Bearer ${this.config.accessKey}`, "Content-Type": "application/json" };
|
|
109
|
+
phase = "upload";
|
|
110
|
+
const reservation = await fetch(base, { method: "POST", headers, body: JSON.stringify({ filename, content_type: contentType, size_bytes: metadata.size }),
|
|
111
|
+
signal: this.requestSignal(), redirect: "error" });
|
|
112
|
+
if (!reservation.ok)
|
|
113
|
+
await this.uploadFailure(reservation, rawPath);
|
|
114
|
+
const slot = await reservation.json();
|
|
115
|
+
if (!slot.file_reference || !slot.upload?.url || slot.upload.method !== "PUT")
|
|
116
|
+
throw new ConnectorFileError("The connector provider returned an invalid upload reservation.");
|
|
117
|
+
if (slot.max_size_bytes !== undefined && metadata.size > slot.max_size_bytes)
|
|
118
|
+
throw new ConnectorFileError("The workspace file exceeds the connector provider's upload limit.");
|
|
119
|
+
const stream = handle.createReadStream({ autoClose: false, end: metadata.size - 1 });
|
|
120
|
+
let uploaded;
|
|
121
|
+
try {
|
|
122
|
+
uploaded = await fetch(this.fileUrl(slot.upload.url, "upload"), { method: "PUT", headers: { Authorization: headers.Authorization,
|
|
123
|
+
"Content-Type": contentType, "Content-Length": String(metadata.size) }, body: stream,
|
|
124
|
+
duplex: "half", signal: this.requestSignal(), redirect: "error" });
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
stream.destroy();
|
|
128
|
+
}
|
|
129
|
+
if (!uploaded.ok)
|
|
130
|
+
await this.uploadFailure(uploaded, rawPath);
|
|
131
|
+
const receipt = await uploaded.json();
|
|
132
|
+
if (receipt.size_bytes !== undefined && receipt.size_bytes !== metadata.size)
|
|
133
|
+
throw new ConnectorFileError("The connector provider received an incomplete file. Arena did not send it to the app.");
|
|
134
|
+
const result = structuredClone(args);
|
|
135
|
+
delete result.input.file_path;
|
|
136
|
+
result.input.file_reference = slot.file_reference;
|
|
137
|
+
if (name === "gmail__create_draft")
|
|
138
|
+
result.input.file_reference_filename = filename;
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (this.signal?.aborted || error instanceof ConnectorFileError)
|
|
143
|
+
throw error;
|
|
144
|
+
if (phase === "upload")
|
|
145
|
+
throw new ConnectorFileError(`The workspace file upload failed before it was sent to the app. ${connectorRepeatGuidance}`);
|
|
146
|
+
if (error.code === "ENOENT")
|
|
147
|
+
throw new ConnectorFileError(`No file exists at ${JSON.stringify(rawPath)}. List the workspace to find the right path.`);
|
|
148
|
+
throw new ConnectorFileError(`Arena could not read the file from the workspace, so it did not send the file to the app. ${connectorRepeatGuidance}`);
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
await handle?.close();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async download(name, result, args) {
|
|
155
|
+
if (!connectorDownloadTools.has(name))
|
|
156
|
+
return undefined;
|
|
157
|
+
const objects = connectorResultObjects(result);
|
|
158
|
+
const payload = objects.map(value => value.data && typeof value.data === "object" ? value.data : value)
|
|
159
|
+
.find(value => value.download || (typeof value.content === "string" && value.encoding));
|
|
160
|
+
if (!payload)
|
|
161
|
+
return undefined;
|
|
162
|
+
if (!this.options.resolvePath)
|
|
163
|
+
throw new ConnectorFileError("No workspace is configured for connector file downloads.");
|
|
164
|
+
const transfer = payload.download;
|
|
165
|
+
const originalName = transfer?.filename || payload.name || payload.filename || args.input?.filename || (args.input?.path && path.posix.basename(args.input.path));
|
|
166
|
+
if (typeof originalName !== "string" || !originalName)
|
|
167
|
+
throw new ConnectorFileError("The connector did not return a file name.");
|
|
168
|
+
const filename = path.posix.basename(originalName.replaceAll("\\", "/")).replace(/[\x00-\x1f\x7f]/g, "_");
|
|
169
|
+
if (!filename || filename === "." || filename === "..")
|
|
170
|
+
throw new ConnectorFileError("The connector returned an invalid file name.");
|
|
171
|
+
const expectedSize = Number(transfer?.size_bytes ?? payload.size);
|
|
172
|
+
if (expectedSize > connectorFileLimit)
|
|
173
|
+
throw oversizedConnectorDownload(expectedSize);
|
|
174
|
+
const relative = `${name.split("__")[0]}/${filename}`;
|
|
175
|
+
let temporary;
|
|
176
|
+
let handle;
|
|
177
|
+
try {
|
|
178
|
+
const target = await this.options.resolvePath(relative);
|
|
179
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
180
|
+
// Resolve again after creating the directory; never follow a changed parent.
|
|
181
|
+
if (await this.options.resolvePath(relative) !== target)
|
|
182
|
+
throw new Error("Download directory changed");
|
|
183
|
+
temporary = path.join(path.dirname(target), `.arena-download-${randomUUID()}`);
|
|
184
|
+
handle = await open(temporary, "wx", 0o600);
|
|
185
|
+
let size = 0;
|
|
186
|
+
const append = async (chunk) => {
|
|
187
|
+
size += chunk.byteLength;
|
|
188
|
+
if (size > connectorFileLimit)
|
|
189
|
+
throw oversizedConnectorDownload(size);
|
|
190
|
+
await handle.writeFile(chunk);
|
|
191
|
+
};
|
|
192
|
+
let contentType = transfer?.content_type || payload.mime_type || payload.content_type || "application/octet-stream";
|
|
193
|
+
if (transfer) {
|
|
194
|
+
if (transfer.method !== "GET" || typeof transfer.url !== "string")
|
|
195
|
+
throw new ConnectorFileError("The connector returned an invalid download descriptor.");
|
|
196
|
+
const response = await fetch(this.fileUrl(transfer.url, "download"), { headers: { Authorization: `Bearer ${this.config.accessKey}` },
|
|
197
|
+
signal: this.requestSignal(), redirect: "error" });
|
|
198
|
+
if (!response.ok || !response.body)
|
|
199
|
+
throw new ConnectorFileError(`The connector file download failed (HTTP ${response.status}).`);
|
|
200
|
+
const length = Number(response.headers.get("content-length"));
|
|
201
|
+
if (length > connectorFileLimit) {
|
|
202
|
+
await response.body.cancel();
|
|
203
|
+
throw oversizedConnectorDownload(length);
|
|
204
|
+
}
|
|
205
|
+
contentType = transfer.content_type || response.headers.get("content-type") || contentType;
|
|
206
|
+
const reader = response.body.getReader();
|
|
207
|
+
try {
|
|
208
|
+
while (true) {
|
|
209
|
+
const next = await reader.read();
|
|
210
|
+
if (next.done)
|
|
211
|
+
break;
|
|
212
|
+
await append(next.value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
await reader.cancel().catch(() => { });
|
|
217
|
+
reader.releaseLock();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
const encoding = String(payload.encoding).toLowerCase();
|
|
222
|
+
if (!["utf-8", "utf8", "text", "base64", "base64url"].includes(encoding))
|
|
223
|
+
throw new ConnectorFileError("The connector returned an unsupported file encoding.");
|
|
224
|
+
if (encoding.startsWith("base64") && !/^[a-zA-Z0-9+/_=\-\s]*$/.test(payload.content))
|
|
225
|
+
throw new ConnectorFileError("The connector returned invalid base64 file bytes.");
|
|
226
|
+
await append(Buffer.from(payload.content, encoding === "base64url" ? "base64url" : encoding === "base64" ? "base64" : "utf8"));
|
|
227
|
+
}
|
|
228
|
+
if (Number.isFinite(expectedSize) && expectedSize >= 0 && expectedSize !== size)
|
|
229
|
+
throw new ConnectorFileError("The connector file download is incomplete. Arena did not save a partial file.");
|
|
230
|
+
await handle.close();
|
|
231
|
+
handle = undefined;
|
|
232
|
+
this.signal?.throwIfAborted();
|
|
233
|
+
await rename(temporary, target);
|
|
234
|
+
temporary = undefined;
|
|
235
|
+
return JSON.stringify({ file_path: relative, name: filename, mime_type: contentType, size });
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
if (this.signal?.aborted || error instanceof ConnectorFileError)
|
|
239
|
+
throw error;
|
|
240
|
+
throw new ConnectorFileError(`Arena could not save the connector file in the workspace. ${connectorRepeatGuidance}`);
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
await handle?.close();
|
|
244
|
+
if (temporary)
|
|
245
|
+
await rm(temporary, { force: true }).catch(() => { });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=connector-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-files.js","sourceRoot":"","sources":["../src/connector-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type Schema = Record<string, any>;
|
|
2
|
+
/** Captured model schemas use anyOf for optional objects. Keep their property order. */
|
|
3
|
+
export declare function connectorSchemaValue(value: unknown, schema: Schema, root?: Schema): unknown;
|
|
4
|
+
/** Documented Notion JSON fields accept an object or a well-formed JSON string. */
|
|
5
|
+
export declare function normalizeConnectorInput(name: string, value: unknown): unknown;
|
|
6
|
+
/** The MCP schema requires explicit nullable fields that Arena omits from its model contract.
|
|
7
|
+
* Apply these only to the backend request, without changing model-visible history.
|
|
8
|
+
*/
|
|
9
|
+
export declare function connectorBackendInput(value: unknown, schema: Schema, root?: Schema): unknown;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2
|
+
function resolve(schema, root) {
|
|
3
|
+
const seen = new Set();
|
|
4
|
+
while (typeof schema.$ref === "string" && schema.$ref.startsWith("#/") && !seen.has(schema.$ref)) {
|
|
5
|
+
seen.add(schema.$ref);
|
|
6
|
+
const target = schema.$ref.slice(2).split("/").reduce((node, key) => node?.[key.replaceAll("~1", "/").replaceAll("~0", "~")], root);
|
|
7
|
+
if (!isObject(target))
|
|
8
|
+
break;
|
|
9
|
+
const { $ref, ...rest } = schema;
|
|
10
|
+
schema = { ...target, ...rest };
|
|
11
|
+
}
|
|
12
|
+
return schema;
|
|
13
|
+
}
|
|
14
|
+
function matchesKind(value, schema, root) {
|
|
15
|
+
schema = resolve(schema, root);
|
|
16
|
+
if (schema.anyOf || schema.oneOf)
|
|
17
|
+
return (schema.anyOf || schema.oneOf).some((s) => matchesKind(value, s, root));
|
|
18
|
+
const type = schema.type;
|
|
19
|
+
if (Array.isArray(type))
|
|
20
|
+
return type.some(t => matchesKind(value, { type: t }, root));
|
|
21
|
+
return !type || (type === "null" ? value === null : type === "object" ? isObject(value)
|
|
22
|
+
: type === "array" ? Array.isArray(value) : type === "integer" ? Number.isInteger(value) : typeof value === type);
|
|
23
|
+
}
|
|
24
|
+
function branch(value, schema, root) {
|
|
25
|
+
schema = resolve(schema, root);
|
|
26
|
+
const alternatives = schema.anyOf || schema.oneOf;
|
|
27
|
+
const selected = alternatives?.find((s) => matchesKind(value, s, root));
|
|
28
|
+
return selected ? branch(value, selected, root) : schema;
|
|
29
|
+
}
|
|
30
|
+
/** Captured model schemas use anyOf for optional objects. Keep their property order. */
|
|
31
|
+
export function connectorSchemaValue(value, schema, root = schema) {
|
|
32
|
+
schema = branch(value, schema, root);
|
|
33
|
+
if (Array.isArray(value))
|
|
34
|
+
return value.map(v => connectorSchemaValue(v, schema.items || {}, root));
|
|
35
|
+
if (!isObject(value) || !schema.properties)
|
|
36
|
+
return value;
|
|
37
|
+
const entries = Object.entries(schema.properties).flatMap(([key, child]) => Object.hasOwn(value, key)
|
|
38
|
+
? [[key, connectorSchemaValue(value[key], child, root)]] : []);
|
|
39
|
+
entries.push(...Object.entries(value).filter(([key]) => !Object.hasOwn(schema.properties, key)));
|
|
40
|
+
return Object.fromEntries(entries);
|
|
41
|
+
}
|
|
42
|
+
/** Documented Notion JSON fields accept an object or a well-formed JSON string. */
|
|
43
|
+
export function normalizeConnectorInput(name, value) {
|
|
44
|
+
const result = structuredClone(value);
|
|
45
|
+
if (!isObject(result) || !isObject(result.input) || !name.startsWith("notion__"))
|
|
46
|
+
return result;
|
|
47
|
+
const fields = name === "notion__search" ? ["sort", "filter"]
|
|
48
|
+
: name === "notion__query_database" ? ["filter"]
|
|
49
|
+
: name === "notion__update_database" ? ["properties"]
|
|
50
|
+
: name === "notion__create_page" || name === "notion__update_page" ? ["properties", "children"] : [];
|
|
51
|
+
for (const field of fields)
|
|
52
|
+
if (typeof result.input[field] === "string")
|
|
53
|
+
result.input[field] = JSON.parse(result.input[field]);
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
/** The MCP schema requires explicit nullable fields that Arena omits from its model contract.
|
|
57
|
+
* Apply these only to the backend request, without changing model-visible history.
|
|
58
|
+
*/
|
|
59
|
+
export function connectorBackendInput(value, schema, root = schema) {
|
|
60
|
+
schema = branch(value, schema, root);
|
|
61
|
+
if ((isObject(value) || Array.isArray(value)) && !matchesKind(value, schema, root) && matchesKind("", schema, root))
|
|
62
|
+
return JSON.stringify(value);
|
|
63
|
+
if (Array.isArray(value))
|
|
64
|
+
return value.map(v => connectorBackendInput(v, schema.items || {}, root));
|
|
65
|
+
if (!isObject(value))
|
|
66
|
+
return value;
|
|
67
|
+
const result = structuredClone(value);
|
|
68
|
+
for (const [key, child] of Object.entries(schema.properties || {})) {
|
|
69
|
+
if (Object.hasOwn(result, key)) {
|
|
70
|
+
// Some connector revisions encode JSON dictionaries as strings. Adapt at
|
|
71
|
+
// that boundary only; a native object schema retains native objects.
|
|
72
|
+
result[key] = connectorBackendInput(result[key], child, root);
|
|
73
|
+
}
|
|
74
|
+
else if (schema.required?.includes(key) && matchesKind(null, child, root))
|
|
75
|
+
result[key] = null;
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=connector-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-input.js","sourceRoot":"","sources":["../src/connector-input.ts"],"names":[],"mappings":"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"}
|
package/dist/connector-mcp.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { type ValidateFunction } from "ajv";
|
|
3
3
|
import { type ConnectorService } from "./connectors.js";
|
|
4
|
+
import { type ConnectorFileOptions } from "./connector-files.js";
|
|
4
5
|
import type { Message, ToolDefinition } from "./types.js";
|
|
5
6
|
export interface MergeConnectorConfig {
|
|
6
7
|
accessKey?: string;
|
|
@@ -16,9 +17,10 @@ interface CatalogEntry {
|
|
|
16
17
|
description: string;
|
|
17
18
|
}
|
|
18
19
|
export declare function capturedConnectorCatalog(service: ConnectorService): CatalogEntry[];
|
|
20
|
+
export declare function capturedConnectorDefinitions(service: ConnectorService): ToolDefinition[] | undefined;
|
|
19
21
|
export declare const connectorFailureText = "Something went wrong. Please try again.";
|
|
20
22
|
export declare const connectorTruncationMarker = "\n...[middle of result omitted]...\n";
|
|
21
|
-
export declare const connectorTruncationNote = "This result is not complete. It holds the start and the end of a larger result, and the middle is missing. Do not parse it as JSON. The same call with the same arguments returns this same truncated result.
|
|
23
|
+
export declare const connectorTruncationNote = "This result is not complete. It holds the start and the end of a larger result, and the middle is missing. Do not parse it as JSON. The same call with the same arguments returns this same truncated result. If this tool offers filters or pagination, use those arguments to request a smaller result. If it offers neither, do not invent arguments or infer values from the omitted content. Use another tool that can return the required detail, or tell the user that the detail is unavailable.";
|
|
22
24
|
/** Captured display shape, independent of the backend's negotiated MCP revision. */
|
|
23
25
|
export declare function formatConnectorResult(result: CallToolResult): string;
|
|
24
26
|
export declare class ConnectorTools {
|
|
@@ -30,15 +32,26 @@ export declare class ConnectorTools {
|
|
|
30
32
|
private readonly connections;
|
|
31
33
|
private readonly loading;
|
|
32
34
|
private readonly loaded;
|
|
33
|
-
|
|
35
|
+
private readonly connected;
|
|
36
|
+
private readonly files;
|
|
37
|
+
private readonly failures;
|
|
38
|
+
private readonly completedWrites;
|
|
39
|
+
private readonly runningWrites;
|
|
40
|
+
private readonly fileSizes;
|
|
41
|
+
constructor(allowed: readonly ConnectorService[], config?: MergeConnectorConfig, disallowed?: readonly string[], signal?: AbortSignal | undefined, options?: ConnectorFileOptions & {
|
|
42
|
+
connected?: readonly string[];
|
|
43
|
+
});
|
|
34
44
|
definitions(): ToolDefinition[];
|
|
35
45
|
validator(name: string): ValidateFunction | undefined;
|
|
46
|
+
normalizeArguments(name: string, value: unknown): unknown;
|
|
47
|
+
historyValue(name: string, value: unknown): unknown;
|
|
36
48
|
has(name: string): boolean;
|
|
37
49
|
recognizes(name: string): boolean;
|
|
38
50
|
discover(service: string): Promise<string>;
|
|
39
51
|
private discoveryResult;
|
|
40
52
|
private load;
|
|
41
53
|
call(name: string, args: Record<string, unknown>): Promise<string>;
|
|
54
|
+
private rememberFileSizes;
|
|
42
55
|
beginTurn(history?: readonly Message[]): Promise<void>;
|
|
43
56
|
close(): Promise<void>;
|
|
44
57
|
}
|