@axlsdk/studio 0.13.7 → 0.14.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 -1
- package/dist/{chunk-YWRYXT7U.js → chunk-HUKUQDYL.js} +232 -90
- package/dist/chunk-HUKUQDYL.js.map +1 -0
- package/dist/{chunk-6VDX5CRP.js → chunk-JGQ3MSIG.js} +5 -2
- package/dist/chunk-JGQ3MSIG.js.map +1 -0
- package/dist/cli.cjs +246 -96
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/index-7aDhMztu.css +1 -0
- package/dist/client/assets/index-Bzr3vDPz.js +255 -0
- package/dist/client/index.html +2 -2
- package/dist/middleware.cjs +242 -93
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.js +9 -2
- package/dist/middleware.js.map +1 -1
- package/dist/server/index.cjs +232 -90
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +5 -4
- package/dist/chunk-6VDX5CRP.js.map +0 -1
- package/dist/chunk-YWRYXT7U.js.map +0 -1
- package/dist/client/assets/index-C_uwupnn.js +0 -221
- package/dist/client/assets/index-DVcH6P9w.css +0 -1
package/dist/client/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Axl Studio</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-Bzr3vDPz.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-7aDhMztu.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/dist/middleware.cjs
CHANGED
|
@@ -340,27 +340,30 @@ var CostAggregator = class {
|
|
|
340
340
|
|
|
341
341
|
// src/server/routes/health.ts
|
|
342
342
|
var import_hono = require("hono");
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
343
|
+
function createHealthRoutes(readOnly) {
|
|
344
|
+
const app6 = new import_hono.Hono();
|
|
345
|
+
app6.get("/health", (c) => {
|
|
346
|
+
const runtime = c.get("runtime");
|
|
347
|
+
return c.json({
|
|
348
|
+
ok: true,
|
|
349
|
+
data: {
|
|
350
|
+
status: "healthy",
|
|
351
|
+
readOnly,
|
|
352
|
+
workflows: runtime.getWorkflowNames().length,
|
|
353
|
+
agents: runtime.getAgents().length,
|
|
354
|
+
tools: runtime.getTools().length
|
|
355
|
+
}
|
|
356
|
+
});
|
|
354
357
|
});
|
|
355
|
-
|
|
356
|
-
|
|
358
|
+
return app6;
|
|
359
|
+
}
|
|
357
360
|
|
|
358
361
|
// src/server/routes/workflows.ts
|
|
359
362
|
var import_hono2 = require("hono");
|
|
360
363
|
var import_axl = require("@axlsdk/axl");
|
|
361
364
|
function createWorkflowRoutes(connMgr) {
|
|
362
|
-
const
|
|
363
|
-
|
|
365
|
+
const app6 = new import_hono2.Hono();
|
|
366
|
+
app6.get("/workflows", (c) => {
|
|
364
367
|
const runtime = c.get("runtime");
|
|
365
368
|
const workflows = runtime.getWorkflows().map((w) => ({
|
|
366
369
|
name: w.name,
|
|
@@ -369,7 +372,7 @@ function createWorkflowRoutes(connMgr) {
|
|
|
369
372
|
}));
|
|
370
373
|
return c.json({ ok: true, data: workflows });
|
|
371
374
|
});
|
|
372
|
-
|
|
375
|
+
app6.get("/workflows/:name", (c) => {
|
|
373
376
|
const runtime = c.get("runtime");
|
|
374
377
|
const name = c.req.param("name");
|
|
375
378
|
const workflow = runtime.getWorkflow(name);
|
|
@@ -388,7 +391,7 @@ function createWorkflowRoutes(connMgr) {
|
|
|
388
391
|
}
|
|
389
392
|
});
|
|
390
393
|
});
|
|
391
|
-
|
|
394
|
+
app6.post("/workflows/:name/execute", async (c) => {
|
|
392
395
|
const runtime = c.get("runtime");
|
|
393
396
|
const name = c.req.param("name");
|
|
394
397
|
const workflow = runtime.getWorkflow(name);
|
|
@@ -412,18 +415,18 @@ function createWorkflowRoutes(connMgr) {
|
|
|
412
415
|
const result = await runtime.execute(name, body.input ?? {}, { metadata: body.metadata });
|
|
413
416
|
return c.json({ ok: true, data: { result } });
|
|
414
417
|
});
|
|
415
|
-
return
|
|
418
|
+
return app6;
|
|
416
419
|
}
|
|
417
420
|
|
|
418
421
|
// src/server/routes/executions.ts
|
|
419
422
|
var import_hono3 = require("hono");
|
|
420
|
-
var
|
|
421
|
-
|
|
423
|
+
var app = new import_hono3.Hono();
|
|
424
|
+
app.get("/executions", async (c) => {
|
|
422
425
|
const runtime = c.get("runtime");
|
|
423
426
|
const executions = await runtime.getExecutions();
|
|
424
427
|
return c.json({ ok: true, data: executions });
|
|
425
428
|
});
|
|
426
|
-
|
|
429
|
+
app.get("/executions/:id", async (c) => {
|
|
427
430
|
const runtime = c.get("runtime");
|
|
428
431
|
const id = c.req.param("id");
|
|
429
432
|
const execution = await runtime.getExecution(id);
|
|
@@ -435,19 +438,19 @@ app2.get("/executions/:id", async (c) => {
|
|
|
435
438
|
}
|
|
436
439
|
return c.json({ ok: true, data: execution });
|
|
437
440
|
});
|
|
438
|
-
|
|
441
|
+
app.post("/executions/:id/abort", (c) => {
|
|
439
442
|
const runtime = c.get("runtime");
|
|
440
443
|
const id = c.req.param("id");
|
|
441
444
|
runtime.abort(id);
|
|
442
445
|
return c.json({ ok: true, data: { aborted: true } });
|
|
443
446
|
});
|
|
444
|
-
var executions_default =
|
|
447
|
+
var executions_default = app;
|
|
445
448
|
|
|
446
449
|
// src/server/routes/sessions.ts
|
|
447
450
|
var import_hono4 = require("hono");
|
|
448
451
|
function createSessionRoutes(connMgr) {
|
|
449
|
-
const
|
|
450
|
-
|
|
452
|
+
const app6 = new import_hono4.Hono();
|
|
453
|
+
app6.get("/sessions", async (c) => {
|
|
451
454
|
const runtime = c.get("runtime");
|
|
452
455
|
const store = runtime.getStateStore();
|
|
453
456
|
if (!store.listSessions) {
|
|
@@ -461,7 +464,7 @@ function createSessionRoutes(connMgr) {
|
|
|
461
464
|
}
|
|
462
465
|
return c.json({ ok: true, data: sessions });
|
|
463
466
|
});
|
|
464
|
-
|
|
467
|
+
app6.get("/sessions/:id", async (c) => {
|
|
465
468
|
const runtime = c.get("runtime");
|
|
466
469
|
const store = runtime.getStateStore();
|
|
467
470
|
const id = c.req.param("id");
|
|
@@ -469,7 +472,7 @@ function createSessionRoutes(connMgr) {
|
|
|
469
472
|
const handoffHistory = await store.getSessionMeta(id, "handoffHistory");
|
|
470
473
|
return c.json({ ok: true, data: { id, history, handoffHistory: handoffHistory ?? [] } });
|
|
471
474
|
});
|
|
472
|
-
|
|
475
|
+
app6.post("/sessions/:id/send", async (c) => {
|
|
473
476
|
const runtime = c.get("runtime");
|
|
474
477
|
const id = c.req.param("id");
|
|
475
478
|
const body = await c.req.json();
|
|
@@ -477,7 +480,7 @@ function createSessionRoutes(connMgr) {
|
|
|
477
480
|
const result = await session.send(body.workflow, body.message);
|
|
478
481
|
return c.json({ ok: true, data: { result } });
|
|
479
482
|
});
|
|
480
|
-
|
|
483
|
+
app6.post("/sessions/:id/stream", async (c) => {
|
|
481
484
|
const runtime = c.get("runtime");
|
|
482
485
|
const id = c.req.param("id");
|
|
483
486
|
const body = await c.req.json();
|
|
@@ -491,21 +494,21 @@ function createSessionRoutes(connMgr) {
|
|
|
491
494
|
})();
|
|
492
495
|
return c.json({ ok: true, data: { executionId, streaming: true } });
|
|
493
496
|
});
|
|
494
|
-
|
|
497
|
+
app6.delete("/sessions/:id", async (c) => {
|
|
495
498
|
const runtime = c.get("runtime");
|
|
496
499
|
const store = runtime.getStateStore();
|
|
497
500
|
const id = c.req.param("id");
|
|
498
501
|
await store.deleteSession(id);
|
|
499
502
|
return c.json({ ok: true, data: { deleted: true } });
|
|
500
503
|
});
|
|
501
|
-
return
|
|
504
|
+
return app6;
|
|
502
505
|
}
|
|
503
506
|
|
|
504
507
|
// src/server/routes/agents.ts
|
|
505
508
|
var import_hono5 = require("hono");
|
|
506
509
|
var import_axl2 = require("@axlsdk/axl");
|
|
507
|
-
var
|
|
508
|
-
|
|
510
|
+
var app2 = new import_hono5.Hono();
|
|
511
|
+
app2.get("/agents", (c) => {
|
|
509
512
|
const runtime = c.get("runtime");
|
|
510
513
|
const agents = runtime.getAgents().map((a) => ({
|
|
511
514
|
name: a._name,
|
|
@@ -524,7 +527,7 @@ app3.get("/agents", (c) => {
|
|
|
524
527
|
}));
|
|
525
528
|
return c.json({ ok: true, data: agents });
|
|
526
529
|
});
|
|
527
|
-
|
|
530
|
+
app2.get("/agents/:name", (c) => {
|
|
528
531
|
const runtime = c.get("runtime");
|
|
529
532
|
const name = c.req.param("name");
|
|
530
533
|
const agent = runtime.getAgent(name);
|
|
@@ -580,13 +583,13 @@ app3.get("/agents/:name", (c) => {
|
|
|
580
583
|
}
|
|
581
584
|
});
|
|
582
585
|
});
|
|
583
|
-
var agents_default =
|
|
586
|
+
var agents_default = app2;
|
|
584
587
|
|
|
585
588
|
// src/server/routes/tools.ts
|
|
586
589
|
var import_hono6 = require("hono");
|
|
587
590
|
var import_axl3 = require("@axlsdk/axl");
|
|
588
|
-
var
|
|
589
|
-
|
|
591
|
+
var app3 = new import_hono6.Hono();
|
|
592
|
+
app3.get("/tools", (c) => {
|
|
590
593
|
const runtime = c.get("runtime");
|
|
591
594
|
const tools = runtime.getTools().map((t) => ({
|
|
592
595
|
name: t.name,
|
|
@@ -597,7 +600,7 @@ app4.get("/tools", (c) => {
|
|
|
597
600
|
}));
|
|
598
601
|
return c.json({ ok: true, data: tools });
|
|
599
602
|
});
|
|
600
|
-
|
|
603
|
+
app3.get("/tools/:name", (c) => {
|
|
601
604
|
const runtime = c.get("runtime");
|
|
602
605
|
const name = c.req.param("name");
|
|
603
606
|
const tool = runtime.getTool(name);
|
|
@@ -624,7 +627,7 @@ app4.get("/tools/:name", (c) => {
|
|
|
624
627
|
}
|
|
625
628
|
});
|
|
626
629
|
});
|
|
627
|
-
|
|
630
|
+
app3.post("/tools/:name/test", async (c) => {
|
|
628
631
|
const runtime = c.get("runtime");
|
|
629
632
|
const name = c.req.param("name");
|
|
630
633
|
const tool = runtime.getTool(name);
|
|
@@ -639,12 +642,12 @@ app4.post("/tools/:name/test", async (c) => {
|
|
|
639
642
|
const result = await tool.run(ctx, body.input);
|
|
640
643
|
return c.json({ ok: true, data: { result } });
|
|
641
644
|
});
|
|
642
|
-
var tools_default =
|
|
645
|
+
var tools_default = app3;
|
|
643
646
|
|
|
644
647
|
// src/server/routes/memory.ts
|
|
645
648
|
var import_hono7 = require("hono");
|
|
646
|
-
var
|
|
647
|
-
|
|
649
|
+
var app4 = new import_hono7.Hono();
|
|
650
|
+
app4.get("/memory/:scope", async (c) => {
|
|
648
651
|
const runtime = c.get("runtime");
|
|
649
652
|
const store = runtime.getStateStore();
|
|
650
653
|
const scope = c.req.param("scope");
|
|
@@ -654,7 +657,7 @@ app5.get("/memory/:scope", async (c) => {
|
|
|
654
657
|
const entries = await store.getAllMemory(scope);
|
|
655
658
|
return c.json({ ok: true, data: entries });
|
|
656
659
|
});
|
|
657
|
-
|
|
660
|
+
app4.get("/memory/:scope/:key", async (c) => {
|
|
658
661
|
const runtime = c.get("runtime");
|
|
659
662
|
const store = runtime.getStateStore();
|
|
660
663
|
const scope = c.req.param("scope");
|
|
@@ -674,7 +677,7 @@ app5.get("/memory/:scope/:key", async (c) => {
|
|
|
674
677
|
}
|
|
675
678
|
return c.json({ ok: true, data: { key, value } });
|
|
676
679
|
});
|
|
677
|
-
|
|
680
|
+
app4.put("/memory/:scope/:key", async (c) => {
|
|
678
681
|
const runtime = c.get("runtime");
|
|
679
682
|
const store = runtime.getStateStore();
|
|
680
683
|
const scope = c.req.param("scope");
|
|
@@ -689,7 +692,7 @@ app5.put("/memory/:scope/:key", async (c) => {
|
|
|
689
692
|
await store.saveMemory(scope, key, body.value);
|
|
690
693
|
return c.json({ ok: true, data: { saved: true } });
|
|
691
694
|
});
|
|
692
|
-
|
|
695
|
+
app4.delete("/memory/:scope/:key", async (c) => {
|
|
693
696
|
const runtime = c.get("runtime");
|
|
694
697
|
const store = runtime.getStateStore();
|
|
695
698
|
const scope = c.req.param("scope");
|
|
@@ -703,61 +706,77 @@ app5.delete("/memory/:scope/:key", async (c) => {
|
|
|
703
706
|
await store.deleteMemory(scope, key);
|
|
704
707
|
return c.json({ ok: true, data: { deleted: true } });
|
|
705
708
|
});
|
|
706
|
-
|
|
709
|
+
app4.post("/memory/search", async (c) => {
|
|
707
710
|
return c.json({
|
|
708
711
|
ok: true,
|
|
709
712
|
data: { results: [], message: "Semantic search requires MemoryManager with vector store" }
|
|
710
713
|
});
|
|
711
714
|
});
|
|
712
|
-
var memory_default =
|
|
715
|
+
var memory_default = app4;
|
|
713
716
|
|
|
714
717
|
// src/server/routes/decisions.ts
|
|
715
718
|
var import_hono8 = require("hono");
|
|
716
|
-
var
|
|
717
|
-
|
|
719
|
+
var app5 = new import_hono8.Hono();
|
|
720
|
+
app5.get("/decisions", async (c) => {
|
|
718
721
|
const runtime = c.get("runtime");
|
|
719
722
|
const decisions = await runtime.getPendingDecisions();
|
|
720
723
|
return c.json({ ok: true, data: decisions });
|
|
721
724
|
});
|
|
722
|
-
|
|
725
|
+
app5.post("/decisions/:executionId/resolve", async (c) => {
|
|
723
726
|
const runtime = c.get("runtime");
|
|
724
727
|
const executionId = c.req.param("executionId");
|
|
725
728
|
const body = await c.req.json();
|
|
726
729
|
await runtime.resolveDecision(executionId, body);
|
|
727
730
|
return c.json({ ok: true, data: { resolved: true } });
|
|
728
731
|
});
|
|
729
|
-
var decisions_default =
|
|
732
|
+
var decisions_default = app5;
|
|
730
733
|
|
|
731
734
|
// src/server/routes/costs.ts
|
|
732
735
|
var import_hono9 = require("hono");
|
|
733
736
|
function createCostRoutes(costAggregator) {
|
|
734
|
-
const
|
|
735
|
-
|
|
737
|
+
const app6 = new import_hono9.Hono();
|
|
738
|
+
app6.get("/costs", (c) => {
|
|
736
739
|
return c.json({ ok: true, data: costAggregator.getData() });
|
|
737
740
|
});
|
|
738
|
-
|
|
741
|
+
app6.post("/costs/reset", (c) => {
|
|
739
742
|
costAggregator.reset();
|
|
740
743
|
return c.json({ ok: true, data: { reset: true } });
|
|
741
744
|
});
|
|
742
|
-
return
|
|
745
|
+
return app6;
|
|
743
746
|
}
|
|
744
747
|
|
|
745
748
|
// src/server/routes/evals.ts
|
|
749
|
+
var import_node_crypto = require("crypto");
|
|
746
750
|
var import_hono10 = require("hono");
|
|
747
751
|
function createEvalRoutes(evalLoader) {
|
|
748
|
-
const
|
|
749
|
-
|
|
752
|
+
const app6 = new import_hono10.Hono();
|
|
753
|
+
app6.get("/evals", async (c) => {
|
|
750
754
|
if (evalLoader) await evalLoader();
|
|
751
755
|
const runtime = c.get("runtime");
|
|
752
756
|
const evals = runtime.getRegisteredEvals();
|
|
753
757
|
return c.json({ ok: true, data: evals });
|
|
754
758
|
});
|
|
755
|
-
|
|
759
|
+
app6.get("/evals/history", async (c) => {
|
|
756
760
|
const runtime = c.get("runtime");
|
|
757
761
|
const history = await runtime.getEvalHistory();
|
|
758
762
|
return c.json({ ok: true, data: history });
|
|
759
763
|
});
|
|
760
|
-
|
|
764
|
+
app6.delete("/evals/history/:id", async (c) => {
|
|
765
|
+
const runtime = c.get("runtime");
|
|
766
|
+
const id = c.req.param("id");
|
|
767
|
+
const deleted = await runtime.deleteEvalResult(id);
|
|
768
|
+
if (!deleted) {
|
|
769
|
+
return c.json(
|
|
770
|
+
{
|
|
771
|
+
ok: false,
|
|
772
|
+
error: { code: "NOT_FOUND", message: `Eval history entry "${id}" not found` }
|
|
773
|
+
},
|
|
774
|
+
404
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
return c.json({ ok: true, data: { id, deleted: true } });
|
|
778
|
+
});
|
|
779
|
+
app6.post("/evals/:name/run", async (c) => {
|
|
761
780
|
if (evalLoader) await evalLoader();
|
|
762
781
|
const runtime = c.get("runtime");
|
|
763
782
|
const name = c.req.param("name");
|
|
@@ -778,9 +797,8 @@ function createEvalRoutes(evalLoader) {
|
|
|
778
797
|
}
|
|
779
798
|
try {
|
|
780
799
|
if (runs > 1) {
|
|
781
|
-
const { randomUUID } = await import("crypto");
|
|
782
800
|
const { aggregateRuns } = await import("@axlsdk/eval");
|
|
783
|
-
const runGroupId = randomUUID();
|
|
801
|
+
const runGroupId = (0, import_node_crypto.randomUUID)();
|
|
784
802
|
const results = [];
|
|
785
803
|
for (let r = 0; r < runs; r++) {
|
|
786
804
|
const result2 = await runtime.runRegisteredEval(name, {
|
|
@@ -802,7 +820,7 @@ function createEvalRoutes(evalLoader) {
|
|
|
802
820
|
return c.json({ ok: false, error: { code: "EVAL_ERROR", message } }, 400);
|
|
803
821
|
}
|
|
804
822
|
});
|
|
805
|
-
|
|
823
|
+
app6.post("/evals/:name/rescore", async (c) => {
|
|
806
824
|
if (evalLoader) await evalLoader();
|
|
807
825
|
const runtime = c.get("runtime");
|
|
808
826
|
const name = c.req.param("name");
|
|
@@ -848,25 +866,146 @@ function createEvalRoutes(evalLoader) {
|
|
|
848
866
|
return c.json({ ok: false, error: { code: "EVAL_ERROR", message } }, 400);
|
|
849
867
|
}
|
|
850
868
|
});
|
|
851
|
-
|
|
869
|
+
app6.post("/evals/compare", async (c) => {
|
|
852
870
|
const runtime = c.get("runtime");
|
|
853
871
|
const body = await c.req.json();
|
|
872
|
+
const validateIdParam = (v, name) => {
|
|
873
|
+
if (typeof v === "string") return v === "" ? `${name} must be non-empty` : null;
|
|
874
|
+
if (Array.isArray(v)) {
|
|
875
|
+
if (v.length === 0) return `${name} must be a non-empty array`;
|
|
876
|
+
for (const elem of v) {
|
|
877
|
+
if (typeof elem !== "string" || elem === "") {
|
|
878
|
+
return `${name} array must contain only non-empty strings`;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
return null;
|
|
882
|
+
}
|
|
883
|
+
return `${name} is required (string or string[])`;
|
|
884
|
+
};
|
|
885
|
+
const baselineErr = validateIdParam(body.baselineId, "baselineId");
|
|
886
|
+
const candidateErr = validateIdParam(body.candidateId, "candidateId");
|
|
887
|
+
if (baselineErr || candidateErr) {
|
|
888
|
+
return c.json(
|
|
889
|
+
{
|
|
890
|
+
ok: false,
|
|
891
|
+
error: {
|
|
892
|
+
code: "BAD_REQUEST",
|
|
893
|
+
message: [baselineErr, candidateErr].filter(Boolean).join("; ")
|
|
894
|
+
}
|
|
895
|
+
},
|
|
896
|
+
400
|
|
897
|
+
);
|
|
898
|
+
}
|
|
899
|
+
const history = await runtime.getEvalHistory();
|
|
900
|
+
const byId = new Map(history.map((h) => [h.id, h.data]));
|
|
901
|
+
const missing = [];
|
|
902
|
+
const resolveOne = (id) => {
|
|
903
|
+
const data = byId.get(id);
|
|
904
|
+
if (!data) missing.push(id);
|
|
905
|
+
return data;
|
|
906
|
+
};
|
|
907
|
+
const resolveSelection = (idOrIds) => {
|
|
908
|
+
if (Array.isArray(idOrIds)) {
|
|
909
|
+
const unique = Array.from(new Set(idOrIds));
|
|
910
|
+
if (unique.length === 1) return resolveOne(unique[0]);
|
|
911
|
+
const results = [];
|
|
912
|
+
for (const id of unique) {
|
|
913
|
+
const data = resolveOne(id);
|
|
914
|
+
if (data) results.push(data);
|
|
915
|
+
}
|
|
916
|
+
return results;
|
|
917
|
+
}
|
|
918
|
+
return resolveOne(idOrIds);
|
|
919
|
+
};
|
|
920
|
+
const baseline = resolveSelection(body.baselineId);
|
|
921
|
+
const candidate = resolveSelection(body.candidateId);
|
|
922
|
+
if (missing.length > 0) {
|
|
923
|
+
return c.json(
|
|
924
|
+
{
|
|
925
|
+
ok: false,
|
|
926
|
+
error: {
|
|
927
|
+
code: "NOT_FOUND",
|
|
928
|
+
message: `Eval result(s) not found in history: ${missing.join(", ")}`
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
404
|
|
932
|
+
);
|
|
933
|
+
}
|
|
854
934
|
try {
|
|
855
|
-
const result = await runtime.evalCompare(
|
|
935
|
+
const result = await runtime.evalCompare(baseline, candidate, body.options);
|
|
856
936
|
return c.json({ ok: true, data: result });
|
|
857
937
|
} catch (err) {
|
|
858
938
|
const message = err instanceof Error ? err.message : String(err);
|
|
859
|
-
return c.json({ ok: false, error: { code: "
|
|
939
|
+
return c.json({ ok: false, error: { code: "COMPARE_FAILED", message } }, 400);
|
|
860
940
|
}
|
|
861
941
|
});
|
|
862
|
-
|
|
942
|
+
app6.post("/evals/import", async (c) => {
|
|
943
|
+
const runtime = c.get("runtime");
|
|
944
|
+
const body = await c.req.json();
|
|
945
|
+
const bad = (message) => c.json({ ok: false, error: { code: "BAD_REQUEST", message } }, 400);
|
|
946
|
+
if (!body.result || typeof body.result !== "object") {
|
|
947
|
+
return bad("result is required");
|
|
948
|
+
}
|
|
949
|
+
const result = body.result;
|
|
950
|
+
if (!Array.isArray(result.items)) {
|
|
951
|
+
return bad("result.items must be an array");
|
|
952
|
+
}
|
|
953
|
+
if (typeof result.summary !== "object" || result.summary == null) {
|
|
954
|
+
return bad("result.summary must be an object");
|
|
955
|
+
}
|
|
956
|
+
if (typeof result.dataset !== "string" || !result.dataset) {
|
|
957
|
+
return bad("result.dataset must be a non-empty string (required for compare)");
|
|
958
|
+
}
|
|
959
|
+
const summary = result.summary;
|
|
960
|
+
if (typeof summary.scorers !== "object" || summary.scorers == null) {
|
|
961
|
+
return bad("result.summary.scorers must be an object");
|
|
962
|
+
}
|
|
963
|
+
const summaryScorerNames = Object.keys(summary.scorers);
|
|
964
|
+
const items = result.items;
|
|
965
|
+
const summaryScorerSet = new Set(summaryScorerNames);
|
|
966
|
+
const uncoveredAcrossItems = /* @__PURE__ */ new Set();
|
|
967
|
+
for (const item of items) {
|
|
968
|
+
const itemScores = item?.scores;
|
|
969
|
+
if (itemScores && typeof itemScores === "object") {
|
|
970
|
+
for (const name of Object.keys(itemScores)) {
|
|
971
|
+
if (!summaryScorerSet.has(name)) uncoveredAcrossItems.add(name);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
if (uncoveredAcrossItems.size > 0) {
|
|
976
|
+
return bad(
|
|
977
|
+
`item scores reference scorer(s) not in summary.scorers: ${[...uncoveredAcrossItems].join(", ")}`
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
const trim = (v) => typeof v === "string" && v.trim() !== "" ? v.trim() : void 0;
|
|
981
|
+
const metadataObj = typeof result.metadata === "object" && result.metadata != null ? result.metadata : {};
|
|
982
|
+
const workflowsFromMeta = Array.isArray(metadataObj.workflows) ? metadataObj.workflows : [];
|
|
983
|
+
const primaryWorkflow = workflowsFromMeta.find((w) => typeof w === "string");
|
|
984
|
+
const evalName = trim(body.eval) ?? trim(primaryWorkflow) ?? // Legacy fallback: pre-0.14 CLI artifacts had workflow at the top level.
|
|
985
|
+
trim(result.workflow) ?? "imported";
|
|
986
|
+
const id = (0, import_node_crypto.randomUUID)();
|
|
987
|
+
const timestamp = Date.now();
|
|
988
|
+
const imported = {
|
|
989
|
+
...result,
|
|
990
|
+
id,
|
|
991
|
+
metadata: typeof result.metadata === "object" && result.metadata != null ? result.metadata : {}
|
|
992
|
+
};
|
|
993
|
+
await runtime.saveEvalResult({
|
|
994
|
+
id,
|
|
995
|
+
eval: evalName,
|
|
996
|
+
timestamp,
|
|
997
|
+
data: imported
|
|
998
|
+
});
|
|
999
|
+
return c.json({ ok: true, data: { id, eval: evalName, timestamp } });
|
|
1000
|
+
});
|
|
1001
|
+
return app6;
|
|
863
1002
|
}
|
|
864
1003
|
|
|
865
1004
|
// src/server/routes/playground.ts
|
|
866
1005
|
var import_hono11 = require("hono");
|
|
867
1006
|
function createPlaygroundRoutes(connMgr) {
|
|
868
|
-
const
|
|
869
|
-
|
|
1007
|
+
const app6 = new import_hono11.Hono();
|
|
1008
|
+
app6.post("/playground/chat", async (c) => {
|
|
870
1009
|
const runtime = c.get("runtime");
|
|
871
1010
|
const body = await c.req.json();
|
|
872
1011
|
if (!body.message || typeof body.message !== "string" || !body.message.trim()) {
|
|
@@ -928,42 +1067,45 @@ function createPlaygroundRoutes(connMgr) {
|
|
|
928
1067
|
data: { sessionId, executionId, streaming: true }
|
|
929
1068
|
});
|
|
930
1069
|
});
|
|
931
|
-
return
|
|
1070
|
+
return app6;
|
|
932
1071
|
}
|
|
933
1072
|
|
|
934
1073
|
// src/server/index.ts
|
|
935
1074
|
function createServer(options) {
|
|
936
1075
|
const { runtime, staticRoot, basePath = "", readOnly = false } = options;
|
|
937
|
-
const
|
|
1076
|
+
const app6 = new import_hono12.Hono();
|
|
938
1077
|
const connMgr = new ConnectionManager();
|
|
939
1078
|
const costAggregator = new CostAggregator(connMgr);
|
|
940
1079
|
if (options.cors !== false) {
|
|
941
|
-
|
|
1080
|
+
app6.use("*", (0, import_cors.cors)());
|
|
942
1081
|
}
|
|
943
|
-
|
|
944
|
-
|
|
1082
|
+
app6.use("*", errorHandler);
|
|
1083
|
+
app6.use("*", async (c, next) => {
|
|
945
1084
|
c.set("runtime", runtime);
|
|
946
1085
|
await next();
|
|
947
1086
|
});
|
|
948
1087
|
if (readOnly) {
|
|
949
1088
|
const blocked = [
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1089
|
+
/^POST \/api\/workflows(\/|$)/,
|
|
1090
|
+
/^POST \/api\/executions(\/|$)/,
|
|
1091
|
+
/^POST \/api\/sessions(\/|$)/,
|
|
1092
|
+
/^DELETE \/api\/sessions(\/|$)/,
|
|
1093
|
+
/^PUT \/api\/memory(\/|$)/,
|
|
1094
|
+
/^DELETE \/api\/memory(\/|$)/,
|
|
1095
|
+
/^POST \/api\/decisions(\/|$)/,
|
|
1096
|
+
/^POST \/api\/costs(\/|$)/,
|
|
1097
|
+
/^POST \/api\/tools(\/|$)/,
|
|
1098
|
+
/^POST \/api\/evals\/import$/,
|
|
1099
|
+
/^POST \/api\/evals\/[^/]+\/run$/,
|
|
1100
|
+
/^POST \/api\/evals\/[^/]+\/rescore$/,
|
|
1101
|
+
/^DELETE \/api\/evals\/history\/[^/]+$/,
|
|
1102
|
+
/^POST \/api\/playground(\/|$)/
|
|
961
1103
|
];
|
|
962
|
-
|
|
1104
|
+
app6.use("/api/*", async (c, next) => {
|
|
963
1105
|
const apiIdx = c.req.path.indexOf("/api/");
|
|
964
1106
|
const apiPath = apiIdx >= 0 ? c.req.path.slice(apiIdx) : c.req.path;
|
|
965
1107
|
const key = `${c.req.method} ${apiPath}`;
|
|
966
|
-
if (blocked.some((
|
|
1108
|
+
if (blocked.some((re) => re.test(key))) {
|
|
967
1109
|
return c.json(
|
|
968
1110
|
{
|
|
969
1111
|
ok: false,
|
|
@@ -976,7 +1118,7 @@ function createServer(options) {
|
|
|
976
1118
|
});
|
|
977
1119
|
}
|
|
978
1120
|
const api = new import_hono12.Hono();
|
|
979
|
-
api.route("/",
|
|
1121
|
+
api.route("/", createHealthRoutes(readOnly));
|
|
980
1122
|
api.route("/", createWorkflowRoutes(connMgr));
|
|
981
1123
|
api.route("/", executions_default);
|
|
982
1124
|
api.route("/", createSessionRoutes(connMgr));
|
|
@@ -987,7 +1129,7 @@ function createServer(options) {
|
|
|
987
1129
|
api.route("/", createCostRoutes(costAggregator));
|
|
988
1130
|
api.route("/", createEvalRoutes(options.evalLoader));
|
|
989
1131
|
api.route("/", createPlaygroundRoutes(connMgr));
|
|
990
|
-
|
|
1132
|
+
app6.route("/api", api);
|
|
991
1133
|
const traceListener = (event) => {
|
|
992
1134
|
const traceEvent = event;
|
|
993
1135
|
if (traceEvent.executionId) {
|
|
@@ -1028,7 +1170,7 @@ function createServer(options) {
|
|
|
1028
1170
|
root: staticRoot,
|
|
1029
1171
|
rewriteRequestPath: basePath ? (path) => path.startsWith(basePath) ? path.slice(basePath.length) || "/" : path : void 0
|
|
1030
1172
|
});
|
|
1031
|
-
|
|
1173
|
+
app6.use("/*", async (c, next) => {
|
|
1032
1174
|
const reqPath = c.req.path;
|
|
1033
1175
|
const resolved = basePath && reqPath.startsWith(basePath) ? reqPath.slice(basePath.length) || "/" : reqPath;
|
|
1034
1176
|
if (resolved === "/" || resolved === "/index.html" || resolved === "/ws") {
|
|
@@ -1037,7 +1179,7 @@ function createServer(options) {
|
|
|
1037
1179
|
return staticHandler(c, next);
|
|
1038
1180
|
});
|
|
1039
1181
|
if (spaHtml) {
|
|
1040
|
-
|
|
1182
|
+
app6.get("*", async (c, next) => {
|
|
1041
1183
|
const resolved = basePath && c.req.path.startsWith(basePath) ? c.req.path.slice(basePath.length) || "/" : c.req.path;
|
|
1042
1184
|
if (resolved === "/ws") return next();
|
|
1043
1185
|
return c.html(spaHtml);
|
|
@@ -1045,7 +1187,7 @@ function createServer(options) {
|
|
|
1045
1187
|
}
|
|
1046
1188
|
}
|
|
1047
1189
|
return {
|
|
1048
|
-
app:
|
|
1190
|
+
app: app6,
|
|
1049
1191
|
connMgr,
|
|
1050
1192
|
costAggregator,
|
|
1051
1193
|
/** Create WS handlers. Call before registering static/SPA routes are reached. */
|
|
@@ -1242,7 +1384,7 @@ function createStudioMiddleware(options) {
|
|
|
1242
1384
|
);
|
|
1243
1385
|
}
|
|
1244
1386
|
const evalLoader = options.evals ? createEvalLoader(options.evals, runtime) : void 0;
|
|
1245
|
-
const { app:
|
|
1387
|
+
const { app: app6, connMgr, traceListener } = createServer({
|
|
1246
1388
|
runtime,
|
|
1247
1389
|
staticRoot,
|
|
1248
1390
|
basePath,
|
|
@@ -1256,7 +1398,7 @@ function createStudioMiddleware(options) {
|
|
|
1256
1398
|
"[axl-studio] WARNING: Studio middleware mounted in production without verifyUpgrade. WebSocket connections are not authenticated. All registered workflows, tools, and agents are accessible. See https://axlsdk.com/docs/studio/security"
|
|
1257
1399
|
);
|
|
1258
1400
|
}
|
|
1259
|
-
const listener = (0, import_node_server.getRequestListener)(
|
|
1401
|
+
const listener = (0, import_node_server.getRequestListener)(app6.fetch, {
|
|
1260
1402
|
overrideGlobalObjects: false
|
|
1261
1403
|
});
|
|
1262
1404
|
let closed = false;
|
|
@@ -1271,6 +1413,13 @@ function createStudioMiddleware(options) {
|
|
|
1271
1413
|
);
|
|
1272
1414
|
return;
|
|
1273
1415
|
}
|
|
1416
|
+
const reqAny = req;
|
|
1417
|
+
if (reqAny.body != null && !reqAny.rawBody) {
|
|
1418
|
+
try {
|
|
1419
|
+
reqAny.rawBody = Buffer.from(JSON.stringify(reqAny.body));
|
|
1420
|
+
} catch {
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1274
1423
|
listener(req, res).catch((err) => {
|
|
1275
1424
|
console.error("[axl-studio] Unhandled error in request handler:", err);
|
|
1276
1425
|
if (!res.headersSent) {
|
|
@@ -1360,7 +1509,7 @@ function createStudioMiddleware(options) {
|
|
|
1360
1509
|
handler,
|
|
1361
1510
|
handleWebSocket,
|
|
1362
1511
|
upgradeWebSocket,
|
|
1363
|
-
app:
|
|
1512
|
+
app: app6,
|
|
1364
1513
|
connectionManager: connMgr,
|
|
1365
1514
|
close
|
|
1366
1515
|
};
|