@axlsdk/axl 0.1.1 → 0.3.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/LICENSE +190 -0
- package/dist/{chunk-EE2BCC37.js → chunk-JBLQKU6X.js} +1 -1
- package/dist/chunk-JBLQKU6X.js.map +1 -0
- package/dist/index.cjs +181 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -10
- package/dist/index.d.ts +67 -10
- package/dist/index.js +181 -19
- package/dist/index.js.map +1 -1
- package/dist/span-manager-3IKXXUTZ.js +7 -0
- package/package.json +9 -9
- package/dist/chunk-EE2BCC37.js.map +0 -1
- package/dist/span-manager-LGX7QHZ7.js +0 -7
- /package/dist/{span-manager-LGX7QHZ7.js.map → span-manager-3IKXXUTZ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__require
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JBLQKU6X.js";
|
|
4
4
|
|
|
5
5
|
// src/tool.ts
|
|
6
6
|
var DEFAULT_MAX_STRING_LENGTH = 1e4;
|
|
@@ -102,6 +102,48 @@ function tool(config) {
|
|
|
102
102
|
};
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
// src/providers/retry.ts
|
|
106
|
+
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 503, 529]);
|
|
107
|
+
var MAX_RETRIES = 2;
|
|
108
|
+
var BASE_DELAY_MS = 1e3;
|
|
109
|
+
function sleep2(ms, signal) {
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
if (signal?.aborted) {
|
|
112
|
+
resolve();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const timer = setTimeout(resolve, ms);
|
|
116
|
+
signal?.addEventListener(
|
|
117
|
+
"abort",
|
|
118
|
+
() => {
|
|
119
|
+
clearTimeout(timer);
|
|
120
|
+
resolve();
|
|
121
|
+
},
|
|
122
|
+
{ once: true }
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async function fetchWithRetry(input, init, maxRetries = MAX_RETRIES) {
|
|
127
|
+
for (let attempt = 0; ; attempt++) {
|
|
128
|
+
const res = await fetch(input, init);
|
|
129
|
+
if (res.ok || !RETRYABLE_STATUS_CODES.has(res.status) || attempt >= maxRetries) {
|
|
130
|
+
return res;
|
|
131
|
+
}
|
|
132
|
+
if (init?.signal?.aborted) {
|
|
133
|
+
return res;
|
|
134
|
+
}
|
|
135
|
+
const retryAfter = res.headers.get("retry-after");
|
|
136
|
+
let delay;
|
|
137
|
+
if (retryAfter && !isNaN(Number(retryAfter))) {
|
|
138
|
+
delay = Number(retryAfter) * 1e3;
|
|
139
|
+
} else {
|
|
140
|
+
delay = BASE_DELAY_MS * 2 ** attempt;
|
|
141
|
+
}
|
|
142
|
+
delay *= 0.75 + Math.random() * 0.5;
|
|
143
|
+
await sleep2(delay, init?.signal ?? void 0);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
105
147
|
// src/providers/openai.ts
|
|
106
148
|
var OPENAI_PRICING = {
|
|
107
149
|
"gpt-4o": [25e-7, 1e-5],
|
|
@@ -161,7 +203,7 @@ var OpenAIProvider = class {
|
|
|
161
203
|
// ---------------------------------------------------------------------------
|
|
162
204
|
async chat(messages, options) {
|
|
163
205
|
const body = this.buildRequestBody(messages, options, false);
|
|
164
|
-
const res = await
|
|
206
|
+
const res = await fetchWithRetry(`${this.baseUrl}/chat/completions`, {
|
|
165
207
|
method: "POST",
|
|
166
208
|
headers: {
|
|
167
209
|
"Content-Type": "application/json",
|
|
@@ -209,7 +251,7 @@ var OpenAIProvider = class {
|
|
|
209
251
|
// ---------------------------------------------------------------------------
|
|
210
252
|
async *stream(messages, options) {
|
|
211
253
|
const body = this.buildRequestBody(messages, options, true);
|
|
212
|
-
const res = await
|
|
254
|
+
const res = await fetchWithRetry(`${this.baseUrl}/chat/completions`, {
|
|
213
255
|
method: "POST",
|
|
214
256
|
headers: {
|
|
215
257
|
"Content-Type": "application/json",
|
|
@@ -368,7 +410,7 @@ var OpenAIResponsesProvider = class {
|
|
|
368
410
|
// ---------------------------------------------------------------------------
|
|
369
411
|
async chat(messages, options) {
|
|
370
412
|
const body = this.buildRequestBody(messages, options, false);
|
|
371
|
-
const res = await
|
|
413
|
+
const res = await fetchWithRetry(`${this.baseUrl}/responses`, {
|
|
372
414
|
method: "POST",
|
|
373
415
|
headers: {
|
|
374
416
|
"Content-Type": "application/json",
|
|
@@ -390,7 +432,7 @@ var OpenAIResponsesProvider = class {
|
|
|
390
432
|
// ---------------------------------------------------------------------------
|
|
391
433
|
async *stream(messages, options) {
|
|
392
434
|
const body = this.buildRequestBody(messages, options, true);
|
|
393
|
-
const res = await
|
|
435
|
+
const res = await fetchWithRetry(`${this.baseUrl}/responses`, {
|
|
394
436
|
method: "POST",
|
|
395
437
|
headers: {
|
|
396
438
|
"Content-Type": "application/json",
|
|
@@ -702,7 +744,7 @@ var AnthropicProvider = class {
|
|
|
702
744
|
async chat(messages, options) {
|
|
703
745
|
this.currentModel = options.model;
|
|
704
746
|
const body = this.buildRequestBody(messages, options, false);
|
|
705
|
-
const res = await
|
|
747
|
+
const res = await fetchWithRetry(`${this.baseUrl}/messages`, {
|
|
706
748
|
method: "POST",
|
|
707
749
|
headers: this.buildHeaders(),
|
|
708
750
|
body: JSON.stringify(body),
|
|
@@ -721,7 +763,7 @@ var AnthropicProvider = class {
|
|
|
721
763
|
// ---------------------------------------------------------------------------
|
|
722
764
|
async *stream(messages, options) {
|
|
723
765
|
const body = this.buildRequestBody(messages, options, true);
|
|
724
|
-
const res = await
|
|
766
|
+
const res = await fetchWithRetry(`${this.baseUrl}/messages`, {
|
|
725
767
|
method: "POST",
|
|
726
768
|
headers: this.buildHeaders(),
|
|
727
769
|
body: JSON.stringify(body),
|
|
@@ -1072,7 +1114,7 @@ var GeminiProvider = class {
|
|
|
1072
1114
|
// ---------------------------------------------------------------------------
|
|
1073
1115
|
async chat(messages, options) {
|
|
1074
1116
|
const body = this.buildRequestBody(messages, options);
|
|
1075
|
-
const res = await
|
|
1117
|
+
const res = await fetchWithRetry(`${this.baseUrl}/models/${options.model}:generateContent`, {
|
|
1076
1118
|
method: "POST",
|
|
1077
1119
|
headers: this.buildHeaders(),
|
|
1078
1120
|
body: JSON.stringify(body),
|
|
@@ -1091,7 +1133,7 @@ var GeminiProvider = class {
|
|
|
1091
1133
|
// ---------------------------------------------------------------------------
|
|
1092
1134
|
async *stream(messages, options) {
|
|
1093
1135
|
const body = this.buildRequestBody(messages, options);
|
|
1094
|
-
const res = await
|
|
1136
|
+
const res = await fetchWithRetry(
|
|
1095
1137
|
`${this.baseUrl}/models/${options.model}:streamGenerateContent?alt=sse`,
|
|
1096
1138
|
{
|
|
1097
1139
|
method: "POST",
|
|
@@ -2173,7 +2215,8 @@ Please fix and try again.`;
|
|
|
2173
2215
|
span.setAttribute("axl.tool.duration", Date.now() - toolStart2);
|
|
2174
2216
|
const isError = r && typeof r === "object" && "error" in r;
|
|
2175
2217
|
span.setAttribute("axl.tool.success", !isError);
|
|
2176
|
-
if (isError)
|
|
2218
|
+
if (isError)
|
|
2219
|
+
span.setStatus("error", r.error);
|
|
2177
2220
|
return r;
|
|
2178
2221
|
}
|
|
2179
2222
|
) : await executeOverride();
|
|
@@ -2285,7 +2328,9 @@ Please fix and try again.`;
|
|
|
2285
2328
|
try {
|
|
2286
2329
|
const mcpResult = await this.mcpManager.callTool(toolName, toolArgs);
|
|
2287
2330
|
toolResult2 = mcpResult;
|
|
2288
|
-
resultContent2 = mcpResult.content.map(
|
|
2331
|
+
resultContent2 = mcpResult.content.map(
|
|
2332
|
+
(c) => c.type === "text" ? c.text : `[${c.type}]`
|
|
2333
|
+
).join("\n");
|
|
2289
2334
|
if (mcpResult.isError) {
|
|
2290
2335
|
resultContent2 = `Error: ${resultContent2}`;
|
|
2291
2336
|
}
|
|
@@ -2327,7 +2372,11 @@ Please fix and try again.`;
|
|
|
2327
2372
|
span.setAttribute("axl.tool.duration", Date.now() - toolStart);
|
|
2328
2373
|
const isError = r.toolResult && typeof r.toolResult === "object" && "error" in r.toolResult;
|
|
2329
2374
|
span.setAttribute("axl.tool.success", !isError);
|
|
2330
|
-
if (isError)
|
|
2375
|
+
if (isError)
|
|
2376
|
+
span.setStatus(
|
|
2377
|
+
"error",
|
|
2378
|
+
r.toolResult.error
|
|
2379
|
+
);
|
|
2331
2380
|
return r;
|
|
2332
2381
|
}
|
|
2333
2382
|
) : await executeTool();
|
|
@@ -3306,6 +3355,10 @@ var MemoryStore = class {
|
|
|
3306
3355
|
async deleteMemory(scope, key) {
|
|
3307
3356
|
this.memories.get(scope)?.delete(key);
|
|
3308
3357
|
}
|
|
3358
|
+
// ── Sessions (Studio introspection) ─────────────────────────────────
|
|
3359
|
+
async listSessions() {
|
|
3360
|
+
return [...this.sessions.keys()];
|
|
3361
|
+
}
|
|
3309
3362
|
// ── Lifecycle ──────────────────────────────────────────────────────
|
|
3310
3363
|
async close() {
|
|
3311
3364
|
}
|
|
@@ -3534,6 +3587,11 @@ var SQLiteStore = class {
|
|
|
3534
3587
|
const rows = stmt.all();
|
|
3535
3588
|
return rows.map((r) => r.execution_id);
|
|
3536
3589
|
}
|
|
3590
|
+
// ── Sessions (Studio introspection) ────────────────────────────────────
|
|
3591
|
+
async listSessions() {
|
|
3592
|
+
const rows = this.db.prepare("SELECT session_id FROM sessions").all();
|
|
3593
|
+
return rows.map((r) => r.session_id);
|
|
3594
|
+
}
|
|
3537
3595
|
// ── Memory ────────────────────────────────────────────────────────────
|
|
3538
3596
|
async saveMemory(scope, key, value) {
|
|
3539
3597
|
this.db.prepare(
|
|
@@ -3567,7 +3625,8 @@ var RedisStore = class {
|
|
|
3567
3625
|
constructor(url) {
|
|
3568
3626
|
let Redis;
|
|
3569
3627
|
try {
|
|
3570
|
-
|
|
3628
|
+
const mod = __require("ioredis");
|
|
3629
|
+
Redis = mod.default ?? mod;
|
|
3571
3630
|
} catch {
|
|
3572
3631
|
throw new Error("ioredis is required for RedisStore. Install it with: npm install ioredis");
|
|
3573
3632
|
}
|
|
@@ -3617,6 +3676,7 @@ var RedisStore = class {
|
|
|
3617
3676
|
// ── Sessions ─────────────────────────────────────────────────────────
|
|
3618
3677
|
async saveSession(sessionId, history) {
|
|
3619
3678
|
await this.client.set(this.sessionKey(sessionId), JSON.stringify(history));
|
|
3679
|
+
await this.client.sadd("axl:session-ids", sessionId);
|
|
3620
3680
|
}
|
|
3621
3681
|
async getSession(sessionId) {
|
|
3622
3682
|
const raw = await this.client.get(this.sessionKey(sessionId));
|
|
@@ -3625,6 +3685,7 @@ var RedisStore = class {
|
|
|
3625
3685
|
async deleteSession(sessionId) {
|
|
3626
3686
|
await this.client.del(this.sessionKey(sessionId));
|
|
3627
3687
|
await this.client.del(this.sessionMetaKey(sessionId));
|
|
3688
|
+
await this.client.srem("axl:session-ids", sessionId);
|
|
3628
3689
|
}
|
|
3629
3690
|
async saveSessionMeta(sessionId, key, value) {
|
|
3630
3691
|
await this.client.hset(this.sessionMetaKey(sessionId), key, JSON.stringify(value));
|
|
@@ -3661,6 +3722,10 @@ var RedisStore = class {
|
|
|
3661
3722
|
async listPendingExecutions() {
|
|
3662
3723
|
return this.client.smembers(this.pendingExecSetKey());
|
|
3663
3724
|
}
|
|
3725
|
+
// ── Sessions (Studio introspection) ────────────────────────────────────
|
|
3726
|
+
async listSessions() {
|
|
3727
|
+
return this.client.smembers("axl:session-ids");
|
|
3728
|
+
}
|
|
3664
3729
|
/** Close the Redis connection. */
|
|
3665
3730
|
async close() {
|
|
3666
3731
|
await this.client.quit();
|
|
@@ -4489,7 +4554,7 @@ async function createSpanManager(config) {
|
|
|
4489
4554
|
if (!config?.enabled) {
|
|
4490
4555
|
return new NoopSpanManager();
|
|
4491
4556
|
}
|
|
4492
|
-
const { OTelSpanManager: OTelSpanManager2 } = await import("./span-manager-
|
|
4557
|
+
const { OTelSpanManager: OTelSpanManager2 } = await import("./span-manager-3IKXXUTZ.js");
|
|
4493
4558
|
return OTelSpanManager2.create(config);
|
|
4494
4559
|
}
|
|
4495
4560
|
|
|
@@ -4505,11 +4570,14 @@ function hashInput(input) {
|
|
|
4505
4570
|
var AxlRuntime = class extends EventEmitter2 {
|
|
4506
4571
|
config;
|
|
4507
4572
|
workflows = /* @__PURE__ */ new Map();
|
|
4573
|
+
tools = /* @__PURE__ */ new Map();
|
|
4574
|
+
agents = /* @__PURE__ */ new Map();
|
|
4508
4575
|
providerRegistry;
|
|
4509
4576
|
stateStore;
|
|
4510
4577
|
executions = /* @__PURE__ */ new Map();
|
|
4511
4578
|
pendingDecisionResolvers = /* @__PURE__ */ new Map();
|
|
4512
4579
|
abortControllers = /* @__PURE__ */ new Map();
|
|
4580
|
+
registeredEvals = /* @__PURE__ */ new Map();
|
|
4513
4581
|
mcpManager;
|
|
4514
4582
|
memoryManager;
|
|
4515
4583
|
spanManager = new NoopSpanManager();
|
|
@@ -4559,9 +4627,102 @@ var AxlRuntime = class extends EventEmitter2 {
|
|
|
4559
4627
|
}
|
|
4560
4628
|
}
|
|
4561
4629
|
/** Register a workflow with the runtime. */
|
|
4630
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4562
4631
|
register(workflow2) {
|
|
4563
4632
|
this.workflows.set(workflow2.name, workflow2);
|
|
4564
4633
|
}
|
|
4634
|
+
/** Register standalone tools for Studio introspection and direct testing. */
|
|
4635
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4636
|
+
registerTool(...tools) {
|
|
4637
|
+
for (const t of tools) {
|
|
4638
|
+
this.tools.set(t.name, t);
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
/** Register standalone agents for Studio playground and introspection. */
|
|
4642
|
+
registerAgent(...agents) {
|
|
4643
|
+
for (const a of agents) {
|
|
4644
|
+
this.agents.set(a._name, a);
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
// ── Introspection (used by Studio) ────────────────────────────────
|
|
4648
|
+
/** Get all registered workflow names. */
|
|
4649
|
+
getWorkflowNames() {
|
|
4650
|
+
return [...this.workflows.keys()];
|
|
4651
|
+
}
|
|
4652
|
+
/** Get a registered workflow by name. */
|
|
4653
|
+
getWorkflow(name) {
|
|
4654
|
+
return this.workflows.get(name);
|
|
4655
|
+
}
|
|
4656
|
+
/** Get all registered workflows. */
|
|
4657
|
+
getWorkflows() {
|
|
4658
|
+
return [...this.workflows.values()];
|
|
4659
|
+
}
|
|
4660
|
+
/** Get all registered standalone tools. */
|
|
4661
|
+
getTools() {
|
|
4662
|
+
return [...this.tools.values()];
|
|
4663
|
+
}
|
|
4664
|
+
/** Get a registered standalone tool by name. */
|
|
4665
|
+
getTool(name) {
|
|
4666
|
+
return this.tools.get(name);
|
|
4667
|
+
}
|
|
4668
|
+
/** Get all registered standalone agents. */
|
|
4669
|
+
getAgents() {
|
|
4670
|
+
return [...this.agents.values()];
|
|
4671
|
+
}
|
|
4672
|
+
/** Get a registered standalone agent by name. */
|
|
4673
|
+
getAgent(name) {
|
|
4674
|
+
return this.agents.get(name);
|
|
4675
|
+
}
|
|
4676
|
+
/**
|
|
4677
|
+
* Register an eval config for Studio introspection and execution.
|
|
4678
|
+
* The config should be the result of `defineEval()` from `@axlsdk/eval`.
|
|
4679
|
+
* An optional `executeWorkflow` function can override the default behavior
|
|
4680
|
+
* of calling `runtime.execute()`.
|
|
4681
|
+
*/
|
|
4682
|
+
registerEval(name, config, executeWorkflow) {
|
|
4683
|
+
this.registeredEvals.set(name, { config, executeWorkflow });
|
|
4684
|
+
}
|
|
4685
|
+
/** Get metadata about all registered evals. */
|
|
4686
|
+
getRegisteredEvals() {
|
|
4687
|
+
const result = [];
|
|
4688
|
+
for (const [name, { config }] of this.registeredEvals) {
|
|
4689
|
+
const cfg = config;
|
|
4690
|
+
result.push({
|
|
4691
|
+
name,
|
|
4692
|
+
workflow: cfg.workflow ?? "unknown",
|
|
4693
|
+
dataset: cfg.dataset?.name ?? "unknown",
|
|
4694
|
+
scorers: (cfg.scorers ?? []).map((s) => s.name ?? "unknown")
|
|
4695
|
+
});
|
|
4696
|
+
}
|
|
4697
|
+
return result;
|
|
4698
|
+
}
|
|
4699
|
+
/** Get a registered eval config by name. */
|
|
4700
|
+
getRegisteredEval(name) {
|
|
4701
|
+
return this.registeredEvals.get(name);
|
|
4702
|
+
}
|
|
4703
|
+
/** Run a registered eval by name. */
|
|
4704
|
+
async runRegisteredEval(name) {
|
|
4705
|
+
const entry = this.registeredEvals.get(name);
|
|
4706
|
+
if (!entry) throw new Error(`Eval "${name}" is not registered`);
|
|
4707
|
+
if (entry.executeWorkflow) {
|
|
4708
|
+
let runEvalFn;
|
|
4709
|
+
try {
|
|
4710
|
+
({ runEval: runEvalFn } = await import("@axlsdk/eval"));
|
|
4711
|
+
} catch {
|
|
4712
|
+
throw new Error(
|
|
4713
|
+
"axl-eval is required for AxlRuntime.runRegisteredEval(). Install it with: npm install @axlsdk/eval"
|
|
4714
|
+
);
|
|
4715
|
+
}
|
|
4716
|
+
return runEvalFn(entry.config, entry.executeWorkflow);
|
|
4717
|
+
}
|
|
4718
|
+
return this.eval(
|
|
4719
|
+
entry.config
|
|
4720
|
+
);
|
|
4721
|
+
}
|
|
4722
|
+
/** Get all execution info (running + completed). */
|
|
4723
|
+
getExecutions() {
|
|
4724
|
+
return [...this.executions.values()];
|
|
4725
|
+
}
|
|
4565
4726
|
/** Register a custom provider instance. */
|
|
4566
4727
|
registerProvider(name, provider) {
|
|
4567
4728
|
this.providerRegistry.registerInstance(name, provider);
|
|
@@ -4941,10 +5102,10 @@ var AxlRuntime = class extends EventEmitter2 {
|
|
|
4941
5102
|
async eval(config) {
|
|
4942
5103
|
let runEval;
|
|
4943
5104
|
try {
|
|
4944
|
-
({ runEval } = await import("
|
|
5105
|
+
({ runEval } = await import("@axlsdk/eval"));
|
|
4945
5106
|
} catch {
|
|
4946
5107
|
throw new Error(
|
|
4947
|
-
"axl-eval is required for AxlRuntime.eval(). Install it with: npm install
|
|
5108
|
+
"axl-eval is required for AxlRuntime.eval(). Install it with: npm install @axlsdk/eval"
|
|
4948
5109
|
);
|
|
4949
5110
|
}
|
|
4950
5111
|
const executeWorkflow = async (input) => {
|
|
@@ -4971,10 +5132,10 @@ var AxlRuntime = class extends EventEmitter2 {
|
|
|
4971
5132
|
async evalCompare(baseline, candidate) {
|
|
4972
5133
|
let evalCompareFn;
|
|
4973
5134
|
try {
|
|
4974
|
-
({ evalCompare: evalCompareFn } = await import("
|
|
5135
|
+
({ evalCompare: evalCompareFn } = await import("@axlsdk/eval"));
|
|
4975
5136
|
} catch {
|
|
4976
5137
|
throw new Error(
|
|
4977
|
-
"axl-eval is required for AxlRuntime.evalCompare(). Install it with: npm install
|
|
5138
|
+
"axl-eval is required for AxlRuntime.evalCompare(). Install it with: npm install @axlsdk/eval"
|
|
4978
5139
|
);
|
|
4979
5140
|
}
|
|
4980
5141
|
return evalCompareFn(baseline, candidate);
|
|
@@ -5260,6 +5421,7 @@ export {
|
|
|
5260
5421
|
createSpanManager,
|
|
5261
5422
|
defineConfig,
|
|
5262
5423
|
tool,
|
|
5263
|
-
workflow
|
|
5424
|
+
workflow,
|
|
5425
|
+
zodToJsonSchema
|
|
5264
5426
|
};
|
|
5265
5427
|
//# sourceMappingURL=index.js.map
|