@qwen-code/arena-agent 0.0.10-dev.8-test.0 → 0.0.10-test.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.
Files changed (151) hide show
  1. package/.env.example +61 -10
  2. package/CHANGELOG.md +148 -17
  3. package/README.md +309 -46
  4. package/dist/agent.d.ts +20 -6
  5. package/dist/agent.js +353 -72
  6. package/dist/agent.js.map +1 -1
  7. package/dist/anthropic.d.ts +1 -1
  8. package/dist/anthropic.js +46 -57
  9. package/dist/anthropic.js.map +1 -1
  10. package/dist/arena-history.d.ts +12 -0
  11. package/dist/arena-history.js +119 -0
  12. package/dist/arena-history.js.map +1 -0
  13. package/dist/ask-user.js +44 -2
  14. package/dist/ask-user.js.map +1 -1
  15. package/dist/attachment-limits.d.ts +4 -0
  16. package/dist/attachment-limits.js +10 -0
  17. package/dist/attachment-limits.js.map +1 -0
  18. package/dist/attachments.d.ts +4 -2
  19. package/dist/attachments.js +9 -11
  20. package/dist/attachments.js.map +1 -1
  21. package/dist/brave-search.js +11 -7
  22. package/dist/brave-search.js.map +1 -1
  23. package/dist/canonical-data.d.ts +9 -0
  24. package/dist/canonical-data.js +12 -3
  25. package/dist/canonical-data.js.map +1 -1
  26. package/dist/cli.js +140 -40
  27. package/dist/cli.js.map +1 -1
  28. package/dist/code-tool-schema.d.ts +3 -0
  29. package/dist/code-tool-schema.js +92 -0
  30. package/dist/code-tool-schema.js.map +1 -0
  31. package/dist/code-tools.d.ts +2 -1
  32. package/dist/code-tools.js +103 -31
  33. package/dist/code-tools.js.map +1 -1
  34. package/dist/compaction-threshold.d.ts +3 -0
  35. package/dist/compaction-threshold.js +6 -0
  36. package/dist/compaction-threshold.js.map +1 -0
  37. package/dist/compaction.d.ts +24 -7
  38. package/dist/compaction.js +242 -66
  39. package/dist/compaction.js.map +1 -1
  40. package/dist/config.d.ts +17 -0
  41. package/dist/config.js +30 -5
  42. package/dist/config.js.map +1 -1
  43. package/dist/connector-errors.d.ts +16 -0
  44. package/dist/connector-errors.js +69 -0
  45. package/dist/connector-errors.js.map +1 -0
  46. package/dist/connector-files.d.ts +31 -0
  47. package/dist/connector-files.js +249 -0
  48. package/dist/connector-files.js.map +1 -0
  49. package/dist/connector-input.d.ts +10 -0
  50. package/dist/connector-input.js +79 -0
  51. package/dist/connector-input.js.map +1 -0
  52. package/dist/connector-mcp.d.ts +60 -0
  53. package/dist/connector-mcp.js +474 -0
  54. package/dist/connector-mcp.js.map +1 -0
  55. package/dist/connectors.d.ts +13 -0
  56. package/dist/connectors.js +69 -0
  57. package/dist/connectors.js.map +1 -0
  58. package/dist/fetch-page.js +2 -2
  59. package/dist/fetch-page.js.map +1 -1
  60. package/dist/history.d.ts +16 -5
  61. package/dist/history.js +73 -14
  62. package/dist/history.js.map +1 -1
  63. package/dist/image-choice.d.ts +23 -0
  64. package/dist/image-choice.js +190 -0
  65. package/dist/image-choice.js.map +1 -0
  66. package/dist/image-input-fallback.js +5 -0
  67. package/dist/image-input-fallback.js.map +1 -1
  68. package/dist/image-model.d.ts +6 -0
  69. package/dist/image-model.js +32 -0
  70. package/dist/image-model.js.map +1 -0
  71. package/dist/midturn-checkpoint-hook.d.ts +14 -1
  72. package/dist/midturn-checkpoint-hook.js.map +1 -1
  73. package/dist/mode.js +1 -1
  74. package/dist/mode.js.map +1 -1
  75. package/dist/model-capabilities.js +18 -8
  76. package/dist/model-capabilities.js.map +1 -1
  77. package/dist/model-router-media.js +55 -3
  78. package/dist/model-router-media.js.map +1 -1
  79. package/dist/model-stream.d.ts +16 -0
  80. package/dist/model-stream.js +129 -0
  81. package/dist/model-stream.js.map +1 -0
  82. package/dist/openai-responses.d.ts +2 -1
  83. package/dist/openai-responses.js +85 -88
  84. package/dist/openai-responses.js.map +1 -1
  85. package/dist/process-manager.js +9 -9
  86. package/dist/process-manager.js.map +1 -1
  87. package/dist/prompts.d.ts +0 -2
  88. package/dist/prompts.js +10 -60
  89. package/dist/prompts.js.map +1 -1
  90. package/dist/protocol.d.ts +5 -1
  91. package/dist/protocol.js +23 -2
  92. package/dist/protocol.js.map +1 -1
  93. package/dist/provider.d.ts +18 -0
  94. package/dist/provider.js +120 -51
  95. package/dist/provider.js.map +1 -1
  96. package/dist/repo.d.ts +1 -1
  97. package/dist/repo.js +26 -4
  98. package/dist/repo.js.map +1 -1
  99. package/dist/routify-web-fetch.js +2 -2
  100. package/dist/routify-web-fetch.js.map +1 -1
  101. package/dist/server.js +55 -27
  102. package/dist/server.js.map +1 -1
  103. package/dist/session-memory-prompts.d.ts +3 -1
  104. package/dist/session-memory-prompts.js +4 -2
  105. package/dist/session-memory-prompts.js.map +1 -1
  106. package/dist/side-query.js +5 -0
  107. package/dist/side-query.js.map +1 -1
  108. package/dist/spec.d.ts +5 -4
  109. package/dist/spec.js +31 -23
  110. package/dist/spec.js.map +1 -1
  111. package/dist/startup-config.d.ts +39 -0
  112. package/dist/startup-config.js +347 -0
  113. package/dist/startup-config.js.map +1 -0
  114. package/dist/startup-main-config.d.ts +63 -0
  115. package/dist/startup-main-config.js +94 -0
  116. package/dist/startup-main-config.js.map +1 -0
  117. package/dist/startup-tool-config.d.ts +8 -0
  118. package/dist/startup-tool-config.js +116 -0
  119. package/dist/startup-tool-config.js.map +1 -0
  120. package/dist/summary-compaction.d.ts +29 -0
  121. package/dist/{legacy-compaction.js → summary-compaction.js} +79 -14
  122. package/dist/summary-compaction.js.map +1 -0
  123. package/dist/tools.d.ts +5 -1
  124. package/dist/tools.js +195 -68
  125. package/dist/tools.js.map +1 -1
  126. package/dist/tui.js +26 -6
  127. package/dist/tui.js.map +1 -1
  128. package/dist/types.d.ts +21 -1
  129. package/dist/web/app.js +30 -5
  130. package/dist/web/app.js.map +1 -1
  131. package/dist/workspace.js +61 -13
  132. package/dist/workspace.js.map +1 -1
  133. package/docs/BINARY_DISTRIBUTION.md +44 -8
  134. package/docs/MODES_AND_RELEASES.md +79 -6
  135. package/docs/SDK.md +1 -0
  136. package/modes/code-arena/capture-provenance.json +57 -0
  137. package/modes/code-arena/full-stack/dependencies.lock.json +8670 -0
  138. package/modes/code-arena/full-stack/system-prompt.txt +1 -1
  139. package/modes/code-arena/full-stack/template/eslint.config.mjs +3 -4
  140. package/modes/code-arena/full-stack/template/postcss.config.mjs +2 -2
  141. package/modes/code-arena/full-stack/tools.json +186 -186
  142. package/modes/code-arena/html/system-prompt.txt +1 -1
  143. package/modes/code-arena/html/tools.json +123 -123
  144. package/modes/code-arena/react/dependencies.lock.json +2707 -0
  145. package/modes/code-arena/react/system-prompt.txt +4 -3
  146. package/modes/code-arena/react/tools.json +178 -184
  147. package/package.json +7 -2
  148. package/scripts/README.md +23 -4
  149. package/web/styles.css +22 -0
  150. package/dist/legacy-compaction.d.ts +0 -16
  151. package/dist/legacy-compaction.js.map +0 -1
@@ -14,6 +14,7 @@ import { executeBraveWebSearch } from "./brave-search.js";
14
14
  import { FetchPageReader } from "./fetch-page.js";
15
15
  import { replaceFirstText, replaceUniqueText } from "./file-edit.js";
16
16
  import { detectedImageMimeType, generatedImageBytesForExtension } from "./image.js";
17
+ import { codeArenaImageModel } from "./image-model.js";
17
18
  import { supportsImageInput } from "./model-capabilities.js";
18
19
  import { generateImageWithModelRouter, } from "./model-router-media.js";
19
20
  import { executeRoutifyWebFetch, routifyWebFetchEnabled, } from "./routify-web-fetch.js";
@@ -224,18 +225,18 @@ function hasReadableImageStructure(data, mediaType) {
224
225
  }
225
226
  return false;
226
227
  }
227
- // All 39 successful, unmutated list_files captures use this exact order,
228
- // independently of whether the requested path is the project root or src/.
229
- // It is the seed manifest order, not an alphabetical/filesystem order.
228
+ // Unmutated React captures on 2026-10-02, 10-13 and 10-21 share this order.
229
+ // Older September captures used a different seed order. Preserve the current
230
+ // manifest order for both root and scoped listings, not filesystem ordering.
230
231
  const capturedReactSeedFileOrder = [
231
- "src/utils/cn.ts",
232
232
  "src/index.css",
233
233
  "src/main.tsx",
234
+ "src/utils/cn.ts",
234
235
  "src/App.tsx",
235
- "vite.config.ts",
236
+ "index.html",
236
237
  "tsconfig.json",
238
+ "vite.config.ts",
237
239
  "package.json",
238
- "index.html",
239
240
  ];
240
241
  const capturedFullStackSeedFileOrder = [
241
242
  "postcss.config.mjs",
@@ -441,6 +442,17 @@ function stringValue(value) {
441
442
  }
442
443
  function contentTypeForFile(filePath) {
443
444
  const extension = path.extname(filePath).toLowerCase();
445
+ const capturedTypes = {
446
+ ".py": "text/x-python",
447
+ ".sh": "text/x-shellscript",
448
+ ".sql": "application/sql",
449
+ ".yaml": "application/x-yaml",
450
+ ".yml": "application/x-yaml",
451
+ ".mjs": "text/plain",
452
+ ".c": "text/plain",
453
+ };
454
+ if (capturedTypes[extension])
455
+ return capturedTypes[extension];
444
456
  if ([".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mts", ".cts"].includes(extension)) {
445
457
  return "text/javascript";
446
458
  }
@@ -578,6 +590,17 @@ function validationIssues(toolName, value, errors, definitions) {
578
590
  continue;
579
591
  }
580
592
  const actual = missing ? undefined : valueAtPath(value, error.instancePath);
593
+ if (error.keyword === "enum") {
594
+ const options = record(error.params).allowedValues;
595
+ issues.push({
596
+ received: actual,
597
+ code: "invalid_enum_value",
598
+ options,
599
+ path: pathParts,
600
+ message: `Invalid enum value. Expected ${options.map((option) => `'${option}'`).join(" | ")}, received '${actual}'`,
601
+ });
602
+ continue;
603
+ }
581
604
  const expected = error.keyword === "type"
582
605
  ? String(record(error.params).type || "string")
583
606
  : requiredPropertyType(toolName, key, definitions);
@@ -794,12 +817,36 @@ export class CodeToolExecutor {
794
817
  this.seedFileRank = capturedSeedFileRank(config.mode);
795
818
  addFormats(this.ajv);
796
819
  for (const definition of this.definitions) {
797
- this.validators.set(definition.function.name, this.ajv.compile(definition.function.parameters));
820
+ const name = definition.function.name;
821
+ // The current execution docs add an optional millisecond timeout. Keep
822
+ // the outgoing captured contract intact until a new capture is approved.
823
+ const parameters = structuredClone(definition.function.parameters);
824
+ if (name === "bash") {
825
+ parameters.properties = {
826
+ ...record(parameters.properties),
827
+ timeout: { type: "integer", minimum: 1, maximum: 600_000 },
828
+ };
829
+ }
830
+ this.validators.set(name, this.ajv.compile(parameters));
831
+ }
832
+ // React Codex uses the same runtime under a different name. Like the
833
+ // existing hidden Codex tools, accept calls without inventing a public
834
+ // contract or switching the standard React prompt/tool set.
835
+ const bashValidator = this.validators.get("bash");
836
+ if (config.mode === "react" &&
837
+ bashValidator &&
838
+ !disallowed.has("shell_command")) {
839
+ this.validators.set("shell_command", bashValidator);
798
840
  }
799
841
  // Hidden mode: advertise nothing, but keep the call executable.
800
842
  if (!advertiseApplyPatch && !disallowed.has("apply_patch")) {
801
843
  this.validators.set("apply_patch", this.ajv.compile(APPLY_PATCH_PARAMETERS));
802
844
  }
845
+ // Captured React/HTML histories call this hidden tool. No public schema was
846
+ // captured: accept its object payload without adding model-visible tools.
847
+ if (config.mode !== "full-stack" && !disallowed.has("update_plan")) {
848
+ this.validators.set("update_plan", this.ajv.compile({ type: "object" }));
849
+ }
803
850
  }
804
851
  // The tools offered to the model for this session, with captured schemas
805
852
  // and descriptions adjusted for current capabilities and workspace runtime.
@@ -821,10 +868,9 @@ export class CodeToolExecutor {
821
868
  const argumentsValue = (this.config.mode === "react" && typeof parsedArguments === "string"
822
869
  ? {}
823
870
  : structuredClone(parsedArguments));
824
- // The captured provider advertises these fields as required, but its
825
- // runtime still applies the documented defaults when a model omits
826
- // them. Preserve the byte-identical outgoing schema while matching the
827
- // observed execution behavior.
871
+ // Captured schemas advertise these fields as required. Keep those public
872
+ // fixtures intact while applying runtime defaults. Since 2026-10-19,
873
+ // official Code Arena accepts optional nulls as omission for all providers.
828
874
  if (name === "read_file") {
829
875
  argumentsValue.offset ??= 1;
830
876
  argumentsValue.limit ??= 2000;
@@ -832,10 +878,13 @@ export class CodeToolExecutor {
832
878
  else if (name === "list_files" || name === "glob_files") {
833
879
  argumentsValue.path ??= "";
834
880
  }
835
- else if (this.config.mode === "full-stack" && name === "bash" &&
881
+ else if ((name === "bash" || name === "shell_command") &&
836
882
  argumentsValue && typeof argumentsValue === "object" &&
837
- !Array.isArray(argumentsValue) && argumentsValue.workdir === undefined) {
838
- argumentsValue.workdir = "";
883
+ !Array.isArray(argumentsValue)) {
884
+ argumentsValue.workdir ??= "";
885
+ argumentsValue.description ??= "";
886
+ if (argumentsValue.timeout === null)
887
+ delete argumentsValue.timeout;
839
888
  }
840
889
  else if (name === "grep_files") {
841
890
  argumentsValue.path ??= "";
@@ -847,6 +896,21 @@ export class CodeToolExecutor {
847
896
  argumentsValue["-C"] ??= 0;
848
897
  argumentsValue.context ??= 0;
849
898
  }
899
+ if (argumentsValue && typeof argumentsValue === "object" && !Array.isArray(argumentsValue)) {
900
+ if (name === "web_fetch") {
901
+ argumentsValue.format ??= "markdown";
902
+ }
903
+ else if (name === "fetch_media") {
904
+ argumentsValue.media_type ??= "both";
905
+ argumentsValue.count ??= 6;
906
+ argumentsValue.orientation ??= "any";
907
+ argumentsValue.size ??= "any";
908
+ argumentsValue.locale ??= "en-US";
909
+ }
910
+ else if (name === "build_and_start") {
911
+ argumentsValue.description ??= "";
912
+ }
913
+ }
850
914
  return argumentsValue;
851
915
  }
852
916
  validationMessage(name, value, validate) {
@@ -1007,6 +1071,8 @@ export class CodeToolExecutor {
1007
1071
  return this.editCodeFile(String(values.path), String(values.context), String(values.replacement));
1008
1072
  case "apply_patch":
1009
1073
  return this.applyCodePatch(String(values.input));
1074
+ case "update_plan":
1075
+ return { status: "success" };
1010
1076
  case "delete_file":
1011
1077
  return this.deleteCodeFile(String(values.path));
1012
1078
  case "list_files":
@@ -1020,7 +1086,8 @@ export class CodeToolExecutor {
1020
1086
  case "build_project":
1021
1087
  return this.buildProject();
1022
1088
  case "bash":
1023
- return this.fullStackBash(String(values.command), String(values.workdir));
1089
+ case "shell_command":
1090
+ return this.codeBash(String(values.command), String(values.workdir), values.timeout);
1024
1091
  case "build_and_start":
1025
1092
  return this.buildAndStart();
1026
1093
  case "web_search":
@@ -1531,6 +1598,11 @@ export class CodeToolExecutor {
1531
1598
  this.forgetListedPath(this.relativePath(target));
1532
1599
  return { status: "success" };
1533
1600
  }
1601
+ discoverableFile(filePath) {
1602
+ // Full Stack captures expose the lock to shell/read_file, but omit it
1603
+ // from both project discovery tools, even before any package installation.
1604
+ return this.config.mode !== "full-stack" || this.relativePath(filePath) !== "package-lock.json";
1605
+ }
1534
1606
  async listCodeFiles(rawPath) {
1535
1607
  if (this.config.mode === "react" && rawPath === "/")
1536
1608
  rawPath = ".";
@@ -1542,7 +1614,7 @@ export class CodeToolExecutor {
1542
1614
  !existsSync(target)) {
1543
1615
  return { status: "success", files: [] };
1544
1616
  }
1545
- const files = this.orderListedFiles(await this.walkFiles(target));
1617
+ const files = this.orderListedFiles((await this.walkFiles(target)).filter(file => this.discoverableFile(file)));
1546
1618
  return {
1547
1619
  status: "success",
1548
1620
  files: (this.config.mode === "react" ? files.slice(0, 500) : files)
@@ -1744,6 +1816,7 @@ export class CodeToolExecutor {
1744
1816
  return { status: "success", paths: [], truncated: false };
1745
1817
  }
1746
1818
  const allPaths = files
1819
+ .filter(file => this.discoverableFile(file))
1747
1820
  .filter((filePath) => matchesGlob(path.relative(target, filePath).split(path.sep).join("/"), pattern) || (this.config.mode === "react" && matchesGlob(this.relativePath(filePath), pattern)))
1748
1821
  .map((filePath) => this.relativePath(filePath));
1749
1822
  return {
@@ -1859,16 +1932,23 @@ export class CodeToolExecutor {
1859
1932
  stderr: this.virtualizeCodeOutput(result.stderr),
1860
1933
  };
1861
1934
  }
1862
- async fullStackBash(command, workdir) {
1935
+ async codeBash(command, workdir, timeoutMs) {
1936
+ if (!command.trim()) {
1937
+ return { status: "error", message: "Command cannot be empty" };
1938
+ }
1863
1939
  const cwd = workdir.trim() || ".";
1864
1940
  if (path.isAbsolute(cwd) || cwd.includes("..")) {
1865
1941
  throw new Error(`Invalid workdir: ${cwd}. Commands run from the project root by default. Only use workdir for relative subdirectories, never absolute paths.`);
1866
1942
  }
1867
- const configuredTimeout = Number(process.env.CODE_HARNESS_BASH_TIMEOUT_SECONDS || 300);
1868
- const timeoutSeconds = Number.isFinite(configuredTimeout) && configuredTimeout > 0
1869
- ? configuredTimeout
1870
- : 300;
1943
+ const configuredTimeout = Number(process.env.CODE_HARNESS_BASH_TIMEOUT_SECONDS || 180);
1944
+ const timeoutSeconds = timeoutMs !== undefined
1945
+ ? timeoutMs / 1000
1946
+ : Number.isFinite(configuredTimeout) && configuredTimeout > 0
1947
+ ? configuredTimeout
1948
+ : 180;
1871
1949
  const result = await this.bash(command, cwd, timeoutSeconds);
1950
+ if (result.timed_out)
1951
+ return { status: "error", message: "Command timed out" };
1872
1952
  const exitCode = result.exit_code;
1873
1953
  const stdout = String(result.stdout || "");
1874
1954
  const stderr = String(result.stderr || "");
@@ -2068,12 +2148,6 @@ export class CodeToolExecutor {
2068
2148
  reject(this.signal.reason || new Error("operation cancelled"));
2069
2149
  return;
2070
2150
  }
2071
- // 生产契约:status 恒为 "completed"(包括非零退出码),超时无参考样本,
2072
- // 按最小猜测同样返回 completed + exit_code null,stderr 附超时说明。
2073
- if (timedOut && this.config.mode !== "full-stack") {
2074
- stderr +=
2075
- (stderr ? "\n" : "") + `command exceeded ${timeoutSeconds}s`;
2076
- }
2077
2151
  const out = capBashOutput(stdout);
2078
2152
  const err = capBashOutput(stderr);
2079
2153
  resolve({
@@ -2081,6 +2155,7 @@ export class CodeToolExecutor {
2081
2155
  stderr: err.text,
2082
2156
  stdout: out.text,
2083
2157
  exit_code: timedOut ? null : code,
2158
+ timed_out: timedOut,
2084
2159
  duration_ms: Date.now() - startedAt,
2085
2160
  stderr_truncated: err.truncated,
2086
2161
  stdout_truncated: out.truncated,
@@ -2299,9 +2374,6 @@ export class CodeToolExecutor {
2299
2374
  throw new Error("file_path must end in .jpg, .jpeg, or .png");
2300
2375
  }
2301
2376
  mkdirSync(path.dirname(target), { recursive: true });
2302
- const model = process.env.CODE_HARNESS_IMAGE_MODEL ||
2303
- process.env.ARENA_IMAGE_MODEL ||
2304
- "gemini-3.1-flash-image";
2305
2377
  const references = [];
2306
2378
  for (const imagePath of images || []) {
2307
2379
  const source = await this.confinedPath(imagePath);
@@ -2322,7 +2394,7 @@ export class CodeToolExecutor {
2322
2394
  }
2323
2395
  const generated = await generateImageWithModelRouter({
2324
2396
  images: references,
2325
- model,
2397
+ model: codeArenaImageModel(),
2326
2398
  prompt,
2327
2399
  signal: this.signal,
2328
2400
  size: process.env.CODE_HARNESS_IMAGE_SIZE ||