@arki-moe/agent-ts 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,10 @@ const agent = new Agent("openai", {
20
20
  apiKey: "sk-...",
21
21
  model: "gpt-5-nano",
22
22
  system: "You are a helpful assistant. Reply concisely.",
23
- onToolCall: (msg) => console.log("tool call:", msg),
23
+ onToolCall: (message, args) => {
24
+ console.log("tool call:", message);
25
+ console.log("tool args:", args);
26
+ },
24
27
  onToolResult: (msg) => console.log("tool result:", msg),
25
28
  });
26
29
  agent.registerTool(getTimeTool);
@@ -58,11 +61,13 @@ When `apiKey` is not provided in config, adapters read from the corresponding en
58
61
  | `model` | `string` | Model name |
59
62
  | `system` | `string` | Optional system prompt |
60
63
  | `endCondition` | `(context, last) => boolean` | Stop condition for `run`. Defaults to `last.role === Role.Ai` |
61
- | `onToolCall` | `(message) => void \| Promise<void>` | Called before each tool execution |
64
+ | `onToolCall` | `(message, args) => boolean \| void \| Promise<boolean \| void>` | Called before each tool execution; return `false` to skip tool execution and `onToolResult` |
62
65
  | `onToolResult` | `(message) => void \| Promise<void>` | Called after each tool execution |
63
66
 
64
67
  `agent.run` always appends new messages to `agent.context`. Multiple tool calls in a single model response are executed in parallel.
65
68
 
69
+ `onToolCall` receives parsed JSON args and can mutate them before execution. Returning `false` skips the tool call and does not emit a `ToolResult` message.
70
+
66
71
  `agent.fork()` shallow-copies the context array, but message objects are shared. This means:
67
72
  - Shallow copy: `forked.context !== agent.context`, so pushing new messages does not affect the other agent.
68
73
  - Shared messages: modifying a message object in one context will be visible in the other.
package/dist/index.js CHANGED
@@ -45,12 +45,29 @@ class Agent {
45
45
  const tool = this.tools.find((t) => t.name === m.toolName);
46
46
  if (!tool)
47
47
  throw new Error(`Tool "${m.toolName}" is not registered`);
48
- if (this.onToolCall)
49
- await Promise.resolve(this.onToolCall(m));
48
+ let args;
49
+ try {
50
+ args = JSON.parse(m.argsText || "{}");
51
+ }
52
+ catch (err) {
53
+ const result = {
54
+ role: types_1.Role.ToolResult,
55
+ callId: m.callId,
56
+ content: err instanceof Error ? err.message : String(err),
57
+ isError: true,
58
+ };
59
+ if (this.onToolResult)
60
+ await Promise.resolve(this.onToolResult(result));
61
+ return result;
62
+ }
63
+ if (this.onToolCall) {
64
+ const shouldRun = await Promise.resolve(this.onToolCall(m, args));
65
+ if (shouldRun === false)
66
+ return null;
67
+ }
50
68
  let content;
51
69
  let isError = false;
52
70
  try {
53
- const args = JSON.parse(m.argsText || "{}");
54
71
  const out = await Promise.resolve(tool.execute(args));
55
72
  content = typeof out === "string" ? out : JSON.stringify(out);
56
73
  }
@@ -63,8 +80,9 @@ class Agent {
63
80
  await Promise.resolve(this.onToolResult(result));
64
81
  return result;
65
82
  }));
66
- this.context.push(...results);
67
- all.push(...results);
83
+ const filteredResults = results.filter((result) => result !== null);
84
+ this.context.push(...filteredResults);
85
+ all.push(...filteredResults);
68
86
  msgs = await this.adapter(this.config, this.context, this.tools);
69
87
  this.context.push(...msgs);
70
88
  all.push(...msgs);
package/dist/types.d.ts CHANGED
@@ -34,7 +34,9 @@ export type Tool = {
34
34
  };
35
35
  export type AgentConfig = {
36
36
  endCondition?: (context: Message[], last: Message) => boolean;
37
- onToolCall?: (message: Message) => void | Promise<void>;
37
+ onToolCall?: (message: Extract<Message, {
38
+ role: Role.ToolCall;
39
+ }>, args: unknown) => boolean | void | Promise<boolean | void>;
38
40
  onToolResult?: (message: Message) => void | Promise<void>;
39
41
  [key: string]: unknown;
40
42
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arki-moe/agent-ts",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Minimal Agent library, zero dependencies",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",