orbitx 0.2.4 → 0.2.6

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 (171) hide show
  1. package/dist/core/ai-provider.d.ts +9 -1
  2. package/dist/core/ai-provider.d.ts.map +1 -1
  3. package/dist/core/ai-provider.js.map +1 -1
  4. package/dist/core/anthropic-provider.d.ts +1 -1
  5. package/dist/core/anthropic-provider.d.ts.map +1 -1
  6. package/dist/core/anthropic-provider.js +71 -62
  7. package/dist/core/anthropic-provider.js.map +1 -1
  8. package/dist/core/base-agent.d.ts +2 -0
  9. package/dist/core/base-agent.d.ts.map +1 -1
  10. package/dist/core/base-agent.js +27 -4
  11. package/dist/core/base-agent.js.map +1 -1
  12. package/dist/core/deepseek-provider.d.ts +1 -1
  13. package/dist/core/deepseek-provider.d.ts.map +1 -1
  14. package/dist/core/deepseek-provider.js +49 -50
  15. package/dist/core/deepseek-provider.js.map +1 -1
  16. package/dist/core/mcp-fs-storage.d.ts.map +1 -1
  17. package/dist/core/mcp-fs-storage.js +2 -1
  18. package/dist/core/mcp-fs-storage.js.map +1 -1
  19. package/dist/core/ollama-provider.d.ts +1 -1
  20. package/dist/core/ollama-provider.d.ts.map +1 -1
  21. package/dist/core/ollama-provider.js +47 -34
  22. package/dist/core/ollama-provider.js.map +1 -1
  23. package/dist/core/openai-provider.d.ts +1 -1
  24. package/dist/core/openai-provider.d.ts.map +1 -1
  25. package/dist/core/openai-provider.js +42 -43
  26. package/dist/core/openai-provider.js.map +1 -1
  27. package/dist/core/retry.d.ts +1 -1
  28. package/dist/core/retry.d.ts.map +1 -1
  29. package/dist/core/retry.js +5 -1
  30. package/dist/core/retry.js.map +1 -1
  31. package/dist/tests/core/mcp-computer.test.js +26 -23
  32. package/dist/tests/core/mcp-computer.test.js.map +1 -1
  33. package/dist/tests/core/mcp-connection.test.js +23 -21
  34. package/dist/tests/core/mcp-connection.test.js.map +1 -1
  35. package/dist/tests/core/mcp-ipc-connection.test.js +30 -28
  36. package/dist/tests/core/mcp-ipc-connection.test.js.map +1 -1
  37. package/dist/tests/core/mcp-ws-connection.test.js +31 -30
  38. package/dist/tests/core/mcp-ws-connection.test.js.map +1 -1
  39. package/dist/tests/index.d.ts +27 -0
  40. package/dist/tests/index.d.ts.map +1 -1
  41. package/dist/tests/index.js +27 -0
  42. package/dist/tests/index.js.map +1 -1
  43. package/dist/tests/tools/agent/agent-tools.test.js +149 -147
  44. package/dist/tests/tools/agent/agent-tools.test.js.map +1 -1
  45. package/dist/tests/tools/bash/fixtures.d.ts +16 -0
  46. package/dist/tests/tools/bash/fixtures.d.ts.map +1 -0
  47. package/dist/tests/tools/bash/fixtures.js +22 -0
  48. package/dist/tests/tools/bash/fixtures.js.map +1 -0
  49. package/dist/tests/tools/bash/kill-tree.d.ts +21 -0
  50. package/dist/tests/tools/bash/kill-tree.d.ts.map +1 -0
  51. package/dist/tests/tools/bash/kill-tree.js +47 -0
  52. package/dist/tests/tools/bash/kill-tree.js.map +1 -0
  53. package/dist/tests/tools/bash/list.test.d.ts +2 -0
  54. package/dist/tests/tools/bash/list.test.d.ts.map +1 -0
  55. package/dist/tests/tools/bash/list.test.js +43 -0
  56. package/dist/tests/tools/bash/list.test.js.map +1 -0
  57. package/dist/tests/tools/bash/logs.test.d.ts +2 -0
  58. package/dist/tests/tools/bash/logs.test.d.ts.map +1 -0
  59. package/dist/tests/tools/bash/logs.test.js +48 -0
  60. package/dist/tests/tools/bash/logs.test.js.map +1 -0
  61. package/dist/tests/tools/bash/run.test.d.ts +2 -0
  62. package/dist/tests/tools/bash/run.test.d.ts.map +1 -0
  63. package/dist/tests/tools/bash/run.test.js +53 -0
  64. package/dist/tests/tools/bash/run.test.js.map +1 -0
  65. package/dist/tests/tools/bash/terminate.test.d.ts +2 -0
  66. package/dist/tests/tools/bash/terminate.test.d.ts.map +1 -0
  67. package/dist/tests/tools/bash/terminate.test.js +60 -0
  68. package/dist/tests/tools/bash/terminate.test.js.map +1 -0
  69. package/dist/tests/tools/bash/wait.test.d.ts +2 -0
  70. package/dist/tests/tools/bash/wait.test.d.ts.map +1 -0
  71. package/dist/tests/tools/bash/wait.test.js +45 -0
  72. package/dist/tests/tools/bash/wait.test.js.map +1 -0
  73. package/dist/tests/tools/bash/write-input.test.d.ts +2 -0
  74. package/dist/tests/tools/bash/write-input.test.d.ts.map +1 -0
  75. package/dist/tests/tools/bash/write-input.test.js +65 -0
  76. package/dist/tests/tools/bash/write-input.test.js.map +1 -0
  77. package/dist/tests/tools/browser/browser-tools.test.d.ts +2 -0
  78. package/dist/tests/tools/browser/browser-tools.test.d.ts.map +1 -0
  79. package/dist/tests/tools/browser/browser-tools.test.js +36 -0
  80. package/dist/tests/tools/browser/browser-tools.test.js.map +1 -0
  81. package/dist/tests/tools/fs/create-dir.test.d.ts +2 -0
  82. package/dist/tests/tools/fs/create-dir.test.d.ts.map +1 -0
  83. package/dist/tests/tools/fs/create-dir.test.js +37 -0
  84. package/dist/tests/tools/fs/create-dir.test.js.map +1 -0
  85. package/dist/tests/tools/fs/delete.test.d.ts +2 -0
  86. package/dist/tests/tools/fs/delete.test.d.ts.map +1 -0
  87. package/dist/tests/tools/fs/delete.test.js +69 -0
  88. package/dist/tests/tools/fs/delete.test.js.map +1 -0
  89. package/dist/tests/tools/fs/edit-file.test.d.ts +2 -0
  90. package/dist/tests/tools/fs/edit-file.test.d.ts.map +1 -0
  91. package/dist/tests/tools/fs/edit-file.test.js +103 -0
  92. package/dist/tests/tools/fs/edit-file.test.js.map +1 -0
  93. package/dist/tests/tools/fs/list-dir.test.d.ts +2 -0
  94. package/dist/tests/tools/fs/list-dir.test.d.ts.map +1 -0
  95. package/dist/tests/tools/fs/list-dir.test.js +65 -0
  96. package/dist/tests/tools/fs/list-dir.test.js.map +1 -0
  97. package/dist/tests/tools/fs/move.test.d.ts +2 -0
  98. package/dist/tests/tools/fs/move.test.d.ts.map +1 -0
  99. package/dist/tests/tools/fs/move.test.js +47 -0
  100. package/dist/tests/tools/fs/move.test.js.map +1 -0
  101. package/dist/tests/tools/fs/read-file.test.d.ts +2 -0
  102. package/dist/tests/tools/fs/read-file.test.d.ts.map +1 -0
  103. package/dist/tests/tools/fs/read-file.test.js +52 -0
  104. package/dist/tests/tools/fs/read-file.test.js.map +1 -0
  105. package/dist/tests/tools/fs/stat.test.d.ts +2 -0
  106. package/dist/tests/tools/fs/stat.test.d.ts.map +1 -0
  107. package/dist/tests/tools/fs/stat.test.js +43 -0
  108. package/dist/tests/tools/fs/stat.test.js.map +1 -0
  109. package/dist/tests/tools/fs/write-file.test.d.ts +2 -0
  110. package/dist/tests/tools/fs/write-file.test.d.ts.map +1 -0
  111. package/dist/tests/tools/fs/write-file.test.js +53 -0
  112. package/dist/tests/tools/fs/write-file.test.js.map +1 -0
  113. package/dist/tests/tools/present/add.test.d.ts +2 -0
  114. package/dist/tests/tools/present/add.test.d.ts.map +1 -0
  115. package/dist/tests/tools/present/add.test.js +51 -0
  116. package/dist/tests/tools/present/add.test.js.map +1 -0
  117. package/dist/tests/tools/present/clear.test.d.ts +2 -0
  118. package/dist/tests/tools/present/clear.test.d.ts.map +1 -0
  119. package/dist/tests/tools/present/clear.test.js +44 -0
  120. package/dist/tests/tools/present/clear.test.js.map +1 -0
  121. package/dist/tests/tools/present/get-list.test.d.ts +2 -0
  122. package/dist/tests/tools/present/get-list.test.d.ts.map +1 -0
  123. package/dist/tests/tools/present/get-list.test.js +50 -0
  124. package/dist/tests/tools/present/get-list.test.js.map +1 -0
  125. package/dist/tests/tools/question-answer/question-answer.test.d.ts +2 -0
  126. package/dist/tests/tools/question-answer/question-answer.test.d.ts.map +1 -0
  127. package/dist/tests/tools/question-answer/question-answer.test.js +34 -0
  128. package/dist/tests/tools/question-answer/question-answer.test.js.map +1 -0
  129. package/dist/tests/tools/todo/check-task.test.d.ts +2 -0
  130. package/dist/tests/tools/todo/check-task.test.d.ts.map +1 -0
  131. package/dist/tests/tools/todo/check-task.test.js +42 -0
  132. package/dist/tests/tools/todo/check-task.test.js.map +1 -0
  133. package/dist/tests/tools/todo/create-list.test.d.ts +2 -0
  134. package/dist/tests/tools/todo/create-list.test.d.ts.map +1 -0
  135. package/dist/tests/tools/todo/create-list.test.js +32 -0
  136. package/dist/tests/tools/todo/create-list.test.js.map +1 -0
  137. package/dist/tests/tools/todo/create-task.test.d.ts +2 -0
  138. package/dist/tests/tools/todo/create-task.test.d.ts.map +1 -0
  139. package/dist/tests/tools/todo/create-task.test.js +53 -0
  140. package/dist/tests/tools/todo/create-task.test.js.map +1 -0
  141. package/dist/tests/tools/todo/get-list.test.d.ts +2 -0
  142. package/dist/tests/tools/todo/get-list.test.d.ts.map +1 -0
  143. package/dist/tests/tools/todo/get-list.test.js +38 -0
  144. package/dist/tests/tools/todo/get-list.test.js.map +1 -0
  145. package/dist/tests/tools/todo/get-lists.test.d.ts +2 -0
  146. package/dist/tests/tools/todo/get-lists.test.d.ts.map +1 -0
  147. package/dist/tests/tools/todo/get-lists.test.js +29 -0
  148. package/dist/tests/tools/todo/get-lists.test.js.map +1 -0
  149. package/dist/tests/tools/todo/remove-list.test.d.ts +2 -0
  150. package/dist/tests/tools/todo/remove-list.test.d.ts.map +1 -0
  151. package/dist/tests/tools/todo/remove-list.test.js +41 -0
  152. package/dist/tests/tools/todo/remove-list.test.js.map +1 -0
  153. package/dist/tests/tools/todo/remove-task.test.d.ts +2 -0
  154. package/dist/tests/tools/todo/remove-task.test.d.ts.map +1 -0
  155. package/dist/tests/tools/todo/remove-task.test.js +45 -0
  156. package/dist/tests/tools/todo/remove-task.test.js.map +1 -0
  157. package/dist/tests/tools/utils/delay.test.js +26 -24
  158. package/dist/tests/tools/utils/delay.test.js.map +1 -1
  159. package/dist/tests/tools/utils/get-current-time.test.js +43 -41
  160. package/dist/tests/tools/utils/get-current-time.test.js.map +1 -1
  161. package/dist/tests/tools/utils/read-image.test.d.ts +2 -0
  162. package/dist/tests/tools/utils/read-image.test.d.ts.map +1 -0
  163. package/dist/tests/tools/utils/read-image.test.js +54 -0
  164. package/dist/tests/tools/utils/read-image.test.js.map +1 -0
  165. package/dist/tools/browser/session-manager.d.ts.map +1 -1
  166. package/dist/tools/browser/session-manager.js +16 -3
  167. package/dist/tools/browser/session-manager.js.map +1 -1
  168. package/docs/agents.md +7 -1
  169. package/docs/mcp-architecture.md +1 -1
  170. package/docs/providers.md +5 -1
  171. package/package.json +1 -1
@@ -0,0 +1,41 @@
1
+ import { test, before, after, describe } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { TodoCreateListTool, TodoCreateTaskTool, TodoRemoveListTool, TodoGetListsTool, TodoGetListTool, MCPClient, MCPConnection, MCPServer, } from "../../../index.js";
4
+ describe("todo/remove-list", () => {
5
+ let mcpConnection;
6
+ let mcpClient;
7
+ let mcpServer;
8
+ before(async () => {
9
+ mcpConnection = new MCPConnection();
10
+ mcpClient = new MCPClient("1234", mcpConnection);
11
+ mcpServer = new MCPServer(mcpConnection);
12
+ mcpServer.registerTool(TodoCreateListTool());
13
+ mcpServer.registerTool(TodoCreateTaskTool());
14
+ mcpServer.registerTool(TodoRemoveListTool());
15
+ mcpServer.registerTool(TodoGetListsTool());
16
+ mcpServer.registerTool(TodoGetListTool());
17
+ });
18
+ after(async () => {
19
+ mcpConnection?.close();
20
+ });
21
+ test("TodoRemoveListTool: removes a list (and its tasks), no longer reachable afterwards", async () => {
22
+ const list = await mcpClient.callTool("todo-create-list", { name: "To remove" });
23
+ const listId = list.output.todoListId;
24
+ await mcpClient.callTool("todo-create-task", { list: listId, tasks: [{ name: "Task" }] });
25
+ const result = await mcpClient.callTool("todo-remove-list", { lists: [listId] });
26
+ assert.strictEqual(result.output.message, "success");
27
+ const lists = await mcpClient.callTool("todo-get-lists", {});
28
+ assert.ok(!lists.output.lists.includes(listId));
29
+ const getResult = await mcpClient.callTool("todo-get-list", { list: listId });
30
+ assert.match(getResult.output.error, /no todo list found with id/);
31
+ });
32
+ test("TodoRemoveListTool: removing an unknown list id is a no-op success, not an error", async () => {
33
+ const result = await mcpClient.callTool("todo-remove-list", { lists: ["0xdoesnotexist"] });
34
+ assert.strictEqual(result.output.message, "success");
35
+ });
36
+ test("TodoRemoveListTool: a non-array lists input is rejected", async () => {
37
+ const result = await mcpClient.callTool("todo-remove-list", { lists: "not-an-array" });
38
+ assert.match(result.output.error, /lists must be an array of list id strings/);
39
+ });
40
+ });
41
+ //# sourceMappingURL=remove-list.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-list.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/todo/remove-list.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=remove-task.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-task.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/tools/todo/remove-task.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,45 @@
1
+ import { test, before, after, describe } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { TodoCreateListTool, TodoCreateTaskTool, TodoRemoveTaskTool, TodoGetListTool, MCPClient, MCPConnection, MCPServer, } from "../../../index.js";
4
+ describe("todo/remove-task", () => {
5
+ let mcpConnection;
6
+ let mcpClient;
7
+ let mcpServer;
8
+ let listId;
9
+ let taskIds;
10
+ before(async () => {
11
+ mcpConnection = new MCPConnection();
12
+ mcpClient = new MCPClient("1234", mcpConnection);
13
+ mcpServer = new MCPServer(mcpConnection);
14
+ mcpServer.registerTool(TodoCreateListTool());
15
+ mcpServer.registerTool(TodoCreateTaskTool());
16
+ mcpServer.registerTool(TodoRemoveTaskTool());
17
+ mcpServer.registerTool(TodoGetListTool());
18
+ const list = await mcpClient.callTool("todo-create-list", { name: "Tasks" });
19
+ listId = list.output.todoListId;
20
+ const created = await mcpClient.callTool("todo-create-task", {
21
+ list: listId,
22
+ tasks: [{ name: "Keep me" }, { name: "Remove me" }],
23
+ });
24
+ taskIds = created.output.todoTaskIds;
25
+ });
26
+ after(async () => {
27
+ mcpConnection?.close();
28
+ });
29
+ test("TodoRemoveTaskTool: removes a task from its list", async () => {
30
+ const result = await mcpClient.callTool("todo-remove-task", { tasks: [taskIds[1]] });
31
+ assert.strictEqual(result.output.message, "success");
32
+ const listResult = await mcpClient.callTool("todo-get-list", { list: listId });
33
+ const names = listResult.output.tasks.map((t) => t.name);
34
+ assert.deepStrictEqual(names, ["Keep me"]);
35
+ });
36
+ test("TodoRemoveTaskTool: removing an unknown task id is a no-op success, not an error", async () => {
37
+ const result = await mcpClient.callTool("todo-remove-task", { tasks: ["0xdoesnotexist"] });
38
+ assert.strictEqual(result.output.message, "success");
39
+ });
40
+ test("TodoRemoveTaskTool: a non-array tasks input is rejected", async () => {
41
+ const result = await mcpClient.callTool("todo-remove-task", { tasks: "not-an-array" });
42
+ assert.match(result.output.error, /tasks must be an array of task id strings/);
43
+ });
44
+ });
45
+ //# sourceMappingURL=remove-task.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-task.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/todo/remove-task.test.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,30 @@
1
- import { test, before, after } from "node:test";
1
+ import { test, before, after, describe } from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
  import { DelayTool, MCPClient, MCPConnection, MCPServer } from "../../../index.js";
4
- let mcpConnection;
5
- let mcpClient;
6
- let mcpServer;
7
- before(async () => {
8
- mcpConnection = new MCPConnection();
9
- mcpClient = new MCPClient("1234", mcpConnection);
10
- mcpServer = new MCPServer(mcpConnection);
11
- mcpServer.registerTool(DelayTool());
12
- });
13
- after(async () => {
14
- mcpConnection?.close();
15
- });
16
- test("DelayTool: delay tool call returns waited field matching requested ms", async () => {
17
- const requestedMs = 50;
18
- const start = Date.now();
19
- const result = await mcpClient.callTool("delay", { ms: requestedMs });
20
- const elapsed = Date.now() - start;
21
- assert.ok(result, "callTool should return a result");
22
- assert.ok(result.output, "result should have an output field");
23
- const { output } = result;
24
- assert.ok("waited" in output, "output should contain 'waited'");
25
- assert.strictEqual(output.waited, requestedMs, "waited should equal the requested ms");
26
- assert.ok(elapsed >= requestedMs, `actual elapsed time (${elapsed}ms) should be at least the requested delay (${requestedMs}ms)`);
4
+ describe("utils/delay", () => {
5
+ let mcpConnection;
6
+ let mcpClient;
7
+ let mcpServer;
8
+ before(async () => {
9
+ mcpConnection = new MCPConnection();
10
+ mcpClient = new MCPClient("1234", mcpConnection);
11
+ mcpServer = new MCPServer(mcpConnection);
12
+ mcpServer.registerTool(DelayTool());
13
+ });
14
+ after(async () => {
15
+ mcpConnection?.close();
16
+ });
17
+ test("DelayTool: delay tool call returns waited field matching requested ms", async () => {
18
+ const requestedMs = 50;
19
+ const start = Date.now();
20
+ const result = await mcpClient.callTool("delay", { ms: requestedMs });
21
+ const elapsed = Date.now() - start;
22
+ assert.ok(result, "callTool should return a result");
23
+ assert.ok(result.output, "result should have an output field");
24
+ const { output } = result;
25
+ assert.ok("waited" in output, "output should contain 'waited'");
26
+ assert.strictEqual(output.waited, requestedMs, "waited should equal the requested ms");
27
+ assert.ok(elapsed >= requestedMs, `actual elapsed time (${elapsed}ms) should be at least the requested delay (${requestedMs}ms)`);
28
+ });
27
29
  });
28
30
  //# sourceMappingURL=delay.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"delay.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/utils/delay.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnF,IAAI,aAAwC,CAAC;AAC7C,IAAI,SAAoB,CAAC;AACzB,IAAI,SAAoB,CAAC;AAEzB,MAAM,CAAC,KAAK,IAAI,EAAE;IACd,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;IACpC,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjD,SAAS,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;IACzC,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,KAAK,IAAI,EAAE;IACb,aAAa,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;IACrF,MAAM,WAAW,GAAG,EAAE,CAAC;IAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAEnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;IAE/D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE1B,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,MAAM,EAAE,gCAAgC,CAAC,CAAC;IAChE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,sCAAsC,CAAC,CAAC;IACvF,MAAM,CAAC,EAAE,CACL,OAAO,IAAI,WAAW,EACtB,wBAAwB,OAAO,+CAA+C,WAAW,KAAK,CACjG,CAAC;AACN,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"delay.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/utils/delay.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IACzB,IAAI,aAAwC,CAAC;IAC7C,IAAI,SAAoB,CAAC;IACzB,IAAI,SAAoB,CAAC;IAEzB,MAAM,CAAC,KAAK,IAAI,EAAE;QACd,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;QACpC,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACjD,SAAS,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;QACzC,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,KAAK,IAAI,EAAE;QACb,aAAa,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,WAAW,GAAG,EAAE,CAAC;QAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAEnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;QAE/D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;QAE1B,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,MAAM,EAAE,gCAAgC,CAAC,CAAC;QAChE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,sCAAsC,CAAC,CAAC;QACvF,MAAM,CAAC,EAAE,CACL,OAAO,IAAI,WAAW,EACtB,wBAAwB,OAAO,+CAA+C,WAAW,KAAK,CACjG,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -1,45 +1,47 @@
1
- import { test, before, after } from "node:test";
1
+ import { test, before, after, describe } from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
  import { GetCurrentTimeTool, MCPClient, MCPConnection, MCPServer } from "../../../index.js";
4
- let mcpConnection;
5
- let mcpClient;
6
- let mcpServer;
7
- before(async () => {
8
- mcpConnection = new MCPConnection();
9
- mcpClient = new MCPClient("1234", mcpConnection);
10
- mcpServer = new MCPServer(mcpConnection);
11
- mcpServer.registerTool(GetCurrentTimeTool());
12
- });
13
- after(async () => {
14
- mcpConnection?.close();
15
- });
16
- test("GetCurrentTimeTool: iso field is a valid ISO 8601 timestamp close to now", async () => {
17
- const before = Date.now();
18
- const result = await mcpClient.callTool("get-current-time", {});
19
- const after = Date.now();
20
- assert.ok(result, "callTool should return a result");
21
- assert.ok(result.output, "result should have an output field");
22
- const { output } = result;
23
- // iso should parse to a valid date
24
- const parsed = new Date(output.iso);
25
- assert.ok(!Number.isNaN(parsed.getTime()), "iso field should be a valid date string");
26
- // iso should correspond to roughly "now" (within the call window)
27
- const parsedMs = parsed.getTime();
28
- assert.ok(parsedMs >= before && parsedMs <= after, `iso timestamp (${parsedMs}) should fall between ${before} and ${after}`);
29
- });
30
- test("GetCurrentTimeTool: unix field matches iso field and timezone is a non-empty string", async () => {
31
- const result = await mcpClient.callTool("get-current-time", {});
32
- assert.ok(result, "callTool should return a result");
33
- assert.ok(result.output, "result should have an output field");
34
- const { output } = result;
35
- // unix should be a number
36
- assert.strictEqual(typeof output.unix, "number", "unix field should be a number");
37
- // unix (assumed seconds) should match iso when converted
38
- const isoMs = new Date(output.iso).getTime();
39
- const unixMs = output.unix * 1000;
40
- assert.ok(Math.abs(isoMs - unixMs) < 1000, `unix field (${output.unix}) should correspond to iso field (${output.iso})`);
41
- // timezone should be a non-empty string
42
- assert.strictEqual(typeof output.timezone, "string", "timezone field should be a string");
43
- assert.ok(output.timezone.length > 0, "timezone field should not be empty");
4
+ describe("utils/get-current-time", () => {
5
+ let mcpConnection;
6
+ let mcpClient;
7
+ let mcpServer;
8
+ before(async () => {
9
+ mcpConnection = new MCPConnection();
10
+ mcpClient = new MCPClient("1234", mcpConnection);
11
+ mcpServer = new MCPServer(mcpConnection);
12
+ mcpServer.registerTool(GetCurrentTimeTool());
13
+ });
14
+ after(async () => {
15
+ mcpConnection?.close();
16
+ });
17
+ test("GetCurrentTimeTool: iso field is a valid ISO 8601 timestamp close to now", async () => {
18
+ const before = Date.now();
19
+ const result = await mcpClient.callTool("get-current-time", {});
20
+ const after = Date.now();
21
+ assert.ok(result, "callTool should return a result");
22
+ assert.ok(result.output, "result should have an output field");
23
+ const { output } = result;
24
+ // iso should parse to a valid date
25
+ const parsed = new Date(output.iso);
26
+ assert.ok(!Number.isNaN(parsed.getTime()), "iso field should be a valid date string");
27
+ // iso should correspond to roughly "now" (within the call window)
28
+ const parsedMs = parsed.getTime();
29
+ assert.ok(parsedMs >= before && parsedMs <= after, `iso timestamp (${parsedMs}) should fall between ${before} and ${after}`);
30
+ });
31
+ test("GetCurrentTimeTool: unix field matches iso field and timezone is a non-empty string", async () => {
32
+ const result = await mcpClient.callTool("get-current-time", {});
33
+ assert.ok(result, "callTool should return a result");
34
+ assert.ok(result.output, "result should have an output field");
35
+ const { output } = result;
36
+ // unix should be a number
37
+ assert.strictEqual(typeof output.unix, "number", "unix field should be a number");
38
+ // unix (assumed seconds) should match iso when converted
39
+ const isoMs = new Date(output.iso).getTime();
40
+ const unixMs = output.unix * 1000;
41
+ assert.ok(Math.abs(isoMs - unixMs) < 1000, `unix field (${output.unix}) should correspond to iso field (${output.iso})`);
42
+ // timezone should be a non-empty string
43
+ assert.strictEqual(typeof output.timezone, "string", "timezone field should be a string");
44
+ assert.ok(output.timezone.length > 0, "timezone field should not be empty");
45
+ });
44
46
  });
45
47
  //# sourceMappingURL=get-current-time.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-current-time.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/utils/get-current-time.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-current-time.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/utils/get-current-time.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=read-image.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-image.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/tools/utils/read-image.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import { test, before, after, describe } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, rmSync, writeFileSync } from "fs";
4
+ import { tmpdir } from "os";
5
+ import { join } from "path";
6
+ import { ReadImageTool, MCPClient, MCPConnection, MCPServer } from "../../../index.js";
7
+ describe("utils/read-image", () => {
8
+ let mcpConnection;
9
+ let mcpClient;
10
+ let mcpServer;
11
+ let tmpDir;
12
+ // smallest possible valid PNG (1x1 transparent pixel)
13
+ const PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=";
14
+ before(async () => {
15
+ tmpDir = mkdtempSync(join(tmpdir(), "orbitx-read-image-"));
16
+ writeFileSync(join(tmpDir, "pixel.png"), Buffer.from(PNG_BASE64, "base64"));
17
+ writeFileSync(join(tmpDir, "not-an-image.txt"), "hello");
18
+ mcpConnection = new MCPConnection();
19
+ mcpClient = new MCPClient("1234", mcpConnection);
20
+ mcpServer = new MCPServer(mcpConnection);
21
+ mcpServer.registerTool(ReadImageTool());
22
+ });
23
+ after(async () => {
24
+ mcpConnection?.close();
25
+ rmSync(tmpDir, { recursive: true, force: true });
26
+ });
27
+ // Like BrowserScreenshotTool, the image content only gets interpreted
28
+ // further downstream by an AI vision model (see
29
+ // BaseAgent#resolveToolOutputForModel); none of that runs here, so this only
30
+ // confirms the tool itself returns an image output, not anything about what
31
+ // the image shows.
32
+ test("ReadImageTool: reads a png file and returns an image tool-output with the right mimeType", async () => {
33
+ const path = join(tmpDir, "pixel.png");
34
+ const result = await mcpClient.callTool("read-image", { path });
35
+ assert.strictEqual(result.type, "image");
36
+ assert.strictEqual(result.output.mimeType, "image/png");
37
+ assert.strictEqual(typeof result.output.image, "string");
38
+ assert.ok(result.output.image.length > 0, "image should not be empty");
39
+ });
40
+ test("ReadImageTool: includes focusHint in the output only when provided", async () => {
41
+ const path = join(tmpDir, "pixel.png");
42
+ const withHint = await mcpClient.callTool("read-image", { path, focusHint: "check the color" });
43
+ assert.strictEqual(withHint.output.focusHint, "check the color");
44
+ const withoutHint = await mcpClient.callTool("read-image", { path });
45
+ assert.strictEqual("focusHint" in withoutHint.output, false);
46
+ });
47
+ test("ReadImageTool: a missing file surfaces a descriptive error instead of throwing raw ENOENT", async () => {
48
+ const path = join(tmpDir, "does-not-exist.png");
49
+ const result = await mcpClient.callTool("read-image", { path });
50
+ assert.ok(result.output.error, "output should contain an error field");
51
+ assert.match(result.output.error, /no file found at/);
52
+ });
53
+ });
54
+ //# sourceMappingURL=read-image.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-image.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/utils/read-image.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/session-manager.ts"],"names":[],"mappings":"AACA,OAAkB,EAAE,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAMD;;;;GAIG;AACH,cAAM,cAAc;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,eAAe,EAAE,CAAM;IACpC,WAAW,EAAE,eAAe,EAAE,CAAM;gBAExB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI;IAMpD,cAAc,CAAC,KAAK,EAAE,eAAe;IAOrC,cAAc,CAAC,KAAK,EAAE,eAAe;CAMxC;AAQD,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAgD3F;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAM5D;AAED,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpE;AAED,eAAe,cAAc,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/session-manager.ts"],"names":[],"mappings":"AACA,OAAkB,EAAE,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAMD;;;;GAIG;AACH,cAAM,cAAc;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,eAAe,EAAE,CAAM;IACpC,WAAW,EAAE,eAAe,EAAE,CAAM;gBAExB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI;IAMpD,cAAc,CAAC,KAAK,EAAE,eAAe;IAOrC,cAAc,CAAC,KAAK,EAAE,eAAe;CAMxC;AAQD,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA4D3F;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAM5D;AAED,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpE;AAED,eAAe,cAAc,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -38,11 +38,24 @@ function truncate(str, cap) {
38
38
  }
39
39
  export async function createSession(url, sessionId) {
40
40
  const browser = await puppeteer.launch({
41
- executablePath: process.env.CHROME_PATH || (os.platform() == "win32" ?
41
+ executablePath: process.env.CHROME_PATH || (os.platform() === "win32" ?
42
42
  "C:/Program Files/Google/Chrome/Application/chrome.exe" :
43
43
  "/usr/bin/google-chrome-stable"),
44
- headless: Boolean(process.env.HEADLESS_BROWSER_SESSIONS || true),
45
- args: ["--no-sandbox"],
44
+ headless: process.env.HEADLESS_BROWSER_SESSIONS !== "false",
45
+ defaultViewport: { width: 1280, height: 800, deviceScaleFactor: 1 },
46
+ args: [
47
+ "--no-sandbox",
48
+ "--disable-dev-shm-usage",
49
+ "--disable-background-networking",
50
+ "--disable-background-timer-throttling",
51
+ "--disable-backgrounding-occluded-windows",
52
+ "--disable-renderer-backgrounding",
53
+ "--disable-sync",
54
+ "--mute-audio",
55
+ "--no-first-run",
56
+ "--force-color-profile=srgb",
57
+ "--font-render-hinting=none",
58
+ ],
46
59
  });
47
60
  const page = await browser.newPage();
48
61
  const session = new BrowserSession(sessionId, browser, page);
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../src/tools/browser/session-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../../src/tools/browser/session-manager.ts"],"names":[],"mappings":"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"}
package/docs/agents.md CHANGED
@@ -56,7 +56,13 @@ This is a deliberate design for absorbing multiple user prompts that arrive whil
56
56
 
57
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
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.
59
+ `safeStop()` 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. It does not interrupt an in-flight model call — that call is left to finish normally, and the loop stops right after.
60
+
61
+ `immediateStop()` requests the same stop but returns right away without waiting for confirmation, **and** aborts the in-flight `chat()` call to the main provider immediately — the underlying HTTP request is cancelled rather than left to run to completion, so no further output tokens get generated (and billed) past that point. Input tokens, and any output already generated before the abort landed, are already committed — cancelling can't retroactively make those free. This is the one to reach for when a call has to be killed regardless of how far through it is (e.g. a credit balance that just went negative). A tool dispatch already in progress isn't aborted (tools have no generic cancellation hook) — the loop stops as soon as that call returns. Abort support is real for Anthropic, OpenAI, and DeepSeek (both streaming and non-streaming); for Ollama it only takes effect on streaming calls — see the note in `ollama-provider.ts`.
62
+
63
+ For a **streaming** call, an abort doesn't throw the turn away: `chat()` resolves normally with whatever text, thinking, and tool calls were already accumulated before the cutoff — the same as if the model had naturally stopped there — so anything already sent to `streamCallback` still ends up recorded in message history instead of vanishing. A tool call the model was still in the middle of generating when the abort hit is dropped even then (its arguments may be truncated JSON); only tool calls that had already fully finished are included — e.g. if the model requested 3 tool calls and the abort landed while the 3rd was still streaming, only the first 2 come back. For a **non-streaming** call there's nothing to salvage (the API only returns a response once, in full) — abort there still surfaces as a thrown error, and `BaseAgent` discards that turn entirely rather than recording a broken one.
64
+
65
+ `stop()` is a deprecated alias for `safeStop()` and will be removed in the 1.0.0 major release.
60
66
 
61
67
  ### Native tool-calling is required
62
68
 
@@ -86,7 +86,7 @@ Requires the `aliafsordeh/orbitx-sandbox:0.1` image (pull it, or build it yourse
86
86
 
87
87
  ## Storage and RNG
88
88
 
89
- - **`MCPStorage`** — abstract `{ get(key): Promise<string>; set(key, value): Promise<void> }`. `MCPFSStorage` is the default filesystem-backed implementation (`new MCPFSStorage(path?)`, defaults to a randomly-named folder under `./data`). `MCPStorage` and `MCPFSStorage` are both exported if you want to implement your own backend (Redis, a database, etc.) or point the default one at a specific path.
89
+ - **`MCPStorage`** — abstract `{ get(key): Promise<string>; set(key, value): Promise<void> }`. `MCPFSStorage` is the default filesystem-backed implementation (`new MCPFSStorage(path?)`, defaults to a randomly-named folder under the OS temp directory). `MCPStorage` and `MCPFSStorage` are both exported if you want to implement your own backend (Redis, a database, etc.) or point the default one at a specific path.
90
90
  - **`MCPRNG`** — deterministic-ish id generator backed by an `MCPStorage` instance (used internally for things like `generateRefId()`, the helper behind ref ids in `BrowserReadTool`'s output).
91
91
 
92
92
  ## `MCPFilter` — redacting tool output
package/docs/providers.md CHANGED
@@ -7,7 +7,8 @@ abstract class AIProvider {
7
7
  abstract chat(
8
8
  messages: Message[],
9
9
  streamCallback?: StreamCallback,
10
- tools?: ToolSchema[]
10
+ tools?: ToolSchema[],
11
+ signal?: AbortSignal
11
12
  ): Promise<ChatResponse>;
12
13
 
13
14
  abstract getCapabilities(): ProviderCapabilities;
@@ -15,6 +16,9 @@ abstract class AIProvider {
15
16
  ```
16
17
 
17
18
  - `chat` sends the full message history (plus a provider-agnostic `tools` schema, when supplied) and returns a `ChatResponse` (`{ content, inputTokens, outputTokens, toolCalls? }`). If `streamCallback` is passed, text is streamed to it incrementally as it arrives — see [Streaming](./streaming.md).
19
+ - `signal`, when passed and later aborted, cancels the in-flight request to the provider's API immediately rather than just abandoning it client-side — `BaseAgent.immediateStop()` uses this so the call stops generating (and billing for) further output right away. It doesn't retroactively waive input tokens or output already generated before the abort. Anthropic, OpenAI, and DeepSeek honor it for both streaming and non-streaming calls (their SDKs forward it straight to `fetch`). Ollama only honors it for streaming calls — its client has no way to abort a non-streaming request — so a `chat()` call made without a `streamCallback` against `OllamaProvider` can't be cancelled mid-flight; see the retry-loop guard in `ollama-provider.ts`.
20
+ - **Streaming calls resolve normally on abort**, returning a `ChatResponse` built from whatever content/thinking/tool-calls were accumulated before the cutoff, instead of throwing — so text already delivered via `streamCallback` still ends up recorded rather than discarded. A tool call still being generated when the abort lands is dropped (its arguments may be truncated JSON); only tool calls that had already fully finished streaming are included in `toolCalls`.
21
+ - **Non-streaming calls still throw on abort** — there's no partial response to salvage since the API only returns once, in full — and `BaseAgent` discards that turn.
18
22
  - `getCapabilities()` returns a static description used by `BaseAgent` to decide things like when to trigger memory compaction — it is **not** re-queried per call:
19
23
 
20
24
  ```ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orbitx",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "An AI SDK providing agents, swarms, planners, skills, MCP tools, workflows, and multi-provider AI integrations.",
5
5
  "repository": {
6
6
  "type": "git",