@anvia/studio 0.5.1 → 0.5.2

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 CHANGED
@@ -161,6 +161,7 @@ type StudioTranscriptChatEntry = {
161
161
  kind: "message";
162
162
  role: "user" | "assistant";
163
163
  text: string;
164
+ tone?: "error";
164
165
  traceId?: string;
165
166
  };
166
167
  type StudioTranscriptReasoningEntry = {
package/dist/index.js CHANGED
@@ -3440,8 +3440,62 @@ function sessionUserId(session) {
3440
3440
  return typeof userId === "string" && userId.trim().length > 0 ? userId : DEFAULT_USER_ID;
3441
3441
  }
3442
3442
 
3443
+ // src/runtime/streams.ts
3444
+ import { createEventStream } from "@anvia/server";
3445
+ var studioJsonlHeaders = {
3446
+ "cache-control": "no-cache, no-transform",
3447
+ connection: "keep-alive",
3448
+ "content-type": "application/x-ndjson; charset=utf-8",
3449
+ "transfer-encoding": "chunked",
3450
+ "x-accel-buffering": "no"
3451
+ };
3452
+ function streamStudioJsonl(events) {
3453
+ return createEventStream(withStudioStreamErrors(events), {
3454
+ format: "jsonl",
3455
+ headers: studioJsonlHeaders
3456
+ });
3457
+ }
3458
+ function withStudioStreamErrors(events) {
3459
+ const iterator = events[Symbol.asyncIterator]();
3460
+ let done = false;
3461
+ return {
3462
+ [Symbol.asyncIterator]() {
3463
+ return {
3464
+ async next() {
3465
+ if (done) {
3466
+ return { done: true, value: void 0 };
3467
+ }
3468
+ try {
3469
+ const next = await iterator.next();
3470
+ if (next.done === true) {
3471
+ done = true;
3472
+ }
3473
+ return next;
3474
+ } catch (error) {
3475
+ done = true;
3476
+ return {
3477
+ done: false,
3478
+ value: studioStreamError(error)
3479
+ };
3480
+ }
3481
+ },
3482
+ async return() {
3483
+ done = true;
3484
+ await iterator.return?.();
3485
+ return { done: true, value: void 0 };
3486
+ }
3487
+ };
3488
+ }
3489
+ };
3490
+ }
3491
+ function studioStreamError(error) {
3492
+ return {
3493
+ type: "error",
3494
+ error: serializeError2(error)
3495
+ };
3496
+ }
3497
+
3443
3498
  // src/runtime/observability.ts
3444
- import { stream as streamResponse } from "hono/streaming";
3445
3499
  var defaultBufferSize = 1e3;
3446
3500
  var StudioObservabilityHub = class {
3447
3501
  subscriptions = /* @__PURE__ */ new Set();
@@ -3485,28 +3539,23 @@ function registerObservabilityRoutes(app, hub) {
3485
3539
  400
3486
3540
  );
3487
3541
  }
3488
- c.header("content-type", "application/x-ndjson; charset=utf-8");
3489
- c.header("cache-control", "no-cache, no-transform");
3490
- c.header("connection", "keep-alive");
3491
- c.header("transfer-encoding", "chunked");
3492
- c.header("x-accel-buffering", "no");
3493
- return streamResponse(c, async (stream) => {
3494
- const subscription = hub.subscribe(types === void 0 ? {} : { types });
3495
- try {
3496
- while (true) {
3497
- const next = await subscription.next();
3498
- if (next.done === true) {
3499
- break;
3500
- }
3501
- await stream.write(`${JSON.stringify(next.value)}
3502
- `);
3503
- }
3504
- } finally {
3505
- subscription.close();
3506
- }
3507
- });
3542
+ return streamStudioJsonl(observabilityEvents(hub, types));
3508
3543
  });
3509
3544
  }
3545
+ function observabilityEvents(hub, types) {
3546
+ const subscription = hub.subscribe(types === void 0 ? {} : { types });
3547
+ return {
3548
+ [Symbol.asyncIterator]() {
3549
+ return {
3550
+ next: () => subscription.next(),
3551
+ async return() {
3552
+ subscription.close();
3553
+ return { done: true, value: void 0 };
3554
+ }
3555
+ };
3556
+ }
3557
+ };
3558
+ }
3510
3559
  function createSubscription(types) {
3511
3560
  const values = [];
3512
3561
  const resolvers = [];
@@ -3630,9 +3679,6 @@ function traceSummary2(trace) {
3630
3679
  };
3631
3680
  }
3632
3681
 
3633
- // src/runtime/pipelines.ts
3634
- import { stream as streamResponse3 } from "hono/streaming";
3635
-
3636
3682
  // src/runtime/pipeline-logs.ts
3637
3683
  async function appendPipelineLog(store, input) {
3638
3684
  return store?.appendPipelineLog(input);
@@ -3781,7 +3827,6 @@ function formatUnknown(value) {
3781
3827
  }
3782
3828
 
3783
3829
  // src/runtime/runs.ts
3784
- import { stream as streamResponse2 } from "hono/streaming";
3785
3830
  var AsyncEventQueue = class {
3786
3831
  values = [];
3787
3832
  resolvers = [];
@@ -3854,25 +3899,8 @@ async function* mergeRunAndApprovalEvents(runEvents, approvalEvents) {
3854
3899
  approvalEvents.close();
3855
3900
  }
3856
3901
  }
3857
- function streamAgentRunEvents(c, events) {
3858
- c.header("content-type", "application/x-ndjson; charset=utf-8");
3859
- c.header("cache-control", "no-cache, no-transform");
3860
- c.header("connection", "keep-alive");
3861
- c.header("transfer-encoding", "chunked");
3862
- c.header("x-accel-buffering", "no");
3863
- return streamResponse2(
3864
- c,
3865
- async (stream) => {
3866
- for await (const event of events) {
3867
- await stream.write(`${JSON.stringify(event)}
3868
- `);
3869
- }
3870
- },
3871
- async (error, stream) => {
3872
- await stream.write(`${JSON.stringify({ type: "error", error: serializeError2(error) })}
3873
- `);
3874
- }
3875
- );
3902
+ function streamAgentRunEvents(_c, events) {
3903
+ return streamStudioJsonl(events);
3876
3904
  }
3877
3905
  function traceForRun(trace, agentId, session) {
3878
3906
  const metadata = {
@@ -3912,6 +3940,7 @@ async function* persistStreamingSessionTranscript(props) {
3912
3940
  yield event;
3913
3941
  }
3914
3942
  } catch (error) {
3943
+ appendTranscriptAssistantError(transcript, errorText(error));
3915
3944
  await props.store.saveSessionRunTranscript({
3916
3945
  id: props.session.id,
3917
3946
  runId: props.runId,
@@ -4040,6 +4069,9 @@ function acceptTranscriptStreamEvent(transcript, event) {
4040
4069
  if (event.type === "final" && event.trace?.traceId !== void 0) {
4041
4070
  assignTranscriptTraceId(transcript, event.trace.traceId);
4042
4071
  }
4072
+ if (event.type === "error") {
4073
+ appendTranscriptAssistantError(transcript, errorText(event.error));
4074
+ }
4043
4075
  }
4044
4076
  function approvalCallId(approval) {
4045
4077
  return approval.callId ?? approval.toolCallId;
@@ -4134,9 +4166,6 @@ function childAgentTranscriptEvent(event) {
4134
4166
  return void 0;
4135
4167
  }
4136
4168
  function errorText(error) {
4137
- if (error instanceof Error) {
4138
- return error.message;
4139
- }
4140
4169
  if (typeof error === "string") {
4141
4170
  return error;
4142
4171
  }
@@ -4217,7 +4246,7 @@ function messageToTranscriptEntry(message, entryId) {
4217
4246
  }
4218
4247
  function appendTranscriptAssistantText(transcript, delta) {
4219
4248
  const last = transcript.at(-1);
4220
- if (last?.kind === "message" && last.role === "assistant") {
4249
+ if (last?.kind === "message" && last.role === "assistant" && last.tone !== "error") {
4221
4250
  last.text = `${last.text}${delta}`;
4222
4251
  return;
4223
4252
  }
@@ -4228,6 +4257,19 @@ function appendTranscriptAssistantText(transcript, delta) {
4228
4257
  text: delta
4229
4258
  });
4230
4259
  }
4260
+ function appendTranscriptAssistantError(transcript, text) {
4261
+ const last = transcript.at(-1);
4262
+ if (last?.kind === "message" && last.role === "assistant" && last.tone === "error" && last.text === text) {
4263
+ return;
4264
+ }
4265
+ transcript.push({
4266
+ entryId: transcript.length,
4267
+ kind: "message",
4268
+ role: "assistant",
4269
+ text,
4270
+ tone: "error"
4271
+ });
4272
+ }
4231
4273
  function assignTranscriptTraceId(transcript, traceId) {
4232
4274
  for (let index = transcript.length - 1; index >= 0; index -= 1) {
4233
4275
  const entry = transcript[index];
@@ -4592,25 +4634,8 @@ function pipelineDetail(pipeline) {
4592
4634
  graph
4593
4635
  };
4594
4636
  }
4595
- function streamPipelineRun(c, props) {
4596
- c.header("content-type", "application/x-ndjson; charset=utf-8");
4597
- c.header("cache-control", "no-cache, no-transform");
4598
- c.header("connection", "keep-alive");
4599
- c.header("transfer-encoding", "chunked");
4600
- c.header("x-accel-buffering", "no");
4601
- return streamResponse3(
4602
- c,
4603
- async (stream) => {
4604
- for await (const event of pipelineRunEvents(props)) {
4605
- await stream.write(`${JSON.stringify(event)}
4606
- `);
4607
- }
4608
- },
4609
- async (error, stream) => {
4610
- await stream.write(`${JSON.stringify({ type: "error", error: serializeError2(error) })}
4611
- `);
4612
- }
4613
- );
4637
+ function streamPipelineRun(_c, props) {
4638
+ return streamStudioJsonl(pipelineRunEvents(props));
4614
4639
  }
4615
4640
  async function* pipelineRunEvents(props) {
4616
4641
  yield* emitPipelineLog(props.logStore, pipelineRunStartedLog(props.pipeline, props.runId));