orbitx 0.0.2 → 0.0.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 (109) hide show
  1. package/Readme.md +3 -3
  2. package/{src/core/ai-provider.ts → dist/core/ai-provider.d.ts} +19 -25
  3. package/dist/core/ai-provider.d.ts.map +1 -0
  4. package/dist/core/ai-provider.js +4 -0
  5. package/dist/core/ai-provider.js.map +1 -0
  6. package/dist/core/base-agent.d.ts +53 -0
  7. package/dist/core/base-agent.d.ts.map +1 -0
  8. package/{src/core/base-agent.ts → dist/core/base-agent.js} +197 -269
  9. package/dist/core/base-agent.js.map +1 -0
  10. package/dist/core/deepseek-provider.d.ts +9 -0
  11. package/dist/core/deepseek-provider.d.ts.map +1 -0
  12. package/{src/core/deepseek-provider.ts → dist/core/deepseek-provider.js} +60 -71
  13. package/dist/core/deepseek-provider.js.map +1 -0
  14. package/dist/core/mcp-client.d.ts +21 -0
  15. package/dist/core/mcp-client.d.ts.map +1 -0
  16. package/{src/core/mcp-client.ts → dist/core/mcp-client.js} +90 -113
  17. package/dist/core/mcp-client.js.map +1 -0
  18. package/dist/core/mcp-computer.d.ts +4 -0
  19. package/dist/core/mcp-computer.d.ts.map +1 -0
  20. package/{src/core/mcp-computer.ts → dist/core/mcp-computer.js} +5 -5
  21. package/dist/core/mcp-computer.js.map +1 -0
  22. package/dist/core/mcp-connection.d.ts +6 -0
  23. package/dist/core/mcp-connection.d.ts.map +1 -0
  24. package/dist/core/mcp-connection.js +10 -0
  25. package/dist/core/mcp-connection.js.map +1 -0
  26. package/dist/core/mcp-ipc-connection.d.ts +20 -0
  27. package/dist/core/mcp-ipc-connection.d.ts.map +1 -0
  28. package/{src/core/mcp-ipc-connection.ts → dist/core/mcp-ipc-connection.js} +126 -153
  29. package/dist/core/mcp-ipc-connection.js.map +1 -0
  30. package/dist/core/mcp-server.d.ts +9 -0
  31. package/dist/core/mcp-server.d.ts.map +1 -0
  32. package/{src/core/mcp-server.ts → dist/core/mcp-server.js} +45 -49
  33. package/dist/core/mcp-server.js.map +1 -0
  34. package/dist/core/mcp.d.ts +29 -0
  35. package/dist/core/mcp.d.ts.map +1 -0
  36. package/dist/core/mcp.js +11 -0
  37. package/dist/core/mcp.js.map +1 -0
  38. package/dist/core/ollama-provider.d.ts +9 -0
  39. package/dist/core/ollama-provider.d.ts.map +1 -0
  40. package/{src/core/ollama-provider.ts → dist/core/ollama-provider.js} +59 -70
  41. package/dist/core/ollama-provider.js.map +1 -0
  42. package/dist/core/skill.d.ts +15 -0
  43. package/dist/core/skill.d.ts.map +1 -0
  44. package/dist/core/skill.js +11 -0
  45. package/dist/core/skill.js.map +1 -0
  46. package/dist/index.d.ts +18 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/{src/index.ts → dist/index.js} +16 -17
  49. package/dist/index.js.map +1 -0
  50. package/dist/templates/researcher.d.ts +27 -0
  51. package/dist/templates/researcher.d.ts.map +1 -0
  52. package/dist/templates/researcher.js +70 -0
  53. package/dist/templates/researcher.js.map +1 -0
  54. package/dist/templates/simple.d.ts +27 -0
  55. package/dist/templates/simple.d.ts.map +1 -0
  56. package/dist/templates/simple.js +35 -0
  57. package/dist/templates/simple.js.map +1 -0
  58. package/dist/tests/mcp.test.d.ts +2 -0
  59. package/dist/tests/mcp.test.d.ts.map +1 -0
  60. package/{src/tests/mcp.test.ts → dist/tests/mcp.test.js} +55 -73
  61. package/dist/tests/mcp.test.js.map +1 -0
  62. package/dist/tools/fs/index.d.ts +3 -0
  63. package/dist/tools/fs/index.d.ts.map +1 -0
  64. package/dist/tools/fs/index.js +3 -0
  65. package/dist/tools/fs/index.js.map +1 -0
  66. package/dist/tools/fs/read-file.d.ts +4 -0
  67. package/dist/tools/fs/read-file.d.ts.map +1 -0
  68. package/{src/tools/fs/read-file.ts → dist/tools/fs/read-file.js} +49 -54
  69. package/dist/tools/fs/read-file.js.map +1 -0
  70. package/dist/tools/fs/write-file.d.ts +4 -0
  71. package/dist/tools/fs/write-file.d.ts.map +1 -0
  72. package/{src/tools/fs/write-file.ts → dist/tools/fs/write-file.js} +68 -73
  73. package/dist/tools/fs/write-file.js.map +1 -0
  74. package/dist/tools/utils/get-current-time.d.ts +4 -0
  75. package/dist/tools/utils/get-current-time.d.ts.map +1 -0
  76. package/{src/tools/utils/get-current-time.ts → dist/tools/utils/get-current-time.js} +40 -45
  77. package/dist/tools/utils/get-current-time.js.map +1 -0
  78. package/dist/tools/utils/index.d.ts +2 -0
  79. package/dist/tools/utils/index.d.ts.map +1 -0
  80. package/dist/tools/utils/index.js +2 -0
  81. package/dist/tools/utils/index.js.map +1 -0
  82. package/dist/tools/www/fetch.d.ts +4 -0
  83. package/dist/tools/www/fetch.d.ts.map +1 -0
  84. package/{src/tools/www/fetch.ts → dist/tools/www/fetch.js} +147 -161
  85. package/dist/tools/www/fetch.js.map +1 -0
  86. package/dist/tools/www/index.d.ts +4 -0
  87. package/dist/tools/www/index.d.ts.map +1 -0
  88. package/dist/tools/www/index.js +4 -0
  89. package/dist/tools/www/index.js.map +1 -0
  90. package/dist/tools/www/read-web-page.d.ts +4 -0
  91. package/dist/tools/www/read-web-page.d.ts.map +1 -0
  92. package/{src/tools/www/read-web-page.ts → dist/tools/www/read-web-page.js} +330 -350
  93. package/dist/tools/www/read-web-page.js.map +1 -0
  94. package/dist/tools/www/web-search.d.ts +4 -0
  95. package/dist/tools/www/web-search.d.ts.map +1 -0
  96. package/{src/tools/www/web-search.ts → dist/tools/www/web-search.js} +82 -102
  97. package/dist/tools/www/web-search.js.map +1 -0
  98. package/package.json +19 -5
  99. package/.env.example +0 -1
  100. package/orbitx.png +0 -0
  101. package/src/core/mcp-connection.ts +0 -12
  102. package/src/core/mcp.ts +0 -23
  103. package/src/core/skill.ts +0 -16
  104. package/src/templates/researcher.ts +0 -73
  105. package/src/templates/simple.ts +0 -64
  106. package/src/tools/fs/index.ts +0 -2
  107. package/src/tools/utils/index.ts +0 -1
  108. package/src/tools/www/index.ts +0 -3
  109. package/tsconfig.json +0 -34
package/Readme.md CHANGED
@@ -1,5 +1,5 @@
1
- [![OrbitX Logo](./orbitx.png)](#)
2
-
1
+ <!-- [![OrbitX Logo](./orbitx.png)](#) -->
2
+ # OrbitX
3
3
 
4
4
  Better DOCS Coming soon Sorry
5
5
 
@@ -34,7 +34,7 @@ const ollamaProvider = new OllamaProvider("gemma3:latest");
34
34
  const agent = new ResearcherAgent({ aiProvider: ollamaProvider });
35
35
 
36
36
  let oldRole: "assistant" | "tool" | undefined;
37
- agent.run("what is IRR Value In USD", (chunk) => {
37
+ agent.run("How artificial intelligence is changing the job market", (chunk) => {
38
38
  if (oldRole != chunk.role) {
39
39
  process.stdout.write(`\n${chunk.role}: `);
40
40
  oldRole = chunk.role;
@@ -1,25 +1,19 @@
1
- export interface Message {
2
- role: "user" | "system" | "assistant" | "tool";
3
- content?: string;
4
- }
5
-
6
- export interface ChatResponse {
7
- content: string;
8
- inputTokens: number;
9
- outputTokens: number;
10
- }
11
-
12
- export type StreamCallback = (chunk: {
13
- role: "assistant" | "tool";
14
- content: string;
15
- done: boolean;
16
- }) => void;
17
-
18
- export abstract class AIProvider {
19
- abstract chat(
20
- messages: Message[],
21
- streamCallback?: StreamCallback
22
- ): Promise<ChatResponse>;
23
- }
24
-
25
- export default AIProvider;
1
+ export interface Message {
2
+ role: "user" | "system" | "assistant" | "tool";
3
+ content?: string;
4
+ }
5
+ export interface ChatResponse {
6
+ content: string;
7
+ inputTokens: number;
8
+ outputTokens: number;
9
+ }
10
+ export type StreamCallback = (chunk: {
11
+ role: "assistant" | "tool";
12
+ content: string;
13
+ done: boolean;
14
+ }) => void;
15
+ export declare abstract class AIProvider {
16
+ abstract chat(messages: Message[], streamCallback?: StreamCallback): Promise<ChatResponse>;
17
+ }
18
+ export default AIProvider;
19
+ //# sourceMappingURL=ai-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-provider.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE;IACjC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACjB,KAAK,IAAI,CAAC;AAEX,8BAAsB,UAAU;IAC5B,QAAQ,CAAC,IAAI,CACT,QAAQ,EAAE,OAAO,EAAE,EACnB,cAAc,CAAC,EAAE,cAAc,GAChC,OAAO,CAAC,YAAY,CAAC;CAC3B;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ export class AIProvider {
2
+ }
3
+ export default AIProvider;
4
+ //# sourceMappingURL=ai-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-provider.js","sourceRoot":"","sources":["../../src/core/ai-provider.ts"],"names":[],"mappings":"AAiBA,MAAM,OAAgB,UAAU;CAK/B;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { AIProvider, Message, StreamCallback } from "./ai-provider";
2
+ import type MCPClient from "./mcp-client";
3
+ import type MCPTool from "./mcp";
4
+ import type Skill from "./skill";
5
+ export interface ParsedToolCall {
6
+ id: string;
7
+ tool: string;
8
+ inputs: Record<string, any>;
9
+ }
10
+ export type ExtractedSegment = {
11
+ type: "text";
12
+ context: string;
13
+ } | {
14
+ type: "tool";
15
+ context: ParsedToolCall;
16
+ };
17
+ export declare class BaseAgent {
18
+ #private;
19
+ constructor({ instruction, allowedTools, aiProvider, mcpClient, initData, skills, maxMemorizeToken }: {
20
+ instruction: string;
21
+ allowedTools: MCPTool[];
22
+ aiProvider: AIProvider;
23
+ mcpClient: MCPClient;
24
+ skills?: Skill[];
25
+ maxMemorizeToken?: number;
26
+ initData?: {
27
+ memory: string;
28
+ messagesFull: Message[];
29
+ fullInputMissTokens: number;
30
+ fullInputHitTokens: number;
31
+ fullOutputTokens: number;
32
+ messagesCompact: Message[];
33
+ currentInputMissTokens: number;
34
+ currentInputHitTokens: number;
35
+ currentOutputTokens: number;
36
+ };
37
+ });
38
+ run(prompt: string, streamCallback?: StreamCallback): Promise<void>;
39
+ getCurrentTotalTokens(): {
40
+ total: number;
41
+ inputHit: number;
42
+ inputMiss: number;
43
+ output: number;
44
+ };
45
+ getFullTotalTokens(): {
46
+ total: number;
47
+ inputHit: number;
48
+ inputMiss: number;
49
+ output: number;
50
+ };
51
+ }
52
+ export default BaseAgent;
53
+ //# sourceMappingURL=base-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-agent.d.ts","sourceRoot":"","sources":["../../src/core/base-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,gBAAgB,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC;AAEhD,qBAAa,SAAS;;gBAwBN,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAU/D,EAAE,MAAW,EAAE,gBAAwB,EAAE,EAAE;QACxC,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,OAAO,EAAE,CAAC;QACxB,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,EAAE,SAAS,CAAC;QACrB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,YAAY,EAAE,OAAO,EAAE,CAAC;YACxB,mBAAmB,EAAE,MAAM,CAAC;YAC5B,kBAAkB,EAAE,MAAM,CAAC;YAC3B,gBAAgB,EAAE,MAAM,CAAC;YACzB,eAAe,EAAE,OAAO,EAAE,CAAC;YAC3B,sBAAsB,EAAE,MAAM,CAAC;YAC/B,qBAAqB,EAAE,MAAM,CAAC;YAC9B,mBAAmB,EAAE,MAAM,CAAC;SAC/B,CAAA;KACJ;IAoJK,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA8DzE,qBAAqB;;;;;;IASrB,kBAAkB;;;;;;CAQrB;AAED,eAAe,SAAS,CAAC"}
@@ -1,160 +1,108 @@
1
- import type { AIProvider, Message, StreamCallback } from "./ai-provider";
2
- import type MCPClient from "./mcp-client";
3
- import type MCPTool from "./mcp";
4
- import type Skill from "./skill";
5
-
6
- export interface ParsedToolCall {
7
- id: string;
8
- tool: string;
9
- inputs: Record<string, any>;
10
- }
11
-
12
- export type ExtractedSegment =
13
- | { type: "text"; context: string }
14
- | { type: "tool"; context: ParsedToolCall };
15
-
16
- export class BaseAgent {
17
- #maxMemorizeToken = 16000;
18
- #instruction: string = "";
19
- #allowedTools: string[] = [];
20
-
21
- #skills: Skill[] = [];
22
-
23
- #memory: string = "";
24
-
25
- #messagesFull: Message[] = [];
26
-
27
- #fullInputMissTokens = 0;
28
- #fullInputHitTokens = 0;
29
- #fullOutputTokens = 0;
30
-
31
- #messagesCompact: Message[] = [];
32
- #currentInputMissTokens = 0;
33
- #currentInputHitTokens = 0;
34
- #currentLastOutputTokens = 0;
35
- #currentOutputTokens = 0;
36
-
37
- #mcpClient: MCPClient;
38
- #aiProvider: AIProvider;
39
-
40
- constructor({ instruction, allowedTools, aiProvider, mcpClient, initData = {
41
- memory: "",
42
- messagesFull: [],
43
- fullInputMissTokens: 0,
44
- fullInputHitTokens: 0,
45
- fullOutputTokens: 0,
46
- messagesCompact: [],
47
- currentInputMissTokens: 0,
48
- currentInputHitTokens: 0,
49
- currentOutputTokens: 0,
50
- }, skills = [], maxMemorizeToken = 16000 }: {
51
- instruction: string;
52
- allowedTools: MCPTool[];
53
- aiProvider: AIProvider;
54
- mcpClient: MCPClient;
55
- skills?: Skill[];
56
- maxMemorizeToken?: number;
57
- initData?: {
58
- memory: string;
59
- messagesFull: Message[];
60
- fullInputMissTokens: number;
61
- fullInputHitTokens: number;
62
- fullOutputTokens: number;
63
- messagesCompact: Message[];
64
- currentInputMissTokens: number;
65
- currentInputHitTokens: number;
66
- currentOutputTokens: number;
67
- }
68
- }) {
69
- this.#instruction = instruction;
70
- this.#allowedTools = allowedTools.map(t => t.getOptions().name);
71
- this.#aiProvider = aiProvider;
72
- this.#mcpClient = mcpClient;
73
- this.#memory = initData.memory;
74
- this.#messagesFull = initData.messagesFull;
75
- this.#fullInputMissTokens = initData.fullInputMissTokens
76
- this.#fullInputHitTokens = initData.fullInputHitTokens
77
- this.#fullOutputTokens = initData.fullOutputTokens
78
- this.#messagesCompact = initData.messagesCompact;
79
- this.#currentInputMissTokens = initData.currentInputMissTokens
80
- this.#currentInputHitTokens = initData.currentInputHitTokens
81
- this.#currentOutputTokens = initData.currentOutputTokens
82
- this.#maxMemorizeToken = maxMemorizeToken;
83
- this.#skills = skills;
84
- }
85
-
86
- #extractJson(str: string): ExtractedSegment[] {
87
- const segments: ExtractedSegment[] = [];
88
- let cursor = 0;
89
- let textStart = 0;
90
-
91
- for (let i = 0; i < str.length; i++) {
92
- if (str[i] !== "{") continue;
93
-
94
- let brace = 0;
95
- for (let j = i; j < str.length; j++) {
96
- if (str[j] === "{") brace++;
97
- if (str[j] === "}") brace--;
98
-
99
- if (brace === 0) {
100
- const candidate = str.slice(i, j + 1);
101
- try {
102
- const result = JSON.parse(candidate);
103
- if (
104
- result &&
105
- typeof result === "object" &&
106
- "tool" in result &&
107
- "inputs" in result &&
108
- typeof result.tool === "string"
109
- ) {
110
- const text = str.slice(textStart, i);
111
- if (text.trim().length > 0) {
112
- segments.push({ type: "text", context: text });
113
- }
114
- segments.push({ type: "tool", context: result as ParsedToolCall });
115
-
116
- i = j;
117
- textStart = j + 1;
118
- cursor = j + 1;
119
- }
120
- } catch {
121
- // not valid JSON, skip
122
- }
123
- break;
124
- }
125
- }
126
- }
127
-
128
- const remaining = str.slice(textStart);
129
- if (remaining.trim().length > 0) {
130
- segments.push({ type: "text", context: remaining });
131
- }
132
-
133
- return segments;
134
- }
135
-
136
- async #buildSystemPrompt(): Promise<string> {
137
- const tools = (await this.#mcpClient.getTools())
138
- .filter(t => this.#allowedTools.includes(t.name));
139
-
140
- const toolBlock = tools.map(t => {
141
- const params = t.inputs.map(ti =>
142
- `${ti.name}${ti.required ? "" : "?"}:${ti.type}${ti.default !== undefined ? `=${JSON.stringify(ti.default)}` : ""} // ${ti.description}`
143
- ).join(", ");
144
-
145
- const example: Record<string, unknown> = {};
146
- t.inputs.forEach(ti => {
147
- example[ti.name] = ti.default !== undefined ? ti.default
148
- : ti.type === "string" ? "..."
149
- : ti.type === "number" ? 0
150
- : ti.type === "boolean" ? true
151
- : ti.type === "array" ? []
152
- : {};
153
- });
154
-
155
- return `${t.name}(${params || ""})\n${t.description}\nex: {"tool":"${t.name}","inputs":${JSON.stringify(example)}}`;
156
- }).join("\n\n");
157
-
1
+ export class BaseAgent {
2
+ #maxMemorizeToken = 16000;
3
+ #instruction = "";
4
+ #allowedTools = [];
5
+ #skills = [];
6
+ #memory = "";
7
+ #messagesFull = [];
8
+ #fullInputMissTokens = 0;
9
+ #fullInputHitTokens = 0;
10
+ #fullOutputTokens = 0;
11
+ #messagesCompact = [];
12
+ #currentInputMissTokens = 0;
13
+ #currentInputHitTokens = 0;
14
+ #currentLastOutputTokens = 0;
15
+ #currentOutputTokens = 0;
16
+ #mcpClient;
17
+ #aiProvider;
18
+ constructor({ instruction, allowedTools, aiProvider, mcpClient, initData = {
19
+ memory: "",
20
+ messagesFull: [],
21
+ fullInputMissTokens: 0,
22
+ fullInputHitTokens: 0,
23
+ fullOutputTokens: 0,
24
+ messagesCompact: [],
25
+ currentInputMissTokens: 0,
26
+ currentInputHitTokens: 0,
27
+ currentOutputTokens: 0,
28
+ }, skills = [], maxMemorizeToken = 16000 }) {
29
+ this.#instruction = instruction;
30
+ this.#allowedTools = allowedTools.map(t => t.getOptions().name);
31
+ this.#aiProvider = aiProvider;
32
+ this.#mcpClient = mcpClient;
33
+ this.#memory = initData.memory;
34
+ this.#messagesFull = initData.messagesFull;
35
+ this.#fullInputMissTokens = initData.fullInputMissTokens;
36
+ this.#fullInputHitTokens = initData.fullInputHitTokens;
37
+ this.#fullOutputTokens = initData.fullOutputTokens;
38
+ this.#messagesCompact = initData.messagesCompact;
39
+ this.#currentInputMissTokens = initData.currentInputMissTokens;
40
+ this.#currentInputHitTokens = initData.currentInputHitTokens;
41
+ this.#currentOutputTokens = initData.currentOutputTokens;
42
+ this.#maxMemorizeToken = maxMemorizeToken;
43
+ this.#skills = skills;
44
+ }
45
+ #extractJson(str) {
46
+ const segments = [];
47
+ let cursor = 0;
48
+ let textStart = 0;
49
+ for (let i = 0; i < str.length; i++) {
50
+ if (str[i] !== "{")
51
+ continue;
52
+ let brace = 0;
53
+ for (let j = i; j < str.length; j++) {
54
+ if (str[j] === "{")
55
+ brace++;
56
+ if (str[j] === "}")
57
+ brace--;
58
+ if (brace === 0) {
59
+ const candidate = str.slice(i, j + 1);
60
+ try {
61
+ const result = JSON.parse(candidate);
62
+ if (result &&
63
+ typeof result === "object" &&
64
+ "tool" in result &&
65
+ "inputs" in result &&
66
+ typeof result.tool === "string") {
67
+ const text = str.slice(textStart, i);
68
+ if (text.trim().length > 0) {
69
+ segments.push({ type: "text", context: text });
70
+ }
71
+ segments.push({ type: "tool", context: result });
72
+ i = j;
73
+ textStart = j + 1;
74
+ cursor = j + 1;
75
+ }
76
+ }
77
+ catch {
78
+ // not valid JSON, skip
79
+ }
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ const remaining = str.slice(textStart);
85
+ if (remaining.trim().length > 0) {
86
+ segments.push({ type: "text", context: remaining });
87
+ }
88
+ return segments;
89
+ }
90
+ async #buildSystemPrompt() {
91
+ const tools = (await this.#mcpClient.getTools())
92
+ .filter(t => this.#allowedTools.includes(t.name));
93
+ const toolBlock = tools.map(t => {
94
+ const params = t.inputs.map(ti => `${ti.name}${ti.required ? "" : "?"}:${ti.type}${ti.default !== undefined ? `=${JSON.stringify(ti.default)}` : ""} // ${ti.description}`).join(", ");
95
+ const example = {};
96
+ t.inputs.forEach(ti => {
97
+ example[ti.name] = ti.default !== undefined ? ti.default
98
+ : ti.type === "string" ? "..."
99
+ : ti.type === "number" ? 0
100
+ : ti.type === "boolean" ? true
101
+ : ti.type === "array" ? []
102
+ : {};
103
+ });
104
+ return `${t.name}(${params || ""})\n${t.description}\nex: {"tool":"${t.name}","inputs":${JSON.stringify(example)}}`;
105
+ }).join("\n\n");
158
106
  return `You are an assistant with tools. CRITICAL RULES:
159
107
  1. Think step by step.
160
108
  ${tools.length > 0 && `2. EVERY tool call MUST include a UNIQUE 10-digit random ID in the format: {"id":"1234567890", "tool":"<name>","inputs":{...}}
@@ -170,7 +118,7 @@ TOOLS:
170
118
  ${toolBlock}
171
119
  `}
172
120
 
173
- ${this.#skills &&`
121
+ ${this.#skills && `
174
122
  SKILLS:
175
123
  ${this.#skills.map(skill => (`${skill.getSkill().name} - ${skill.getSkill().description}
176
124
  ${skill.getSkill().instructions}
@@ -182,116 +130,96 @@ ${this.#memory || "(empty)"}
182
130
 
183
131
  INSTRUCTIONS:
184
132
  ${this.#instruction}
185
- `;
186
- }
187
-
188
- #buildMemoryPrompt(): string {
133
+ `;
134
+ }
135
+ #buildMemoryPrompt() {
189
136
  return `Summarize all important facts and pending tasks from this conversation.
190
137
  Output only this JSON line, nothing else:
191
- {"tool":"set_memory","inputs":{"new_memory":"<compact summary>"}}`;
192
- }
193
-
194
- async #extractToolCalls(content: string): Promise<ParsedToolCall[]> {
195
- return await this.#extractJson(content)
196
- .filter((r: { type: string }) => r.type === "tool")
197
- .map((t) => t.context as ParsedToolCall);
198
- }
199
-
200
- async #dispatchTool(toolCall: ParsedToolCall): Promise<string> {
201
- if (toolCall.tool === "set_memory") {
202
- if (typeof toolCall.inputs?.new_memory === "string") {
203
- this.#memory = toolCall.inputs.new_memory;
204
- return "Memory updated.";
205
- }
206
- return `Error: set_memory requires new_memory:string, got ${JSON.stringify(toolCall.inputs)}`;
207
- }
208
-
209
- if (this.#allowedTools.includes(toolCall.tool)) {
210
- return JSON.stringify({ id: toolCall.id, output: await this.#mcpClient.callTool(toolCall.tool, toolCall.inputs) });
211
- }
212
-
213
- return `Error: tool "${toolCall.tool}" not found or not allowed.`;
214
- }
215
-
216
- async run(prompt: string, streamCallback?: StreamCallback): Promise<void> {
217
- let toolsCalls: ParsedToolCall[] = [];
218
-
219
- do {
220
- const systemPrompt = await this.#buildSystemPrompt();
221
-
222
- const chat = await this.#aiProvider.chat([
223
- { role: "system", content: systemPrompt },
224
- ...this.#messagesCompact,
225
- { role: "user", content: prompt }
226
- ], streamCallback);
227
-
228
- this.#messagesFull.push({ role: "user", content: prompt });
229
- this.#messagesCompact.push({ role: "user", content: prompt });
230
- this.#messagesFull.push({ role: "assistant", content: chat.content });
231
- this.#messagesCompact.push({ role: "assistant", content: chat.content });
232
-
233
- this.#currentInputHitTokens += this.#currentInputMissTokens;
234
- this.#currentInputMissTokens += chat.inputTokens - this.#currentInputMissTokens;
235
- this.#currentOutputTokens += this.#currentOutputTokens;
236
- this.#currentLastOutputTokens = this.#currentOutputTokens;
237
-
238
- toolsCalls = await this.#extractToolCalls(chat.content);
239
-
240
- for (const toolCall of toolsCalls) {
241
- const toolResponse = await this.#dispatchTool(toolCall);
242
- this.#messagesFull.push({ role: "system", content: toolResponse });
243
- this.#messagesCompact.push({ role: "system", content: toolResponse });
244
- streamCallback?.({ role: "tool", content: toolResponse, done: true });
245
- }
246
-
247
- if (this.#currentInputMissTokens + this.#currentLastOutputTokens > this.#maxMemorizeToken) {
248
- const memChat = await this.#aiProvider.chat([
249
- { role: "system", content: systemPrompt },
250
- ...this.#messagesCompact,
251
- { role: "user", content: this.#buildMemoryPrompt() }
252
- ]);
253
-
254
- this.#currentInputHitTokens += this.#currentInputMissTokens;
255
- this.#currentInputMissTokens += memChat.inputTokens - this.#currentInputMissTokens;
256
- this.#currentOutputTokens += this.#currentOutputTokens;
257
-
258
- for (const mc of await this.#extractToolCalls(memChat.content)) {
259
- const toolResponse = await this.#dispatchTool(mc);
260
- streamCallback?.({ role: "tool", content: toolResponse, done: true });
261
- }
262
-
263
- this.#messagesCompact = [];
264
- this.#fullInputHitTokens += this.#currentInputHitTokens;
265
- this.#fullInputMissTokens += this.#currentInputMissTokens;
266
- this.#fullOutputTokens += this.#currentOutputTokens;
267
- this.#currentInputHitTokens = 0;
268
- this.#currentInputMissTokens = 0;
269
- this.#currentOutputTokens = 0;
270
- this.#currentLastOutputTokens = 0;
271
- }
272
-
273
- prompt = "";
274
-
275
- } while (toolsCalls.length > 0);
276
- }
277
-
278
- getCurrentTotalTokens() {
279
- return {
280
- total: this.#currentInputHitTokens + this.#currentInputMissTokens + this.#currentOutputTokens,
281
- inputHit: this.#currentInputHitTokens,
282
- inputMiss: this.#currentInputMissTokens,
283
- output: this.#currentOutputTokens
284
- };
285
- }
286
-
287
- getFullTotalTokens() {
288
- return {
289
- total: this.#fullInputHitTokens + this.#fullInputMissTokens + this.#fullOutputTokens,
290
- inputHit: this.#fullInputHitTokens,
291
- inputMiss: this.#fullInputMissTokens,
292
- output: this.#fullOutputTokens
293
- };
294
- }
295
- }
296
-
297
- export default BaseAgent;
138
+ {"tool":"set_memory","inputs":{"new_memory":"<compact summary>"}}`;
139
+ }
140
+ async #extractToolCalls(content) {
141
+ return await this.#extractJson(content)
142
+ .filter((r) => r.type === "tool")
143
+ .map((t) => t.context);
144
+ }
145
+ async #dispatchTool(toolCall) {
146
+ if (toolCall.tool === "set_memory") {
147
+ if (typeof toolCall.inputs?.new_memory === "string") {
148
+ this.#memory = toolCall.inputs.new_memory;
149
+ return "Memory updated.";
150
+ }
151
+ return `Error: set_memory requires new_memory:string, got ${JSON.stringify(toolCall.inputs)}`;
152
+ }
153
+ if (this.#allowedTools.includes(toolCall.tool)) {
154
+ return JSON.stringify({ id: toolCall.id, output: await this.#mcpClient.callTool(toolCall.tool, toolCall.inputs) });
155
+ }
156
+ return `Error: tool "${toolCall.tool}" not found or not allowed.`;
157
+ }
158
+ async run(prompt, streamCallback) {
159
+ let toolsCalls = [];
160
+ do {
161
+ const systemPrompt = await this.#buildSystemPrompt();
162
+ const chat = await this.#aiProvider.chat([
163
+ { role: "system", content: systemPrompt },
164
+ ...this.#messagesCompact,
165
+ { role: "user", content: prompt }
166
+ ], streamCallback);
167
+ this.#messagesFull.push({ role: "user", content: prompt });
168
+ this.#messagesCompact.push({ role: "user", content: prompt });
169
+ this.#messagesFull.push({ role: "assistant", content: chat.content });
170
+ this.#messagesCompact.push({ role: "assistant", content: chat.content });
171
+ this.#currentInputHitTokens += this.#currentInputMissTokens;
172
+ this.#currentInputMissTokens += chat.inputTokens - this.#currentInputMissTokens;
173
+ this.#currentOutputTokens += chat.outputTokens;
174
+ this.#currentLastOutputTokens = chat.outputTokens;
175
+ toolsCalls = await this.#extractToolCalls(chat.content);
176
+ for (const toolCall of toolsCalls) {
177
+ const toolResponse = await this.#dispatchTool(toolCall);
178
+ this.#messagesFull.push({ role: "system", content: toolResponse });
179
+ this.#messagesCompact.push({ role: "system", content: toolResponse });
180
+ streamCallback?.({ role: "tool", content: toolResponse, done: true });
181
+ }
182
+ if (this.#currentInputMissTokens + this.#currentLastOutputTokens > this.#maxMemorizeToken) {
183
+ const memChat = await this.#aiProvider.chat([
184
+ { role: "system", content: systemPrompt },
185
+ ...this.#messagesCompact,
186
+ { role: "user", content: this.#buildMemoryPrompt() }
187
+ ]);
188
+ this.#currentInputHitTokens += this.#currentInputMissTokens;
189
+ this.#currentInputMissTokens += memChat.inputTokens - this.#currentInputMissTokens;
190
+ this.#currentOutputTokens += memChat.outputTokens;
191
+ for (const mc of await this.#extractToolCalls(memChat.content)) {
192
+ const toolResponse = await this.#dispatchTool(mc);
193
+ streamCallback?.({ role: "tool", content: toolResponse, done: true });
194
+ }
195
+ this.#messagesCompact = [];
196
+ this.#fullInputHitTokens += this.#currentInputHitTokens;
197
+ this.#fullInputMissTokens += this.#currentInputMissTokens;
198
+ this.#fullOutputTokens += this.#currentOutputTokens;
199
+ this.#currentInputHitTokens = 0;
200
+ this.#currentInputMissTokens = 0;
201
+ this.#currentOutputTokens = 0;
202
+ this.#currentLastOutputTokens = 0;
203
+ }
204
+ prompt = "";
205
+ } while (toolsCalls.length > 0);
206
+ }
207
+ getCurrentTotalTokens() {
208
+ return {
209
+ total: this.#currentInputHitTokens + this.#currentInputMissTokens + this.#currentOutputTokens,
210
+ inputHit: this.#currentInputHitTokens,
211
+ inputMiss: this.#currentInputMissTokens,
212
+ output: this.#currentOutputTokens
213
+ };
214
+ }
215
+ getFullTotalTokens() {
216
+ return {
217
+ total: this.#fullInputHitTokens + this.#fullInputMissTokens + this.#fullOutputTokens,
218
+ inputHit: this.#fullInputHitTokens,
219
+ inputMiss: this.#fullInputMissTokens,
220
+ output: this.#fullOutputTokens
221
+ };
222
+ }
223
+ }
224
+ export default BaseAgent;
225
+ //# sourceMappingURL=base-agent.js.map