@antseed/ant-agent 0.1.14

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 ADDED
@@ -0,0 +1,212 @@
1
+ # @antseed/ant-agent
2
+
3
+ Ant agent runtime for AntSeed. Lets seed runners monetize their knowledge by wrapping any provider with a persona, guardrails, on-demand knowledge modules, and custom tools.
4
+
5
+ An ant agent is a **read-only, knowledge-augmented AI service**. It doesn't act on the user's behalf — it answers questions using curated expertise that the creator packages and maintains.
6
+
7
+ ## How it works
8
+
9
+ 1. Creator defines an agent: persona + guardrails + knowledge modules (markdown files)
10
+ 2. On each buyer request, persona, guardrails, and an `antseed_load_knowledge` tool are injected
11
+ 3. The LLM decides when to load knowledge — it calls the tool with a module name and receives the content
12
+ 4. The agent loop executes internal tool calls and re-prompts until the LLM produces a final text response
13
+ 5. The buyer gets a clean streamed response — no internal tools or loop artifacts
14
+
15
+ When no knowledge modules are defined, no tools are injected and it's a single-call injection (persona + guardrails only).
16
+
17
+ ## Agent directory structure
18
+
19
+ ```
20
+ my-agent/
21
+ agent.json # manifest
22
+ persona.md # who the agent is
23
+ knowledge/ # knowledge modules
24
+ linkedin-posting.md
25
+ content-strategy.md
26
+ tools/ # custom tool scripts (optional)
27
+ fetch-trends.js
28
+ ```
29
+
30
+ ### agent.json
31
+
32
+ ```json
33
+ {
34
+ "name": "social-media-advisor",
35
+ "persona": "./persona.md",
36
+ "guardrails": [
37
+ "Never write posts without explicit request",
38
+ "Always disclose AI-generated content when asked"
39
+ ],
40
+ "knowledge": [
41
+ {
42
+ "name": "linkedin-posting",
43
+ "description": "Creating and optimizing LinkedIn posts",
44
+ "file": "./knowledge/linkedin-posting.md"
45
+ },
46
+ {
47
+ "name": "content-strategy",
48
+ "description": "Content calendars and strategy frameworks",
49
+ "file": "./knowledge/content-strategy.md"
50
+ }
51
+ ],
52
+ "tools": [
53
+ {
54
+ "name": "fetch_trends",
55
+ "description": "Fetch trending topics for a platform",
56
+ "parameters": {
57
+ "type": "object",
58
+ "properties": { "platform": { "type": "string" } },
59
+ "required": ["platform"]
60
+ },
61
+ "execute": "./tools/fetch-trends.js"
62
+ }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ | Field | Required | Description |
68
+ |---|---|---|
69
+ | `name` | Yes | Agent name |
70
+ | `persona` | No | Path to markdown file with the agent's system prompt / personality |
71
+ | `guardrails` | No | Array of hard rules the agent must follow |
72
+ | `knowledge` | No | Array of knowledge modules for on-demand loading |
73
+ | `knowledge[].name` | Yes | Unique identifier for the module |
74
+ | `knowledge[].description` | Yes | Short description — shown to the LLM to decide relevance |
75
+ | `knowledge[].file` | Yes | Path to the markdown file with the full content |
76
+ | `tools` | No | Array of custom tools the LLM can call |
77
+ | `tools[].name` | Yes | Tool name (auto-prefixed with `antseed_`) |
78
+ | `tools[].description` | Yes | Description shown to the LLM |
79
+ | `tools[].parameters` | No | JSON Schema for tool parameters (defaults to empty object) |
80
+ | `tools[].execute` | Yes | Path to a JS file that exports a default function |
81
+ | `confidentialityPrompt` | No | Custom confidentiality instruction (has a sensible default) |
82
+
83
+ ## Usage
84
+
85
+ ### Programmatic
86
+
87
+ ```typescript
88
+ import { loadAntAgent, AntAgentProvider } from '@antseed/ant-agent';
89
+
90
+ // Load agent (knowledge + tools from agent.json)
91
+ const agent = await loadAntAgent('./my-agent');
92
+ const boundProvider = new AntAgentProvider(innerProvider, agent);
93
+
94
+ // Per-service agents
95
+ const socialAgent = await loadAntAgent('./social-agent');
96
+ const codingAgent = await loadAntAgent('./coding-agent');
97
+ const boundProvider = new AntAgentProvider(innerProvider, {
98
+ 'social-model-v1': socialAgent,
99
+ 'coding-model-v1': codingAgent,
100
+ '*': socialAgent,
101
+ });
102
+
103
+ node.registerProvider(boundProvider);
104
+ ```
105
+
106
+ ### CLI
107
+
108
+ Add `agentDir` to your antseed config. Use a string for a single agent (all services), or a map for per-service agents:
109
+
110
+ ```json
111
+ {
112
+ "seller": {
113
+ "agentDir": "./my-agent"
114
+ }
115
+ }
116
+ ```
117
+
118
+ Per-service:
119
+
120
+ ```json
121
+ {
122
+ "seller": {
123
+ "agentDir": {
124
+ "social-model-v1": "./agents/social",
125
+ "coding-model-v1": "./agents/coding",
126
+ "*": "./agents/default"
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ The `"*"` key is a fallback for services with no explicit agent. Services with no matching agent pass through unchanged.
133
+
134
+ Then run `antseed seed` as usual.
135
+
136
+ ## Knowledge loading
137
+
138
+ When knowledge modules are defined, the `antseed_load_knowledge` tool is injected into the request alongside any buyer tools. The tool description includes a catalog of available module names and descriptions.
139
+
140
+ The LLM decides which modules to load based on the conversation. It can:
141
+
142
+ - Load one module, get the content, then respond
143
+ - Load multiple modules across successive tool calls
144
+ - Respond directly without loading any modules if the question doesn't require specialized knowledge
145
+
146
+ This keeps the context focused — only the knowledge the LLM judges relevant gets loaded. A buyer asking about LinkedIn won't get X/Twitter knowledge bloating the context.
147
+
148
+ ## Custom tools
149
+
150
+ Beyond knowledge loading, creators can add custom tools that the LLM can call during the agent loop. Define tools in `agent.json` with an `execute` field pointing to a JS file:
151
+
152
+ ```json
153
+ {
154
+ "tools": [{
155
+ "name": "fetch_trends",
156
+ "description": "Fetch trending topics for a platform",
157
+ "parameters": {
158
+ "type": "object",
159
+ "properties": { "platform": { "type": "string" } },
160
+ "required": ["platform"]
161
+ },
162
+ "execute": "./tools/fetch-trends.js"
163
+ }]
164
+ }
165
+ ```
166
+
167
+ The JS file exports a default function that receives the tool arguments and returns a string:
168
+
169
+ ```js
170
+ // tools/fetch-trends.js
171
+ export default async function(args) {
172
+ const res = await fetch(`https://api.example.com/trends/${args.platform}`);
173
+ return await res.text();
174
+ }
175
+ ```
176
+
177
+ Tool names are automatically prefixed with `antseed_` when injected (e.g., `fetch_trends` becomes `antseed_fetch_trends`). The LLM sees all internal tools alongside buyer tools, with system prompt instructions to use `antseed_*` tools for context gathering and buyer tools only as requested.
178
+
179
+ If a tool's execute function throws, the error message is returned to the LLM as an error result so it can recover gracefully.
180
+
181
+ ### Programmatic tools
182
+
183
+ Tools can also be added programmatically via the options parameter (useful when tools need access to runtime state):
184
+
185
+ ```typescript
186
+ import { AntAgentProvider, loadAntAgent, type AntAgentTool } from '@antseed/ant-agent';
187
+
188
+ const customTool: AntAgentTool = {
189
+ name: 'lookup_user',
190
+ description: 'Look up user details',
191
+ parameters: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
192
+ execute: async (args) => db.users.findById(args.id),
193
+ };
194
+
195
+ const agent = await loadAntAgent('./my-agent');
196
+ new AntAgentProvider(innerProvider, agent, { tools: [customTool] });
197
+ ```
198
+
199
+ Manifest tools and programmatic tools are merged together.
200
+
201
+ ## What gets injected
202
+
203
+ The system prompt is assembled in this order:
204
+
205
+ 1. **Persona** — the agent's identity and expertise
206
+ 2. **Tool-set instructions** — tells the LLM how to use `antseed_` tools vs buyer tools (only when knowledge modules exist)
207
+ 3. **Guardrails** — hard rules
208
+ 4. **Confidentiality prompt** — prevents the LLM from revealing injected content
209
+
210
+ Additionally, `antseed_*` tools are added to the request's tool list alongside any buyer-provided tools. This includes the built-in `antseed_load_knowledge` (when knowledge modules are defined) and any custom tools passed via options.
211
+
212
+ The buyer's own system prompt (if any) is preserved after the agent's content.
@@ -0,0 +1,27 @@
1
+ import type { Provider, SerializedHttpRequest, SerializedHttpResponse, ProviderStreamCallbacks } from '@antseed/node';
2
+ import type { AntAgentDefinition } from './loader.js';
3
+ import type { AntAgentTool } from './tools.js';
4
+ export interface AgentLoopOptions {
5
+ /** Maximum tool-call rounds before forcing a final request. Total LLM calls = maxIterations + 1. Default: 5. */
6
+ maxIterations?: number;
7
+ /** Additional tools available to the agent loop. Auto-prefixed with `antseed_`. */
8
+ tools?: AntAgentTool[];
9
+ }
10
+ /** Agent definition paired with its pre-built tool list. Created once at construction. */
11
+ export interface ResolvedAgent {
12
+ definition: AntAgentDefinition;
13
+ tools: AntAgentTool[];
14
+ }
15
+ export type AgentResolver = (body: Record<string, unknown>) => ResolvedAgent | undefined;
16
+ /**
17
+ * Non-streaming agent loop. Runs tool iterations buffered, returns final response.
18
+ */
19
+ export declare function runAgentLoop(inner: Provider, req: SerializedHttpRequest, resolve: AgentResolver, options?: AgentLoopOptions): Promise<SerializedHttpResponse>;
20
+ /**
21
+ * Streaming agent loop. Every LLM call streams to the buyer in real time.
22
+ * Tool calls are intercepted at the end of each stream, executed, and the
23
+ * next iteration streams again — so the buyer sees tokens arriving live
24
+ * throughout the entire conversation.
25
+ */
26
+ export declare function runAgentLoopStream(inner: Provider, req: SerializedHttpRequest, resolve: AgentResolver, callbacks: ProviderStreamCallbacks, options?: AgentLoopOptions): Promise<SerializedHttpResponse>;
27
+ //# sourceMappingURL=agent-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoB/C,MAAM,WAAW,gBAAgB;IAC/B,gHAAgH;IAChH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,aAAa,GAAG,SAAS,CAAC;AAwFzF;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,qBAAqB,EAC1B,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAuDjC;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,qBAAqB,EAC1B,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,uBAAuB,EAClC,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAoIjC"}
@@ -0,0 +1,278 @@
1
+ import { detectRequestFormat, isToolChoiceForced, injectTools, inspectResponse, executeTools, appendToolLoop, stripInternalToolCalls, } from './tools.js';
2
+ import { buildSystemPrompt, injectSystemPrompt } from './system-prompt.js';
3
+ import { parseSSEResponse } from './sse-parser.js';
4
+ import { TOOL_PREFIX } from './tools.js';
5
+ const encoder = new TextEncoder();
6
+ const decoder = new TextDecoder();
7
+ const DEFAULT_MAX_ITERATIONS = 5;
8
+ function normalizeDebugValue(value) {
9
+ return (value ?? '').trim().toLowerCase();
10
+ }
11
+ function isDebugEnabled() {
12
+ const fromAntseed = normalizeDebugValue(process.env['ANTSEED_DEBUG']);
13
+ if (['1', 'true', 'yes', 'on'].includes(fromAntseed))
14
+ return true;
15
+ return normalizeDebugValue(process.env['DEBUG'])
16
+ .split(',')
17
+ .some((ns) => {
18
+ const trimmed = ns.trim();
19
+ return trimmed === '*' || trimmed === 'antseed' || trimmed === 'antseed:*';
20
+ });
21
+ }
22
+ const DEBUG_ENABLED = isDebugEnabled();
23
+ function debugLog(...args) {
24
+ if (DEBUG_ENABLED)
25
+ console.log(...args);
26
+ }
27
+ /** Check if an SSE chunk contains an Anthropic message_start event. */
28
+ function chunkHasMessageStart(data) {
29
+ const text = decoder.decode(data);
30
+ return text.includes('event: message_start') || text.includes('"type":"message_start"') || text.includes('"type": "message_start"');
31
+ }
32
+ /** Check if an SSE chunk contains a Responses API response.created event. */
33
+ function chunkHasResponseCreated(data) {
34
+ const text = decoder.decode(data);
35
+ return text.includes('event: response.created');
36
+ }
37
+ /**
38
+ * Check if an SSE chunk contains an internal (antseed_*) tool call.
39
+ * Used during streaming to decide whether to forward chunks to the buyer.
40
+ */
41
+ function chunkHasInternalToolCall(data, format) {
42
+ const text = decoder.decode(data);
43
+ if (format === 'openai') {
44
+ // OpenAI: look for "name":"antseed_" in tool_calls deltas
45
+ for (const line of text.split('\n')) {
46
+ if (!line.startsWith('data: ') || line === 'data: [DONE]')
47
+ continue;
48
+ try {
49
+ const chunk = JSON.parse(line.slice(6).trimEnd());
50
+ const choices = chunk.choices;
51
+ const toolCalls = choices?.[0]?.delta?.tool_calls;
52
+ if (toolCalls?.some(tc => tc.function?.name?.startsWith(TOOL_PREFIX)))
53
+ return true;
54
+ }
55
+ catch { /* ignore */ }
56
+ }
57
+ }
58
+ else {
59
+ // Anthropic & Responses API: look for antseed_ name in content blocks or output items
60
+ if (text.includes(`"name":"${TOOL_PREFIX}`) || text.includes(`"name": "${TOOL_PREFIX}`))
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+ /** Prepare the request body: parse, resolve agent, inject system prompt + tools. */
66
+ function prepareBody(req, resolve) {
67
+ let body;
68
+ try {
69
+ body = JSON.parse(decoder.decode(req.body));
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ const agent = resolve(body);
75
+ if (!agent)
76
+ return null;
77
+ const { definition, tools } = agent;
78
+ const willInjectTools = tools.length > 0 && !isToolChoiceForced(body);
79
+ const reqTag = `[AntAgent] ${req.method} ${req.path} (reqId=${req.requestId.slice(0, 8)})`;
80
+ debugLog(`${reqTag}: resolved agent "${definition.name}" with ${tools.length} tool(s): ${tools.map(t => t.name).join(', ') || 'none'}${willInjectTools ? '' : ' (tools skipped)'}`);
81
+ const systemPrompt = buildSystemPrompt(definition, willInjectTools);
82
+ body = injectSystemPrompt(body, systemPrompt, detectRequestFormat(req.path));
83
+ body = injectTools(body, tools, detectRequestFormat(req.path));
84
+ return { body, agent, reqTag };
85
+ }
86
+ /**
87
+ * Non-streaming agent loop. Runs tool iterations buffered, returns final response.
88
+ */
89
+ export async function runAgentLoop(inner, req, resolve, options) {
90
+ const prepared = prepareBody(req, resolve);
91
+ if (!prepared)
92
+ return inner.handleRequest(req);
93
+ const { agent, reqTag } = prepared;
94
+ let { body } = prepared;
95
+ const format = detectRequestFormat(req.path);
96
+ const maxIterations = options?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
97
+ // Force non-streaming for the buffered loop
98
+ delete body.stream;
99
+ for (let i = 0; i < maxIterations; i++) {
100
+ debugLog(`${reqTag}: loop iteration ${i + 1}/${maxIterations}`);
101
+ const augReq = {
102
+ ...req,
103
+ body: encoder.encode(JSON.stringify(body)),
104
+ };
105
+ const response = await inner.handleRequest(augReq);
106
+ let responseBody;
107
+ try {
108
+ responseBody = JSON.parse(decoder.decode(response.body));
109
+ }
110
+ catch {
111
+ return response;
112
+ }
113
+ const action = inspectResponse(responseBody, format);
114
+ if (action.type === 'done') {
115
+ const cleaned = stripInternalToolCalls(responseBody, format);
116
+ return { ...response, body: encoder.encode(JSON.stringify(cleaned)) };
117
+ }
118
+ debugLog(`${reqTag}: executing ${action.internalCalls.length} tool(s): ${action.internalCalls.map(c => c.name).join(', ')}`);
119
+ const results = await executeTools(action.internalCalls, agent.tools);
120
+ debugLog(`${reqTag}: tool results: ${results.map(r => `${r.id}:${r.isError ? 'error' : 'ok'}`).join(', ')}`);
121
+ body = appendToolLoop(body, responseBody, results, format);
122
+ }
123
+ // Max iterations — one final call
124
+ debugLog(`${reqTag}: max iterations (${maxIterations}) reached`);
125
+ const finalReq = {
126
+ ...req,
127
+ body: encoder.encode(JSON.stringify(body)),
128
+ };
129
+ const response = await inner.handleRequest(finalReq);
130
+ try {
131
+ const responseBody = JSON.parse(decoder.decode(response.body));
132
+ const cleaned = stripInternalToolCalls(responseBody, format);
133
+ return { ...response, body: encoder.encode(JSON.stringify(cleaned)) };
134
+ }
135
+ catch {
136
+ return response;
137
+ }
138
+ }
139
+ /**
140
+ * Streaming agent loop. Every LLM call streams to the buyer in real time.
141
+ * Tool calls are intercepted at the end of each stream, executed, and the
142
+ * next iteration streams again — so the buyer sees tokens arriving live
143
+ * throughout the entire conversation.
144
+ */
145
+ export async function runAgentLoopStream(inner, req, resolve, callbacks, options) {
146
+ const prepared = prepareBody(req, resolve);
147
+ if (!prepared)
148
+ return inner.handleRequestStream(req, callbacks);
149
+ const { agent, reqTag } = prepared;
150
+ let { body } = prepared;
151
+ const format = detectRequestFormat(req.path);
152
+ const maxIterations = options?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
153
+ let headersSent = false;
154
+ let messageStartSent = false;
155
+ for (let i = 0; i < maxIterations; i++) {
156
+ debugLog(`${reqTag}: stream iteration ${i + 1}/${maxIterations}`);
157
+ const isLastAllowedIteration = i === maxIterations - 1;
158
+ const augReq = {
159
+ ...req,
160
+ body: encoder.encode(JSON.stringify({ ...body, stream: true })),
161
+ };
162
+ // Stream the call, forwarding chunks to the buyer.
163
+ // For Anthropic format: suppress message_start on non-first iterations and
164
+ // message_stop on non-final iterations to maintain one continuous SSE envelope.
165
+ // For both formats: suppress antseed_* tool call chunks.
166
+ let streamResponse;
167
+ let suppressingChunks = false;
168
+ try {
169
+ streamResponse = await inner.handleRequestStream(augReq, {
170
+ onResponseStart: (res) => {
171
+ if (!headersSent) {
172
+ callbacks.onResponseStart(res);
173
+ headersSent = true;
174
+ }
175
+ },
176
+ onResponseChunk: (chunk) => {
177
+ if (suppressingChunks)
178
+ return;
179
+ if (!chunk.done && chunk.data.length > 0) {
180
+ // Check if this chunk reveals an internal tool call
181
+ if (chunkHasInternalToolCall(chunk.data, format)) {
182
+ suppressingChunks = true;
183
+ return;
184
+ }
185
+ if (format === 'anthropic' && chunkHasMessageStart(chunk.data)) {
186
+ // Suppress message_start if we already sent one (one continuous envelope)
187
+ if (messageStartSent)
188
+ return;
189
+ messageStartSent = true;
190
+ }
191
+ if (format === 'openai-responses' && chunkHasResponseCreated(chunk.data)) {
192
+ if (messageStartSent)
193
+ return;
194
+ messageStartSent = true;
195
+ }
196
+ }
197
+ callbacks.onResponseChunk(chunk);
198
+ },
199
+ });
200
+ }
201
+ catch (err) {
202
+ // If streaming fails, try non-streaming fallback with tool call stripping
203
+ debugLog(`${reqTag}: stream failed, falling back to non-streaming`);
204
+ const augReqNonStream = {
205
+ ...req,
206
+ body: encoder.encode(JSON.stringify({ ...body, stream: false })),
207
+ };
208
+ const response = await inner.handleRequest(augReqNonStream);
209
+ let responseBody = response.body;
210
+ try {
211
+ const parsed = JSON.parse(decoder.decode(response.body));
212
+ const cleaned = stripInternalToolCalls(parsed, format);
213
+ responseBody = encoder.encode(JSON.stringify(cleaned));
214
+ }
215
+ catch { /* non-JSON — use as-is */ }
216
+ const cleanedResponse = { ...response, body: responseBody };
217
+ if (!headersSent) {
218
+ callbacks.onResponseStart(cleanedResponse);
219
+ headersSent = true;
220
+ }
221
+ callbacks.onResponseChunk({ requestId: req.requestId, data: responseBody, done: true });
222
+ return cleanedResponse;
223
+ }
224
+ // Parse the buffered SSE response to check for tool calls
225
+ let responseBody;
226
+ try {
227
+ responseBody = parseSSEResponse(streamResponse.body, format);
228
+ }
229
+ catch {
230
+ // Can't parse — treat as done
231
+ return streamResponse;
232
+ }
233
+ const action = inspectResponse(responseBody, format);
234
+ if (action.type === 'done') {
235
+ if (suppressingChunks) {
236
+ // We suppressed chunks (detected internal tool call) but inspectResponse
237
+ // resolved as done (e.g. mixed buyer+internal calls). Close the buyer's stream.
238
+ callbacks.onResponseChunk({ requestId: req.requestId, data: new Uint8Array(0), done: true });
239
+ }
240
+ debugLog(`${reqTag}: stream iteration ${i + 1} done (no internal tool calls)`);
241
+ return streamResponse;
242
+ }
243
+ // Internal tool calls found — execute them
244
+ debugLog(`${reqTag}: stream iteration ${i + 1} — executing ${action.internalCalls.length} tool(s): ${action.internalCalls.map(c => c.name).join(', ')}`);
245
+ const results = await executeTools(action.internalCalls, agent.tools);
246
+ debugLog(`${reqTag}: stream iteration ${i + 1} — tool results: ${results.map(r => `${r.id}:${r.isError ? 'error' : 'ok'}`).join(', ')}`);
247
+ body = appendToolLoop(body, responseBody, results, format);
248
+ // If this was the last allowed iteration, break to make a final streaming call
249
+ if (isLastAllowedIteration) {
250
+ debugLog(`${reqTag}: max iterations (${maxIterations}) reached, making final streaming call`);
251
+ break;
252
+ }
253
+ }
254
+ // Final streaming call after max iterations (or maxIterations=0)
255
+ const finalReq = {
256
+ ...req,
257
+ body: encoder.encode(JSON.stringify({ ...body, stream: true })),
258
+ };
259
+ return inner.handleRequestStream(finalReq, {
260
+ onResponseStart: (res) => {
261
+ if (!headersSent) {
262
+ callbacks.onResponseStart(res);
263
+ }
264
+ },
265
+ onResponseChunk: (chunk) => {
266
+ if (!chunk.done && chunk.data.length > 0) {
267
+ // Anthropic: suppress message_start if we already sent one (continuing the envelope)
268
+ if (format === 'anthropic' && messageStartSent && chunkHasMessageStart(chunk.data))
269
+ return;
270
+ // Responses API: suppress response.created if we already sent one
271
+ if (format === 'openai-responses' && messageStartSent && chunkHasResponseCreated(chunk.data))
272
+ return;
273
+ }
274
+ callbacks.onResponseChunk(chunk);
275
+ },
276
+ });
277
+ }
278
+ //# sourceMappingURL=agent-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { AntAgentProvider } from './provider.js';
2
+ export { loadAntAgent, type AntAgentDefinition, type KnowledgeModule } from './loader.js';
3
+ export { type AgentLoopOptions } from './agent-loop.js';
4
+ export { type AntAgentTool, knowledgeTool } from './tools.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,KAAK,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { AntAgentProvider } from './provider.js';
2
+ export { loadAntAgent } from './loader.js';
3
+ export { knowledgeTool } from './tools.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAiD,MAAM,aAAa,CAAC;AAE1F,OAAO,EAAqB,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { AntAgentTool } from './tools.js';
2
+ export interface KnowledgeModule {
3
+ /** Unique name for this knowledge module. */
4
+ name: string;
5
+ /** Short description shown to the LLM during knowledge selection. */
6
+ description: string;
7
+ /** Full markdown content loaded from file. */
8
+ content: string;
9
+ }
10
+ export interface AntAgentDefinition {
11
+ /** Agent name. */
12
+ name: string;
13
+ /** Persona / system prompt content (loaded from markdown file). */
14
+ persona: string;
15
+ /** Hard rules the agent must follow. */
16
+ guardrails: string[];
17
+ /** Knowledge modules available for selective loading. */
18
+ knowledge: KnowledgeModule[];
19
+ /** Tools loaded from the manifest (execute files dynamically imported). */
20
+ tools?: AntAgentTool[];
21
+ /** Custom confidentiality prompt. Uses a built-in default when omitted. */
22
+ confidentialityPrompt?: string;
23
+ }
24
+ /**
25
+ * Load an ant agent definition from a directory containing `agent.json`.
26
+ *
27
+ * The directory structure:
28
+ * ```
29
+ * my-agent/
30
+ * agent.json # manifest
31
+ * persona.md # persona / system prompt
32
+ * knowledge/ # knowledge modules (markdown files)
33
+ * topic-a.md
34
+ * topic-b.md
35
+ * ```
36
+ */
37
+ export declare function loadAntAgent(agentDir: string): Promise<AntAgentDefinition>;
38
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yDAAyD;IACzD,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,2EAA2E;IAC3E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AA8BD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgEhF"}