@node-llm/core 1.10.0 → 1.12.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 +54 -6
- package/dist/agent/Agent.d.ts +178 -0
- package/dist/agent/Agent.d.ts.map +1 -0
- package/dist/agent/Agent.js +293 -0
- package/dist/aliases.d.ts +130 -0
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +134 -4
- package/dist/chat/Chat.d.ts +1 -0
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +16 -1
- package/dist/chat/Tool.d.ts +43 -2
- package/dist/chat/Tool.d.ts.map +1 -1
- package/dist/chat/Tool.js +50 -0
- package/dist/chat/ToolHandler.d.ts +10 -5
- package/dist/chat/ToolHandler.d.ts.map +1 -1
- package/dist/chat/ToolHandler.js +10 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/models/models.json +2519 -596
- package/dist/types/Middleware.d.ts +13 -5
- package/dist/types/Middleware.d.ts.map +1 -1
- package/dist/utils/middleware-runner.d.ts.map +1 -1
- package/dist/utils/middleware-runner.js +4 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @node-llm/core
|
|
2
2
|
|
|
3
3
|
<p align="left">
|
|
4
|
-
<a href="https://
|
|
5
|
-
<img src="https://
|
|
4
|
+
<a href="https://nodellm.dev/">
|
|
5
|
+
<img src="https://nodellm.dev/assets/images/logo.jpg" alt="NodeLLM logo" width="300" />
|
|
6
6
|
</a>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
@@ -139,6 +139,54 @@ const safetyMiddleware = {
|
|
|
139
139
|
|
|
140
140
|
---
|
|
141
141
|
|
|
142
|
+
## 🤖 Agent Class
|
|
143
|
+
|
|
144
|
+
Define reusable, class-configured agents with a declarative DSL:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { Agent, Tool, z } from "@node-llm/core";
|
|
148
|
+
|
|
149
|
+
class LookupOrderTool extends Tool<{ orderId: string }> {
|
|
150
|
+
name = "lookup_order";
|
|
151
|
+
description = "Look up an order by ID";
|
|
152
|
+
schema = z.object({ orderId: z.string() });
|
|
153
|
+
|
|
154
|
+
async execute({ orderId }: { orderId: string }) {
|
|
155
|
+
return { status: "shipped", eta: "Tomorrow" };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
class SupportAgent extends Agent {
|
|
160
|
+
static model = "gpt-4.1";
|
|
161
|
+
static instructions = "You are a helpful support agent.";
|
|
162
|
+
static tools = [LookupOrderTool];
|
|
163
|
+
static temperature = 0.2;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Use anywhere in your app
|
|
167
|
+
const agent = new SupportAgent();
|
|
168
|
+
const response = await agent.ask("Where is order #123?");
|
|
169
|
+
console.log(response.content);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### ToolHalt - Early Loop Termination
|
|
173
|
+
|
|
174
|
+
Stop the agentic loop early when a definitive answer is found:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
class FinalAnswerTool extends Tool<{ answer: string }> {
|
|
178
|
+
name = "final_answer";
|
|
179
|
+
description = "Return the final answer to the user";
|
|
180
|
+
schema = z.object({ answer: z.string() });
|
|
181
|
+
|
|
182
|
+
async execute({ answer }: { answer: string }) {
|
|
183
|
+
return this.halt(answer); // Stops the loop, returns this result
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
142
190
|
## 💾 Ecosystem
|
|
143
191
|
|
|
144
192
|
Looking for persistence? use **[@node-llm/orm](https://www.npmjs.com/package/@node-llm/orm)**.
|
|
@@ -150,11 +198,11 @@ Looking for persistence? use **[@node-llm/orm](https://www.npmjs.com/package/@no
|
|
|
150
198
|
|
|
151
199
|
## 📚 Full Documentation
|
|
152
200
|
|
|
153
|
-
Visit **[
|
|
201
|
+
Visit **[nodellm.dev](https://nodellm.dev/)** for:
|
|
154
202
|
|
|
155
|
-
- [Deep Dive into Tool Calling](https://
|
|
156
|
-
- [Multi-modal Vision & Audio Guide](https://
|
|
157
|
-
- [Custom Provider Plugin System](https://
|
|
203
|
+
- [Deep Dive into Tool Calling](https://nodellm.dev/core-features/tools)
|
|
204
|
+
- [Multi-modal Vision & Audio Guide](https://nodellm.dev/core-features/multimodal)
|
|
205
|
+
- [Custom Provider Plugin System](https://nodellm.dev/advanced/custom-providers)
|
|
158
206
|
|
|
159
207
|
---
|
|
160
208
|
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Chat, AskOptions } from "../chat/Chat.js";
|
|
3
|
+
import { ChatOptions } from "../chat/ChatOptions.js";
|
|
4
|
+
import { ChatResponseString } from "../chat/ChatResponse.js";
|
|
5
|
+
import { ToolResolvable } from "../chat/Tool.js";
|
|
6
|
+
import { ThinkingConfig, ThinkingResult } from "../providers/Provider.js";
|
|
7
|
+
import { Schema } from "../schema/Schema.js";
|
|
8
|
+
import { NodeLLMCore } from "../llm.js";
|
|
9
|
+
/**
|
|
10
|
+
* A value that can be a static T or a function that returns T based on inputs.
|
|
11
|
+
*/
|
|
12
|
+
export type LazyValue<T, I = any> = T | ((inputs: I) => T);
|
|
13
|
+
/**
|
|
14
|
+
* Configuration options for Agent.
|
|
15
|
+
*/
|
|
16
|
+
export interface AgentConfig<I = any> {
|
|
17
|
+
/** The model ID to use (e.g., "gpt-4o") */
|
|
18
|
+
model?: string;
|
|
19
|
+
/** The provider to use (e.g., "openai") */
|
|
20
|
+
provider?: string;
|
|
21
|
+
/** System instructions for the agent (can be lazy) */
|
|
22
|
+
instructions?: LazyValue<string, I>;
|
|
23
|
+
/** Tools available to the agent (can be lazy) */
|
|
24
|
+
tools?: LazyValue<ToolResolvable[], I>;
|
|
25
|
+
/** Temperature for response generation (0.0 - 1.0) */
|
|
26
|
+
temperature?: number;
|
|
27
|
+
/** Extended thinking configuration */
|
|
28
|
+
thinking?: ThinkingConfig;
|
|
29
|
+
/** Output schema for structured responses */
|
|
30
|
+
schema?: z.ZodType | Schema | Record<string, unknown>;
|
|
31
|
+
/** Provider-specific parameters */
|
|
32
|
+
params?: Record<string, unknown>;
|
|
33
|
+
/** Custom headers for requests */
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
/** Maximum tokens in response */
|
|
36
|
+
maxTokens?: number;
|
|
37
|
+
/** Maximum tool call iterations */
|
|
38
|
+
maxToolCalls?: number;
|
|
39
|
+
/** Assume model exists without validation */
|
|
40
|
+
assumeModelExists?: boolean;
|
|
41
|
+
/** Optional LLM instance to use instead of global NodeLLM */
|
|
42
|
+
llm?: NodeLLMCore;
|
|
43
|
+
/** Optional initial inputs to resolve lazy config immediately */
|
|
44
|
+
inputs?: I;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Base class for creating reusable, class-configured agents.
|
|
48
|
+
*/
|
|
49
|
+
export declare abstract class Agent<I extends Record<string, any> = Record<string, any>, S extends Record<string, unknown> = Record<string, unknown>> {
|
|
50
|
+
static model?: string;
|
|
51
|
+
static provider?: string;
|
|
52
|
+
static instructions?: LazyValue<string, any>;
|
|
53
|
+
static tools?: LazyValue<ToolResolvable[], any>;
|
|
54
|
+
static temperature?: number;
|
|
55
|
+
static thinking?: ThinkingConfig;
|
|
56
|
+
static schema?: z.ZodType | Schema | Record<string, unknown>;
|
|
57
|
+
static params?: Record<string, unknown>;
|
|
58
|
+
static headers?: Record<string, string>;
|
|
59
|
+
static maxTokens?: number;
|
|
60
|
+
static maxToolCalls?: number;
|
|
61
|
+
static assumeModelExists?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Explicitly declare which inputs this agent expects.
|
|
64
|
+
* Useful for introspection and validation.
|
|
65
|
+
*/
|
|
66
|
+
static inputs?: string[];
|
|
67
|
+
/**
|
|
68
|
+
* Hook called when the agent starts a new session (ask/stream).
|
|
69
|
+
*/
|
|
70
|
+
static onStart(_context: {
|
|
71
|
+
messages: unknown[];
|
|
72
|
+
}): void | Promise<void>;
|
|
73
|
+
static onThinking(_thinking: ThinkingResult, _result: ChatResponseString): void | Promise<void>;
|
|
74
|
+
static onToolStart(_toolCall: unknown): void | Promise<void>;
|
|
75
|
+
static onToolEnd(_toolCall: unknown, _result: unknown): void | Promise<void>;
|
|
76
|
+
static onToolError(_toolCall: unknown, _error: Error): void | Promise<void>;
|
|
77
|
+
static onComplete(_result: ChatResponseString): void | Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Run the agent immediately with a prompt.
|
|
80
|
+
*/
|
|
81
|
+
static ask<I extends Record<string, any>, S extends Record<string, any>>(this: new (overrides?: Partial<AgentConfig<I> & ChatOptions>) => Agent<I, S>, message: string, options?: AskOptions & {
|
|
82
|
+
inputs?: I;
|
|
83
|
+
}): Promise<ChatResponseString>;
|
|
84
|
+
/**
|
|
85
|
+
* Stream the agent response immediately.
|
|
86
|
+
*/
|
|
87
|
+
static stream<I extends Record<string, any>, S extends Record<string, any>>(this: new (overrides?: Partial<AgentConfig<I> & ChatOptions>) => Agent<I, S>, message: string, options?: AskOptions & {
|
|
88
|
+
inputs?: I;
|
|
89
|
+
}): import("../index.js").Stream<import("../providers/Provider.js").ChatChunk>;
|
|
90
|
+
/** The underlying Chat instance */
|
|
91
|
+
protected readonly chat: Chat<S>;
|
|
92
|
+
/** Private reference to configuration overrides for lazy resolution */
|
|
93
|
+
private readonly config;
|
|
94
|
+
/**
|
|
95
|
+
* Create a new agent instance.
|
|
96
|
+
* @param overrides - Optional configuration to override static properties
|
|
97
|
+
*/
|
|
98
|
+
constructor(overrides?: Partial<AgentConfig<I> & ChatOptions>);
|
|
99
|
+
/**
|
|
100
|
+
* Helper to resolve lazy instructions and tools based on inputs.
|
|
101
|
+
*/
|
|
102
|
+
private resolveLazyConfig;
|
|
103
|
+
/**
|
|
104
|
+
* Add instructions to the agent (replaces or appends).
|
|
105
|
+
*/
|
|
106
|
+
withInstructions(instructions: string, options?: {
|
|
107
|
+
replace?: boolean;
|
|
108
|
+
}): this;
|
|
109
|
+
/**
|
|
110
|
+
* Add tools to the agent.
|
|
111
|
+
*/
|
|
112
|
+
withTools(tools: ToolResolvable[], options?: {
|
|
113
|
+
replace?: boolean;
|
|
114
|
+
}): this;
|
|
115
|
+
/**
|
|
116
|
+
* Alias for withTools([tool]).
|
|
117
|
+
*/
|
|
118
|
+
use(tool: ToolResolvable): this;
|
|
119
|
+
/**
|
|
120
|
+
* Send a message to the agent and get a response.
|
|
121
|
+
*/
|
|
122
|
+
ask(message: string, options?: AskOptions & {
|
|
123
|
+
inputs?: I;
|
|
124
|
+
}): Promise<ChatResponseString>;
|
|
125
|
+
/**
|
|
126
|
+
* Hook called when a tool call starts.
|
|
127
|
+
*/
|
|
128
|
+
onToolCallStart(handler: (toolCall: any) => void | Promise<void>): this;
|
|
129
|
+
/**
|
|
130
|
+
* Hook called when a tool call ends.
|
|
131
|
+
*/
|
|
132
|
+
onToolCallEnd(handler: (toolCall: any, result: any) => void | Promise<void>): this;
|
|
133
|
+
/**
|
|
134
|
+
* Hook called when a tool call errors.
|
|
135
|
+
*/
|
|
136
|
+
onToolCallError(handler: (toolCall: any, error: Error) => any): this;
|
|
137
|
+
/**
|
|
138
|
+
* Hook called before a request.
|
|
139
|
+
*/
|
|
140
|
+
beforeRequest(handler: (messages: any[]) => any): this;
|
|
141
|
+
/**
|
|
142
|
+
* Hook called after a response.
|
|
143
|
+
*/
|
|
144
|
+
afterResponse(handler: (response: ChatResponseString) => any): this;
|
|
145
|
+
/**
|
|
146
|
+
* Alias for ask()
|
|
147
|
+
*/
|
|
148
|
+
say(message: string, options?: AskOptions & {
|
|
149
|
+
inputs?: I;
|
|
150
|
+
}): Promise<ChatResponseString>;
|
|
151
|
+
/**
|
|
152
|
+
* Stream a response from the agent.
|
|
153
|
+
*/
|
|
154
|
+
stream(message: string, options?: AskOptions & {
|
|
155
|
+
inputs?: I;
|
|
156
|
+
}): import("../index.js").Stream<import("../providers/Provider.js").ChatChunk>;
|
|
157
|
+
/**
|
|
158
|
+
* Get the conversation history.
|
|
159
|
+
*/
|
|
160
|
+
get history(): readonly import("../index.js").Message[];
|
|
161
|
+
/**
|
|
162
|
+
* Get the model ID being used.
|
|
163
|
+
*/
|
|
164
|
+
get modelId(): string;
|
|
165
|
+
/**
|
|
166
|
+
* Get aggregate token usage across the conversation.
|
|
167
|
+
*/
|
|
168
|
+
get totalUsage(): import("../providers/Provider.js").Usage;
|
|
169
|
+
/**
|
|
170
|
+
* Access the underlying Chat instance for advanced operations.
|
|
171
|
+
*/
|
|
172
|
+
get underlyingChat(): Chat<S>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Helper function to define an agent inline without creating a class.
|
|
176
|
+
*/
|
|
177
|
+
export declare function defineAgent<I extends Record<string, any> = Record<string, any>, S extends Record<string, unknown> = Record<string, unknown>>(config: AgentConfig<I>): new (overrides?: Partial<AgentConfig<I> & ChatOptions>) => Agent<I, S>;
|
|
178
|
+
//# sourceMappingURL=Agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Agent.d.ts","sourceRoot":"","sources":["../../src/agent/Agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { NodeLLM } from "../llm.js";
|
|
2
|
+
/**
|
|
3
|
+
* Base class for creating reusable, class-configured agents.
|
|
4
|
+
*/
|
|
5
|
+
export class Agent {
|
|
6
|
+
// Static configuration properties - override these in subclasses
|
|
7
|
+
static model;
|
|
8
|
+
static provider;
|
|
9
|
+
static instructions;
|
|
10
|
+
static tools;
|
|
11
|
+
static temperature;
|
|
12
|
+
static thinking;
|
|
13
|
+
static schema;
|
|
14
|
+
static params;
|
|
15
|
+
static headers;
|
|
16
|
+
static maxTokens;
|
|
17
|
+
static maxToolCalls;
|
|
18
|
+
static assumeModelExists;
|
|
19
|
+
/**
|
|
20
|
+
* Explicitly declare which inputs this agent expects.
|
|
21
|
+
* Useful for introspection and validation.
|
|
22
|
+
*/
|
|
23
|
+
static inputs;
|
|
24
|
+
/**
|
|
25
|
+
* Hook called when the agent starts a new session (ask/stream).
|
|
26
|
+
*/
|
|
27
|
+
static onStart(_context) {
|
|
28
|
+
// Override in subclass
|
|
29
|
+
}
|
|
30
|
+
static onThinking(_thinking, _result) {
|
|
31
|
+
// Override in subclass
|
|
32
|
+
}
|
|
33
|
+
static onToolStart(_toolCall) {
|
|
34
|
+
// Override in subclass
|
|
35
|
+
}
|
|
36
|
+
static onToolEnd(_toolCall, _result) {
|
|
37
|
+
// Override in subclass
|
|
38
|
+
}
|
|
39
|
+
static onToolError(_toolCall, _error) {
|
|
40
|
+
// Override in subclass
|
|
41
|
+
}
|
|
42
|
+
static onComplete(_result) {
|
|
43
|
+
// Override in subclass
|
|
44
|
+
}
|
|
45
|
+
// --- Static Execution API ---
|
|
46
|
+
/**
|
|
47
|
+
* Run the agent immediately with a prompt.
|
|
48
|
+
*/
|
|
49
|
+
static async ask(message, options) {
|
|
50
|
+
const agent = new this({ ...options });
|
|
51
|
+
return agent.ask(message, options);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stream the agent response immediately.
|
|
55
|
+
*/
|
|
56
|
+
static stream(message, options) {
|
|
57
|
+
const agent = new this({ ...options });
|
|
58
|
+
return agent.stream(message, options);
|
|
59
|
+
}
|
|
60
|
+
/** The underlying Chat instance */
|
|
61
|
+
chat;
|
|
62
|
+
/** Private reference to configuration overrides for lazy resolution */
|
|
63
|
+
config;
|
|
64
|
+
/**
|
|
65
|
+
* Create a new agent instance.
|
|
66
|
+
* @param overrides - Optional configuration to override static properties
|
|
67
|
+
*/
|
|
68
|
+
constructor(overrides = {}) {
|
|
69
|
+
this.config = overrides;
|
|
70
|
+
const ctor = this.constructor;
|
|
71
|
+
// Build chat options from static properties + overrides
|
|
72
|
+
const chatOptions = {
|
|
73
|
+
provider: overrides.provider ?? ctor.provider,
|
|
74
|
+
assumeModelExists: overrides.assumeModelExists ?? ctor.assumeModelExists,
|
|
75
|
+
temperature: overrides.temperature ?? ctor.temperature,
|
|
76
|
+
maxTokens: overrides.maxTokens ?? ctor.maxTokens,
|
|
77
|
+
maxToolCalls: overrides.maxToolCalls ?? ctor.maxToolCalls,
|
|
78
|
+
headers: { ...ctor.headers, ...overrides.headers },
|
|
79
|
+
params: { ...ctor.params, ...overrides.params },
|
|
80
|
+
thinking: overrides.thinking ?? ctor.thinking,
|
|
81
|
+
messages: overrides.messages
|
|
82
|
+
};
|
|
83
|
+
// Determine model
|
|
84
|
+
const model = overrides.model ?? ctor.model;
|
|
85
|
+
if (!model) {
|
|
86
|
+
throw new Error(`[Agent] No model specified. Set static model property or pass model in constructor.`);
|
|
87
|
+
}
|
|
88
|
+
const llm = overrides.llm ?? NodeLLM;
|
|
89
|
+
this.chat = llm.chat(model, chatOptions);
|
|
90
|
+
// Initial resolution if inputs are provided in constructor
|
|
91
|
+
if (overrides.inputs) {
|
|
92
|
+
this.resolveLazyConfig(overrides.inputs);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Fallback: apply static/direct instructions immediately if they aren't functions
|
|
96
|
+
const instructions = overrides.instructions ?? ctor.instructions;
|
|
97
|
+
if (instructions && typeof instructions !== "function") {
|
|
98
|
+
this.chat.withInstructions(instructions);
|
|
99
|
+
}
|
|
100
|
+
const tools = overrides.tools ?? ctor.tools;
|
|
101
|
+
if (tools && typeof tools !== "function" && tools.length > 0) {
|
|
102
|
+
this.chat.withTools(tools);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Apply schema
|
|
106
|
+
const schema = overrides.schema ?? ctor.schema;
|
|
107
|
+
if (schema) {
|
|
108
|
+
this.chat.withSchema(schema);
|
|
109
|
+
}
|
|
110
|
+
// Wire up telemetry hooks
|
|
111
|
+
if (ctor.onStart) {
|
|
112
|
+
this.chat.beforeRequest(async (messages) => {
|
|
113
|
+
if (ctor.onStart)
|
|
114
|
+
await ctor.onStart({ messages });
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (ctor.onToolStart) {
|
|
118
|
+
this.chat.onToolCallStart(async (toolCall) => {
|
|
119
|
+
if (ctor.onToolStart)
|
|
120
|
+
await ctor.onToolStart(toolCall);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (ctor.onToolEnd) {
|
|
124
|
+
this.chat.onToolCallEnd(async (toolCall, result) => {
|
|
125
|
+
if (ctor.onToolEnd)
|
|
126
|
+
await ctor.onToolEnd(toolCall, result);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (ctor.onToolError) {
|
|
130
|
+
this.chat.onToolCallError(async (toolCall, error) => {
|
|
131
|
+
if (ctor.onToolError)
|
|
132
|
+
await ctor.onToolError(toolCall, error);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (ctor.onComplete || ctor.onThinking) {
|
|
136
|
+
this.chat.onEndMessage(async (msg) => {
|
|
137
|
+
if (msg.thinking && ctor.onThinking) {
|
|
138
|
+
await ctor.onThinking(msg.thinking, msg);
|
|
139
|
+
}
|
|
140
|
+
if (ctor.onComplete) {
|
|
141
|
+
await ctor.onComplete(msg);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Helper to resolve lazy instructions and tools based on inputs.
|
|
148
|
+
*/
|
|
149
|
+
resolveLazyConfig(inputs) {
|
|
150
|
+
if (!inputs)
|
|
151
|
+
return;
|
|
152
|
+
const ctor = this.constructor;
|
|
153
|
+
// 1. Resolve Instructions
|
|
154
|
+
let instructions = this.config.instructions ?? ctor.instructions;
|
|
155
|
+
if (typeof instructions === "function") {
|
|
156
|
+
instructions = instructions(inputs);
|
|
157
|
+
}
|
|
158
|
+
if (typeof instructions === "string") {
|
|
159
|
+
this.chat.withInstructions(instructions, { replace: true });
|
|
160
|
+
}
|
|
161
|
+
// 2. Resolve Tools
|
|
162
|
+
let tools = this.config.tools ?? ctor.tools;
|
|
163
|
+
if (typeof tools === "function") {
|
|
164
|
+
tools = tools(inputs);
|
|
165
|
+
}
|
|
166
|
+
if (Array.isArray(tools)) {
|
|
167
|
+
this.chat.withTools(tools, { replace: true });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// --- Fluent Configuration ---
|
|
171
|
+
/**
|
|
172
|
+
* Add instructions to the agent (replaces or appends).
|
|
173
|
+
*/
|
|
174
|
+
withInstructions(instructions, options) {
|
|
175
|
+
this.chat.withInstructions(instructions, options);
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Add tools to the agent.
|
|
180
|
+
*/
|
|
181
|
+
withTools(tools, options) {
|
|
182
|
+
this.chat.withTools(tools, options);
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Alias for withTools([tool]).
|
|
187
|
+
*/
|
|
188
|
+
use(tool) {
|
|
189
|
+
return this.withTools([tool]);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Send a message to the agent and get a response.
|
|
193
|
+
*/
|
|
194
|
+
async ask(message, options) {
|
|
195
|
+
if (options?.inputs) {
|
|
196
|
+
this.resolveLazyConfig(options.inputs);
|
|
197
|
+
}
|
|
198
|
+
return this.chat.ask(message, options);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Hook called when a tool call starts.
|
|
202
|
+
*/
|
|
203
|
+
onToolCallStart(handler) {
|
|
204
|
+
this.chat.onToolCallStart(handler);
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Hook called when a tool call ends.
|
|
209
|
+
*/
|
|
210
|
+
onToolCallEnd(handler) {
|
|
211
|
+
this.chat.onToolCallEnd(handler);
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Hook called when a tool call errors.
|
|
216
|
+
*/
|
|
217
|
+
onToolCallError(handler) {
|
|
218
|
+
this.chat.onToolCallError(handler);
|
|
219
|
+
return this;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Hook called before a request.
|
|
223
|
+
*/
|
|
224
|
+
beforeRequest(handler) {
|
|
225
|
+
this.chat.beforeRequest(handler);
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Hook called after a response.
|
|
230
|
+
*/
|
|
231
|
+
afterResponse(handler) {
|
|
232
|
+
this.chat.afterResponse(handler);
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Alias for ask()
|
|
237
|
+
*/
|
|
238
|
+
async say(message, options) {
|
|
239
|
+
return this.ask(message, options);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Stream a response from the agent.
|
|
243
|
+
*/
|
|
244
|
+
stream(message, options) {
|
|
245
|
+
if (options?.inputs) {
|
|
246
|
+
this.resolveLazyConfig(options.inputs);
|
|
247
|
+
}
|
|
248
|
+
return this.chat.stream(message, options);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get the conversation history.
|
|
252
|
+
*/
|
|
253
|
+
get history() {
|
|
254
|
+
return this.chat.history;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get the model ID being used.
|
|
258
|
+
*/
|
|
259
|
+
get modelId() {
|
|
260
|
+
return this.chat.modelId;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get aggregate token usage across the conversation.
|
|
264
|
+
*/
|
|
265
|
+
get totalUsage() {
|
|
266
|
+
return this.chat.totalUsage;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Access the underlying Chat instance for advanced operations.
|
|
270
|
+
*/
|
|
271
|
+
get underlyingChat() {
|
|
272
|
+
return this.chat;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Helper function to define an agent inline without creating a class.
|
|
277
|
+
*/
|
|
278
|
+
export function defineAgent(config) {
|
|
279
|
+
return class extends Agent {
|
|
280
|
+
static model = config.model;
|
|
281
|
+
static provider = config.provider;
|
|
282
|
+
static instructions = config.instructions;
|
|
283
|
+
static tools = config.tools;
|
|
284
|
+
static temperature = config.temperature;
|
|
285
|
+
static thinking = config.thinking;
|
|
286
|
+
static schema = config.schema;
|
|
287
|
+
static params = config.params;
|
|
288
|
+
static headers = config.headers;
|
|
289
|
+
static maxTokens = config.maxTokens;
|
|
290
|
+
static maxToolCalls = config.maxToolCalls;
|
|
291
|
+
static assumeModelExists = config.assumeModelExists;
|
|
292
|
+
};
|
|
293
|
+
}
|