@axlsdk/studio 0.19.0 → 0.20.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/dist/cli.cjs CHANGED
@@ -48,8 +48,7 @@ var SAFE_ERROR_NAMES = /* @__PURE__ */ new Set([
48
48
  "NoConsensus",
49
49
  "TimeoutError",
50
50
  "MaxTurnsError",
51
- "BudgetExceededError",
52
- "ToolDenied"
51
+ "BudgetExceededError"
53
52
  ]);
54
53
  function redactErrorMessage(err, redact) {
55
54
  const raw = err instanceof Error ? err.message : String(err);
@@ -117,7 +116,7 @@ function redactSessionHistory(history, redact) {
117
116
  }
118
117
  function redactStreamEvent(event, redact) {
119
118
  if (!redact) return event;
120
- return (0, import_axl.redactEvent)(event);
119
+ return (0, import_axl.redactHistoricalEvent)(event);
121
120
  }
122
121
  function redactEvalItem(item) {
123
122
  const scrubbed = {
@@ -180,31 +179,29 @@ function redactPendingDecisionList(decisions, redact) {
180
179
  }
181
180
 
182
181
  // src/server/middleware/error-handler.ts
183
- async function errorHandler(c, next) {
184
- try {
185
- await next();
186
- } catch (err) {
187
- const rawMessage = err instanceof Error ? err.message : String(err);
188
- const code = err.code ?? "INTERNAL_ERROR";
189
- let status = 500;
190
- if ("status" in err) {
191
- const errStatus = err.status;
192
- if (typeof errStatus === "number" && errStatus >= 400 && errStatus < 600) {
193
- status = errStatus;
194
- }
195
- } else if (code === "NOT_FOUND" || rawMessage.includes("not found") || rawMessage.includes("not registered")) {
196
- status = 404;
197
- } else if (code === "VALIDATION_ERROR" || rawMessage.includes("Expected") || rawMessage.includes("invalid")) {
198
- status = 400;
199
- }
200
- const runtime = c.get("runtime");
201
- const redactOn = runtime?.isRedactEnabled?.() ?? false;
202
- const body = {
203
- ok: false,
204
- error: { code, message: redactErrorMessage(err, redactOn) }
205
- };
206
- return c.json(body, status);
182
+ function errorHandler(err, c) {
183
+ const rawMessage = err.message;
184
+ const code = err.code ?? "INTERNAL_ERROR";
185
+ let status = 500;
186
+ if ("status" in err) {
187
+ const errStatus = err.status;
188
+ if (typeof errStatus === "number" && errStatus >= 400 && errStatus < 600) {
189
+ status = errStatus;
190
+ }
191
+ } else if (code === "CROSS_PROCESS_RESUME_UNSUPPORTED") {
192
+ status = 409;
193
+ } else if (code === "NOT_FOUND" || code === "PENDING_DECISION_NOT_FOUND" || rawMessage.includes("not found") || rawMessage.includes("not registered")) {
194
+ status = 404;
195
+ } else if (code === "VALIDATION_ERROR" || code === "INVALID_HUMAN_DECISION" || rawMessage.includes("Expected") || rawMessage.includes("invalid")) {
196
+ status = 400;
207
197
  }
198
+ const runtime = c.get("runtime");
199
+ const redactOn = runtime?.isRedactEnabled?.() ?? false;
200
+ const body = {
201
+ ok: false,
202
+ error: { code, message: redactErrorMessage(err, redactOn) }
203
+ };
204
+ return c.json(body, status);
208
205
  }
209
206
 
210
207
  // src/server/ws/connection-manager.ts
@@ -1120,19 +1117,58 @@ function reduceTraceStats(acc, event) {
1120
1117
  const eventTypeCounts = { ...acc.eventTypeCounts };
1121
1118
  eventTypeCounts[event.type] = (eventTypeCounts[event.type] ?? 0) + 1;
1122
1119
  const byTool = { ...acc.byTool };
1123
- if (event.type === "tool_call_end" || event.type === "tool_denied" || event.type === "tool_approval") {
1120
+ if (event.type === "tool_call_start" || event.type === "tool_call_end" || event.type === "tool_call_rejected" || event.type === "tool_denied" || event.type === "tool_approval") {
1124
1121
  const toolName = event.tool;
1125
- const prev = byTool[toolName] ?? { calls: 0, denied: 0, approved: 0 };
1126
- const isDeniedEvent = event.type === "tool_denied";
1127
- const isApprovalEvent = event.type === "tool_approval";
1128
- const eventData = isDeniedEvent || isApprovalEvent ? event.data : void 0;
1129
- const isApproved = isDeniedEvent && eventData?.approved === true || isApprovalEvent && eventData?.approved === true;
1130
- const isDenied = isDeniedEvent && !eventData?.approved || isApprovalEvent && eventData?.approved === false;
1131
- byTool[toolName] = {
1132
- calls: prev.calls + (event.type === "tool_call_end" ? 1 : 0),
1133
- denied: prev.denied + (isDenied ? 1 : 0),
1134
- approved: prev.approved + (isApproved ? 1 : 0)
1122
+ const prev = byTool[toolName] ?? {
1123
+ accepted: 0,
1124
+ succeeded: 0,
1125
+ failed: 0,
1126
+ failedByPhase: {},
1127
+ denied: 0,
1128
+ cancelled: 0,
1129
+ rejected: 0,
1130
+ approved: 0,
1131
+ legacy: { calls: 0, denied: 0, approved: 0 }
1132
+ };
1133
+ const next = {
1134
+ ...prev,
1135
+ failedByPhase: { ...prev.failedByPhase },
1136
+ legacy: { ...prev.legacy }
1135
1137
  };
1138
+ if (event.schemaVersion === 2) {
1139
+ if (event.type === "tool_call_start") next.accepted++;
1140
+ if (event.type === "tool_call_rejected") next.rejected++;
1141
+ if (event.type === "tool_approval" && event.data?.approved) next.approved++;
1142
+ if (event.type === "tool_call_end") {
1143
+ switch (event.data.outcome.status) {
1144
+ case "succeeded":
1145
+ next.succeeded++;
1146
+ break;
1147
+ case "failed": {
1148
+ next.failed++;
1149
+ const phase = event.data.outcome.failure.phase;
1150
+ next.failedByPhase[phase] = (next.failedByPhase[phase] ?? 0) + 1;
1151
+ break;
1152
+ }
1153
+ case "denied":
1154
+ next.denied++;
1155
+ break;
1156
+ case "cancelled":
1157
+ next.cancelled++;
1158
+ break;
1159
+ }
1160
+ }
1161
+ } else if (event.type === "tool_call_end") {
1162
+ next.legacy.calls++;
1163
+ } else if (event.type === "tool_denied") {
1164
+ const approved = event.data?.approved === true;
1165
+ if (approved) next.legacy.approved++;
1166
+ else next.legacy.denied++;
1167
+ } else if (event.type === "tool_approval") {
1168
+ if (event.data?.approved === true) next.legacy.approved++;
1169
+ else if (event.data?.approved === false) next.legacy.denied++;
1170
+ }
1171
+ byTool[toolName] = next;
1136
1172
  }
1137
1173
  const retryByAgent = { ...acc.retryByAgent };
1138
1174
  if (event.agent && event.type === "agent_call_end") {
@@ -1612,7 +1648,14 @@ app4.get("/decisions", async (c) => {
1612
1648
  app4.post("/decisions/:executionId/resolve", async (c) => {
1613
1649
  const runtime = c.get("runtime");
1614
1650
  const executionId = c.req.param("executionId");
1615
- const body = await c.req.json();
1651
+ let body;
1652
+ try {
1653
+ body = await c.req.json();
1654
+ } catch {
1655
+ const error48 = new Error("Invalid JSON request body");
1656
+ Object.assign(error48, { code: "INVALID_HUMAN_DECISION", status: 400 });
1657
+ throw error48;
1658
+ }
1616
1659
  await runtime.resolveDecision(executionId, body);
1617
1660
  return c.json({ ok: true, data: { resolved: true } });
1618
1661
  });
@@ -15952,6 +15995,7 @@ function createPlaygroundRoutes(connMgr) {
15952
15995
  (async () => {
15953
15996
  let stepCounter = Number.MAX_SAFE_INTEGER - 1;
15954
15997
  const terminalFields = () => ({
15998
+ schemaVersion: 2,
15955
15999
  executionId,
15956
16000
  step: stepCounter++,
15957
16001
  timestamp: Date.now()
@@ -16068,7 +16112,7 @@ function createServer(options) {
16068
16112
  if (options.cors !== false) {
16069
16113
  app5.use("*", (0, import_cors.cors)());
16070
16114
  }
16071
- app5.use("*", errorHandler);
16115
+ app5.onError(errorHandler);
16072
16116
  app5.use("*", async (c, next) => {
16073
16117
  c.set("runtime", runtime);
16074
16118
  await next();