@arki-moe/agent-ts 1.0.2 → 2.0.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 +18 -11
- package/dist/index.d.ts +7 -5
- package/dist/index.js +22 -18
- package/dist/types.d.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,18 +19,16 @@ const getTimeTool: Tool = {
|
|
|
19
19
|
const agent = new Agent("openai", {
|
|
20
20
|
apiKey: "sk-...",
|
|
21
21
|
model: "gpt-5-nano",
|
|
22
|
-
system: "You are a helpful assistant. Reply concisely.",
|
|
22
|
+
system: "You are a helpful assistant. Reply concisely.",
|
|
23
|
+
onToolCall: (msg) => console.log("tool call:", msg),
|
|
24
|
+
onToolResult: (msg) => console.log("tool result:", msg),
|
|
23
25
|
});
|
|
24
26
|
agent.registerTool(getTimeTool);
|
|
25
27
|
|
|
26
28
|
// run: Executes tool chain automatically, returns new messages, context is maintained automatically
|
|
27
|
-
const msgs = await agent.run(
|
|
29
|
+
const msgs = await agent.run("What time is it?");
|
|
28
30
|
console.log(msgs);
|
|
29
31
|
|
|
30
|
-
// step: Single-step inference, returns new messages from the model
|
|
31
|
-
const msgs2 = await agent.step({ role: Role.User, content: "Hello" });
|
|
32
|
-
console.log(msgs2);
|
|
33
|
-
|
|
34
32
|
// context is a public property that can be read directly
|
|
35
33
|
console.log(agent.context);
|
|
36
34
|
```
|
|
@@ -46,15 +44,24 @@ When `apiKey` is not provided in config, adapters read from the corresponding en
|
|
|
46
44
|
|
|
47
45
|
## API
|
|
48
46
|
|
|
49
|
-
- `Agent(adapterName, config)` - Create Agent
|
|
47
|
+
- `Agent(adapterName, config)` - Create Agent
|
|
50
48
|
- `agent.context` - Public property, complete conversation history
|
|
51
49
|
- `agent.registerTool(tool)` - Register tool
|
|
52
|
-
- `agent.
|
|
53
|
-
- `agent.run(message, endCondition?)` - Execute tool chain automatically, returns all new `Message[]`
|
|
50
|
+
- `agent.run(message)` - Execute tool chain automatically, returns all new `Message[]`
|
|
54
51
|
- `agent.fork()` - Create a new agent with a copied context
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
### Config
|
|
54
|
+
|
|
55
|
+
| Field | Type | Description |
|
|
56
|
+
|-------|------|-------------|
|
|
57
|
+
| `apiKey` | `string` | API key (or use env var) |
|
|
58
|
+
| `model` | `string` | Model name |
|
|
59
|
+
| `system` | `string` | Optional system prompt |
|
|
60
|
+
| `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 |
|
|
62
|
+
| `onToolResult` | `(message) => void \| Promise<void>` | Called after each tool execution |
|
|
63
|
+
|
|
64
|
+
`agent.run` always appends new messages to `agent.context`. Multiple tool calls in a single model response are executed in parallel.
|
|
58
65
|
|
|
59
66
|
`agent.fork()` shallow-copies the context array, but message objects are shared. This means:
|
|
60
67
|
- Shallow copy: `forked.context !== agent.context`, so pushing new messages does not affect the other agent.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Context, Message, Tool } from "./types";
|
|
1
|
+
import type { AgentConfig, Context, Message, Tool } from "./types";
|
|
2
2
|
export { openaiAdapter } from "./adapter/openai";
|
|
3
3
|
export { openrouterAdapter } from "./adapter/openrouter";
|
|
4
|
-
export type { Adapter, Context, Message, Tool } from "./types";
|
|
4
|
+
export type { Adapter, AgentConfig, Context, Message, Tool } from "./types";
|
|
5
5
|
export { Role } from "./types";
|
|
6
6
|
export declare class Agent {
|
|
7
7
|
context: Context;
|
|
@@ -9,9 +9,11 @@ export declare class Agent {
|
|
|
9
9
|
private adapterName;
|
|
10
10
|
private config;
|
|
11
11
|
private tools;
|
|
12
|
-
|
|
12
|
+
private endCondition;
|
|
13
|
+
private onToolCall?;
|
|
14
|
+
private onToolResult?;
|
|
15
|
+
constructor(adapterName: string, config: AgentConfig);
|
|
13
16
|
registerTool(tool: Tool): void;
|
|
14
|
-
|
|
15
|
-
run(message: Message, endCondition?: (context: Message[], last: Message) => boolean): Promise<Message[]>;
|
|
17
|
+
run(message: string): Promise<Message[]>;
|
|
16
18
|
fork(): Agent;
|
|
17
19
|
}
|
package/dist/index.js
CHANGED
|
@@ -21,32 +21,32 @@ class Agent {
|
|
|
21
21
|
this.adapterName = adapterName;
|
|
22
22
|
this.adapter = adapters[adapterName] ?? (() => { throw new Error(`Adapter "${adapterName}" not found`); })();
|
|
23
23
|
this.config = config;
|
|
24
|
+
this.endCondition = config.endCondition ?? ((_ctx, last) => last.role === types_1.Role.Ai);
|
|
25
|
+
this.onToolCall = config.onToolCall;
|
|
26
|
+
this.onToolResult = config.onToolResult;
|
|
24
27
|
}
|
|
25
28
|
registerTool(tool) {
|
|
26
29
|
this.tools.push(tool);
|
|
27
30
|
}
|
|
28
|
-
async
|
|
29
|
-
|
|
30
|
-
this.context.push(message);
|
|
31
|
-
}
|
|
32
|
-
const msgs = await this.adapter(this.config, this.context, this.tools);
|
|
33
|
-
this.context.push(...msgs);
|
|
34
|
-
return msgs;
|
|
35
|
-
}
|
|
36
|
-
async run(message, endCondition = (_context, last) => last.role === types_1.Role.Ai) {
|
|
31
|
+
async run(message) {
|
|
32
|
+
this.context.push({ role: types_1.Role.User, content: message });
|
|
37
33
|
const all = [];
|
|
38
|
-
let msgs = await this.
|
|
34
|
+
let msgs = await this.adapter(this.config, this.context, this.tools);
|
|
35
|
+
this.context.push(...msgs);
|
|
39
36
|
all.push(...msgs);
|
|
40
37
|
for (;;) {
|
|
41
38
|
const last = msgs[msgs.length - 1];
|
|
42
|
-
if (endCondition(this.context, last))
|
|
39
|
+
if (this.endCondition(this.context, last))
|
|
40
|
+
return all;
|
|
41
|
+
const toolCalls = msgs.filter((m) => m.role === types_1.Role.ToolCall);
|
|
42
|
+
if (toolCalls.length === 0)
|
|
43
43
|
return all;
|
|
44
|
-
|
|
45
|
-
if (m.role !== types_1.Role.ToolCall)
|
|
46
|
-
continue;
|
|
44
|
+
const results = await Promise.all(toolCalls.map(async (m) => {
|
|
47
45
|
const tool = this.tools.find((t) => t.name === m.toolName);
|
|
48
46
|
if (!tool)
|
|
49
47
|
throw new Error(`Tool "${m.toolName}" is not registered`);
|
|
48
|
+
if (this.onToolCall)
|
|
49
|
+
await Promise.resolve(this.onToolCall(m));
|
|
50
50
|
let content;
|
|
51
51
|
let isError = false;
|
|
52
52
|
try {
|
|
@@ -59,10 +59,14 @@ class Agent {
|
|
|
59
59
|
content = err instanceof Error ? err.message : String(err);
|
|
60
60
|
}
|
|
61
61
|
const result = { role: types_1.Role.ToolResult, callId: m.callId, content, isError };
|
|
62
|
-
this.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
if (this.onToolResult)
|
|
63
|
+
await Promise.resolve(this.onToolResult(result));
|
|
64
|
+
return result;
|
|
65
|
+
}));
|
|
66
|
+
this.context.push(...results);
|
|
67
|
+
all.push(...results);
|
|
68
|
+
msgs = await this.adapter(this.config, this.context, this.tools);
|
|
69
|
+
this.context.push(...msgs);
|
|
66
70
|
all.push(...msgs);
|
|
67
71
|
}
|
|
68
72
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -32,4 +32,10 @@ export type Tool = {
|
|
|
32
32
|
parameters: unknown;
|
|
33
33
|
execute: (args: unknown) => Promise<unknown> | unknown;
|
|
34
34
|
};
|
|
35
|
+
export type AgentConfig = {
|
|
36
|
+
endCondition?: (context: Message[], last: Message) => boolean;
|
|
37
|
+
onToolCall?: (message: Message) => void | Promise<void>;
|
|
38
|
+
onToolResult?: (message: Message) => void | Promise<void>;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
};
|
|
35
41
|
export type Adapter = (config: Record<string, unknown>, context: Message[], tools: Tool[]) => Promise<Message[]>;
|