@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.
@@ -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-C_uwupnn.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-DVcH6P9w.css">
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>
@@ -340,27 +340,30 @@ var CostAggregator = class {
340
340
 
341
341
  // src/server/routes/health.ts
342
342
  var import_hono = require("hono");
343
- var app = new import_hono.Hono();
344
- app.get("/health", (c) => {
345
- const runtime = c.get("runtime");
346
- return c.json({
347
- ok: true,
348
- data: {
349
- status: "healthy",
350
- workflows: runtime.getWorkflowNames().length,
351
- agents: runtime.getAgents().length,
352
- tools: runtime.getTools().length
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
- var health_default = app;
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 app7 = new import_hono2.Hono();
363
- app7.get("/workflows", (c) => {
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
- app7.get("/workflows/:name", (c) => {
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
- app7.post("/workflows/:name/execute", async (c) => {
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 app7;
418
+ return app6;
416
419
  }
417
420
 
418
421
  // src/server/routes/executions.ts
419
422
  var import_hono3 = require("hono");
420
- var app2 = new import_hono3.Hono();
421
- app2.get("/executions", async (c) => {
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
- app2.get("/executions/:id", async (c) => {
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
- app2.post("/executions/:id/abort", (c) => {
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 = app2;
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 app7 = new import_hono4.Hono();
450
- app7.get("/sessions", async (c) => {
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
- app7.get("/sessions/:id", async (c) => {
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
- app7.post("/sessions/:id/send", async (c) => {
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
- app7.post("/sessions/:id/stream", async (c) => {
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
- app7.delete("/sessions/:id", async (c) => {
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 app7;
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 app3 = new import_hono5.Hono();
508
- app3.get("/agents", (c) => {
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
- app3.get("/agents/:name", (c) => {
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 = app3;
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 app4 = new import_hono6.Hono();
589
- app4.get("/tools", (c) => {
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
- app4.get("/tools/:name", (c) => {
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
- app4.post("/tools/:name/test", async (c) => {
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 = app4;
645
+ var tools_default = app3;
643
646
 
644
647
  // src/server/routes/memory.ts
645
648
  var import_hono7 = require("hono");
646
- var app5 = new import_hono7.Hono();
647
- app5.get("/memory/:scope", async (c) => {
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
- app5.get("/memory/:scope/:key", async (c) => {
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
- app5.put("/memory/:scope/:key", async (c) => {
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
- app5.delete("/memory/:scope/:key", async (c) => {
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
- app5.post("/memory/search", async (c) => {
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 = app5;
715
+ var memory_default = app4;
713
716
 
714
717
  // src/server/routes/decisions.ts
715
718
  var import_hono8 = require("hono");
716
- var app6 = new import_hono8.Hono();
717
- app6.get("/decisions", async (c) => {
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
- app6.post("/decisions/:executionId/resolve", async (c) => {
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 = app6;
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 app7 = new import_hono9.Hono();
735
- app7.get("/costs", (c) => {
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
- app7.post("/costs/reset", (c) => {
741
+ app6.post("/costs/reset", (c) => {
739
742
  costAggregator.reset();
740
743
  return c.json({ ok: true, data: { reset: true } });
741
744
  });
742
- return app7;
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 app7 = new import_hono10.Hono();
749
- app7.get("/evals", async (c) => {
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
- app7.get("/evals/history", async (c) => {
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
- app7.post("/evals/:name/run", async (c) => {
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
- app7.post("/evals/:name/rescore", async (c) => {
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
- app7.post("/evals/compare", async (c) => {
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(body.baseline, body.candidate, body.options);
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: "EVAL_ERROR", message } }, 400);
939
+ return c.json({ ok: false, error: { code: "COMPARE_FAILED", message } }, 400);
860
940
  }
861
941
  });
862
- return app7;
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 app7 = new import_hono11.Hono();
869
- app7.post("/playground/chat", async (c) => {
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 app7;
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 app7 = new import_hono12.Hono();
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
- app7.use("*", (0, import_cors.cors)());
1080
+ app6.use("*", (0, import_cors.cors)());
942
1081
  }
943
- app7.use("*", errorHandler);
944
- app7.use("*", async (c, next) => {
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
- "POST /api/workflows",
951
- "POST /api/executions",
952
- "POST /api/sessions",
953
- "DELETE /api/sessions",
954
- "PUT /api/memory",
955
- "DELETE /api/memory",
956
- "POST /api/decisions",
957
- "POST /api/costs",
958
- "POST /api/tools",
959
- "POST /api/evals",
960
- "POST /api/playground"
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
- app7.use("/api/*", async (c, next) => {
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((b) => key.startsWith(b))) {
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("/", health_default);
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
- app7.route("/api", api);
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
- app7.use("/*", async (c, next) => {
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
- app7.get("*", async (c, next) => {
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: app7,
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: app7, connMgr, traceListener } = createServer({
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)(app7.fetch, {
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: app7,
1512
+ app: app6,
1364
1513
  connectionManager: connMgr,
1365
1514
  close
1366
1515
  };