@tanstack/ai-devtools-core 0.5.16 → 0.5.18

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.
@@ -6512,6 +6512,9 @@ var AIProvider = (props) => {
6512
6512
  }
6513
6513
  const newIteration = {
6514
6514
  requestId,
6515
+ ...e.payload.runId ? {
6516
+ runId: e.payload.runId
6517
+ } : {},
6515
6518
  index: iteration,
6516
6519
  messageId,
6517
6520
  startedAt: e.payload.timestamp,
@@ -7571,6 +7574,241 @@ var formatDuration = (ms) => {
7571
7574
  if (ms < 1e3) return `${ms}ms`;
7572
7575
  return `${(ms / 1e3).toFixed(2)}s`;
7573
7576
  };
7577
+
7578
+ // src/store/subagent-steps.ts
7579
+ function isRecord(value) {
7580
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
7581
+ }
7582
+ function text(value) {
7583
+ return typeof value === "string" ? value : "";
7584
+ }
7585
+ function collectSubagents(messages) {
7586
+ const out = [];
7587
+ let turn = -1;
7588
+ const visit = (list, parentPath, parentTurn) => {
7589
+ for (const message of list) {
7590
+ if (!isRecord(message)) continue;
7591
+ if (parentTurn === void 0 && message.role === "user") turn += 1;
7592
+ if (!Array.isArray(message.parts)) continue;
7593
+ for (const part of message.parts) {
7594
+ if (!isRecord(part) || part.type !== "subagent") continue;
7595
+ const subagent = part.subagent;
7596
+ if (!isRecord(subagent) || typeof subagent.id !== "string") continue;
7597
+ const name = text(subagent.name) || "subagent";
7598
+ const path = parentPath ? `${parentPath} > ${name}` : name;
7599
+ const error = isRecord(subagent.error) ? text(subagent.error.message) : "";
7600
+ const childMessages = Array.isArray(subagent.messages) ? subagent.messages : [];
7601
+ const info = {
7602
+ id: subagent.id,
7603
+ name,
7604
+ path,
7605
+ ...typeof subagent.status === "string" ? { status: subagent.status } : {},
7606
+ ...error ? { error } : {},
7607
+ turn: parentTurn ?? Math.max(turn, 0),
7608
+ messages: childMessages
7609
+ };
7610
+ out.push(info);
7611
+ visit(childMessages, path, info.turn);
7612
+ }
7613
+ }
7614
+ };
7615
+ visit(messages, void 0, void 0);
7616
+ return out;
7617
+ }
7618
+ function subagentIdForRunId(runId, ids) {
7619
+ if (!runId) return void 0;
7620
+ if (ids.has(runId)) return runId;
7621
+ const last = runId.slice(runId.lastIndexOf(":") + 1);
7622
+ return last !== runId && ids.has(last) ? last : void 0;
7623
+ }
7624
+ function childRequestAgents(iterations, subagents) {
7625
+ const ids = new Set(subagents.map((agent) => agent.id));
7626
+ const pathById = new Map(subagents.map((agent) => [agent.id, agent.path]));
7627
+ const out = /* @__PURE__ */ new Map();
7628
+ for (const iteration of iterations) {
7629
+ const id = subagentIdForRunId(iteration.runId, ids);
7630
+ const path = id ? pathById.get(id) : void 0;
7631
+ if (path && iteration.requestId) out.set(iteration.requestId, path);
7632
+ }
7633
+ return out;
7634
+ }
7635
+ function collectServerSteps(root, conversations, subagents) {
7636
+ const ids = new Set(subagents.map((agent) => agent.id));
7637
+ const iterations = [...root?.iterations ?? []];
7638
+ const messages = [...root?.messages ?? []];
7639
+ const seenSteps = new Set(
7640
+ iterations.map((iteration) => `${iteration.requestId}:${iteration.index}`)
7641
+ );
7642
+ const seenMessages = new Set(messages.map((message) => message.id));
7643
+ for (const conversation of conversations) {
7644
+ if (conversation === root) continue;
7645
+ const child = conversation.iterations.filter(
7646
+ (iteration) => subagentIdForRunId(iteration.runId, ids)
7647
+ );
7648
+ if (child.length === 0) continue;
7649
+ for (const iteration of child) {
7650
+ const key = `${iteration.requestId}:${iteration.index}`;
7651
+ if (seenSteps.has(key)) continue;
7652
+ seenSteps.add(key);
7653
+ iterations.push(iteration);
7654
+ }
7655
+ for (const message of conversation.messages) {
7656
+ if (seenMessages.has(message.id)) continue;
7657
+ seenMessages.add(message.id);
7658
+ messages.push(message);
7659
+ }
7660
+ }
7661
+ return { iterations, messages };
7662
+ }
7663
+ function timestampOf(value) {
7664
+ if (value instanceof Date) return value.getTime();
7665
+ if (typeof value !== "string" && typeof value !== "number") return void 0;
7666
+ const time = new Date(value).getTime();
7667
+ return Number.isNaN(time) ? void 0 : time;
7668
+ }
7669
+ function snapshotTurns(messages) {
7670
+ const turns = [];
7671
+ for (const message of messages) {
7672
+ if (!isRecord(message) || message.role !== "user") continue;
7673
+ const timestamp = timestampOf(message.createdAt);
7674
+ if (timestamp === void 0 || typeof message.id !== "string") return [];
7675
+ const content = Array.isArray(message.parts) ? message.parts.map(
7676
+ (part) => isRecord(part) && part.type === "text" ? text(part.content) : ""
7677
+ ).join("") : text(message.content);
7678
+ turns.push({ id: message.id, role: "user", content, timestamp });
7679
+ }
7680
+ return turns;
7681
+ }
7682
+ function groupTimeline(iterations, messages, subagents, turns = []) {
7683
+ const ids = new Set(subagents.map((agent) => agent.id));
7684
+ const childRequests = childRequestAgents(iterations, subagents);
7685
+ const rootIterations = iterations.filter(
7686
+ (iteration) => !subagentIdForRunId(iteration.runId, ids)
7687
+ );
7688
+ const agents = subagents.map((agent) => {
7689
+ const server = iterations.filter(
7690
+ (iteration) => subagentIdForRunId(iteration.runId, ids) === agent.id
7691
+ );
7692
+ return server.length > 0 ? { agent, iterations: server, messages, source: "server" } : { agent, ...buildSubagentSteps(agent), source: "snapshot" };
7693
+ });
7694
+ const users = (turns.length > 0 ? [...turns] : messages.filter(
7695
+ (message) => message.role === "user" && !(message.requestId && childRequests.has(message.requestId))
7696
+ )).sort((a, b) => a.timestamp - b.timestamp);
7697
+ if (users.length === 0) {
7698
+ return rootIterations.length > 0 || agents.length > 0 ? [{ userMessage: null, iterations: rootIterations, agents }] : [];
7699
+ }
7700
+ const groups = [];
7701
+ const first = users[0];
7702
+ const early = first ? rootIterations.filter(
7703
+ (iteration) => iteration.startedAt < first.timestamp
7704
+ ) : [];
7705
+ if (early.length > 0) {
7706
+ groups.push({ userMessage: null, iterations: early, agents: [] });
7707
+ }
7708
+ users.forEach((user, turn) => {
7709
+ const next = users[turn + 1];
7710
+ const own = rootIterations.filter(
7711
+ (iteration) => iteration.startedAt >= user.timestamp && (!next || iteration.startedAt < next.timestamp)
7712
+ );
7713
+ const isLast = turn === users.length - 1;
7714
+ const ownAgents = agents.filter(
7715
+ (group) => isLast ? group.agent.turn >= turn : group.agent.turn === turn
7716
+ );
7717
+ if (own.length > 0 || ownAgents.length > 0) {
7718
+ groups.push({ userMessage: user, iterations: own, agents: ownAgents });
7719
+ }
7720
+ });
7721
+ return groups;
7722
+ }
7723
+ function resultText(value) {
7724
+ if (typeof value === "string") return value;
7725
+ if (value === void 0) return "";
7726
+ try {
7727
+ return JSON.stringify(value);
7728
+ } catch {
7729
+ return String(value);
7730
+ }
7731
+ }
7732
+ function buildSubagentSteps(agent) {
7733
+ const iterations = [];
7734
+ const messages = [];
7735
+ let current;
7736
+ const close = () => {
7737
+ if (!current) return;
7738
+ const index = iterations.length;
7739
+ const { message, results } = current;
7740
+ const hasContent = message.content || message.thinkingContent || (message.toolCalls?.length ?? 0) > 0 || results.length > 0;
7741
+ if (hasContent) {
7742
+ messages.push(message, ...results);
7743
+ iterations.push({
7744
+ requestId: `subagent:${agent.id}`,
7745
+ index,
7746
+ messageId: message.id,
7747
+ // ponytail: the snapshot has no timestamps, so steps have no duration.
7748
+ startedAt: 1,
7749
+ completedAt: 1,
7750
+ finishReason: (message.toolCalls?.length ?? 0) > 0 ? "tool_calls" : "stop",
7751
+ middlewareEvents: [],
7752
+ messageIds: [message.id, ...results.map((result) => result.id)]
7753
+ });
7754
+ }
7755
+ current = void 0;
7756
+ };
7757
+ const open = () => {
7758
+ const index = iterations.length;
7759
+ current = {
7760
+ message: {
7761
+ id: `${agent.id}:step-${index}`,
7762
+ role: "assistant",
7763
+ content: "",
7764
+ timestamp: 1,
7765
+ toolCalls: []
7766
+ },
7767
+ results: [],
7768
+ hasResult: false
7769
+ };
7770
+ return current;
7771
+ };
7772
+ for (const message of agent.messages) {
7773
+ if (!isRecord(message) || message.role !== "assistant") continue;
7774
+ if (!Array.isArray(message.parts)) continue;
7775
+ for (const part of message.parts) {
7776
+ if (!isRecord(part)) continue;
7777
+ const step = part.type === "tool-result" ? current ?? open() : current && !current.hasResult ? current : (close(), open());
7778
+ if (part.type === "thinking") {
7779
+ step.message.thinkingContent = (step.message.thinkingContent ?? "") + text(part.content);
7780
+ } else if (part.type === "text") {
7781
+ step.message.content += text(part.content);
7782
+ } else if (part.type === "tool-call") {
7783
+ const toolCall = {
7784
+ id: text(part.id),
7785
+ name: text(part.name) || "tool",
7786
+ arguments: text(part.arguments),
7787
+ state: text(part.state),
7788
+ ...part.output !== void 0 ? { result: part.output } : {}
7789
+ };
7790
+ step.message.toolCalls?.push(toolCall);
7791
+ } else if (part.type === "tool-result") {
7792
+ const toolCallId = text(part.toolCallId);
7793
+ const content = resultText(part.content ?? part.error);
7794
+ const call = step.message.toolCalls?.find((tc) => tc.id === toolCallId);
7795
+ if (call && call.result === void 0) call.result = content;
7796
+ step.results.push({
7797
+ id: `${agent.id}:result-${toolCallId || step.results.length}`,
7798
+ role: "tool",
7799
+ content,
7800
+ timestamp: 1
7801
+ });
7802
+ step.hasResult = true;
7803
+ }
7804
+ }
7805
+ }
7806
+ close();
7807
+ const last = iterations.at(-1);
7808
+ if (last && agent.status === "running") delete last.completedAt;
7809
+ if (last && agent.status === "error") last.finishReason = "error";
7810
+ return { iterations, messages };
7811
+ }
7574
7812
  var _tmpl$10 = /* @__PURE__ */ template(`<span>ms`);
7575
7813
  var _tmpl$22 = /* @__PURE__ */ template(`<span>`);
7576
7814
  var _tmpl$32 = /* @__PURE__ */ template(`<div><span>Middleware</span><span></span><span>`);
@@ -7935,9 +8173,9 @@ var AssistantStep = (props) => {
7935
8173
  const contentLength = () => (msg().content || "").length;
7936
8174
  const isLong = () => contentLength() > 200;
7937
8175
  const preview = () => {
7938
- const text = msg().content || "";
7939
- if (text.length <= 200) return text;
7940
- return truncate(text, 200);
8176
+ const text2 = msg().content || "";
8177
+ if (text2.length <= 200) return text2;
8178
+ return truncate(text2, 200);
7941
8179
  };
7942
8180
  return [(() => {
7943
8181
  var _el$22 = _tmpl$92(), _el$23 = _el$22.firstChild, _el$24 = _el$23.nextSibling;
@@ -8172,8 +8410,8 @@ var ToolResultStep = (props) => {
8172
8410
  const [isOpen, setIsOpen] = createSignal(false);
8173
8411
  const msg = () => props.step.message;
8174
8412
  const parsedContent = () => {
8175
- const text = msg().content || "";
8176
- return tryParseJson(text) || text;
8413
+ const text2 = msg().content || "";
8414
+ return tryParseJson(text2) || text2;
8177
8415
  };
8178
8416
  return [(() => {
8179
8417
  var _el$46 = _tmpl$11(), _el$47 = _el$46.firstChild, _el$48 = _el$47.nextSibling;
@@ -8853,46 +9091,11 @@ var _tmpl$142 = /* @__PURE__ */ template(`<div><span>Model Options</span><div>`)
8853
9091
  var _tmpl$152 = /* @__PURE__ */ template(`<div><div><div>U</div><div><span></span><div></div></div><div></div><span>\u25B6</span></div><div><div><div></div></div></div><div><div><div>`);
8854
9092
  var _tmpl$162 = /* @__PURE__ */ template(`<span>\u{1F3AF} `);
8855
9093
  var _tmpl$172 = /* @__PURE__ */ template(`<span><span>`);
9094
+ var _tmpl$182 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-subagent-steps style=margin-top:8px><div role=button tabindex=0><div></div><div><span></span><div><span>subagent</span></div></div><div><span>\u{1F504} </span></div><span>\u25B6</span></div><div><div><div>`);
8856
9095
  var IterationTimeline = (props) => {
8857
9096
  const styles = useStyles();
8858
9097
  const s = () => styles().iterationTimeline;
8859
- const groups = createMemo(() => {
8860
- const userMessages = props.messages.filter((m) => m.role === "user");
8861
- const iters = props.iterations;
8862
- if (userMessages.length === 0) {
8863
- return iters.length > 0 ? [{
8864
- userMessage: null,
8865
- iterations: iters
8866
- }] : [];
8867
- }
8868
- const result = [];
8869
- const sortedUsers = [...userMessages].sort((a, b) => a.timestamp - b.timestamp);
8870
- for (const [u, currentUser] of sortedUsers.entries()) {
8871
- const nextUser = sortedUsers[u + 1];
8872
- const groupIters = iters.filter((it) => {
8873
- if (it.startedAt < currentUser.timestamp) return false;
8874
- if (nextUser && it.startedAt >= nextUser.timestamp) return false;
8875
- return true;
8876
- });
8877
- if (groupIters.length > 0) {
8878
- result.push({
8879
- userMessage: currentUser,
8880
- iterations: groupIters
8881
- });
8882
- }
8883
- }
8884
- const firstUser = sortedUsers[0];
8885
- if (firstUser) {
8886
- const earlyIters = iters.filter((it) => it.startedAt < firstUser.timestamp);
8887
- if (earlyIters.length > 0) {
8888
- result.unshift({
8889
- userMessage: null,
8890
- iterations: earlyIters
8891
- });
8892
- }
8893
- }
8894
- return result;
8895
- });
9098
+ const groups = createMemo(() => groupTimeline(props.iterations, props.messages, props.subagents ?? [], props.turns ?? []));
8896
9099
  return (() => {
8897
9100
  var _el$ = _tmpl$30();
8898
9101
  insert(_el$, createComponent(Show, {
@@ -9066,8 +9269,8 @@ var UserMessageGroupCard = (props) => {
9066
9269
  const userContent = () => {
9067
9270
  const msg = userMsg();
9068
9271
  if (!msg) return "(no user message)";
9069
- const text = msg.content || "";
9070
- return text.length > 120 ? text.slice(0, 120) + "..." : text;
9272
+ const text2 = msg.content || "";
9273
+ return text2.length > 120 ? text2.slice(0, 120) + "..." : text2;
9071
9274
  };
9072
9275
  const handleUserMouseEnter = () => {
9073
9276
  const messageId = userMessageId();
@@ -9404,7 +9607,21 @@ var UserMessageGroupCard = (props) => {
9404
9607
  return props.onHoverTarget;
9405
9608
  }
9406
9609
  })
9407
- }));
9610
+ }), null);
9611
+ insert(_el$49, createComponent(For, {
9612
+ get each() {
9613
+ return group().agents;
9614
+ },
9615
+ children: (agentGroup) => createComponent(SubagentStepsCard, {
9616
+ group: agentGroup,
9617
+ get hoverTarget() {
9618
+ return props.hoverTarget;
9619
+ },
9620
+ get onHoverTarget() {
9621
+ return props.onHoverTarget;
9622
+ }
9623
+ })
9624
+ }), null);
9408
9625
  effect((_p$) => {
9409
9626
  var _v$17 = s().cardHeader, _v$18 = s().userBubble, _v$19 = s().cardHeaderContent, _v$20 = s().cardHeaderLabel, _v$21 = s().cardSubtitle, _v$22 = s().cardHeaderBadges, _v$23 = `${s().chevron} ${isOpen() ? s().chevronOpen : ""}`, _v$24 = `${s().configPanelWrapper} ${configExpanded() ? s().configPanelWrapperOpen : ""}`, _v$25 = s().configPanel, _v$26 = `${s().cardBody} ${isOpen() ? s().cardBodyOpen : ""}`, _v$27 = s().cardBodyInner, _v$28 = s().iterList;
9410
9627
  _v$17 !== _p$.e && className(_el$10, _p$.e = _v$17);
@@ -9437,7 +9654,135 @@ var UserMessageGroupCard = (props) => {
9437
9654
  return _el$1;
9438
9655
  })();
9439
9656
  };
9440
- delegateEvents(["click"]);
9657
+ var SubagentStepsCard = (props) => {
9658
+ const styles = useStyles();
9659
+ const s = () => styles().iterationTimeline;
9660
+ const [isOpen, setIsOpen] = createSignal(true);
9661
+ const group = createMemo(() => {
9662
+ if (props.group) return props.group;
9663
+ if (!props.agent) return void 0;
9664
+ return {
9665
+ agent: props.agent,
9666
+ ...buildSubagentSteps(props.agent),
9667
+ source: "snapshot"
9668
+ };
9669
+ });
9670
+ const agent = () => group()?.agent;
9671
+ const iterations = () => group()?.iterations ?? [];
9672
+ const accentClass = () => {
9673
+ const status = agent()?.status;
9674
+ if (status === "running") return s().cardActive;
9675
+ if (status === "error") return s().cardError;
9676
+ if (status === "finished") return s().cardCompleted;
9677
+ return "";
9678
+ };
9679
+ return createComponent(Show, {
9680
+ get when() {
9681
+ return agent();
9682
+ },
9683
+ children: (current) => (() => {
9684
+ var _el$54 = _tmpl$182(), _el$55 = _el$54.firstChild, _el$56 = _el$55.firstChild, _el$57 = _el$56.nextSibling, _el$58 = _el$57.firstChild, _el$59 = _el$58.nextSibling, _el$60 = _el$59.firstChild, _el$63 = _el$57.nextSibling, _el$64 = _el$63.firstChild; _el$64.firstChild; var _el$66 = _el$63.nextSibling, _el$67 = _el$55.nextSibling, _el$68 = _el$67.firstChild, _el$69 = _el$68.firstChild;
9685
+ _el$55.$$keydown = (event) => {
9686
+ if (event.key !== "Enter" && event.key !== " ") return;
9687
+ event.preventDefault();
9688
+ setIsOpen(!isOpen());
9689
+ };
9690
+ _el$55.$$click = () => setIsOpen(!isOpen());
9691
+ insert(_el$56, () => current().name.charAt(0).toUpperCase());
9692
+ insert(_el$58, () => current().path);
9693
+ insert(_el$59, createComponent(Show, {
9694
+ get when() {
9695
+ return current().status;
9696
+ },
9697
+ get children() {
9698
+ var _el$61 = _tmpl$33();
9699
+ insert(_el$61, () => current().status);
9700
+ effect(() => className(_el$61, s().subtitleBadge));
9701
+ return _el$61;
9702
+ }
9703
+ }), null);
9704
+ insert(_el$59, createComponent(Show, {
9705
+ get when() {
9706
+ return current().error;
9707
+ },
9708
+ get children() {
9709
+ var _el$62 = _tmpl$33();
9710
+ insert(_el$62, () => current().error);
9711
+ effect(() => className(_el$62, s().subtitleBadgeWarn));
9712
+ return _el$62;
9713
+ }
9714
+ }), null);
9715
+ insert(_el$64, () => iterations().length, null);
9716
+ insert(_el$69, createComponent(For, {
9717
+ get each() {
9718
+ return iterations();
9719
+ },
9720
+ children: (iteration, index) => createComponent(IterationCard, {
9721
+ iteration,
9722
+ get previousIteration() {
9723
+ return memo(() => index() > 0)() ? iterations()[index() - 1] : void 0;
9724
+ },
9725
+ get messages() {
9726
+ return group()?.messages ?? [];
9727
+ },
9728
+ get index() {
9729
+ return index();
9730
+ },
9731
+ get isLast() {
9732
+ return index() === iterations().length - 1;
9733
+ },
9734
+ get hoverTarget() {
9735
+ return props.hoverTarget;
9736
+ },
9737
+ get onHoverTarget() {
9738
+ return props.onHoverTarget;
9739
+ }
9740
+ })
9741
+ }));
9742
+ effect((_p$) => {
9743
+ var _v$33 = `${s().card} ${accentClass()}`, _v$34 = current().path, _v$35 = group()?.source, _v$36 = s().cardHeader, _v$37 = isOpen(), _v$38 = s().userBubble, _v$39 = s().cardHeaderContent, _v$40 = s().cardHeaderLabel, _v$41 = s().cardSubtitle, _v$42 = s().subtitleText, _v$43 = s().cardHeaderBadges, _v$44 = `${s().badge} ${s().badgeDuration}`, _v$45 = `${iterations().length} ${iterations().length === 1 ? "iteration" : "iterations"}`, _v$46 = `${s().chevron} ${isOpen() ? s().chevronOpen : ""}`, _v$47 = `${s().cardBody} ${isOpen() ? s().cardBodyOpen : ""}`, _v$48 = s().cardBodyInner, _v$49 = s().iterList;
9744
+ _v$33 !== _p$.e && className(_el$54, _p$.e = _v$33);
9745
+ _v$34 !== _p$.t && setAttribute(_el$54, "data-agent", _p$.t = _v$34);
9746
+ _v$35 !== _p$.a && setAttribute(_el$54, "data-source", _p$.a = _v$35);
9747
+ _v$36 !== _p$.o && className(_el$55, _p$.o = _v$36);
9748
+ _v$37 !== _p$.i && setAttribute(_el$55, "aria-expanded", _p$.i = _v$37);
9749
+ _v$38 !== _p$.n && className(_el$56, _p$.n = _v$38);
9750
+ _v$39 !== _p$.s && className(_el$57, _p$.s = _v$39);
9751
+ _v$40 !== _p$.h && className(_el$58, _p$.h = _v$40);
9752
+ _v$41 !== _p$.r && className(_el$59, _p$.r = _v$41);
9753
+ _v$42 !== _p$.d && className(_el$60, _p$.d = _v$42);
9754
+ _v$43 !== _p$.l && className(_el$63, _p$.l = _v$43);
9755
+ _v$44 !== _p$.u && className(_el$64, _p$.u = _v$44);
9756
+ _v$45 !== _p$.c && setAttribute(_el$64, "title", _p$.c = _v$45);
9757
+ _v$46 !== _p$.w && className(_el$66, _p$.w = _v$46);
9758
+ _v$47 !== _p$.m && className(_el$67, _p$.m = _v$47);
9759
+ _v$48 !== _p$.f && className(_el$68, _p$.f = _v$48);
9760
+ _v$49 !== _p$.y && className(_el$69, _p$.y = _v$49);
9761
+ return _p$;
9762
+ }, {
9763
+ e: void 0,
9764
+ t: void 0,
9765
+ a: void 0,
9766
+ o: void 0,
9767
+ i: void 0,
9768
+ n: void 0,
9769
+ s: void 0,
9770
+ h: void 0,
9771
+ r: void 0,
9772
+ d: void 0,
9773
+ l: void 0,
9774
+ u: void 0,
9775
+ c: void 0,
9776
+ w: void 0,
9777
+ m: void 0,
9778
+ f: void 0,
9779
+ y: void 0
9780
+ });
9781
+ return _el$54;
9782
+ })()
9783
+ });
9784
+ };
9785
+ delegateEvents(["click", "keydown"]);
9441
9786
  var _tmpl$31 = /* @__PURE__ */ template(`<form data-testid=ai-devtools-fixture-save-popover><label><span>Fixture name</span><input data-testid=ai-devtools-fixture-name-input></label><div><button data-testid=ai-devtools-fixture-save-confirm type=submit>Save</button><button data-testid=ai-devtools-fixture-save-cancel type=button>Cancel`);
9442
9787
  var FixtureNamePopover = (props) => {
9443
9788
  const styles = useStyles();
@@ -9734,7 +10079,7 @@ var FieldInput = (props) => {
9734
10079
  function fieldsFromSchema(schema) {
9735
10080
  if (!isJsonSchemaObject(schema)) return [];
9736
10081
  const properties = schema.properties;
9737
- if (!isRecord(properties)) return [];
10082
+ if (!isRecord2(properties)) return [];
9738
10083
  const required = Array.isArray(schema.required) ? new Set(schema.required.filter((item) => typeof item === "string")) : /* @__PURE__ */ new Set();
9739
10084
  return Object.entries(properties).map(([name, property]) => {
9740
10085
  const propertySchema = isJsonSchemaObject(property) ? property : void 0;
@@ -9814,9 +10159,9 @@ function normalizeType(value) {
9814
10159
  return "string";
9815
10160
  }
9816
10161
  function isJsonSchemaObject(value) {
9817
- return isRecord(value);
10162
+ return isRecord2(value);
9818
10163
  }
9819
- function isRecord(value) {
10164
+ function isRecord2(value) {
9820
10165
  return typeof value === "object" && value !== null;
9821
10166
  }
9822
10167
  delegateEvents(["input", "click"]);
@@ -9848,7 +10193,7 @@ function mergePreviewMessagesForUserView(conversationMessages, snapshotMessages)
9848
10193
  }
9849
10194
  function partsToMessageText(parts) {
9850
10195
  return parts.map((part) => {
9851
- if (!isRecord2(part)) return "";
10196
+ if (!isRecord3(part)) return "";
9852
10197
  if (part.type !== "text") return "";
9853
10198
  if (typeof part.text === "string") return part.text;
9854
10199
  if (typeof part.content === "string") return part.content;
@@ -9887,7 +10232,7 @@ function isRenderablePreviewMessage(message) {
9887
10232
  function isNonUserPreviewMessage(message) {
9888
10233
  return message.role !== void 0 && message.role !== "user";
9889
10234
  }
9890
- function isRecord2(value) {
10235
+ function isRecord3(value) {
9891
10236
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
9892
10237
  }
9893
10238
  function normalizeText(value) {
@@ -10479,7 +10824,7 @@ function runSortTime(run) {
10479
10824
  return run.startedAt ?? run.updatedAt ?? run.completedAt ?? 0;
10480
10825
  }
10481
10826
  function runFromUnknown(value) {
10482
- if (!isRecord3(value) || typeof value.id !== "string") {
10827
+ if (!isRecord4(value) || typeof value.id !== "string") {
10483
10828
  return void 0;
10484
10829
  }
10485
10830
  const progress = progressFromUnknown(value.progress);
@@ -10612,7 +10957,7 @@ function isGenerationRunView(value) {
10612
10957
  return value !== void 0;
10613
10958
  }
10614
10959
  function previewFromUnknown(value, fallbackResult) {
10615
- if (isRecord3(value) && typeof value.kind === "string") {
10960
+ if (isRecord4(value) && typeof value.kind === "string") {
10616
10961
  if (value.kind === "image") {
10617
10962
  return {
10618
10963
  kind: "image",
@@ -10663,7 +11008,7 @@ function previewFromUnknown(value, fallbackResult) {
10663
11008
  };
10664
11009
  }
10665
11010
  function progressFromUnknown(value) {
10666
- if (!isRecord3(value) || typeof value.value !== "number") {
11011
+ if (!isRecord4(value) || typeof value.value !== "number") {
10667
11012
  return void 0;
10668
11013
  }
10669
11014
  return {
@@ -10678,17 +11023,17 @@ function mediaItemsFromUnknown(value) {
10678
11023
  return value.filter(isMediaItem);
10679
11024
  }
10680
11025
  function isMediaItem(value) {
10681
- if (!isRecord3(value) || typeof value.src !== "string") {
11026
+ if (!isRecord4(value) || typeof value.src !== "string") {
10682
11027
  return false;
10683
11028
  }
10684
11029
  return true;
10685
11030
  }
10686
11031
  function isVideoJob(value) {
10687
- return isRecord3(value) && typeof value.jobId === "string";
11032
+ return isRecord4(value) && typeof value.jobId === "string";
10688
11033
  }
10689
11034
  function errorTextFromUnknown(value) {
10690
11035
  if (typeof value === "string") return value;
10691
- if (isRecord3(value) && typeof value.message === "string") {
11036
+ if (isRecord4(value) && typeof value.message === "string") {
10692
11037
  return value.message;
10693
11038
  }
10694
11039
  return void 0;
@@ -10700,7 +11045,7 @@ function numberFromUnknown(value) {
10700
11045
  return typeof value === "number" ? value : void 0;
10701
11046
  }
10702
11047
  function videoStatusLabel(value) {
10703
- if (!isRecord3(value)) return void 0;
11048
+ if (!isRecord4(value)) return void 0;
10704
11049
  const status = stringFromUnknown(value.status);
10705
11050
  const progress = numberFromUnknown(value.progress);
10706
11051
  if (!status && progress === void 0) return void 0;
@@ -10722,7 +11067,7 @@ function formatTime(timestamp) {
10722
11067
  if (timestamp === void 0) return "unknown";
10723
11068
  return new Date(timestamp).toLocaleTimeString();
10724
11069
  }
10725
- function isRecord3(value) {
11070
+ function isRecord4(value) {
10726
11071
  return typeof value === "object" && value !== null && !Array.isArray(value);
10727
11072
  }
10728
11073
  delegateEvents(["click"]);
@@ -11542,7 +11887,7 @@ var _tmpl$144 = /* @__PURE__ */ template(`<div>`);
11542
11887
  var _tmpl$154 = /* @__PURE__ */ template(`<div>No messages.`);
11543
11888
  var _tmpl$164 = /* @__PURE__ */ template(`<div><div>`);
11544
11889
  var _tmpl$173 = /* @__PURE__ */ template(`<div><button type=button data-testid=ai-devtools-preview-save-tool-call>Save</button><button type=button data-testid=ai-devtools-preview-replay-tool-call>Replay`);
11545
- var _tmpl$182 = /* @__PURE__ */ template(`<div><span>`);
11890
+ var _tmpl$183 = /* @__PURE__ */ template(`<div><span>`);
11546
11891
  var _tmpl$192 = /* @__PURE__ */ template(`<div><span></span><div>`);
11547
11892
  var _tmpl$202 = /* @__PURE__ */ template(`<div>No messages yet. Start a conversation to see messages here.`);
11548
11893
  var _tmpl$217 = /* @__PURE__ */ template(`<div data-testid=ai-devtools-tools><div></div><div>`);
@@ -11589,13 +11934,34 @@ var HookDetails = () => {
11589
11934
  setActiveTab("conversation");
11590
11935
  }
11591
11936
  });
11937
+ const subagents = createMemo(() => {
11938
+ const messages = hook()?.state.messages;
11939
+ return Array.isArray(messages) ? collectSubagents(messages) : [];
11940
+ });
11941
+ const serverSteps = createMemo(() => collectServerSteps(conversation(), Object.values(state.conversations), subagents()));
11942
+ const turns = createMemo(() => {
11943
+ const messages = hook()?.state.messages;
11944
+ return Array.isArray(messages) ? snapshotTurns(messages) : [];
11945
+ });
11592
11946
  const previewMessages = createMemo(() => {
11593
11947
  const activeHook = hook();
11594
11948
  if (!activeHook) return [];
11595
11949
  const snapshotMessages = messagesFromSnapshot(activeHook.state);
11950
+ if (snapshotMessages.length > 0 && subagents().length > 0) {
11951
+ return snapshotMessages;
11952
+ }
11596
11953
  const conversationMessages = conversation()?.messages ?? [];
11597
11954
  if (conversationMessages.length > 0) {
11598
- return mergePreviewMessagesForUserView(conversationMessages.map(messageFromConversation), snapshotMessages);
11955
+ const childAgents = childRequestAgents(conversation()?.iterations ?? [], subagents());
11956
+ const agentOf = (message) => message.requestId ? childAgents.get(message.requestId) : void 0;
11957
+ return mergePreviewMessagesForUserView(conversationMessages.filter((message) => !(message.role === "user" && agentOf(message))).map((message) => {
11958
+ const preview = messageFromConversation(message);
11959
+ const agent = agentOf(message);
11960
+ return agent ? {
11961
+ ...preview,
11962
+ agent
11963
+ } : preview;
11964
+ }), snapshotMessages);
11599
11965
  }
11600
11966
  if (snapshotMessages.length > 0) return snapshotMessages;
11601
11967
  return [];
@@ -11736,6 +12102,15 @@ var HookDetails = () => {
11736
12102
  get messages() {
11737
12103
  return previewMessages();
11738
12104
  },
12105
+ get subagents() {
12106
+ return subagents();
12107
+ },
12108
+ get steps() {
12109
+ return serverSteps();
12110
+ },
12111
+ get turns() {
12112
+ return turns();
12113
+ },
11739
12114
  get hoverTarget() {
11740
12115
  return hoverTarget();
11741
12116
  },
@@ -12233,7 +12608,7 @@ var ConversationPanel = (props) => {
12233
12608
  const styles = useStyles();
12234
12609
  return createComponent(Show, {
12235
12610
  get when() {
12236
- return props.conversation;
12611
+ return props.conversation || props.steps.iterations.length > 0;
12237
12612
  },
12238
12613
  get fallback() {
12239
12614
  return createComponent(Show, {
@@ -12268,6 +12643,9 @@ var ConversationPanel = (props) => {
12268
12643
  get messages() {
12269
12644
  return props.messages;
12270
12645
  },
12646
+ get subagents() {
12647
+ return props.subagents;
12648
+ },
12271
12649
  get hoverTarget() {
12272
12650
  return props.hoverTarget;
12273
12651
  },
@@ -12278,40 +12656,51 @@ var ConversationPanel = (props) => {
12278
12656
  }
12279
12657
  });
12280
12658
  },
12281
- children: (conversation) => createComponent(Show, {
12282
- get when() {
12283
- return conversation().iterations.length > 0;
12284
- },
12285
- get fallback() {
12286
- return createComponent(HookMessageTimeline, {
12287
- get messages() {
12288
- return props.messages;
12289
- },
12290
- get hoverTarget() {
12291
- return props.hoverTarget;
12292
- },
12293
- get onHoverTarget() {
12294
- return props.onHoverTarget;
12295
- }
12296
- });
12297
- },
12298
- get children() {
12299
- return createComponent(IterationTimeline, {
12300
- get iterations() {
12301
- return conversation().iterations;
12302
- },
12303
- get messages() {
12304
- return conversation().messages;
12305
- },
12306
- get hoverTarget() {
12307
- return props.hoverTarget;
12308
- },
12309
- get onHoverTarget() {
12310
- return props.onHoverTarget;
12311
- }
12312
- });
12313
- }
12314
- })
12659
+ get children() {
12660
+ return createComponent(Show, {
12661
+ get when() {
12662
+ return props.steps.iterations.length > 0;
12663
+ },
12664
+ get fallback() {
12665
+ return createComponent(HookMessageTimeline, {
12666
+ get messages() {
12667
+ return props.messages;
12668
+ },
12669
+ get subagents() {
12670
+ return props.subagents;
12671
+ },
12672
+ get hoverTarget() {
12673
+ return props.hoverTarget;
12674
+ },
12675
+ get onHoverTarget() {
12676
+ return props.onHoverTarget;
12677
+ }
12678
+ });
12679
+ },
12680
+ get children() {
12681
+ return createComponent(IterationTimeline, {
12682
+ get iterations() {
12683
+ return props.steps.iterations;
12684
+ },
12685
+ get messages() {
12686
+ return props.steps.messages;
12687
+ },
12688
+ get subagents() {
12689
+ return props.subagents;
12690
+ },
12691
+ get turns() {
12692
+ return props.turns;
12693
+ },
12694
+ get hoverTarget() {
12695
+ return props.hoverTarget;
12696
+ },
12697
+ get onHoverTarget() {
12698
+ return props.onHoverTarget;
12699
+ }
12700
+ });
12701
+ }
12702
+ });
12703
+ }
12315
12704
  });
12316
12705
  };
12317
12706
  var MessagesPreview = (props) => {
@@ -12379,7 +12768,7 @@ var MessagesPreview = (props) => {
12379
12768
  return props.messages;
12380
12769
  },
12381
12770
  children: (message) => {
12382
- const visibleParts = () => visiblePreviewPartsForMessage(message);
12771
+ const visibleParts = () => visiblePreviewPartsForMessage(message).filter((part) => !hiddenInUserView(message, part));
12383
12772
  return (() => {
12384
12773
  var _el$51 = _tmpl$164(), _el$52 = _el$51.firstChild;
12385
12774
  spread(_el$51, mergeProps(() => getHoverDataAttributes({
@@ -12402,7 +12791,7 @@ var MessagesPreview = (props) => {
12402
12791
  })),
12403
12792
  "onMouseLeave": () => props.onHoverTarget(null)
12404
12793
  }), false, true);
12405
- insert(_el$52, () => message.role);
12794
+ insert(_el$52, () => roleLabel(message));
12406
12795
  insert(_el$51, createComponent(Show, {
12407
12796
  get when() {
12408
12797
  return message.content;
@@ -12419,7 +12808,7 @@ var MessagesPreview = (props) => {
12419
12808
  return visibleParts();
12420
12809
  },
12421
12810
  children: (part) => (() => {
12422
- var _el$54 = _tmpl$182(), _el$55 = _el$54.firstChild;
12811
+ var _el$54 = _tmpl$183(), _el$55 = _el$54.firstChild;
12423
12812
  spread(_el$54, mergeProps(() => getHoverDataAttributes({
12424
12813
  messageIds: [message.id],
12425
12814
  partIds: [part.id]
@@ -12573,7 +12962,7 @@ var HookMessageTimeline = (props) => {
12573
12962
  })),
12574
12963
  "onMouseLeave": () => props.onHoverTarget(null)
12575
12964
  }), false, true);
12576
- insert(_el$67, () => message.role);
12965
+ insert(_el$67, () => roleLabel(message));
12577
12966
  insert(_el$66, createComponent(Show, {
12578
12967
  get when() {
12579
12968
  return message.content;
@@ -12587,75 +12976,93 @@ var HookMessageTimeline = (props) => {
12587
12976
  }), null);
12588
12977
  insert(_el$66, createComponent(For, {
12589
12978
  get each() {
12590
- return visiblePreviewPartsForMessage(message);
12979
+ return visiblePreviewPartsForMessage(message).filter((part) => part.subagentId || !part.subagentPath);
12591
12980
  },
12592
- children: (part) => (() => {
12593
- var _el$69 = _tmpl$182(), _el$70 = _el$69.firstChild;
12594
- spread(_el$69, mergeProps(() => getHoverDataAttributes({
12595
- messageIds: [message.id],
12596
- partIds: [part.id]
12597
- }), {
12598
- get ["class"]() {
12599
- return styles().hookDetails.previewPart;
12600
- },
12601
- "data-testid": "ai-devtools-timeline-part",
12602
- get ["data-part-id"]() {
12603
- return part.id;
12604
- },
12605
- get ["data-part-kind"]() {
12606
- return part.kind;
12607
- }
12608
- }), false, true);
12609
- insert(_el$70, () => part.label);
12610
- insert(_el$69, createComponent(Show, {
12611
- get when() {
12612
- return part.jsonItems?.length;
12613
- },
12614
- get fallback() {
12615
- return (() => {
12616
- var _el$72 = _tmpl$07();
12617
- insert(_el$72, () => part.content);
12618
- effect(() => className(_el$72, styles().hookDetails.previewPartContent));
12619
- return _el$72;
12620
- })();
12621
- },
12622
- get children() {
12623
- var _el$71 = _tmpl$144();
12624
- insert(_el$71, createComponent(For, {
12625
- get each() {
12626
- return part.jsonItems;
12981
+ children: (part) => createComponent(Show, {
12982
+ get when() {
12983
+ return props.subagents.find((agent) => agent.id === part.subagentId);
12984
+ },
12985
+ get fallback() {
12986
+ return (() => {
12987
+ var _el$69 = _tmpl$183(), _el$70 = _el$69.firstChild;
12988
+ spread(_el$69, mergeProps(() => getHoverDataAttributes({
12989
+ messageIds: [message.id],
12990
+ partIds: [part.id]
12991
+ }), {
12992
+ get ["class"]() {
12993
+ return styles().hookDetails.previewPart;
12994
+ },
12995
+ "data-testid": "ai-devtools-timeline-part",
12996
+ get ["data-part-id"]() {
12997
+ return part.id;
12627
12998
  },
12628
- children: (item) => (() => {
12629
- var _el$73 = _tmpl$192(), _el$74 = _el$73.firstChild, _el$75 = _el$74.nextSibling;
12630
- insert(_el$74, () => item.label);
12631
- insert(_el$75, createComponent(JsonTree, {
12632
- get value() {
12633
- return item.value;
12999
+ get ["data-part-kind"]() {
13000
+ return part.kind;
13001
+ }
13002
+ }), false, true);
13003
+ insert(_el$70, () => part.label);
13004
+ insert(_el$69, createComponent(Show, {
13005
+ get when() {
13006
+ return part.jsonItems?.length;
13007
+ },
13008
+ get fallback() {
13009
+ return (() => {
13010
+ var _el$72 = _tmpl$07();
13011
+ insert(_el$72, () => part.content);
13012
+ effect(() => className(_el$72, styles().hookDetails.previewPartContent));
13013
+ return _el$72;
13014
+ })();
13015
+ },
13016
+ get children() {
13017
+ var _el$71 = _tmpl$144();
13018
+ insert(_el$71, createComponent(For, {
13019
+ get each() {
13020
+ return part.jsonItems;
12634
13021
  },
12635
- defaultExpansionDepth: 1,
12636
- copyable: true
13022
+ children: (item) => (() => {
13023
+ var _el$73 = _tmpl$192(), _el$74 = _el$73.firstChild, _el$75 = _el$74.nextSibling;
13024
+ insert(_el$74, () => item.label);
13025
+ insert(_el$75, createComponent(JsonTree, {
13026
+ get value() {
13027
+ return item.value;
13028
+ },
13029
+ defaultExpansionDepth: 1,
13030
+ copyable: true
13031
+ }));
13032
+ effect((_p$) => {
13033
+ var _v$51 = styles().hookDetails.previewJsonItem, _v$52 = styles().hookDetails.previewJsonItemLabel, _v$53 = styles().hookDetails.previewJsonPanel;
13034
+ _v$51 !== _p$.e && className(_el$73, _p$.e = _v$51);
13035
+ _v$52 !== _p$.t && className(_el$74, _p$.t = _v$52);
13036
+ _v$53 !== _p$.a && className(_el$75, _p$.a = _v$53);
13037
+ return _p$;
13038
+ }, {
13039
+ e: void 0,
13040
+ t: void 0,
13041
+ a: void 0
13042
+ });
13043
+ return _el$73;
13044
+ })()
12637
13045
  }));
12638
- effect((_p$) => {
12639
- var _v$51 = styles().hookDetails.previewJsonItem, _v$52 = styles().hookDetails.previewJsonItemLabel, _v$53 = styles().hookDetails.previewJsonPanel;
12640
- _v$51 !== _p$.e && className(_el$73, _p$.e = _v$51);
12641
- _v$52 !== _p$.t && className(_el$74, _p$.t = _v$52);
12642
- _v$53 !== _p$.a && className(_el$75, _p$.a = _v$53);
12643
- return _p$;
12644
- }, {
12645
- e: void 0,
12646
- t: void 0,
12647
- a: void 0
12648
- });
12649
- return _el$73;
12650
- })()
12651
- }));
12652
- effect(() => className(_el$71, `${styles().hookDetails.previewJsonItems} ${part.kind === "structured-output" ? styles().hookDetails.previewJsonItemsCompare : ""}`));
12653
- return _el$71;
13046
+ effect(() => className(_el$71, `${styles().hookDetails.previewJsonItems} ${part.kind === "structured-output" ? styles().hookDetails.previewJsonItemsCompare : ""}`));
13047
+ return _el$71;
13048
+ }
13049
+ }), null);
13050
+ effect(() => className(_el$70, styles().hookDetails.previewPartLabel));
13051
+ return _el$69;
13052
+ })();
13053
+ },
13054
+ children: (agent) => createComponent(SubagentStepsCard, {
13055
+ get agent() {
13056
+ return agent();
13057
+ },
13058
+ get hoverTarget() {
13059
+ return props.hoverTarget;
13060
+ },
13061
+ get onHoverTarget() {
13062
+ return props.onHoverTarget;
12654
13063
  }
12655
- }), null);
12656
- effect(() => className(_el$70, styles().hookDetails.previewPartLabel));
12657
- return _el$69;
12658
- })()
13064
+ })
13065
+ })
12659
13066
  }), null);
12660
13067
  effect(() => className(_el$67, styles().hookDetails.messageRole));
12661
13068
  return _el$66;
@@ -12666,6 +13073,13 @@ var HookMessageTimeline = (props) => {
12666
13073
  }
12667
13074
  });
12668
13075
  };
13076
+ function roleLabel(message) {
13077
+ return message.agent ? `${message.role} (${message.agent})` : message.role;
13078
+ }
13079
+ function hiddenInUserView(message, part) {
13080
+ if (!message.agent && !part.subagentPath) return false;
13081
+ return part.kind === "thinking" || part.kind === "tool-call";
13082
+ }
12669
13083
  var ToolsView = (props) => {
12670
13084
  const {
12671
13085
  state,
@@ -12937,7 +13351,7 @@ function findConversationForHook(hook, conversations) {
12937
13351
  }
12938
13352
  const snapshotMessages = hook.state.messages;
12939
13353
  if (Array.isArray(snapshotMessages)) {
12940
- const messageIds = new Set(snapshotMessages.map((message) => isRecord4(message) && typeof message.id === "string" ? message.id : void 0).filter((id) => typeof id === "string"));
13354
+ const messageIds = new Set(snapshotMessages.map((message) => isRecord5(message) && typeof message.id === "string" ? message.id : void 0).filter((id) => typeof id === "string"));
12941
13355
  if (messageIds.size > 0) {
12942
13356
  addCandidate(Object.values(conversations).find((conversation) => conversation.messages.some((message) => messageIds.has(message.id))));
12943
13357
  }
@@ -12965,7 +13379,7 @@ function messageFromConversation(message) {
12965
13379
  };
12966
13380
  }
12967
13381
  function messageFromUnknown(value) {
12968
- if (!isRecord4(value)) return void 0;
13382
+ if (!isRecord5(value)) return void 0;
12969
13383
  const id = typeof value.id === "string" ? value.id : void 0;
12970
13384
  const role = typeof value.role === "string" ? value.role : void 0;
12971
13385
  if (!id || !role) return void 0;
@@ -12982,10 +13396,49 @@ function messageFromUnknown(value) {
12982
13396
  };
12983
13397
  }
12984
13398
  function partsFromMessageParts(parts, messageId) {
12985
- return parts.map((part, index) => previewPartFromRecord(part, index, messageId));
13399
+ return parts.flatMap((part, index) => previewPartsFromRecord(part, index, messageId));
12986
13400
  }
12987
13401
  function partsFromUnknown(parts, messageId) {
12988
- return parts.map((part, index) => isRecord4(part) ? previewPartFromRecord(part, index, messageId) : void 0).filter(isPreviewPart);
13402
+ return parts.flatMap((part, index) => isRecord5(part) ? previewPartsFromRecord(part, index, messageId) : []);
13403
+ }
13404
+ function previewPartsFromRecord(part, index, messageId, path) {
13405
+ if (part.type === "subagent" && isRecord5(part.subagent)) {
13406
+ return subagentPreviewParts(part.subagent, index, path);
13407
+ }
13408
+ const preview = previewPartFromRecord(part, index, messageId);
13409
+ if (!path) return [preview];
13410
+ const {
13411
+ fixture: _fixture,
13412
+ ...childPart
13413
+ } = preview;
13414
+ return [{
13415
+ ...childPart,
13416
+ id: `${path}:${messageId ?? index}:${preview.id}`,
13417
+ label: `${path} > ${preview.label}`,
13418
+ subagentPath: path
13419
+ }];
13420
+ }
13421
+ function subagentPreviewParts(subagent, index, parentPath) {
13422
+ const name = typeof subagent.name === "string" ? subagent.name : "subagent";
13423
+ const status = typeof subagent.status === "string" ? subagent.status : void 0;
13424
+ const id = typeof subagent.id === "string" ? subagent.id : `${index}`;
13425
+ const error = isRecord5(subagent.error) ? subagent.error.message : void 0;
13426
+ const path = parentPath ? `${parentPath} > ${name}` : name;
13427
+ const header = {
13428
+ id: `subagent:${id}`,
13429
+ label: status ? `subagent ${path} - ${status}` : `subagent ${path}`,
13430
+ ...typeof error === "string" ? {
13431
+ content: error
13432
+ } : {},
13433
+ kind: "subagent",
13434
+ subagentId: id
13435
+ };
13436
+ const messages = Array.isArray(subagent.messages) ? subagent.messages : [];
13437
+ return [header, ...messages.flatMap((message, messageIndex) => {
13438
+ if (!isRecord5(message) || !Array.isArray(message.parts)) return [];
13439
+ const childMessageId = typeof message.id === "string" ? message.id : `${id}:${messageIndex}`;
13440
+ return message.parts.flatMap((child, childIndex) => isRecord5(child) ? previewPartsFromRecord(child, childIndex, childMessageId, path) : []);
13441
+ })];
12989
13442
  }
12990
13443
  function previewPartFromRecord(part, index, messageId) {
12991
13444
  const type = typeof part.type === "string" ? part.type : "part";
@@ -13172,7 +13625,7 @@ function approvalStatusFromToolCall(tool) {
13172
13625
  return void 0;
13173
13626
  }
13174
13627
  function approvalStatusFromRecord(approval, state) {
13175
- if (isRecord4(approval)) {
13628
+ if (isRecord5(approval)) {
13176
13629
  if (approval.approved === true) return "approved";
13177
13630
  if (approval.approved === false) return "denied";
13178
13631
  if (approval.needsApproval === true) return "approval requested";
@@ -13246,10 +13699,7 @@ function formatUnknown(value) {
13246
13699
  function isPreviewMessage(value) {
13247
13700
  return Boolean(value);
13248
13701
  }
13249
- function isPreviewPart(value) {
13250
- return Boolean(value);
13251
- }
13252
- function isRecord4(value) {
13702
+ function isRecord5(value) {
13253
13703
  return typeof value === "object" && value !== null;
13254
13704
  }
13255
13705
  function isToolFixtureMessageRole(role) {