@~lyre/ai-agents 0.5.1 → 0.5.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.
- package/dist/index.d.ts +35 -1
- package/dist/index.js +187 -11
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,33 @@ type Message = {
|
|
|
51
51
|
type ClientDefaults = {
|
|
52
52
|
apiKey?: string;
|
|
53
53
|
model?: ModelLike;
|
|
54
|
+
/**
|
|
55
|
+
* Remote agent source (e.g. Axis Intelligence). When set, a run for an agent NOT registered locally
|
|
56
|
+
* fetches its definition from `${remoteBaseUrl}/agents/{slug}/definition`, runs it locally against the
|
|
57
|
+
* provider, and reports the result to `${remoteBaseUrl}/runs`. Tools the definition names that aren't
|
|
58
|
+
* registered locally become proxy tools that POST to `${remoteBaseUrl}/tools/{slug}/call`.
|
|
59
|
+
*/
|
|
60
|
+
remoteBaseUrl?: string;
|
|
61
|
+
/** Bearer token (service key) sent to the remote source for fetch/proxy/report calls. */
|
|
62
|
+
remoteToken?: string;
|
|
63
|
+
};
|
|
64
|
+
/** A tool spec carried by a remote agent definition (name-only for built-ins; schema for apiTools). */
|
|
65
|
+
type RemoteToolSpec = {
|
|
66
|
+
name: string;
|
|
67
|
+
description?: string | null;
|
|
68
|
+
inputSchema?: any;
|
|
69
|
+
/** The slug the consumer POSTs to `${remoteBaseUrl}/tools/{proxySlug}/call`. Null for built-ins. */
|
|
70
|
+
proxySlug?: string | null;
|
|
71
|
+
};
|
|
72
|
+
/** A registered remote proxy tool — materialized (with the run's context) into an AI-SDK tool at run time
|
|
73
|
+
* in buildTools, so the tool call sent to the source carries the run's scope (appId/tenantId/etc.). */
|
|
74
|
+
type ProxyToolSpec = {
|
|
75
|
+
name: string;
|
|
76
|
+
description: string;
|
|
77
|
+
inputSchema: any;
|
|
78
|
+
proxySlug: string;
|
|
79
|
+
base: string;
|
|
80
|
+
headers: Record<string, string>;
|
|
54
81
|
};
|
|
55
82
|
type AgentDefinition = {
|
|
56
83
|
/** Stable identifier; used as the lookup key. Defaults to `name`. */
|
|
@@ -212,8 +239,15 @@ type RunObjectResult<T = unknown> = {
|
|
|
212
239
|
*/
|
|
213
240
|
declare class Registry {
|
|
214
241
|
readonly tools: Map<string, ToolDefinition>;
|
|
242
|
+
readonly proxyTools: Map<string, ProxyToolSpec>;
|
|
215
243
|
readonly agents: Map<string, Agent>;
|
|
216
244
|
registerTool<I, O>(tool: ToolDefinition<I, O>): ToolDefinition<I, O>;
|
|
245
|
+
/** Register a remote proxy tool spec by name (materialized with run context in buildTools). */
|
|
246
|
+
registerProxyTool(spec: ProxyToolSpec): void;
|
|
247
|
+
/** True if a tool with this name is registered (either shape). */
|
|
248
|
+
hasTool(name: string): boolean;
|
|
249
|
+
/** True if an agent with this id/name is registered. */
|
|
250
|
+
hasAgent(idOrName: string): boolean;
|
|
217
251
|
createAgent(definition: AgentDefinition): Agent;
|
|
218
252
|
resolveAgent(input: string | AgentDefinition): Agent;
|
|
219
253
|
resolveTools(agent: Agent): ToolDefinition[];
|
|
@@ -269,4 +303,4 @@ declare const SUPPORTED_PROVIDERS: string[];
|
|
|
269
303
|
*/
|
|
270
304
|
declare function resolveModelString(model: string, apiKey?: string): LanguageModel | string;
|
|
271
305
|
|
|
272
|
-
export { type Agent, type AgentDefinition, AiAgentsClient, type ClientDefaults, type Message, type ModelId, type ModelLike, Registry, type RunObjectParams, type RunObjectResult, type RunParams, type RunResult, SUPPORTED_PROVIDERS, type StreamEvent, type ToolContext, type ToolDefinition, createClient, resolveModelString, run, runObject, runStream };
|
|
306
|
+
export { type Agent, type AgentDefinition, AiAgentsClient, type ClientDefaults, type Message, type ModelId, type ModelLike, type ProxyToolSpec, Registry, type RemoteToolSpec, type RunObjectParams, type RunObjectResult, type RunParams, type RunResult, SUPPORTED_PROVIDERS, type StreamEvent, type ToolContext, type ToolDefinition, createClient, resolveModelString, run, runObject, runStream };
|
package/dist/index.js
CHANGED
|
@@ -5,11 +5,26 @@ import {
|
|
|
5
5
|
// src/agents.ts
|
|
6
6
|
var Registry = class {
|
|
7
7
|
tools = /* @__PURE__ */ new Map();
|
|
8
|
+
// Remote proxy tool specs — materialized into AI-SDK tools at run time in buildTools, so each call can
|
|
9
|
+
// fold the run's CONTEXT (scope: appId/tenantId/targetApps/…) into the request sent to the source.
|
|
10
|
+
proxyTools = /* @__PURE__ */ new Map();
|
|
8
11
|
agents = /* @__PURE__ */ new Map();
|
|
9
12
|
registerTool(tool2) {
|
|
10
13
|
this.tools.set(tool2.name, tool2);
|
|
11
14
|
return tool2;
|
|
12
15
|
}
|
|
16
|
+
/** Register a remote proxy tool spec by name (materialized with run context in buildTools). */
|
|
17
|
+
registerProxyTool(spec) {
|
|
18
|
+
this.proxyTools.set(spec.name, spec);
|
|
19
|
+
}
|
|
20
|
+
/** True if a tool with this name is registered (either shape). */
|
|
21
|
+
hasTool(name) {
|
|
22
|
+
return this.tools.has(name) || this.proxyTools.has(name);
|
|
23
|
+
}
|
|
24
|
+
/** True if an agent with this id/name is registered. */
|
|
25
|
+
hasAgent(idOrName) {
|
|
26
|
+
return this.agents.has(idOrName);
|
|
27
|
+
}
|
|
13
28
|
createAgent(definition) {
|
|
14
29
|
const agent = {
|
|
15
30
|
id: definition.id ?? definition.name,
|
|
@@ -80,7 +95,103 @@ function resolveModelString(model, apiKey) {
|
|
|
80
95
|
return model;
|
|
81
96
|
}
|
|
82
97
|
|
|
98
|
+
// src/remote.ts
|
|
99
|
+
import { tool as aiTool, jsonSchema } from "ai";
|
|
100
|
+
function authHeaders(defaults) {
|
|
101
|
+
const h = { "Content-Type": "application/json" };
|
|
102
|
+
if (defaults.remoteToken) h.Authorization = `Bearer ${defaults.remoteToken}`;
|
|
103
|
+
return h;
|
|
104
|
+
}
|
|
105
|
+
async function ensureRemoteAgent(registry, agentSlug, defaults) {
|
|
106
|
+
if (!defaults.remoteBaseUrl) return null;
|
|
107
|
+
if (registry.hasAgent(agentSlug)) return agentSlug;
|
|
108
|
+
const base = defaults.remoteBaseUrl.replace(/\/+$/, "");
|
|
109
|
+
let def;
|
|
110
|
+
try {
|
|
111
|
+
const res = await fetch(`${base}/agents/${encodeURIComponent(agentSlug)}/definition`, {
|
|
112
|
+
method: "GET",
|
|
113
|
+
headers: authHeaders(defaults)
|
|
114
|
+
});
|
|
115
|
+
if (!res.ok) return null;
|
|
116
|
+
def = await res.json();
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
for (const spec of def.tools ?? []) {
|
|
121
|
+
if (!spec?.name || registry.hasTool(spec.name)) continue;
|
|
122
|
+
if (!spec.proxySlug) continue;
|
|
123
|
+
registry.registerProxyTool({
|
|
124
|
+
name: spec.name,
|
|
125
|
+
description: spec.description ?? `Proxied tool "${spec.proxySlug}".`,
|
|
126
|
+
inputSchema: spec.inputSchema ?? { type: "object", properties: {} },
|
|
127
|
+
proxySlug: spec.proxySlug,
|
|
128
|
+
base,
|
|
129
|
+
headers: authHeaders(defaults)
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
registry.createAgent({
|
|
133
|
+
id: def.slug,
|
|
134
|
+
name: def.slug,
|
|
135
|
+
model: def.model,
|
|
136
|
+
instructions: def.instructions ?? "",
|
|
137
|
+
temperature: def.temperature,
|
|
138
|
+
maxOutputTokens: def.maxOutputTokens,
|
|
139
|
+
tools: (def.tools ?? []).map((t) => t.name)
|
|
140
|
+
});
|
|
141
|
+
return def.slug;
|
|
142
|
+
}
|
|
143
|
+
function buildProxyTool(spec, context) {
|
|
144
|
+
const schema = spec.inputSchema ?? { type: "object", properties: {} };
|
|
145
|
+
const scope = pickScope(context);
|
|
146
|
+
return aiTool({
|
|
147
|
+
description: spec.description,
|
|
148
|
+
inputSchema: jsonSchema(schema),
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
+
execute: async (input) => {
|
|
151
|
+
const res = await fetch(`${spec.base}/tools/${encodeURIComponent(spec.proxySlug)}/call`, {
|
|
152
|
+
method: "POST",
|
|
153
|
+
headers: spec.headers,
|
|
154
|
+
body: JSON.stringify({ input, ...scope })
|
|
155
|
+
});
|
|
156
|
+
if (!res.ok) {
|
|
157
|
+
const text = await res.text().catch(() => "");
|
|
158
|
+
return { error: `Proxied tool "${spec.proxySlug}" failed: HTTP ${res.status} ${text}`.trim() };
|
|
159
|
+
}
|
|
160
|
+
const body = await res.json().catch(() => ({}));
|
|
161
|
+
return body.output ?? body;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function pickScope(context) {
|
|
166
|
+
const out = {};
|
|
167
|
+
for (const key of ["appId", "tenantId", "scopeMode", "targetApps", "collectionIds", "range"]) {
|
|
168
|
+
if (context[key] !== void 0 && context[key] !== null) out[key] = context[key];
|
|
169
|
+
}
|
|
170
|
+
if (context.toolContext && typeof context.toolContext === "object") {
|
|
171
|
+
out.toolContext = context.toolContext;
|
|
172
|
+
}
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
async function reportRun(defaults, report) {
|
|
176
|
+
if (!defaults.remoteBaseUrl) return;
|
|
177
|
+
const base = defaults.remoteBaseUrl.replace(/\/+$/, "");
|
|
178
|
+
try {
|
|
179
|
+
await fetch(`${base}/runs`, {
|
|
180
|
+
method: "POST",
|
|
181
|
+
headers: authHeaders(defaults),
|
|
182
|
+
body: JSON.stringify(report)
|
|
183
|
+
});
|
|
184
|
+
} catch {
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
83
188
|
// src/run.ts
|
|
189
|
+
async function resolveAgentMaybeRemote(registry, agentInput, defaults) {
|
|
190
|
+
if (typeof agentInput === "string" && defaults?.remoteBaseUrl && !registry.hasAgent(agentInput)) {
|
|
191
|
+
await ensureRemoteAgent(registry, agentInput, defaults);
|
|
192
|
+
}
|
|
193
|
+
return registry.resolveAgent(agentInput);
|
|
194
|
+
}
|
|
84
195
|
function resolveModel(agent, defaults) {
|
|
85
196
|
const model = agent.model ?? defaults?.model;
|
|
86
197
|
if (typeof model === "string") return resolveModelString(model, defaults?.apiKey);
|
|
@@ -109,6 +220,11 @@ function buildTools(registry, agent, context) {
|
|
|
109
220
|
execute: async (input, opts) => def.execute(input, { toolCallId: opts.toolCallId, app: context })
|
|
110
221
|
});
|
|
111
222
|
}
|
|
223
|
+
const allowed = agent.tools && agent.tools.length > 0 ? new Set(agent.tools) : null;
|
|
224
|
+
for (const [name, spec] of registry.proxyTools) {
|
|
225
|
+
if (allowed && !allowed.has(name)) continue;
|
|
226
|
+
if (!out[name]) out[name] = buildProxyTool(spec, context);
|
|
227
|
+
}
|
|
112
228
|
return out;
|
|
113
229
|
}
|
|
114
230
|
function buildRunOptions(params) {
|
|
@@ -127,7 +243,8 @@ function buildRunOptions(params) {
|
|
|
127
243
|
return opts;
|
|
128
244
|
}
|
|
129
245
|
async function run(registry, params, defaults) {
|
|
130
|
-
const
|
|
246
|
+
const startedAt = Date.now();
|
|
247
|
+
const agent = await resolveAgentMaybeRemote(registry, params.agent, defaults);
|
|
131
248
|
const messages = buildMessages(agent, params);
|
|
132
249
|
const tools = buildTools(registry, agent, params.context ?? {});
|
|
133
250
|
const result = await generateText({
|
|
@@ -140,7 +257,7 @@ async function run(registry, params, defaults) {
|
|
|
140
257
|
stopWhen: ({ steps }) => steps.length >= (params.maxSteps ?? 8),
|
|
141
258
|
providerOptions: agent.providerOptions
|
|
142
259
|
});
|
|
143
|
-
|
|
260
|
+
const runResult = {
|
|
144
261
|
text: result.text,
|
|
145
262
|
finishReason: result.finishReason,
|
|
146
263
|
usage: {
|
|
@@ -161,11 +278,36 @@ async function run(registry, params, defaults) {
|
|
|
161
278
|
...params.output ? { object: result.experimental_output } : {},
|
|
162
279
|
raw: result
|
|
163
280
|
};
|
|
281
|
+
void reportRun(defaults ?? {}, buildRunReport(agent, params, runResult, true, null, startedAt));
|
|
282
|
+
return runResult;
|
|
283
|
+
}
|
|
284
|
+
function buildRunReport(agent, params, result, ok, error, startedAt) {
|
|
285
|
+
return {
|
|
286
|
+
operation: "agent_ask",
|
|
287
|
+
agentSlug: agent.name,
|
|
288
|
+
model: typeof agent.model === "string" ? agent.model : null,
|
|
289
|
+
question: params.message ?? null,
|
|
290
|
+
requestPayload: { message: params.message ?? null, context: params.context ?? null },
|
|
291
|
+
responsePayload: { text: result.text, object: result.object ?? null, finishReason: result.finishReason ?? null },
|
|
292
|
+
toolCalls: result.toolCalls,
|
|
293
|
+
toolResults: result.toolResults,
|
|
294
|
+
inputTokens: result.usage.inputTokens,
|
|
295
|
+
outputTokens: result.usage.outputTokens,
|
|
296
|
+
totalTokens: result.usage.totalTokens,
|
|
297
|
+
latencyMs: Date.now() - startedAt,
|
|
298
|
+
ok,
|
|
299
|
+
error
|
|
300
|
+
};
|
|
164
301
|
}
|
|
165
302
|
async function* runStream(registry, params, defaults) {
|
|
166
|
-
const
|
|
303
|
+
const startedAt = Date.now();
|
|
304
|
+
const agent = await resolveAgentMaybeRemote(registry, params.agent, defaults);
|
|
167
305
|
const messages = buildMessages(agent, params);
|
|
168
306
|
const tools = buildTools(registry, agent, params.context ?? {});
|
|
307
|
+
let reportText = "";
|
|
308
|
+
let reportObject;
|
|
309
|
+
const reportToolCalls = [];
|
|
310
|
+
const reportToolResults = [];
|
|
169
311
|
const result = streamText({
|
|
170
312
|
model: resolveModel(agent, defaults),
|
|
171
313
|
messages,
|
|
@@ -185,13 +327,17 @@ async function* runStream(registry, params, defaults) {
|
|
|
185
327
|
};
|
|
186
328
|
for await (const part of result.fullStream) {
|
|
187
329
|
switch (part.type) {
|
|
188
|
-
case "text-delta":
|
|
189
|
-
|
|
330
|
+
case "text-delta": {
|
|
331
|
+
const t = part.text ?? part.delta ?? "";
|
|
332
|
+
reportText += t;
|
|
333
|
+
yield { type: "text-delta", text: t };
|
|
190
334
|
break;
|
|
335
|
+
}
|
|
191
336
|
case "finish-step":
|
|
192
337
|
addUsage(part.usage);
|
|
193
338
|
break;
|
|
194
339
|
case "tool-call":
|
|
340
|
+
reportToolCalls.push({ toolCallId: part.toolCallId, toolName: part.toolName, input: part.input ?? part.args });
|
|
195
341
|
yield {
|
|
196
342
|
type: "tool-call",
|
|
197
343
|
toolCallId: part.toolCallId,
|
|
@@ -200,6 +346,7 @@ async function* runStream(registry, params, defaults) {
|
|
|
200
346
|
};
|
|
201
347
|
break;
|
|
202
348
|
case "tool-result":
|
|
349
|
+
reportToolResults.push({ toolCallId: part.toolCallId, toolName: part.toolName, output: part.output ?? part.result });
|
|
203
350
|
yield {
|
|
204
351
|
type: "tool-result",
|
|
205
352
|
toolCallId: part.toolCallId,
|
|
@@ -221,19 +368,43 @@ async function* runStream(registry, params, defaults) {
|
|
|
221
368
|
if (params.output) {
|
|
222
369
|
object = await result.experimental_output;
|
|
223
370
|
}
|
|
371
|
+
reportObject = object;
|
|
372
|
+
const usage = {
|
|
373
|
+
inputTokens: finalUsage?.inputTokens ?? accumulatedUsage.inputTokens,
|
|
374
|
+
outputTokens: finalUsage?.outputTokens ?? accumulatedUsage.outputTokens,
|
|
375
|
+
totalTokens: finalUsage?.totalTokens ?? accumulatedUsage.totalTokens
|
|
376
|
+
};
|
|
377
|
+
void reportRun(
|
|
378
|
+
defaults ?? {},
|
|
379
|
+
buildRunReport(
|
|
380
|
+
agent,
|
|
381
|
+
params,
|
|
382
|
+
{ text: reportText, usage, toolCalls: reportToolCalls, toolResults: reportToolResults, object: reportObject, finishReason: part.finishReason },
|
|
383
|
+
true,
|
|
384
|
+
null,
|
|
385
|
+
startedAt
|
|
386
|
+
)
|
|
387
|
+
);
|
|
224
388
|
yield {
|
|
225
389
|
type: "finish",
|
|
226
390
|
finishReason: part.finishReason,
|
|
227
|
-
usage
|
|
228
|
-
inputTokens: finalUsage?.inputTokens ?? accumulatedUsage.inputTokens,
|
|
229
|
-
outputTokens: finalUsage?.outputTokens ?? accumulatedUsage.outputTokens,
|
|
230
|
-
totalTokens: finalUsage?.totalTokens ?? accumulatedUsage.totalTokens
|
|
231
|
-
},
|
|
391
|
+
usage,
|
|
232
392
|
...params.output ? { object } : {}
|
|
233
393
|
};
|
|
234
394
|
break;
|
|
235
395
|
}
|
|
236
396
|
case "error":
|
|
397
|
+
void reportRun(
|
|
398
|
+
defaults ?? {},
|
|
399
|
+
buildRunReport(
|
|
400
|
+
agent,
|
|
401
|
+
params,
|
|
402
|
+
{ text: reportText, usage: accumulatedUsage, toolCalls: reportToolCalls, toolResults: reportToolResults, object: reportObject },
|
|
403
|
+
false,
|
|
404
|
+
part.error instanceof Error ? part.error.message : String(part.error),
|
|
405
|
+
startedAt
|
|
406
|
+
)
|
|
407
|
+
);
|
|
237
408
|
yield { type: "error", error: part.error };
|
|
238
409
|
break;
|
|
239
410
|
}
|
|
@@ -272,7 +443,12 @@ var AiAgentsClient = class {
|
|
|
272
443
|
defaults;
|
|
273
444
|
constructor(config) {
|
|
274
445
|
this.registry = new Registry();
|
|
275
|
-
this.defaults = {
|
|
446
|
+
this.defaults = {
|
|
447
|
+
apiKey: config?.apiKey,
|
|
448
|
+
model: config?.model,
|
|
449
|
+
remoteBaseUrl: config?.remoteBaseUrl,
|
|
450
|
+
remoteToken: config?.remoteToken
|
|
451
|
+
};
|
|
276
452
|
}
|
|
277
453
|
registerTool(tool2) {
|
|
278
454
|
return this.registry.registerTool(tool2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@~lyre/ai-agents",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Multi-provider AI agents SDK for SvelteKit + Node. Thin agent/tool/run/runStream surface over the Vercel AI SDK — OpenAI, Anthropic, Google Gemini, Mistral, Cohere. Zod-typed tools, full streaming event surface, optional HTML sanitizer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|