orbitx 0.2.1 → 0.2.4

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 (113) hide show
  1. package/Readme.md +26 -0
  2. package/dist/core/ai-provider.d.ts +31 -1
  3. package/dist/core/ai-provider.d.ts.map +1 -1
  4. package/dist/core/ai-provider.js.map +1 -1
  5. package/dist/core/anthropic-provider.d.ts +1 -0
  6. package/dist/core/anthropic-provider.d.ts.map +1 -1
  7. package/dist/core/anthropic-provider.js +83 -3
  8. package/dist/core/anthropic-provider.js.map +1 -1
  9. package/dist/core/base-agent.d.ts +13 -0
  10. package/dist/core/base-agent.d.ts.map +1 -1
  11. package/dist/core/base-agent.js +77 -109
  12. package/dist/core/base-agent.js.map +1 -1
  13. package/dist/core/deepseek-provider.d.ts +2 -0
  14. package/dist/core/deepseek-provider.d.ts.map +1 -1
  15. package/dist/core/deepseek-provider.js +56 -2
  16. package/dist/core/deepseek-provider.js.map +1 -1
  17. package/dist/core/image-describer.d.ts +7 -1
  18. package/dist/core/image-describer.d.ts.map +1 -1
  19. package/dist/core/image-describer.js +5 -1
  20. package/dist/core/image-describer.js.map +1 -1
  21. package/dist/core/ollama-provider.d.ts +1 -0
  22. package/dist/core/ollama-provider.d.ts.map +1 -1
  23. package/dist/core/ollama-provider.js +45 -1
  24. package/dist/core/ollama-provider.js.map +1 -1
  25. package/dist/core/openai-provider.d.ts +1 -0
  26. package/dist/core/openai-provider.d.ts.map +1 -1
  27. package/dist/core/openai-provider.js +54 -1
  28. package/dist/core/openai-provider.js.map +1 -1
  29. package/dist/core/think-effort.d.ts +21 -0
  30. package/dist/core/think-effort.d.ts.map +1 -0
  31. package/dist/core/think-effort.js +19 -0
  32. package/dist/core/think-effort.js.map +1 -0
  33. package/dist/core/worker-agent.d.ts +43 -0
  34. package/dist/core/worker-agent.d.ts.map +1 -0
  35. package/dist/core/worker-agent.js +40 -0
  36. package/dist/core/worker-agent.js.map +1 -0
  37. package/dist/index.d.ts +8 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +4 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/templates/simple.d.ts +2 -0
  42. package/dist/templates/simple.d.ts.map +1 -1
  43. package/dist/templates/simple.js.map +1 -1
  44. package/dist/tests/index.d.ts +1 -0
  45. package/dist/tests/index.d.ts.map +1 -1
  46. package/dist/tests/index.js +1 -0
  47. package/dist/tests/index.js.map +1 -1
  48. package/dist/tests/tools/agent/agent-tools.test.d.ts +2 -0
  49. package/dist/tests/tools/agent/agent-tools.test.d.ts.map +1 -0
  50. package/dist/tests/tools/agent/agent-tools.test.js +156 -0
  51. package/dist/tests/tools/agent/agent-tools.test.js.map +1 -0
  52. package/dist/tools/agent/hire.d.ts +6 -0
  53. package/dist/tools/agent/hire.d.ts.map +1 -0
  54. package/dist/tools/agent/hire.js +32 -0
  55. package/dist/tools/agent/hire.js.map +1 -0
  56. package/dist/tools/agent/index.d.ts +27 -0
  57. package/dist/tools/agent/index.d.ts.map +1 -0
  58. package/dist/tools/agent/index.js +31 -0
  59. package/dist/tools/agent/index.js.map +1 -0
  60. package/dist/tools/agent/interaction.d.ts +25 -0
  61. package/dist/tools/agent/interaction.d.ts.map +1 -0
  62. package/dist/tools/agent/interaction.js +14 -0
  63. package/dist/tools/agent/interaction.js.map +1 -0
  64. package/dist/tools/agent/list.d.ts +5 -0
  65. package/dist/tools/agent/list.d.ts.map +1 -0
  66. package/dist/tools/agent/list.js +16 -0
  67. package/dist/tools/agent/list.js.map +1 -0
  68. package/dist/tools/agent/prompt.d.ts +6 -0
  69. package/dist/tools/agent/prompt.d.ts.map +1 -0
  70. package/dist/tools/agent/prompt.js +73 -0
  71. package/dist/tools/agent/prompt.js.map +1 -0
  72. package/dist/tools/agent/registry.d.ts +33 -0
  73. package/dist/tools/agent/registry.d.ts.map +1 -0
  74. package/dist/tools/agent/registry.js +68 -0
  75. package/dist/tools/agent/registry.js.map +1 -0
  76. package/dist/tools/agent/report.d.ts +12 -0
  77. package/dist/tools/agent/report.d.ts.map +1 -0
  78. package/dist/tools/agent/report.js +31 -0
  79. package/dist/tools/agent/report.js.map +1 -0
  80. package/dist/tools/fs/edit-file.d.ts.map +1 -1
  81. package/dist/tools/fs/edit-file.js +9 -8
  82. package/dist/tools/fs/edit-file.js.map +1 -1
  83. package/dist/tools/fs/list-dir.d.ts.map +1 -1
  84. package/dist/tools/fs/list-dir.js +0 -1
  85. package/dist/tools/fs/list-dir.js.map +1 -1
  86. package/dist/tools/fs/read-file.js +3 -3
  87. package/dist/tools/fs/read-file.js.map +1 -1
  88. package/dist/tools/fs/utils.d.ts +7 -0
  89. package/dist/tools/fs/utils.d.ts.map +1 -1
  90. package/dist/tools/fs/utils.js +9 -2
  91. package/dist/tools/fs/utils.js.map +1 -1
  92. package/dist/tools/utils/index.d.ts +1 -0
  93. package/dist/tools/utils/index.d.ts.map +1 -1
  94. package/dist/tools/utils/index.js +4 -1
  95. package/dist/tools/utils/index.js.map +1 -1
  96. package/dist/tools/utils/read-image.d.ts +12 -0
  97. package/dist/tools/utils/read-image.d.ts.map +1 -0
  98. package/dist/tools/utils/read-image.js +70 -0
  99. package/dist/tools/utils/read-image.js.map +1 -0
  100. package/docs/agents.md +181 -0
  101. package/docs/api-reference.md +54 -0
  102. package/docs/getting-started.md +78 -0
  103. package/docs/index.md +23 -0
  104. package/docs/mcp-architecture.md +103 -0
  105. package/docs/providers.md +151 -0
  106. package/docs/skills.md +68 -0
  107. package/docs/streaming.md +116 -0
  108. package/docs/tools.md +179 -0
  109. package/package.json +4 -3
  110. package/dist/tests/mcp.test.d.ts +0 -2
  111. package/dist/tests/mcp.test.d.ts.map +0 -1
  112. package/dist/tests/mcp.test.js +0 -3
  113. package/dist/tests/mcp.test.js.map +0 -1
@@ -0,0 +1,31 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ /**
3
+ * For WorkerAgents, not planners: include this in a worker's own
4
+ * `allowedTools` (and register it on whatever MCPServer that worker uses)
5
+ * so it can hand a result back to whoever hired and prompted it. Calling
6
+ * this always ends the worker's current turn immediately
7
+ * (stopIterationAfterUsingThisTool) — AgentPromptTool picks the reported
8
+ * text back up on the hiring agent's side once agent.run() resolves.
9
+ */
10
+ export const AgentReportTool = () => new MCPTool({
11
+ name: "agent-report",
12
+ description: "report your result back to whichever agent hired and prompted you, then stop. This ends your current turn immediately — do not call any other tool or add commentary after this. The hiring agent decides what happens next: it may prompt you again to continue this same task, or move on and not call you again if your report shows you're done.",
13
+ inputs: [
14
+ {
15
+ name: "report",
16
+ type: "string",
17
+ description: "the result/findings/answer to hand back — write it so it's understandable on its own, without the hiring agent needing to see your internal reasoning",
18
+ required: true,
19
+ },
20
+ ],
21
+ stopIterationAfterUsingThisTool: true,
22
+ execute: async (_envID, inputs) => {
23
+ const { report } = inputs;
24
+ if (!report || typeof report !== "string") {
25
+ throw new Error("report must be a non-empty string");
26
+ }
27
+ return { report };
28
+ },
29
+ });
30
+ export default AgentReportTool;
31
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/tools/agent/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC;IAC7C,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,sVAAsV;IACnW,MAAM,EAAE;QACJ;YACI,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,uJAAuJ;YACpK,QAAQ,EAAE,IAAI;SACjB;KACJ;IACD,+BAA+B,EAAE,IAAI;IACrC,OAAO,EAAE,KAAK,EAAE,MAAc,EAAE,MAA2B,EAAgB,EAAE;QACzE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;QAE1B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,CAAC;IACtB,CAAC;CACJ,CAAC,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"edit-file.d.ts","sourceRoot":"","sources":["../../../src/tools/fs/edit-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,eAAO,MAAM,cAAc,8BAiFzB,CAAC;AAEH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"edit-file.d.ts","sourceRoot":"","sources":["../../../src/tools/fs/edit-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,eAAO,MAAM,cAAc,8BAkFzB,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -4,7 +4,7 @@ import { FsInteraction } from "./interaction.js";
4
4
  import { resolvePath, toLines } from "./utils.js";
5
5
  export const FsEditFileTool = () => new MCPTool({
6
6
  name: "fs-edit-file",
7
- description: "replace a specific line range in an existing file without rewriting the whole file. lines are 0-indexed; the range [offsetLine, offsetLine+limitLine) is replaced entirely by `content` (use limitLine 0 to insert at offsetLine without deleting anything). read the file first (fs-read-file) to get accurate line numbers, since another edit may have shifted them.",
7
+ description: "replace a specific line range in an existing file without rewriting the whole file. lines are 1-indexed (line 1 is the first line of the file, matching fs-read-file); the range [offsetLine, offsetLine+limitLine) 1-indexed lines is replaced entirely by `content` (use limitLine 0 to insert before offsetLine without deleting anything; use offsetLine totalLines+1 to append at end of file). read the file first (fs-read-file) to get accurate line numbers, since another edit may have shifted them.",
8
8
  inputs: [
9
9
  {
10
10
  name: "path",
@@ -15,7 +15,7 @@ export const FsEditFileTool = () => new MCPTool({
15
15
  {
16
16
  name: "offsetLine",
17
17
  type: "number",
18
- description: "0-indexed line to start replacing from",
18
+ description: "1-indexed line to start replacing from (line 1 is the first line of the file)",
19
19
  required: true,
20
20
  },
21
21
  {
@@ -34,8 +34,8 @@ export const FsEditFileTool = () => new MCPTool({
34
34
  customClass: new FsInteraction(),
35
35
  execute: async (_envID, inputs, _mcp, customClass) => {
36
36
  const { path, offsetLine, limitLine, content } = inputs;
37
- if (typeof offsetLine !== "number" || offsetLine < 0) {
38
- throw new Error("offsetLine must be a non-negative number");
37
+ if (typeof offsetLine !== "number" || offsetLine < 1) {
38
+ throw new Error("offsetLine is 1-indexed (line 1 is the first line of the file) and must be >= 1");
39
39
  }
40
40
  if (typeof limitLine !== "number" || limitLine < 0) {
41
41
  throw new Error("limitLine must be a non-negative number");
@@ -55,12 +55,13 @@ export const FsEditFileTool = () => new MCPTool({
55
55
  throw err;
56
56
  }
57
57
  const lines = toLines(raw);
58
- if (offsetLine > lines.length) {
59
- throw new Error(`offsetLine ${offsetLine} is past end of file (${lines.length} lines)`);
58
+ const index = offsetLine - 1;
59
+ if (index > lines.length) {
60
+ throw new Error(`offsetLine ${offsetLine} is past end of file (${lines.length} lines; use offsetLine ${lines.length + 1} to append)`);
60
61
  }
61
- const removedCount = Math.min(limitLine, lines.length - offsetLine);
62
+ const removedCount = Math.min(limitLine, lines.length - index);
62
63
  const insertedLines = content.length === 0 ? [] : content.split(/\r\n|\r|\n/);
63
- lines.splice(offsetLine, removedCount, ...insertedLines);
64
+ lines.splice(index, removedCount, ...insertedLines);
64
65
  await writeFile(fullPath, lines.join("\n"), { encoding: "utf-8" });
65
66
  return {
66
67
  message: "success",
@@ -1 +1 @@
1
- {"version":3,"file":"edit-file.js","sourceRoot":"","sources":["../../../src/tools/fs/edit-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAgB;IAC3D,IAAI,EAAE,cAAc;IACpB,WAAW,EACP,yWAAyW;IAC7W,MAAM,EAAE;QACJ;YACI,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,IAAI;SACjB;QACD;YACI,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wCAAwC;YACrD,QAAQ,EAAE,IAAI;SACjB;QACD;YACI,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2DAA2D;YACxE,QAAQ,EAAE,IAAI;SACjB;QACD;YACI,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wGAAwG;YACrH,QAAQ,EAAE,IAAI;SACjB;KACJ;IACD,WAAW,EAAE,IAAI,aAAa,EAAE;IAChC,OAAO,EAAE,KAAK,EACV,MAAc,EACd,MAA2B,EAC3B,IAAU,EACV,WAA2B,EACf,EAAE;QACd,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAExD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,WAAW,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE9D,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;YACzE,MAAM,GAAG,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAE3B,IAAI,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,cAAc,UAAU,yBAAyB,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;QACpE,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAE9E,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,aAAa,CAAC,CAAC;QAEzD,MAAM,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,OAAO;YACH,OAAO,EAAE,SAAS;YAClB,YAAY,EAAE,YAAY;YAC1B,aAAa,EAAE,aAAa,CAAC,MAAM;YACnC,UAAU,EAAE,KAAK,CAAC,MAAM;SAC3B,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AAEH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"edit-file.js","sourceRoot":"","sources":["../../../src/tools/fs/edit-file.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"list-dir.d.ts","sourceRoot":"","sources":["../../../src/tools/fs/list-dir.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAmEjD,eAAO,MAAM,aAAa,8BAuFxB,CAAC;AAEH,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"list-dir.d.ts","sourceRoot":"","sources":["../../../src/tools/fs/list-dir.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAmEjD,eAAO,MAAM,aAAa,8BAsFxB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -109,7 +109,6 @@ export const FsListDirTool = () => new MCPTool({
109
109
  const end = Math.max(start, Math.min(start + limitResult, totalResult));
110
110
  const page = entries.slice(start, end);
111
111
  return {
112
- entries: page,
113
112
  result: page,
114
113
  total: totalResult,
115
114
  totalResult,
@@ -1 +1 @@
1
- {"version":3,"file":"list-dir.js","sourceRoot":"","sources":["../../../src/tools/fs/list-dir.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list-dir.js","sourceRoot":"","sources":["../../../src/tools/fs/list-dir.ts"],"names":[],"mappings":"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"}
@@ -15,9 +15,9 @@ export const FsReadFileTool = () => new MCPTool({
15
15
  {
16
16
  name: "offsetLine",
17
17
  type: "number",
18
- description: "line offset to start reading from",
18
+ description: "1-indexed line number to start reading from (line 1 is the first line of the file)",
19
19
  required: false,
20
- default: 0,
20
+ default: 1,
21
21
  },
22
22
  {
23
23
  name: "limitLine",
@@ -29,7 +29,7 @@ export const FsReadFileTool = () => new MCPTool({
29
29
  ],
30
30
  customClass: new FsInteraction(),
31
31
  execute: async (_envID, inputs, _mcp, customClass) => {
32
- const { path, offsetLine = 0, limitLine = 2000 } = inputs;
32
+ const { path, offsetLine = 1, limitLine = 2000 } = inputs;
33
33
  const fullPath = resolvePath(path);
34
34
  customClass?.emitFsEvent({ type: "reading", path: fullPath });
35
35
  let raw;
@@ -1 +1 @@
1
- {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../../src/tools/fs/read-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAgB;IAC3D,IAAI,EAAE,cAAc;IACpB,WAAW,EACP,mHAAmH;IACvH,MAAM,EAAE;QACJ;YACI,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,IAAI;SACjB;QACD;YACI,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,mCAAmC;YAChD,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,CAAC;SACb;QACD;YACI,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,+BAA+B;YAC5C,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,IAAI;SAChB;KACJ;IACD,WAAW,EAAE,IAAI,aAAa,EAAE;IAChC,OAAO,EAAE,KAAK,EACV,MAAc,EACd,MAA2B,EAC3B,IAAU,EACV,WAA2B,EACf,EAAE;QACd,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;QAE1D,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,WAAW,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE9D,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;YACzE,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,8BAA8B,CAAC,CAAC;YACnF,MAAM,GAAG,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAEhG,OAAO;YACH,OAAO;YACP,UAAU;YACV,SAAS;YACT,OAAO;SACV,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AAEH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../../src/tools/fs/read-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAgB;IAC3D,IAAI,EAAE,cAAc;IACpB,WAAW,EACP,mHAAmH;IACvH,MAAM,EAAE;QACJ;YACI,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,2CAA2C;YACxD,QAAQ,EAAE,IAAI;SACjB;QACD;YACI,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,oFAAoF;YACjG,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,CAAC;SACb;QACD;YACI,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,+BAA+B;YAC5C,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,IAAI;SAChB;KACJ;IACD,WAAW,EAAE,IAAI,aAAa,EAAE;IAChC,OAAO,EAAE,KAAK,EACV,MAAc,EACd,MAA2B,EAC3B,IAAU,EACV,WAA2B,EACf,EAAE;QACd,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;QAE1D,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,WAAW,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE9D,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;YACzE,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,8BAA8B,CAAC,CAAC;YACnF,MAAM,GAAG,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAEhG,OAAO;YACH,OAAO;YACP,UAAU;YACV,SAAS;YACT,OAAO;SACV,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -10,6 +10,13 @@ export declare function toLines(content: string): string[];
10
10
  * Slices an array of lines by offset/limit, clamping to bounds, and returns
11
11
  * both the slice and the total line count so callers can page through large
12
12
  * files without ever loading the whole thing into a response.
13
+ *
14
+ * `offsetLine` is 1-indexed (the first line of the file is line 1), matching
15
+ * the convention every fs tool that talks about line numbers uses — this is
16
+ * what LLMs already expect from editors/`cat -n`, and keeping it consistent
17
+ * with `fs-edit-file`'s `offsetLine` is the whole point: a line number read
18
+ * here can be pasted straight into an edit call without an off-by-one.
19
+ * `startLine`/`endLine` in the result are 1-indexed and inclusive.
13
20
  */
14
21
  export declare function paginateLines(lines: string[], offsetLine: number, limitLine: number): {
15
22
  content: string;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/fs/utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;EAUnF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/fs/utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;EAUnF"}
@@ -18,15 +18,22 @@ export function toLines(content) {
18
18
  * Slices an array of lines by offset/limit, clamping to bounds, and returns
19
19
  * both the slice and the total line count so callers can page through large
20
20
  * files without ever loading the whole thing into a response.
21
+ *
22
+ * `offsetLine` is 1-indexed (the first line of the file is line 1), matching
23
+ * the convention every fs tool that talks about line numbers uses — this is
24
+ * what LLMs already expect from editors/`cat -n`, and keeping it consistent
25
+ * with `fs-edit-file`'s `offsetLine` is the whole point: a line number read
26
+ * here can be pasted straight into an edit call without an off-by-one.
27
+ * `startLine`/`endLine` in the result are 1-indexed and inclusive.
21
28
  */
22
29
  export function paginateLines(lines, offsetLine, limitLine) {
23
30
  const totalLines = lines.length;
24
- const start = Math.max(0, Math.min(offsetLine, totalLines));
31
+ const start = Math.max(0, Math.min(offsetLine - 1, totalLines));
25
32
  const end = Math.max(start, Math.min(start + limitLine, totalLines));
26
33
  return {
27
34
  content: lines.slice(start, end).join("\n"),
28
35
  totalLines,
29
- startLine: start,
36
+ startLine: start + 1,
30
37
  endLine: end,
31
38
  };
32
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/tools/fs/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,OAAO,CAAC,OAAe;IACnC,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAe,EAAE,UAAkB,EAAE,SAAiB;IAChF,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACrE,OAAO;QACH,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,UAAU;QACV,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,GAAG;KACf,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/tools/fs/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,OAAO,CAAC,OAAe;IACnC,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAe,EAAE,UAAkB,EAAE,SAAiB;IAChF,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACrE,OAAO;QACH,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,UAAU;QACV,SAAS,EAAE,KAAK,GAAG,CAAC;QACpB,OAAO,EAAE,GAAG;KACf,CAAC;AACN,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { GetCurrentTimeTool } from "./get-current-time.js";
2
2
  export { DelayTool } from "./delay.js";
3
+ export { ReadImageTool } from "./read-image.js";
3
4
  export declare const UtilTools: () => import("../../index.js").MCPTool<undefined>[];
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOvC,eAAO,MAAM,SAAS,qDAGrB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAQhD,eAAO,MAAM,SAAS,qDAIrB,CAAC"}
@@ -1,9 +1,12 @@
1
1
  export { GetCurrentTimeTool } from "./get-current-time.js";
2
2
  export { DelayTool } from "./delay.js";
3
+ export { ReadImageTool } from "./read-image.js";
3
4
  import { GetCurrentTimeTool } from "./get-current-time.js";
4
5
  import { DelayTool } from "./delay.js";
6
+ import { ReadImageTool } from "./read-image.js";
5
7
  export const UtilTools = () => [
6
8
  GetCurrentTimeTool(),
7
- DelayTool()
9
+ DelayTool(),
10
+ ReadImageTool()
8
11
  ];
9
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IAC3B,kBAAkB,EAAE;IACpB,SAAS,EAAE;CACd,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IAC3B,kBAAkB,EAAE;IACpB,SAAS,EAAE;IACX,aAAa,EAAE;CAClB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ /**
3
+ * Reads an image straight off disk and hands it to the agent as an image
4
+ * tool-output — same shape and same downstream handling as
5
+ * `browser-screenshot` (see BaseAgent#resolveToolOutputForModel): depending
6
+ * on how the agent is configured, the raw bytes go straight to the main
7
+ * model, or a separate image-capable provider describes it first so the
8
+ * main conversation doesn't have to carry image bytes.
9
+ */
10
+ export declare const ReadImageTool: () => MCPTool<undefined>;
11
+ export default ReadImageTool;
12
+ //# sourceMappingURL=read-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-image.d.ts","sourceRoot":"","sources":["../../../src/tools/utils/read-image.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAgB5C;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,0BA8CxB,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { readFile } from "fs/promises";
2
+ import { extname } from "path";
3
+ import { MCPTool } from "../../core/mcp.js";
4
+ import { resolvePath } from "../fs/utils.js";
5
+ const MIME_TYPES = {
6
+ ".png": "image/png",
7
+ ".jpg": "image/jpeg",
8
+ ".jpeg": "image/jpeg",
9
+ ".gif": "image/gif",
10
+ ".webp": "image/webp",
11
+ ".bmp": "image/bmp",
12
+ };
13
+ function mimeTypeForPath(path) {
14
+ return MIME_TYPES[extname(path).toLowerCase()] ?? "image/png";
15
+ }
16
+ /**
17
+ * Reads an image straight off disk and hands it to the agent as an image
18
+ * tool-output — same shape and same downstream handling as
19
+ * `browser-screenshot` (see BaseAgent#resolveToolOutputForModel): depending
20
+ * on how the agent is configured, the raw bytes go straight to the main
21
+ * model, or a separate image-capable provider describes it first so the
22
+ * main conversation doesn't have to carry image bytes.
23
+ */
24
+ export const ReadImageTool = () => new MCPTool({
25
+ name: "read-image",
26
+ description: "read an image file from disk and hand it to the agent. works just like browser-screenshot: returns an image tool-output — depending on how the agent is configured, the raw image may be handed directly to the model, or first described by a separate image-capable AI so the main conversation doesn't have to carry image bytes. " +
27
+ "use `focusHint` to tell that description step what you actually care about (e.g. 'read out any visible text' or 'check whether the chart trend is up or down'), so the resulting description is useful for your task instead of a generic caption.",
28
+ inputs: [
29
+ {
30
+ name: "path",
31
+ type: "string",
32
+ description: "absolute or cwd-relative path to the image file (png, jpg, gif, webp, bmp)",
33
+ required: true,
34
+ },
35
+ {
36
+ name: "focusHint",
37
+ type: "string",
38
+ description: "what to focus on when describing the image",
39
+ required: false,
40
+ },
41
+ ],
42
+ execute: async (_envID, inputs) => {
43
+ const { path, focusHint } = inputs;
44
+ if (!path || typeof path !== "string") {
45
+ throw new Error("path must be a non-empty string");
46
+ }
47
+ const fullPath = resolvePath(path);
48
+ let image;
49
+ try {
50
+ image = (await readFile(fullPath)).toString("base64");
51
+ }
52
+ catch (err) {
53
+ if (err.code === "ENOENT")
54
+ throw new Error(`no file found at "${path}"`);
55
+ if (err.code === "EISDIR")
56
+ throw new Error(`"${path}" is a directory, not a file`);
57
+ throw err;
58
+ }
59
+ return {
60
+ type: "image",
61
+ output: {
62
+ image,
63
+ mimeType: mimeTypeForPath(fullPath),
64
+ ...(focusHint ? { focusHint } : {}),
65
+ },
66
+ };
67
+ },
68
+ });
69
+ export default ReadImageTool;
70
+ //# sourceMappingURL=read-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-image.js","sourceRoot":"","sources":["../../../src/tools/utils/read-image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,UAAU,GAA2B;IACvC,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;CACtB,CAAC;AAEF,SAAS,eAAe,CAAC,IAAY;IACjC,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,WAAW,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC;IAC3C,IAAI,EAAE,YAAY;IAClB,WAAW,EACP,uUAAuU;QACvU,oPAAoP;IACxP,MAAM,EAAE;QACJ;YACI,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,4EAA4E;YACzF,QAAQ,EAAE,IAAI;SACjB;QACD;YACI,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,4CAA4C;YACzD,QAAQ,EAAE,KAAK;SAClB;KACJ;IACD,OAAO,EAAE,KAAK,EAAE,MAAc,EAAE,MAA2B,EAAgB,EAAE;QACzE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;QAEnC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnC,IAAI,KAAa,CAAC;QAClB,IAAI,CAAC;YACD,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;YACzE,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,8BAA8B,CAAC,CAAC;YACnF,MAAM,GAAG,CAAC;QACd,CAAC;QAED,OAAO;YACH,IAAI,EAAE,OAAO;YACb,MAAM,EAAE;gBACJ,KAAK;gBACL,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;gBACnC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtC;SACJ,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AAEH,eAAe,aAAa,CAAC"}
package/docs/agents.md ADDED
@@ -0,0 +1,181 @@
1
+ # Agents
2
+
3
+ ## `BaseAgent` vs `SimpleAgent`
4
+
5
+ - **`BaseAgent`** (`src/core/base-agent.ts`) is the real engine — the run loop, memory compaction, tool dispatch, token accounting. It requires you to bring your own `MCPClient` (and therefore your own `MCPServer`/connection), which is what gives you the choice of in-process, IPC, or WebSocket execution (see [MCP Architecture](./mcp-architecture.md)).
6
+ - **`SimpleAgent`** (`src/templates/simple.ts`) is a thin subclass that wires up an in-process `MCPConnection` + `MCPServer` + `MCPClient` for you from a flat `tools`/`skills` list. Use this unless you specifically need a different transport.
7
+ - **`WorkerAgent`** *(experimental)* (`src/core/worker-agent.ts`) is a `BaseAgent` with an identity — name, description, per-task-type rating — so another agent can list, compare, hire, and prompt it as a sub-agent. See [Multi-agent: WorkerAgent](#multi-agent-workeragent-experimental) below.
8
+
9
+ ## `BaseAgent` constructor
10
+
11
+ ```ts
12
+ new BaseAgent({
13
+ instruction: string;
14
+ allowedTools: MCPTool<any>[];
15
+ aiProvider: AIProvider | AgentProviderEntry[]; // see Providers doc
16
+ mcpClient: MCPClient;
17
+ skills?: Skill[];
18
+ maxMemorizeToken?: number; // default: derived from the main provider's contextWindow * safeUsageRatio
19
+ initData?: {
20
+ memory: string;
21
+ messagesFull: Message[];
22
+ fullInputMissTokens: number;
23
+ fullInputHitTokens: number;
24
+ fullOutputTokens: number;
25
+ messagesCompact: Message[];
26
+ currentInputMissTokens: number;
27
+ currentInputHitTokens: number;
28
+ currentOutputTokens: number;
29
+ };
30
+ });
31
+ ```
32
+
33
+ `SimpleAgent`'s constructor is the same shape minus `mcpClient`/`allowedTools` (it builds those from `tools`), plus `tools?: MCPTool<any>[]` and `maxMemorizeToken` defaulting to `16000` instead of being derived.
34
+
35
+ ## The run loop
36
+
37
+ ```ts
38
+ await agent.run(prompt: string, streamCallback?: StreamCallback): Promise<void>;
39
+ ```
40
+
41
+ Each call to `run()`:
42
+
43
+ 1. Pushes the user prompt onto the message history and emits it as a `role: "user"` stream chunk.
44
+ 2. Sends `[system, ...history]` plus the full tool schema list to the main provider's `chat()`.
45
+ 3. If the model requested tool calls, dispatches each one (via the `MCPClient` this agent was built with), pushes a `role: "tool"` message + stream chunk per result, and loops back to step 2.
46
+ 4. Repeats until the model's turn produces no tool calls (or a tool marked `stopIterationAfterUsingThisTool` fired — see [Tools](./tools.md)).
47
+
48
+ If `run()` is called again while a previous call is still in flight, the new call is queued and resolves once the current run finishes (or times out after 4 minutes) — it does not run concurrently or interleave.
49
+
50
+ ### Calling `run()` again mid-flight: prompt coalescing, not truncation
51
+
52
+ This is a deliberate design for absorbing multiple user prompts that arrive while the agent is still mid-turn (e.g. a chat UI where the user sends a couple of follow-up messages before the first reply lands) — not a bug, and nothing gets cut off mid-tool-call. The currently running loop iteration (one model turn plus all of that turn's tool dispatches) always finishes; only the *next* iteration is skipped once another `run()` call has queued:
53
+
54
+ - **One call queues up:** the in-flight run finishes its current iteration and stops there; the queued call then runs its own fresh loop from scratch, in a context that already contains everything the first run produced (including any pending tool results).
55
+ - **Multiple calls queue up:** every queued call except the last one has its prompt appended straight into history as a plain `role: "user"` message (with a matching stream chunk) and its own `run()` promise resolves immediately — no model turn is generated for that prompt specifically. The *last* queued call is the one that actually drives a real model turn, in a context that now includes every prompt that queued before it. The model's eventual reply addresses the whole accumulated batch at once, not each queued prompt individually.
56
+
57
+ Practical implication: don't treat an early queued call's resolved `run()` promise as "the model has now answered this prompt" — for anything but the last queued call, it only means the prompt was recorded. Drive replies off `streamCallback` if you need to know when the model has actually responded.
58
+
59
+ `stop()` requests the current run stop at the next safe point; it resolves once the loop has actually stopped, or rejects if it doesn't stop within 4 minutes.
60
+
61
+ ### Native tool-calling is required
62
+
63
+ `run()` throws immediately if the main provider's `getCapabilities().supportsTools` is `false`. There is no legacy JSON-in-text fallback in the main loop anymore — pick a provider/model combination (or pass `{ supportsTools: true }`) that supports native function calling.
64
+
65
+ ## Memory compaction
66
+
67
+ OrbitX never truncates or deletes conversation history. Compaction happens through a real, always-available native tool — `compact_memory({ new_memory: string })` — that `BaseAgent` appends to every tool schema list alongside whatever MCP tools you allowed. This means the model can compact its own context whenever *it* judges the conversation has grown long, not only when forced to.
68
+
69
+ Calling `compact_memory`:
70
+
71
+ 1. Replaces the running `memory` string with `new_memory`, which is injected into every future system prompt (`MEMORY:` section).
72
+ 2. Clears `messagesCompact` — the *working* context sent to the provider each turn.
73
+ 3. Leaves `messagesFull` — the complete, ever-appended history — untouched, so nothing is lost; it's just no longer replayed to the model every turn.
74
+ 4. Rolls the current token counters into the lifetime totals (see [Token accounting](#token-accounting)) and resets them to zero.
75
+
76
+ `BaseAgent` also tracks two token totals per run: `currentInputMissTokens` (uncached input) and `currentLastOutputTokens` (the last turn's output). When their sum exceeds `maxMemorizeToken`, the agent doesn't compact on the model's behalf — instead it appends a `role: "user"` message telling the model to call `compact_memory` before doing anything else, and loops back for another turn. This keeps compaction on the same native tool-call path the model already uses for everything else, rather than a hidden side-channel; a model that ignores the nudge (rare, since the instruction is explicit) will simply see it repeated on the next turn until it complies.
77
+
78
+ `maxMemorizeToken`, if not passed explicitly, is derived as `contextWindow * safeUsageRatio` (default ratio `0.5`) from the main provider's `getCapabilities()` — so it scales automatically with whatever model you plug in.
79
+
80
+ ## Persisting and resuming state
81
+
82
+ `getCurrentAgentStates()` returns exactly the shape expected by the `initData` constructor option — `memory`, `messagesFull`, `messagesCompact`, the six main-loop token counters, and the two image-usage counters (`imageInputMissTokens`, `imageOutputTokens` — see [Token accounting](#token-accounting)). Serialize it (it's plain JSON) after any `run()` call, and pass it back into a fresh `BaseAgent`/`SimpleAgent` to resume — same conversation, same memory, same token history. See the example in [Getting Started](./getting-started.md#recovering-an-agents-state).
83
+
84
+ The two image counters are optional on `initData` — a snapshot taken before image-usage tracking existed still loads, with both defaulting to `0`.
85
+
86
+ ## Token accounting
87
+
88
+ Four read methods, all returning `{ total, inputHit, inputMiss, output }`:
89
+
90
+ - `getCurrentTotalTokens()` — main-loop tokens used since the last memory compaction.
91
+ - `getFullTotalTokens()` — main-loop tokens used across all *prior* compacted segments.
92
+ - `getImageTotalTokens()` — tokens used by every `ImageDescriber` call this agent has made (see [Providers](./providers.md#two-provider-roles-main--image)), tracked separately since a one-off image-description call has no conversation history to compact and so doesn't fit the current/full split.
93
+ - `getTotalTokens()` — the sum of all three (lifetime total for this agent instance, main loop and image calls combined).
94
+
95
+ `inputHit`/`inputMiss` on the main-loop methods track cached vs. uncached input tokens, since the compacted-context-replay pattern means most of a long conversation's prefix is a cache hit on providers that support prompt caching — this is a heuristic `BaseAgent` computes itself from the growing/reset conversation history: whatever was `inputMiss` last turn rolls into `inputHit` this turn, and `inputMiss` becomes this turn's raw input token count.
96
+
97
+ `getImageTotalTokens()`'s `inputHit` is always `0` — each `ImageDescriber` call is a fresh, standalone chat with no prior turns to replay, so there's nothing for that heuristic to apply to. Every input token an image call reports counts as `inputMiss`.
98
+
99
+ ## Instructions, skills, and memory in the system prompt
100
+
101
+ The system prompt is built once (lazily, on first use) and never changes for the lifetime of an agent instance — a stable prefix, which matters for provider-side prompt caching. It's assembled from: a fixed "you have tools" preamble, each skill's name/description/instructions (see [Skills](./skills.md)), the current `MEMORY:` block, and your `instruction` string, in that order.
102
+
103
+ ## Multi-agent: `WorkerAgent` *(experimental)*
104
+
105
+ **Experimental:** this whole feature (`WorkerAgent`, `AgentTools`, `AgentReportTool`) is new and still settling — names, the hire/prompt/report shape, and the fallback behavior when a worker never reports may change in a future release. Treat it as unstable if you're building something you don't want to have to revisit.
106
+
107
+ `WorkerAgent` (`src/core/worker-agent.ts`) is a `BaseAgent` with three extra fields on top of the usual constructor options:
108
+
109
+ ```ts
110
+ new WorkerAgent({
111
+ name: string; // unique id used to hire/prompt this worker
112
+ description: string; // persona/specialty, written for a hiring agent to judge fit from
113
+ rating?: Record<string, number>; // per-task-type fit score, e.g. { backend: 9, "3d-web": 10 }, convention 0-10
114
+ // ...plus every BaseAgent option: instruction, allowedTools, aiProvider, mcpClient, skills?, maxMemorizeToken?, initData?
115
+ });
116
+
117
+ worker.getName();
118
+ worker.getDescription();
119
+ worker.getRating();
120
+ ```
121
+
122
+ It's a raw building block, same as `BaseAgent` — you still bring your own `mcpClient`/`allowedTools` for it. The only thing `WorkerAgent` adds is identity metadata; running it (`.run()`, streaming, memory, tokens) is unchanged.
123
+
124
+ ### The `agent-*` tools
125
+
126
+ `AgentTools(availableAgents: WorkerAgent[], options?: { maxHired?: number })` (from `src/tools/agent/`) builds a fixed roster of hireable workers into three planner-facing tools:
127
+
128
+ | Tool | Purpose |
129
+ |---|---|
130
+ | `agent-list` | List every worker in the roster — name, description, rating, and whether it's currently hired. Also returns `hiredCount` and (when set) `maxHired`. |
131
+ | `agent-hire` | Hire a worker by name, making it eligible for `agent-prompt`. Hiring an already-hired worker is a no-op. |
132
+ | `agent-prompt` | Send a prompt to a hired worker and wait for its response. |
133
+
134
+ `maxHired` caps how many workers can be hired at once — omit it for no limit. When set, it's woven directly into `agent-hire`'s own tool description (so the model learns the constraint from the tool itself, not out-of-band instructions) and exceeding it throws a clear error naming the current limit and who's currently hired. Re-hiring an already-hired worker is still a free no-op and never counts against the cap.
135
+
136
+ Give these to your **planner** agent (the one that decides which workers to use), not to the workers themselves:
137
+
138
+ ```ts
139
+ import { AgentTools, SimpleAgent, WorkerAgent, AnthropicProvider, AgentReportTool, MCPConnection, MCPServer, MCPClient } from "orbitx";
140
+
141
+ function buildWorker(name: string, description: string, rating: Record<string, number>) {
142
+ const connection = new MCPConnection();
143
+ const server = new MCPServer(connection);
144
+ const reportTool = AgentReportTool();
145
+ server.registerTool(reportTool);
146
+ // ...register whatever other tools this worker needs on `server` too...
147
+
148
+ return new WorkerAgent({
149
+ name,
150
+ description,
151
+ rating,
152
+ instruction: `You are the ${name} specialist.`,
153
+ aiProvider: new AnthropicProvider("api-key", "claude-sonnet-5"),
154
+ mcpClient: new MCPClient(name, connection),
155
+ allowedTools: [reportTool /* , ...other tools registered above */],
156
+ });
157
+ }
158
+
159
+ const backendWorker = buildWorker("backend-worker", "Node.js APIs, databases, servers.", { backend: 9, frontend: 2 });
160
+ const frontendWorker = buildWorker("frontend-worker", "React UI work.", { backend: 2, frontend: 9 });
161
+
162
+ const planner = new SimpleAgent({
163
+ aiProvider: new AnthropicProvider("api-key", "claude-sonnet-5"),
164
+ instruction: "You coordinate work across specialist worker agents.",
165
+ // At most 1 hired at a time here, just as an example constraint.
166
+ tools: AgentTools([backendWorker, frontendWorker], { maxHired: 1 }),
167
+ });
168
+ ```
169
+
170
+ ### `agent-report` — for workers, not the planner
171
+
172
+ Include `AgentReportTool()` in each **worker's own** `allowedTools` (and register it on that worker's own `MCPServer`, as in the example above) — it's what lets a worker hand a result back once it's done. Calling it always ends the worker's current turn immediately (`stopIterationAfterUsingThisTool`), so a worker should call it and stop, not keep reasoning afterward.
173
+
174
+ ### How a prompt/report round-trip actually works
175
+
176
+ 1. Planner calls `agent-hire`, then `agent-prompt` with a task.
177
+ 2. `agent-prompt`'s implementation calls `workerAgent.run(prompt)` and waits for it to resolve — the worker runs its own full turn (its own reasoning, its own tools), completely independently of the planner's own loop.
178
+ 3. Once the worker's `run()` resolves, `agent-prompt` looks at only the messages that turn produced: if the worker called `agent-report`, that report text is returned (`{ report, reported: true }`); otherwise it falls back to the worker's last plain-text answer (`{ report, reported: false }`).
179
+ 4. The planner sees this as a normal tool result. It's the planner's call what happens next — prompt the same worker again to continue (its message history persists across `agent-prompt` calls, same as any agent's `run()`), or move on and never call it again if the report shows the work is done. Nothing about the worker's lifecycle is automatic.
180
+
181
+ `AgentTools(...)` state (which agents are hired) is scoped to that one call — building a second, independent planner with its own `AgentTools([...])` call gets its own hire state, even in the same process.
@@ -0,0 +1,54 @@
1
+ # API Reference
2
+
3
+ Flat index of every public export from `orbitx` (see `src/index.ts`), grouped by area. Each links to the doc page with the actual explanation and examples.
4
+
5
+ ## Core / Providers — see [Providers](./providers.md)
6
+
7
+ - `AIProvider` (abstract base class)
8
+ - `OpenAIProvider`, `AnthropicProvider`, `DeepSeekProvider`, `OllamaProvider`
9
+ - `resolveAgentProviders()`
10
+ - Types: `AgentProviderRole`, `AgentProviderEntry`, `AgentProvidersInput`, `ResolvedAgentProviders`
11
+ - Types: `ChatResponse`, `Message`, `StreamCallback`, `ToolSchema`, `ToolCallRequest`, `MessageContentPart`, `ProviderCapabilities`
12
+ - `resolveThinkEffortLevel()`, `clampThinkEffort()` — the universal 0-1 `thinkEffort` → provider-native-level mapping helpers; see [Providers](./providers.md#think-effort)
13
+ - Type: `ThinkEffortLevel`
14
+ - `ImageDescriber`, type `ImageDescription` — used internally by `BaseAgent` to describe image tool output via the `image` provider role; exported for direct use if you want to describe an image outside the agent loop. `describe()` returns an `ImageDescription` (`{ description, inputTokens, outputTokens }`), not a bare string.
15
+ - `toOpenAIFunctionTools()` — translates a `ToolSchema[]` into OpenAI's function-calling format; exported for building custom providers.
16
+
17
+ ## Agents — see [Agents](./agents.md)
18
+
19
+ - `BaseAgent`
20
+ - `SimpleAgent`
21
+ - `WorkerAgent` *(experimental)*, type `WorkerAgentRating`
22
+ - Types: `ExtractedSegment`, `ParsedToolCall`
23
+
24
+ ## Tools — see [Tools](./tools.md)
25
+
26
+ - `MCPTool`, `MCPCustomClass`, `generateRefId()`, `normalizeToolOutput()`
27
+ - Types: `MCP`, `MCPToolOutput`
28
+
29
+ Built-in tool factories, grouped by domain (each domain also exports a `*Tools()` array and a `*Interaction` EventEmitter):
30
+
31
+ | Domain | Exports |
32
+ |---|---|
33
+ | Filesystem | `FsReadFileTool`, `FsWriteFileTool`, `FsEditFileTool`, `FsListDirTool`, `FsCreateDirTool`, `FsDeleteTool`, `FsMoveTool`, `FsStatTool`, `FsTools`, `FsInteraction`, type `FsEvent` |
34
+ | Bash | `BashRunTool`, `BashWaitTool`, `BashLogsTool`, `BashListTool`, `BashWriteInputTool`, `BashTerminateTool`, `BashTools`, `BashInteraction`, type `BashEvent` |
35
+ | Browser | `BrowserCreateSessionTool`, `BrowserRemoveSessionTool`, `BrowserGetSessionsTool`, `BrowserNavigateTool`, `BrowserConsoleTool`, `BrowserInjectTool`, `BrowserReadTool`, `BrowserClickTool`, `BrowserFillTool`, `BrowserScrollInfoTool`, `BrowserScrollTool`, `BrowserNetworkStatusTool`, `BrowserNetworkTool`, `BrowserSubmitFormTool`, `BrowserScreenshotTool`, `BrowserTools`, `BrowserInteraction`, type `BrowserEvent` |
36
+ | Todo | `TodoCreateListTool`, `TodoRemoveListTool`, `TodoGetListsTool`, `TodoGetListTool`, `TodoCreateTaskTool`, `TodoRemoveTaskTool`, `TodoCheckTaskTool`, `TodoTools`, `TodoInteraction`, types `TodoTask`, `TodoList`, `TodoEvent` |
37
+ | Present | `PresentAddTool`, `PresentClearTool`, `PresentGetListTool`, `PresentTools`, `getPresentFolder()`, `PresentInteraction`, type `PresentEvent` |
38
+ | Question/Answer | `QuestionAnswerTool`, `QuestionAnswerTools`, `QuestionAnswerInteraction`, type `QuestionAnswerEvent` |
39
+ | Utility | `GetCurrentTimeTool`, `DelayTool`, `ReadImageTool`, `UtilTools` |
40
+ | Multi-agent *(experimental)* | `AgentTools(availableAgents, options?)`, `AgentListTool`, `AgentHireTool`, `AgentPromptTool`, `AgentReportTool`, `AgentRegistry`, `AgentInteraction`, type `AgentInfo`, type `AgentEvent`, type `AgentToolsOptions` — see [Agents](./agents.md#multi-agent-workeragent-experimental) |
41
+
42
+ ## Skills — see [Skills](./skills.md)
43
+
44
+ - `Skill`
45
+ - `BackendSecuritySkill`, `BigTaskSkill`, `CodeVerificationSkill`, `LongTaskEfficiencySkill`, `NodeBackendSkill`, `PlannerSkill`, `PresentSkill`, `QuestionAnswerSkill`, `ReactFrontendSkill`, `ResearchSkill`, `ShoppingSkill`, `UiUxDesignSkill`, `WebEndToEndTestSkill`
46
+
47
+ ## MCP transport — see [MCP Architecture](./mcp-architecture.md)
48
+
49
+ - `MCPServer`, `MCPClient`
50
+ - `MCPConnection`, `MCPIPCConnection`, `MCPWSConnection`
51
+ - `MCPComputer` *(experimental)*
52
+ - `MCPStorage`, `MCPFSStorage`
53
+ - `MCPRNG`
54
+ - `MCPFilter`