@qwen-code/arena-agent 0.0.10-dev.14 → 0.0.10-dev.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/.env.example +32 -6
  2. package/CHANGELOG.md +36 -1
  3. package/README.md +144 -31
  4. package/dist/agent.d.ts +8 -2
  5. package/dist/agent.js +101 -28
  6. package/dist/agent.js.map +1 -1
  7. package/dist/arena-history.d.ts +12 -0
  8. package/dist/arena-history.js +119 -0
  9. package/dist/arena-history.js.map +1 -0
  10. package/dist/brave-search.js +7 -4
  11. package/dist/brave-search.js.map +1 -1
  12. package/dist/canonical-data.d.ts +7 -0
  13. package/dist/canonical-data.js +10 -3
  14. package/dist/canonical-data.js.map +1 -1
  15. package/dist/cli.js +75 -13
  16. package/dist/cli.js.map +1 -1
  17. package/dist/code-tools.js +2 -4
  18. package/dist/code-tools.js.map +1 -1
  19. package/dist/compaction.d.ts +4 -0
  20. package/dist/compaction.js +54 -10
  21. package/dist/compaction.js.map +1 -1
  22. package/dist/config.d.ts +4 -2
  23. package/dist/config.js +5 -5
  24. package/dist/config.js.map +1 -1
  25. package/dist/connector-errors.d.ts +16 -0
  26. package/dist/connector-errors.js +69 -0
  27. package/dist/connector-errors.js.map +1 -0
  28. package/dist/connector-files.d.ts +31 -0
  29. package/dist/connector-files.js +249 -0
  30. package/dist/connector-files.js.map +1 -0
  31. package/dist/connector-input.d.ts +10 -0
  32. package/dist/connector-input.js +79 -0
  33. package/dist/connector-input.js.map +1 -0
  34. package/dist/connector-mcp.d.ts +15 -2
  35. package/dist/connector-mcp.js +201 -41
  36. package/dist/connector-mcp.js.map +1 -1
  37. package/dist/connectors.d.ts +7 -2
  38. package/dist/connectors.js +42 -30
  39. package/dist/connectors.js.map +1 -1
  40. package/dist/fetch-page.js +2 -2
  41. package/dist/fetch-page.js.map +1 -1
  42. package/dist/history.d.ts +4 -2
  43. package/dist/history.js +4 -1
  44. package/dist/history.js.map +1 -1
  45. package/dist/image-choice.d.ts +23 -0
  46. package/dist/image-choice.js +190 -0
  47. package/dist/image-choice.js.map +1 -0
  48. package/dist/image-model.d.ts +6 -0
  49. package/dist/image-model.js +32 -0
  50. package/dist/image-model.js.map +1 -0
  51. package/dist/model-router-media.js +5 -3
  52. package/dist/model-router-media.js.map +1 -1
  53. package/dist/process-manager.js +9 -9
  54. package/dist/process-manager.js.map +1 -1
  55. package/dist/prompts.d.ts +0 -1
  56. package/dist/prompts.js +3 -27
  57. package/dist/prompts.js.map +1 -1
  58. package/dist/provider.d.ts +18 -0
  59. package/dist/provider.js +52 -16
  60. package/dist/provider.js.map +1 -1
  61. package/dist/repo.d.ts +1 -1
  62. package/dist/repo.js +26 -4
  63. package/dist/repo.js.map +1 -1
  64. package/dist/routify-web-fetch.js +2 -2
  65. package/dist/routify-web-fetch.js.map +1 -1
  66. package/dist/server.js +24 -12
  67. package/dist/server.js.map +1 -1
  68. package/dist/session-memory-prompts.d.ts +2 -1
  69. package/dist/session-memory-prompts.js +2 -1
  70. package/dist/session-memory-prompts.js.map +1 -1
  71. package/dist/spec.d.ts +4 -4
  72. package/dist/spec.js +25 -12
  73. package/dist/spec.js.map +1 -1
  74. package/dist/startup-config.d.ts +39 -0
  75. package/dist/startup-config.js +346 -0
  76. package/dist/startup-config.js.map +1 -0
  77. package/dist/startup-main-config.d.ts +63 -0
  78. package/dist/startup-main-config.js +94 -0
  79. package/dist/startup-main-config.js.map +1 -0
  80. package/dist/startup-tool-config.d.ts +8 -0
  81. package/dist/startup-tool-config.js +116 -0
  82. package/dist/startup-tool-config.js.map +1 -0
  83. package/dist/summary-compaction.d.ts +2 -0
  84. package/dist/summary-compaction.js +17 -3
  85. package/dist/summary-compaction.js.map +1 -1
  86. package/dist/tools.d.ts +2 -0
  87. package/dist/tools.js +133 -49
  88. package/dist/tools.js.map +1 -1
  89. package/dist/tui.js +15 -2
  90. package/dist/tui.js.map +1 -1
  91. package/dist/types.d.ts +6 -0
  92. package/dist/web/app.js +8 -0
  93. package/dist/web/app.js.map +1 -1
  94. package/docs/BINARY_DISTRIBUTION.md +43 -8
  95. package/docs/MODES_AND_RELEASES.md +23 -5
  96. package/package.json +1 -1
  97. package/web/styles.css +22 -0
@@ -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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"}
@@ -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. Make the query more narrow with a filter, or use a pagination option that this tool provides.";
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
- constructor(allowed: readonly ConnectorService[], config?: MergeConnectorConfig, disallowed?: readonly string[], signal?: AbortSignal | undefined);
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
  }
@@ -1,11 +1,15 @@
1
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { StreamableHTTPClientTransport, StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
- import { CallToolResultSchema, ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
3
+ import { CallToolResultSchema, ListToolsResultSchema, McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
4
4
  import { Ajv } from "ajv";
5
5
  import { Ajv2020 } from "ajv/dist/2020.js";
6
6
  import addFormats from "ajv-formats";
7
- import { connectorCatalogJson } from "./canonical-data.js";
8
- import { normalizeConnectors } from "./connectors.js";
7
+ import { connectorCatalogJson, connectorToolDefinitionsJson } from "./canonical-data.js";
8
+ import { normalizeConnectors, normalizeConnectedConnectors, connectorSlug } from "./connectors.js";
9
+ import { storedJson } from "./arena-history.js";
10
+ import { connectorBackendInput, connectorSchemaValue, normalizeConnectorInput } from "./connector-input.js";
11
+ import { connectorErrorText, connectorResultFailure, connectorWrites, completedConnectorWrite, describeConnectorFailure, repeatedConnectorFailure } from "./connector-errors.js";
12
+ import { ConnectorFiles, ConnectorFileError, connectorApiBase, connectorDownloadTools, connectorFileLimit, connectorResultObjects, oversizedConnectorDownload } from "./connector-files.js";
9
13
  export function mergeConnectorConfigFromEnv() {
10
14
  const timeout = process.env.ARENA_CONNECTOR_TIMEOUT_MS;
11
15
  if (timeout && (!Number.isSafeInteger(Number(timeout)) || Number(timeout) <= 0)) {
@@ -20,17 +24,19 @@ export function mergeConnectorConfigFromEnv() {
20
24
  };
21
25
  }
22
26
  const catalog = JSON.parse(connectorCatalogJson);
27
+ const capturedDefinitions = JSON.parse(connectorToolDefinitionsJson);
23
28
  export function capturedConnectorCatalog(service) {
24
29
  return structuredClone(catalog[service]);
25
30
  }
31
+ export function capturedConnectorDefinitions(service) {
32
+ return structuredClone(capturedDefinitions[service]);
33
+ }
26
34
  // 1008-dashscope.jsonl, row 359 (also duplicated in rows 1706 and 1871).
27
35
  export const connectorFailureText = "Something went wrong. Please try again.";
28
36
  export const connectorTruncationMarker = "\n...[middle of result omitted]...\n";
29
- export 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. Make the query more narrow with a filter, or use a pagination option that this tool provides.";
37
+ export 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.";
30
38
  /** Captured display shape, independent of the backend's negotiated MCP revision. */
31
39
  export function formatConnectorResult(result) {
32
- if (result.isError)
33
- return connectorFailureText;
34
40
  // Newer MCP revisions duplicate text into structuredContent. The captured
35
41
  // Arena surface only exposes these fields; do not re-serialize content.text.
36
42
  const text = JSON.stringify({
@@ -42,24 +48,28 @@ export function formatConnectorResult(result) {
42
48
  // this export has no untruncated examples close enough to prove the threshold.
43
49
  const characters = Array.from(text);
44
50
  if (characters.length > 20_000) {
45
- return JSON.stringify({ status: "success", truncated: true,
51
+ return JSON.stringify({ status: "success",
46
52
  result_text: characters.slice(0, 15_000).join("") + connectorTruncationMarker + characters.slice(-4_000).join(""),
53
+ truncated: true,
47
54
  truncation_note: connectorTruncationNote });
48
55
  }
49
56
  return JSON.stringify({ status: "success", result_text: text });
50
57
  }
51
58
  function localDiscoveryError(service, error, message) {
52
- // Unconnected/disabled discovery responses were not captured. These are
53
- // explicit local diagnostics, never fabricated official enabled responses.
59
+ // Backend configuration failures are local diagnostics, separate from the
60
+ // captured enabled/disconnected/unsupported app states.
54
61
  return JSON.stringify({ status: "error", connector: service, error, message });
55
62
  }
63
+ function compileConnectorSchema(schema, defaults = false) {
64
+ const options = { strict: false, allErrors: true, removeAdditional: false,
65
+ coerceTypes: false, useDefaults: defaults };
66
+ const ajv = String(schema.$schema || "").includes("2020-12")
67
+ ? new Ajv2020(options) : new Ajv(options);
68
+ addFormats(ajv);
69
+ return ajv.compile(structuredClone(schema));
70
+ }
56
71
  function mergeUrl(config, service) {
57
- const url = new URL(config.apiBase || "https://ah-api.merge.dev");
58
- const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
59
- if ((url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) ||
60
- url.username || url.password || url.search || url.hash) {
61
- throw new Error("ARENA_MERGE_API_BASE must be an HTTPS origin (HTTP loopback is allowed for testing)");
62
- }
72
+ const url = connectorApiBase(config);
63
73
  url.pathname = `${url.pathname.replace(/\/$/, "")}/api/v1/tool-packs/${encodeURIComponent(config.toolPackId)}/registered-users/${encodeURIComponent(config.registeredUserId)}/mcp`;
64
74
  url.searchParams.set("connectors", service);
65
75
  url.searchParams.set("paginated", "true");
@@ -159,23 +169,45 @@ export class ConnectorTools {
159
169
  connections = new Map();
160
170
  loading = new Map();
161
171
  loaded = [];
162
- constructor(allowed, config = {}, disallowed = [], signal) {
172
+ connected;
173
+ files;
174
+ failures = new Map();
175
+ completedWrites = new Set();
176
+ runningWrites = new Set();
177
+ fileSizes = new Map();
178
+ constructor(allowed, config = {}, disallowed = [], signal, options = {}) {
163
179
  this.config = config;
164
180
  this.disallowed = disallowed;
165
181
  this.signal = signal;
166
182
  this.allowed = normalizeConnectors(allowed);
183
+ this.connected = normalizeConnectedConnectors(options.connected) || this.allowed;
184
+ this.files = new ConnectorFiles(config, options, signal);
167
185
  }
168
186
  definitions() {
169
187
  return [...this.registered.values()].map(tool => structuredClone(tool.definition));
170
188
  }
171
189
  validator(name) { return this.registered.get(name)?.validate; }
190
+ normalizeArguments(name, value) { return normalizeConnectorInput(name, value); }
191
+ historyValue(name, value) {
192
+ const schema = this.registered.get(name)?.definition.function.parameters;
193
+ return schema ? connectorSchemaValue(value, schema) : value;
194
+ }
172
195
  has(name) { return this.registered.has(name); }
173
196
  recognizes(name) {
174
197
  return this.allowed.some(service => catalog[service].some(tool => `${service}__${tool.name}` === name));
175
198
  }
176
199
  async discover(service) {
177
- if (!this.allowed.includes(service) || this.disallowed.includes("list_connector_tools")) {
178
- return localDiscoveryError(service, "connector_not_enabled", "This app is not enabled by ARENA_CONNECTORS.");
200
+ service = connectorSlug(service);
201
+ if (!Object.hasOwn(catalog, service)) {
202
+ return this.connected.includes(service) ? localDiscoveryError(service, "connector_not_implemented", "This connected app has no captured tool contract in this harness.")
203
+ : JSON.stringify({ status: "unsupported" });
204
+ }
205
+ if (this.disallowed.includes("list_connector_tools"))
206
+ return localDiscoveryError(service, "connector_not_enabled", "Connector discovery is disabled.");
207
+ if (!this.connected.includes(service))
208
+ return JSON.stringify({ status: "disconnected", connector: service });
209
+ if (!this.allowed.includes(service)) {
210
+ return JSON.stringify({ status: this.connected.includes(service) ? "disabled" : "disconnected", connector: service });
179
211
  }
180
212
  const slug = service;
181
213
  if (this.loaded.includes(slug))
@@ -193,8 +225,10 @@ export class ConnectorTools {
193
225
  }
194
226
  }
195
227
  discoveryResult(service) {
196
- return JSON.stringify({ tools: catalog[service].filter(tool => this.registered.has(`${service}__${tool.name}`)),
197
- status: "enabled", connector: service });
228
+ // Current-reply captures put status first; persisted history later sorts
229
+ // the same value to tools/status/connector through storedJson.
230
+ return JSON.stringify({ status: "enabled", connector: service,
231
+ tools: catalog[service].filter(tool => this.registered.has(`${service}__${tool.name}`)) });
198
232
  }
199
233
  async load(service) {
200
234
  const missing = [["accessKey", "ARENA_MERGE_ACCESS_KEY"], ["toolPackId", "ARENA_MERGE_TOOL_PACK_ID"],
@@ -217,16 +251,15 @@ export class ConnectorTools {
217
251
  for (const captured of expected) {
218
252
  const name = `${service}__${captured.name}`;
219
253
  const tool = byName.get(name);
220
- // Keep the captured description/order, but never invent missing schemas.
221
- // Independent non-mutating validation preserves open JSON dictionaries.
222
- const schema = structuredClone(tool.inputSchema);
223
- const ajvOptions = { strict: false, allErrors: true, removeAdditional: false,
224
- coerceTypes: false, useDefaults: false };
225
- const ajv = String(schema.$schema || "").includes("draft-07")
226
- ? new Ajv(ajvOptions) : new Ajv2020(ajvOptions);
227
- addFormats(ajv);
228
- pending.push({ service, definition: { type: "function", function: { name,
229
- description: captured.description, parameters: schema } }, validate: ajv.compile(schema) });
254
+ // Arena's model schema differs from Merge's schema, including file_path
255
+ // and relaxed nullable fields. Preserve both sides of that boundary.
256
+ const definition = capturedDefinitions[service]?.find(t => t.function.name === name)
257
+ || { type: "function", function: { name, description: captured.description, parameters: structuredClone(tool.inputSchema) } };
258
+ const schema = structuredClone(definition.function.parameters);
259
+ const validateBackend = compileConnectorSchema(tool.inputSchema);
260
+ pending.push({ service, definition: structuredClone(definition), validate: capturedDefinitions[service]
261
+ ? compileConnectorSchema(schema, true) : validateBackend,
262
+ backendSchema: structuredClone(tool.inputSchema), validateBackend });
230
263
  }
231
264
  // Publish atomically: a failed page or schema never leaves half an app loaded.
232
265
  for (const tool of pending)
@@ -246,19 +279,98 @@ export class ConnectorTools {
246
279
  const tool = this.registered.get(name);
247
280
  if (!tool)
248
281
  return connectorFailureText;
282
+ const key = storedJson({ name, args }), write = connectorWrites(name);
283
+ const failed = this.failures.get(key);
284
+ if (failed) {
285
+ const repeated = repeatedConnectorFailure(failed.code);
286
+ if (failed.code === "file_transfer_failed")
287
+ repeated.error = failed.error + " " + repeated.error;
288
+ return connectorErrorText(repeated);
289
+ }
290
+ if (write && (this.runningWrites.has(key) || this.completedWrites.has(key)))
291
+ return connectorErrorText(completedConnectorWrite(this.runningWrites.has(key)));
292
+ if (write)
293
+ this.runningWrites.add(key);
249
294
  try {
250
- const result = await this.connections.get(tool.service).callTool(name, args);
295
+ if (name === "google_drive__download_file") {
296
+ const size = this.fileSizes.get(String(args.input?.file_id));
297
+ if (size !== undefined && size > connectorFileLimit)
298
+ throw oversizedConnectorDownload(size);
299
+ }
300
+ let backendArgs = await this.files.upload(name, structuredClone(args));
301
+ if (connectorDownloadTools.has(name)) {
302
+ // These flags are hidden by the captured Arena schema; file bytes are
303
+ // returned to the workspace instead of being exposed to the model.
304
+ const inputSchema = tool.backendSchema.properties?.input;
305
+ const properties = inputSchema?.properties || inputSchema?.anyOf?.find((s) => s.type === "object")?.properties;
306
+ const flag = properties?.return_download_url ? "return_download_url" : properties?.returnDownloadUrl ? "returnDownloadUrl" : undefined;
307
+ if (flag && backendArgs.input && typeof backendArgs.input === "object")
308
+ backendArgs.input[flag] = true;
309
+ }
310
+ backendArgs = connectorBackendInput(backendArgs, tool.backendSchema);
311
+ if (!tool.validateBackend(backendArgs)) {
312
+ const failure = { code: "invalid_request", error: "The configured MCP backend schema does not accept this captured Arena input. Check the connector version and configuration." };
313
+ this.failures.set(key, failure);
314
+ return connectorErrorText(failure);
315
+ }
316
+ const result = await this.connections.get(tool.service).callTool(name, backendArgs);
317
+ const failure = connectorResultFailure(result, write, name);
318
+ if (failure) {
319
+ this.failures.set(key, failure);
320
+ return connectorErrorText(failure);
321
+ }
322
+ this.rememberFileSizes(name, result);
323
+ const file = await this.files.download(name, result, backendArgs);
324
+ if (write)
325
+ this.completedWrites.add(key);
326
+ if (file !== undefined)
327
+ return JSON.stringify({ status: "success", result_text: file });
251
328
  return formatConnectorResult(result);
252
329
  }
253
330
  catch (error) {
254
331
  if (this.signal?.aborted)
255
332
  throw error;
256
- return connectorFailureText;
333
+ if (error instanceof ConnectorFileError) {
334
+ const failure = { code: "file_transfer_failed", error: error.message };
335
+ if (error.cacheFailure)
336
+ this.failures.set(key, failure);
337
+ return connectorErrorText(failure);
338
+ }
339
+ if (error instanceof McpError && error.code === ErrorCode.InvalidParams) {
340
+ // JSON-RPC error messages can contain credentials or backend request
341
+ // bodies. Preserve the classification without echoing those diagnostics.
342
+ const failure = describeConnectorFailure("The connector rejected the arguments.", write, "invalid_request");
343
+ this.failures.set(key, failure);
344
+ return connectorErrorText(failure);
345
+ }
346
+ // Transport diagnostics can contain credentials. Expose only status/type.
347
+ const failure = describeConnectorFailure(error instanceof StreamableHTTPError ? `HTTP ${error.code}` : "The connector request failed.", write, error instanceof StreamableHTTPError ? undefined : "provider_unavailable", error instanceof StreamableHTTPError ? error.code : undefined);
348
+ this.failures.set(key, failure);
349
+ return connectorErrorText(failure);
350
+ }
351
+ finally {
352
+ this.runningWrites.delete(key);
353
+ }
354
+ }
355
+ rememberFileSizes(name, result) {
356
+ if (!["google_drive__get_file", "google_drive__list_files", "google_drive__search_files"].includes(name))
357
+ return;
358
+ for (const object of connectorResultObjects(result)) {
359
+ const data = object.data && typeof object.data === "object" ? object.data : object;
360
+ for (const file of [data, data.file, ...(Array.isArray(data.files) ? data.files : [])]) {
361
+ if (file && typeof file.id === "string" && file.size !== null && file.size !== undefined && Number.isFinite(Number(file.size)))
362
+ this.fileSizes.set(file.id, Number(file.size));
363
+ }
257
364
  }
258
365
  }
259
366
  async beginTurn(history) {
260
367
  this.registered.clear();
261
368
  this.loaded.length = 0;
369
+ this.failures.clear();
370
+ this.completedWrites.clear();
371
+ this.runningWrites.clear();
372
+ this.fileSizes.clear();
373
+ this.files.reset();
262
374
  if (!history)
263
375
  return;
264
376
  for (const service of loadedConnectorsFromHistory(history)) {
@@ -268,6 +380,52 @@ export class ConnectorTools {
268
380
  if (result.status !== "enabled")
269
381
  throw new Error(result.message);
270
382
  }
383
+ const calls = new Map();
384
+ for (const message of history) {
385
+ if (connectorTurnBoundary(message)) {
386
+ calls.clear();
387
+ this.failures.clear();
388
+ this.completedWrites.clear();
389
+ this.fileSizes.clear();
390
+ this.files.reset();
391
+ }
392
+ if (message.role === "assistant")
393
+ for (const call of message.tool_calls || []) {
394
+ if (!this.has(call.function.name))
395
+ continue;
396
+ try {
397
+ const args = this.normalizeArguments(call.function.name, JSON.parse(call.function.arguments));
398
+ if (this.validator(call.function.name)?.(args))
399
+ calls.set(call.id, { name: call.function.name, args: args });
400
+ }
401
+ catch { /* malformed history */ }
402
+ }
403
+ if (message.role !== "tool")
404
+ continue;
405
+ const call = calls.get(message.tool_call_id);
406
+ if (!call)
407
+ continue;
408
+ try {
409
+ const result = JSON.parse(message.content), key = storedJson(call);
410
+ if (result.status === "error" && typeof result.error === "string" && !result.error.startsWith("This exact write ")) {
411
+ if (["invalid_request", "provider_unavailable", "unknown"].includes(result.code)
412
+ || (result.code === "file_transfer_failed" && /^(Arena did not send this download\.|A security filter at the connector provider)/.test(result.error))) {
413
+ if (!this.failures.has(key))
414
+ this.failures.set(key, { code: result.code, error: result.error });
415
+ }
416
+ if (result.code === "file_transfer_failed")
417
+ this.files.restoreFailure(result.error);
418
+ }
419
+ if (result.status === "success" && connectorWrites(call.name))
420
+ this.completedWrites.add(key);
421
+ if (result.status === "success" && !result.truncated) {
422
+ const mcp = JSON.parse(result.result_text);
423
+ if (Array.isArray(mcp.content))
424
+ this.rememberFileSizes(call.name, mcp);
425
+ }
426
+ }
427
+ catch { /* Plain text or truncated results do not establish successful side effects. */ }
428
+ }
271
429
  }
272
430
  async close() {
273
431
  await Promise.all([...this.connections.values()].map(connection => connection.close()));
@@ -276,25 +434,27 @@ export class ConnectorTools {
276
434
  this.loaded.length = 0;
277
435
  }
278
436
  }
437
+ function connectorTurnBoundary(message) {
438
+ if (message.role !== "user")
439
+ return false;
440
+ const text = typeof message.content === "string" ? message.content : message.content.flatMap(part => "text" in part ? [part.text] : []).join("\n");
441
+ return !/^<arena-system-message>\nThe image\(s\) below are the result of the preceding tool call\.[\s\S]*?<\/arena-system-message>\s*$/.test(text);
442
+ }
279
443
  /** Restore discovery only, never replay page/event writes when resuming a turn. */
280
444
  export function loadedConnectorsFromHistory(history) {
281
445
  const calls = new Map();
282
446
  const loaded = new Set();
283
447
  for (const message of history) {
284
- if (message.role === "user") {
285
- const text = typeof message.content === "string" ? message.content : message.content.flatMap(part => "text" in part ? [part.text] : []).join("\n");
286
- const toolImage = /^<arena-system-message>\nThe image\(s\) below are the result of the preceding tool call\.[\s\S]*?<\/arena-system-message>\s*$/.test(text);
287
- if (!toolImage) {
288
- calls.clear();
289
- loaded.clear();
290
- }
448
+ if (connectorTurnBoundary(message)) {
449
+ calls.clear();
450
+ loaded.clear();
291
451
  }
292
452
  if (message.role === "assistant") {
293
453
  for (const call of message.tool_calls || []) {
294
454
  if (call.function.name !== "list_connector_tools")
295
455
  continue;
296
456
  try {
297
- calls.set(call.id, JSON.parse(call.function.arguments).service);
457
+ calls.set(call.id, connectorSlug(JSON.parse(call.function.arguments).service));
298
458
  }
299
459
  catch { /* malformed history */ }
300
460
  }
@@ -303,7 +463,7 @@ export function loadedConnectorsFromHistory(history) {
303
463
  try {
304
464
  const service = calls.get(message.tool_call_id);
305
465
  const result = JSON.parse(message.content);
306
- if ((service === "notion" || service === "google_calendar") && result.status === "enabled" && result.connector === service)
466
+ if (service && Object.hasOwn(catalog, service) && result.status === "enabled" && result.connector === service)
307
467
  loaded.add(service);
308
468
  }
309
469
  catch { /* Only a paired, successful discovery enables restoration. */ }