@elizaos/plugin-trajectory-logger 2.0.3-beta.6 → 2.0.3-beta.7

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.
Files changed (67) hide show
  1. package/dist/api-client.d.ts +88 -0
  2. package/dist/api-client.d.ts.map +1 -0
  3. package/dist/api-client.js +68 -0
  4. package/dist/api-client.js.map +1 -0
  5. package/dist/components/PhaseChip.d.ts +13 -0
  6. package/dist/components/PhaseChip.d.ts.map +1 -0
  7. package/dist/components/PhaseChip.js +100 -0
  8. package/dist/components/PhaseChip.js.map +1 -0
  9. package/dist/components/PhaseDrilldown.d.ts +5 -0
  10. package/dist/components/PhaseDrilldown.d.ts.map +1 -0
  11. package/dist/components/PhaseDrilldown.js +118 -0
  12. package/dist/components/PhaseDrilldown.js.map +1 -0
  13. package/dist/components/TrajectoryLoggerAppView.d.ts +14 -0
  14. package/dist/components/TrajectoryLoggerAppView.d.ts.map +1 -0
  15. package/dist/components/TrajectoryLoggerAppView.js +184 -0
  16. package/dist/components/TrajectoryLoggerAppView.js.map +1 -0
  17. package/dist/components/TrajectoryLoggerSpatialView.d.ts +53 -0
  18. package/dist/components/TrajectoryLoggerSpatialView.d.ts.map +1 -0
  19. package/dist/components/TrajectoryLoggerSpatialView.js +293 -0
  20. package/dist/components/TrajectoryLoggerSpatialView.js.map +1 -0
  21. package/dist/components/TrajectoryLoggerView.d.ts +23 -0
  22. package/dist/components/TrajectoryLoggerView.d.ts.map +1 -0
  23. package/dist/components/TrajectoryLoggerView.interact.d.ts +2 -0
  24. package/dist/components/TrajectoryLoggerView.interact.d.ts.map +1 -0
  25. package/dist/components/TrajectoryLoggerView.interact.js +35 -0
  26. package/dist/components/TrajectoryLoggerView.interact.js.map +1 -0
  27. package/dist/components/TrajectoryLoggerView.js +64 -0
  28. package/dist/components/TrajectoryLoggerView.js.map +1 -0
  29. package/dist/components/trajectory-logger-app.d.ts +8 -0
  30. package/dist/components/trajectory-logger-app.d.ts.map +1 -0
  31. package/dist/components/trajectory-logger-app.js +24 -0
  32. package/dist/components/trajectory-logger-app.js.map +1 -0
  33. package/dist/components/trajectory-logger-view-bundle.d.ts +3 -0
  34. package/dist/components/trajectory-logger-view-bundle.d.ts.map +1 -0
  35. package/dist/components/trajectory-logger-view-bundle.js +7 -0
  36. package/dist/components/trajectory-logger-view-bundle.js.map +1 -0
  37. package/dist/index.d.ts +16 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +22 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/phases.d.ts +21 -0
  42. package/dist/phases.d.ts.map +1 -0
  43. package/dist/phases.js +154 -0
  44. package/dist/phases.js.map +1 -0
  45. package/dist/plugin.d.ts +14 -0
  46. package/dist/plugin.d.ts.map +1 -0
  47. package/dist/plugin.js +51 -0
  48. package/dist/plugin.js.map +1 -0
  49. package/dist/register-terminal-view.d.ts +16 -0
  50. package/dist/register-terminal-view.d.ts.map +1 -0
  51. package/dist/register-terminal-view.js +21 -0
  52. package/dist/register-terminal-view.js.map +1 -0
  53. package/dist/register.d.ts +7 -0
  54. package/dist/register.d.ts.map +1 -0
  55. package/dist/register.js +18 -0
  56. package/dist/register.js.map +1 -0
  57. package/dist/ui.d.ts +4 -0
  58. package/dist/ui.d.ts.map +1 -0
  59. package/dist/ui.js +15 -0
  60. package/dist/ui.js.map +1 -0
  61. package/dist/usePollingTrajectories.d.ts +18 -0
  62. package/dist/usePollingTrajectories.d.ts.map +1 -0
  63. package/dist/usePollingTrajectories.js +87 -0
  64. package/dist/usePollingTrajectories.js.map +1 -0
  65. package/dist/views/bundle.js +646 -0
  66. package/dist/views/bundle.js.map +1 -0
  67. package/package.json +5 -5
@@ -0,0 +1,184 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Button } from "@elizaos/ui";
3
+ import { useAgentElement } from "@elizaos/ui/agent-surface";
4
+ import { Activity, ChevronLeft, History, Route } from "lucide-react";
5
+ import { useState } from "react";
6
+ import { summarizePhases } from "../phases.js";
7
+ import { usePollingTrajectories } from "../usePollingTrajectories.js";
8
+ import { PhaseChip } from "./PhaseChip.js";
9
+ import { PhaseDrilldown } from "./PhaseDrilldown.js";
10
+ function TrajectoryLoggerAppView({ exitToApps }) {
11
+ const state = usePollingTrajectories(true);
12
+ const [sel, setSel] = useState(null);
13
+ const backButton = useAgentElement({
14
+ id: "action-back",
15
+ role: "button",
16
+ label: "Back",
17
+ group: "trajectory-nav",
18
+ description: "Return to the apps list"
19
+ });
20
+ const nowPhases = summarizePhases(state.activeDetail, {
21
+ trajectoryActive: true
22
+ });
23
+ const lastPhases = summarizePhases(state.lastDetail, {
24
+ trajectoryActive: false
25
+ });
26
+ const selected = !sel ? null : (sel.slot === "now" ? nowPhases : lastPhases).find(
27
+ (p) => p.phase === sel.phase
28
+ ) ?? null;
29
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full w-full flex-col bg-bg text-xs", children: [
30
+ /* @__PURE__ */ jsxs("header", { className: "flex items-center justify-between gap-2 px-2 py-2", children: [
31
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
32
+ /* @__PURE__ */ jsx(
33
+ Button,
34
+ {
35
+ ref: backButton.ref,
36
+ variant: "ghost",
37
+ size: "sm",
38
+ onClick: exitToApps,
39
+ "aria-label": "Back",
40
+ ...backButton.agentProps,
41
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
42
+ }
43
+ ),
44
+ /* @__PURE__ */ jsx("span", { className: "grid h-7 w-7 place-items-center", children: /* @__PURE__ */ jsx(Route, { className: "h-3.5 w-3.5 text-accent", "aria-hidden": true }) }),
45
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-txt", children: "Trajectories" })
46
+ ] }),
47
+ state.unavailable ? /* @__PURE__ */ jsx("span", { className: "sr-only max-w-[42vw] truncate text-2xs text-muted/60", children: "Trajectory logging unavailable on this surface" }) : state.error ? /* @__PURE__ */ jsx("span", { className: "max-w-[42vw] truncate text-2xs text-danger", children: state.error }) : !state.ready ? /* @__PURE__ */ jsx("span", { className: "sr-only text-2xs text-muted/60", children: "loading\u2026" }) : /* @__PURE__ */ jsx(LoggingStatusBadge, { active: !!state.active })
48
+ ] }),
49
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-2 overflow-y-auto p-2 pb-32", children: [
50
+ /* @__PURE__ */ jsx(
51
+ PhaseStrip,
52
+ {
53
+ live: true,
54
+ slot: "now",
55
+ trajectory: state.active,
56
+ phases: nowPhases,
57
+ selectedPhase: sel?.slot === "now" ? sel.phase : null,
58
+ onSelect: (phase) => setSel(
59
+ (p) => p?.slot === "now" && p.phase === phase ? null : { slot: "now", phase }
60
+ )
61
+ }
62
+ ),
63
+ /* @__PURE__ */ jsx(
64
+ PhaseStrip,
65
+ {
66
+ live: false,
67
+ slot: "last",
68
+ trajectory: state.last,
69
+ phases: lastPhases,
70
+ selectedPhase: sel?.slot === "last" ? sel.phase : null,
71
+ onSelect: (phase) => setSel(
72
+ (p) => p?.slot === "last" && p.phase === phase ? null : { slot: "last", phase }
73
+ )
74
+ }
75
+ ),
76
+ selected ? /* @__PURE__ */ jsx("div", { className: "max-h-[52vh] overflow-auto px-1 py-2", children: /* @__PURE__ */ jsx(PhaseDrilldown, { phase: selected }) }) : null
77
+ ] })
78
+ ] });
79
+ }
80
+ function PhaseStrip({
81
+ live,
82
+ slot,
83
+ trajectory,
84
+ phases,
85
+ selectedPhase,
86
+ onSelect
87
+ }) {
88
+ const Icon = live ? Activity : History;
89
+ const recording = live && !!trajectory;
90
+ let lastDone = -1;
91
+ phases.forEach((p, i) => {
92
+ if (p.status !== "idle") lastDone = i;
93
+ });
94
+ const fillPct = phases.length > 1 ? Math.max(0, lastDone) / (phases.length - 1) * 100 : 0;
95
+ return /* @__PURE__ */ jsxs(
96
+ "div",
97
+ {
98
+ className: [
99
+ "flex min-w-0 flex-col gap-2 px-2 py-2 transition-colors",
100
+ recording ? "animate-[pulse_2.4s_ease-in-out_infinite]" : ""
101
+ ].join(" "),
102
+ children: [
103
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
104
+ /* @__PURE__ */ jsxs(
105
+ "span",
106
+ {
107
+ title: live ? "Current turn" : "Last turn",
108
+ className: [
109
+ "flex items-center gap-2 text-[11px] font-semibold uppercase tracking-normal",
110
+ recording ? "text-accent" : "text-muted"
111
+ ].join(" "),
112
+ children: [
113
+ /* @__PURE__ */ jsx(
114
+ Icon,
115
+ {
116
+ className: ["h-3.5 w-3.5", recording ? "animate-pulse" : ""].join(
117
+ " "
118
+ ),
119
+ "aria-label": live ? "Current turn" : "Last turn"
120
+ }
121
+ ),
122
+ live ? "Now" : "Last"
123
+ ]
124
+ }
125
+ ),
126
+ !trajectory ? /* @__PURE__ */ jsx("span", { className: "sr-only text-2xs text-muted/50", children: "no turn yet" }) : null
127
+ ] }),
128
+ /* @__PURE__ */ jsxs("div", { className: "relative min-w-0", title: trajectory ? void 0 : "None", children: [
129
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-[12.5%] top-[18px] h-0.5 bg-border/20", children: /* @__PURE__ */ jsx(
130
+ "div",
131
+ {
132
+ className: [
133
+ "h-full transition-all duration-500",
134
+ recording ? "bg-accent/70" : "bg-ok/55"
135
+ ].join(" "),
136
+ style: { width: `${fillPct}%` }
137
+ }
138
+ ) }),
139
+ /* @__PURE__ */ jsx("div", { className: "relative grid min-w-0 grid-cols-4 gap-1", children: phases.map((p) => /* @__PURE__ */ jsx(
140
+ PhaseChip,
141
+ {
142
+ slot,
143
+ phase: p.phase,
144
+ status: p.status,
145
+ summary: p.summary,
146
+ selected: selectedPhase === p.phase,
147
+ onClick: () => onSelect(p.phase)
148
+ },
149
+ p.phase
150
+ )) })
151
+ ] })
152
+ ]
153
+ }
154
+ );
155
+ }
156
+ function LoggingStatusBadge({ active }) {
157
+ const tone = active ? "text-danger" : "text-muted";
158
+ const label = active ? "recording" : "idle";
159
+ return /* @__PURE__ */ jsxs(
160
+ "span",
161
+ {
162
+ title: "Trajectory logging status",
163
+ className: `inline-flex items-center gap-1.5 px-1 py-1 text-2xs font-semibold uppercase tracking-wide ${tone}`,
164
+ "data-testid": "trajectory-logging-badge",
165
+ children: [
166
+ /* @__PURE__ */ jsx(
167
+ "span",
168
+ {
169
+ className: [
170
+ "h-1.5 w-1.5 rounded-full",
171
+ active ? "bg-danger animate-pulse" : "bg-muted/40"
172
+ ].join(" "),
173
+ "aria-hidden": true
174
+ }
175
+ ),
176
+ label
177
+ ]
178
+ }
179
+ );
180
+ }
181
+ export {
182
+ TrajectoryLoggerAppView
183
+ };
184
+ //# sourceMappingURL=TrajectoryLoggerAppView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/TrajectoryLoggerAppView.tsx"],"sourcesContent":["/**\n * TrajectoryLoggerAppView - the legacy full-screen GUI overlay for the\n * Trajectory Logger app, mounted through the OverlayApp loader\n * (`trajectory-logger-app.ts`) and the app-shell page (`register.ts`).\n *\n * The unified GUI/XR/TUI surface is `TrajectoryLoggerView` (a thin data wrapper\n * over `TrajectoryLoggerSpatialView`); this hand-written overlay stays for the\n * OverlayApp mount path, mirroring how the Phone surface keeps `PhoneAppView`\n * alongside the collapsed `PhoneView`.\n */\n\nimport { Button, type OverlayAppContext } from \"@elizaos/ui\";\nimport { useAgentElement } from \"@elizaos/ui/agent-surface\";\nimport { Activity, ChevronLeft, History, Route } from \"lucide-react\";\nimport { useState } from \"react\";\nimport type { TrajectoryListItem } from \"../api-client.js\";\nimport { type PhaseName, type PhaseSummary, summarizePhases } from \"../phases.js\";\nimport { usePollingTrajectories } from \"../usePollingTrajectories.js\";\nimport { PhaseChip } from \"./PhaseChip.js\";\nimport { PhaseDrilldown } from \"./PhaseDrilldown.js\";\n\nexport type Slot = \"now\" | \"last\";\ntype Selection = { slot: Slot; phase: PhaseName } | null;\n\nexport function TrajectoryLoggerAppView({ exitToApps }: OverlayAppContext) {\n const state = usePollingTrajectories(true);\n const [sel, setSel] = useState<Selection>(null);\n\n const backButton = useAgentElement<HTMLButtonElement>({\n id: \"action-back\",\n role: \"button\",\n label: \"Back\",\n group: \"trajectory-nav\",\n description: \"Return to the apps list\",\n });\n\n const nowPhases = summarizePhases(state.activeDetail, {\n trajectoryActive: true,\n });\n const lastPhases = summarizePhases(state.lastDetail, {\n trajectoryActive: false,\n });\n const selected: PhaseSummary | null = !sel\n ? null\n : ((sel.slot === \"now\" ? nowPhases : lastPhases).find(\n (p) => p.phase === sel.phase,\n ) ?? null);\n\n return (\n <div className=\"flex h-full w-full flex-col bg-bg text-xs\">\n <header className=\"flex items-center justify-between gap-2 px-2 py-2\">\n <div className=\"flex items-center gap-2\">\n <Button\n ref={backButton.ref}\n variant=\"ghost\"\n size=\"sm\"\n onClick={exitToApps}\n aria-label=\"Back\"\n {...backButton.agentProps}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </Button>\n <span className=\"grid h-7 w-7 place-items-center\">\n <Route className=\"h-3.5 w-3.5 text-accent\" aria-hidden />\n </span>\n <span className=\"text-sm font-semibold text-txt\">Trajectories</span>\n </div>\n {state.unavailable ? (\n <span className=\"sr-only max-w-[42vw] truncate text-2xs text-muted/60\">\n Trajectory logging unavailable on this surface\n </span>\n ) : state.error ? (\n <span className=\"max-w-[42vw] truncate text-2xs text-danger\">\n {state.error}\n </span>\n ) : !state.ready ? (\n <span className=\"sr-only text-2xs text-muted/60\">loading…</span>\n ) : (\n <LoggingStatusBadge active={!!state.active} />\n )}\n </header>\n\n <div className=\"flex flex-1 flex-col gap-2 overflow-y-auto p-2 pb-32\">\n <PhaseStrip\n live\n slot=\"now\"\n trajectory={state.active}\n phases={nowPhases}\n selectedPhase={sel?.slot === \"now\" ? sel.phase : null}\n onSelect={(phase) =>\n setSel((p) =>\n p?.slot === \"now\" && p.phase === phase\n ? null\n : { slot: \"now\", phase },\n )\n }\n />\n <PhaseStrip\n live={false}\n slot=\"last\"\n trajectory={state.last}\n phases={lastPhases}\n selectedPhase={sel?.slot === \"last\" ? sel.phase : null}\n onSelect={(phase) =>\n setSel((p) =>\n p?.slot === \"last\" && p.phase === phase\n ? null\n : { slot: \"last\", phase },\n )\n }\n />\n {selected ? (\n <div className=\"max-h-[52vh] overflow-auto px-1 py-2\">\n <PhaseDrilldown phase={selected} />\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction PhaseStrip({\n live,\n slot,\n trajectory,\n phases,\n selectedPhase,\n onSelect,\n}: {\n live: boolean;\n slot: Slot;\n trajectory: TrajectoryListItem | null;\n phases: PhaseSummary[];\n selectedPhase: PhaseName | null;\n onSelect: (phase: PhaseName) => void;\n}) {\n const Icon = live ? Activity : History;\n const recording = live && !!trajectory;\n // How far the progress line should fill: up to and including the last\n // non-idle phase. 0 when nothing has run.\n let lastDone = -1;\n phases.forEach((p, i) => {\n if (p.status !== \"idle\") lastDone = i;\n });\n const fillPct =\n phases.length > 1 ? (Math.max(0, lastDone) / (phases.length - 1)) * 100 : 0;\n return (\n <div\n className={[\n \"flex min-w-0 flex-col gap-2 px-2 py-2 transition-colors\",\n recording ? \"animate-[pulse_2.4s_ease-in-out_infinite]\" : \"\",\n ].join(\" \")}\n >\n <div className=\"flex items-center justify-between\">\n <span\n title={live ? \"Current turn\" : \"Last turn\"}\n className={[\n \"flex items-center gap-2 text-[11px] font-semibold uppercase tracking-normal\",\n recording ? \"text-accent\" : \"text-muted\",\n ].join(\" \")}\n >\n <Icon\n className={[\"h-3.5 w-3.5\", recording ? \"animate-pulse\" : \"\"].join(\n \" \",\n )}\n aria-label={live ? \"Current turn\" : \"Last turn\"}\n />\n {live ? \"Now\" : \"Last\"}\n </span>\n {!trajectory ? (\n <span className=\"sr-only text-2xs text-muted/50\">no turn yet</span>\n ) : null}\n </div>\n <div className=\"relative min-w-0\" title={trajectory ? undefined : \"None\"}>\n {/* Progress rail behind the medallion row */}\n <div className=\"pointer-events-none absolute inset-x-[12.5%] top-[18px] h-0.5 bg-border/20\">\n <div\n className={[\n \"h-full transition-all duration-500\",\n recording ? \"bg-accent/70\" : \"bg-ok/55\",\n ].join(\" \")}\n style={{ width: `${fillPct}%` }}\n />\n </div>\n <div className=\"relative grid min-w-0 grid-cols-4 gap-1\">\n {phases.map((p) => (\n <PhaseChip\n key={p.phase}\n slot={slot}\n phase={p.phase}\n status={p.status}\n summary={p.summary}\n selected={selectedPhase === p.phase}\n onClick={() => onSelect(p.phase)}\n />\n ))}\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * Compact status badge for the overlay header.\n */\nfunction LoggingStatusBadge({ active }: { active: boolean }) {\n const tone = active ? \"text-danger\" : \"text-muted\";\n const label = active ? \"recording\" : \"idle\";\n return (\n <span\n title=\"Trajectory logging status\"\n className={`inline-flex items-center gap-1.5 px-1 py-1 text-2xs font-semibold uppercase tracking-wide ${tone}`}\n data-testid=\"trajectory-logging-badge\"\n >\n <span\n className={[\n \"h-1.5 w-1.5 rounded-full\",\n active ? \"bg-danger animate-pulse\" : \"bg-muted/40\",\n ].join(\" \")}\n aria-hidden\n />\n {label}\n </span>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * TrajectoryLoggerSpatialView — the trajectory inspector authored once with the
3
+ * spatial vocabulary, so it renders correctly wherever it is displayed:
4
+ *
5
+ * - GUI / XR - mounted in `<SpatialSurface>` (DOM; XR scales up).
6
+ * - TUI - rendered to real terminal lines by the agent terminal, via
7
+ * `registerSpatialTerminalView` (see `register-terminal-view.tsx`).
8
+ *
9
+ * It is purely presentational (a snapshot + an action callback in, primitives
10
+ * out) and imports only the cross-modality primitives plus type-only views of
11
+ * the trajectory wire shapes, so it is safe to render in the Node agent process
12
+ * where the terminal lives (no browser/runtime import, no polling hook).
13
+ */
14
+ import type { PhaseName, PhaseSummary } from "../phases.ts";
15
+ export type Slot = "now" | "last";
16
+ /** One trajectory track: its phase tabs plus a recording/empty indicator. */
17
+ export interface TrajectoryTrack {
18
+ /** True once the agent has captured at least one turn for this slot. */
19
+ hasTrajectory: boolean;
20
+ /** Phase summaries in canonical order (HANDLE / PLAN / ACTION / EVALUATE). */
21
+ phases: PhaseSummary[];
22
+ }
23
+ export interface TrajectorySnapshot {
24
+ /** False while the first poll is still in flight. */
25
+ ready: boolean;
26
+ /** Whether the active ("now") trajectory is currently recording. */
27
+ recording: boolean;
28
+ /**
29
+ * True when the trajectory routes are not mounted on this surface (the
30
+ * provider plugin is absent). Distinct from `error`: the view shows a calm
31
+ * "unavailable on this surface" message instead of the strips.
32
+ */
33
+ unavailable?: boolean;
34
+ /** Fetch error from the trajectories endpoint, if any. */
35
+ error?: string | null;
36
+ /** In-flight trajectory track. */
37
+ now: TrajectoryTrack;
38
+ /** Last completed trajectory track. */
39
+ last: TrajectoryTrack;
40
+ /** Which phase tab (if any) is expanded into its drilldown body. */
41
+ selected?: {
42
+ slot: Slot;
43
+ phase: PhaseName;
44
+ } | null;
45
+ }
46
+ export interface TrajectoryLoggerSpatialViewProps {
47
+ snapshot: TrajectorySnapshot;
48
+ /** Dispatch by agent id: `back`, `select:<slot>:<phase>`, `refresh`. */
49
+ onAction?: (action: string) => void;
50
+ }
51
+ export declare const EMPTY_TRAJECTORY_SNAPSHOT: TrajectorySnapshot;
52
+ export declare function TrajectoryLoggerSpatialView({ snapshot, onAction, }: TrajectoryLoggerSpatialViewProps): import("react/jsx-runtime").JSX.Element;
53
+ //# sourceMappingURL=TrajectoryLoggerSpatialView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrajectoryLoggerSpatialView.d.ts","sourceRoot":"","sources":["../../src/components/TrajectoryLoggerSpatialView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkBH,OAAO,KAAK,EAAE,SAAS,EAAe,YAAY,EAAE,MAAM,cAAc,CAAC;AAGzE,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAElC,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,aAAa,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kCAAkC;IAClC,GAAG,EAAE,eAAe,CAAC;IACrB,uCAAuC;IACvC,IAAI,EAAE,eAAe,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAeD,eAAO,MAAM,yBAAyB,EAAE,kBAQvC,CAAC;AAiCF,wBAAgB,2BAA2B,CAAC,EAC1C,QAAQ,EACR,QAAQ,GACT,EAAE,gCAAgC,2CAsElC"}
@@ -0,0 +1,293 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import {
3
+ Button,
4
+ Card,
5
+ Divider,
6
+ HStack,
7
+ List,
8
+ Text,
9
+ VStack
10
+ } from "@elizaos/ui/spatial";
11
+ import { extractShouldRespondDecision, PHASES } from "../phases.js";
12
+ const EMPTY_TRACK = {
13
+ hasTrajectory: false,
14
+ phases: PHASES.map((phase) => ({
15
+ phase,
16
+ status: "idle",
17
+ summary: null,
18
+ llmCalls: [],
19
+ providerAccesses: [],
20
+ toolEvents: [],
21
+ evaluationEvents: []
22
+ }))
23
+ };
24
+ const EMPTY_TRAJECTORY_SNAPSHOT = {
25
+ ready: false,
26
+ recording: false,
27
+ unavailable: false,
28
+ error: null,
29
+ now: EMPTY_TRACK,
30
+ last: EMPTY_TRACK,
31
+ selected: null
32
+ };
33
+ function statusTone(status) {
34
+ switch (status) {
35
+ case "active":
36
+ return "primary";
37
+ case "done":
38
+ return "success";
39
+ case "error":
40
+ return "danger";
41
+ case "skipped":
42
+ return "warning";
43
+ default:
44
+ return "muted";
45
+ }
46
+ }
47
+ function statusMark(status) {
48
+ switch (status) {
49
+ case "active":
50
+ return "*";
51
+ case "done":
52
+ return "+";
53
+ case "error":
54
+ return "x";
55
+ case "skipped":
56
+ return "-";
57
+ default:
58
+ return ".";
59
+ }
60
+ }
61
+ function TrajectoryLoggerSpatialView({
62
+ snapshot,
63
+ onAction
64
+ }) {
65
+ const selected = resolveSelected(snapshot);
66
+ return /* @__PURE__ */ jsxs(Card, { gap: 1, padding: 1, children: [
67
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
68
+ /* @__PURE__ */ jsx(
69
+ Button,
70
+ {
71
+ variant: "ghost",
72
+ tone: "default",
73
+ agent: "back",
74
+ onPress: () => onAction?.("back"),
75
+ children: "Back"
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", grow: 1, children: "route" }),
79
+ snapshot.unavailable ? null : !snapshot.ready ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: "loading" }) : /* @__PURE__ */ jsx(
80
+ Text,
81
+ {
82
+ style: "caption",
83
+ tone: snapshot.recording ? "danger" : "muted",
84
+ bold: snapshot.recording,
85
+ children: snapshot.recording ? "[*] recording" : "[ ] idle"
86
+ }
87
+ )
88
+ ] }),
89
+ snapshot.unavailable ? /* @__PURE__ */ jsx(Text, { tone: "muted", style: "caption", dim: true, children: "Trajectory logging unavailable on this surface" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
90
+ snapshot.error ? /* @__PURE__ */ jsx(Text, { tone: "danger", style: "caption", children: snapshot.error }) : null,
91
+ /* @__PURE__ */ jsx(
92
+ PhaseStrip,
93
+ {
94
+ live: true,
95
+ slot: "now",
96
+ track: snapshot.now,
97
+ selectedPhase: selected?.slot === "now" ? selected.phase : null,
98
+ onSelect: (phase) => onAction?.(`select:now:${phase}`)
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsx(
102
+ PhaseStrip,
103
+ {
104
+ live: false,
105
+ slot: "last",
106
+ track: snapshot.last,
107
+ selectedPhase: selected?.slot === "last" ? selected.phase : null,
108
+ onSelect: (phase) => onAction?.(`select:last:${phase}`)
109
+ }
110
+ ),
111
+ selected.summary ? /* @__PURE__ */ jsxs(VStack, { gap: 1, children: [
112
+ /* @__PURE__ */ jsx(
113
+ Divider,
114
+ {
115
+ label: `${selected.slot === "now" ? "now" : "last"} / ${selected.summary.phase}`
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsx(PhaseDrilldownBody, { phase: selected.summary })
119
+ ] }) : null
120
+ ] })
121
+ ] });
122
+ }
123
+ function resolveSelected(snapshot) {
124
+ const sel = snapshot.selected ?? null;
125
+ if (!sel) return { slot: "now", phase: "HANDLE", summary: null };
126
+ const track = sel.slot === "now" ? snapshot.now : snapshot.last;
127
+ const summary = track.phases.find((p) => p.phase === sel.phase) ?? null;
128
+ return { slot: sel.slot, phase: sel.phase, summary };
129
+ }
130
+ function PhaseStrip({
131
+ live,
132
+ slot,
133
+ track,
134
+ selectedPhase,
135
+ onSelect
136
+ }) {
137
+ const recording = live && track.hasTrajectory;
138
+ const lastDone = track.phases.reduce(
139
+ (acc, p, i) => p.status !== "idle" ? i : acc,
140
+ -1
141
+ );
142
+ const total = track.phases.length;
143
+ return /* @__PURE__ */ jsxs(VStack, { gap: 1, agent: `strip-${slot}`, children: [
144
+ /* @__PURE__ */ jsx(Divider, { label: live ? "now" : "last" }),
145
+ /* @__PURE__ */ jsx(
146
+ Text,
147
+ {
148
+ style: "caption",
149
+ tone: recording ? "primary" : "muted",
150
+ align: "center",
151
+ children: !track.hasTrajectory ? "no turn yet" : progressBar(lastDone, total)
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx(List, { gap: 0, children: track.phases.map((p) => /* @__PURE__ */ jsxs(
155
+ HStack,
156
+ {
157
+ gap: 1,
158
+ align: "center",
159
+ agent: `phase-${slot}-${p.phase}`,
160
+ children: [
161
+ /* @__PURE__ */ jsx(Text, { tone: statusTone(p.status), bold: true, children: statusMark(p.status) }),
162
+ /* @__PURE__ */ jsx(Text, { bold: selectedPhase === p.phase, width: "30%", wrap: false, children: p.phase }),
163
+ /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", grow: 1, wrap: false, children: p.summary ?? p.status }),
164
+ /* @__PURE__ */ jsx(
165
+ Button,
166
+ {
167
+ variant: selectedPhase === p.phase ? "solid" : "ghost",
168
+ tone: statusTone(p.status),
169
+ agent: `select-${slot}-${p.phase}`,
170
+ onPress: () => onSelect(p.phase),
171
+ children: phaseCount(p) || "open"
172
+ }
173
+ )
174
+ ]
175
+ },
176
+ p.phase
177
+ )) })
178
+ ] });
179
+ }
180
+ function progressBar(lastDone, total) {
181
+ if (total <= 0) return "";
182
+ const filled = Math.max(0, lastDone + 1);
183
+ return `[${"=".repeat(filled)}${"-".repeat(Math.max(0, total - filled))}]`;
184
+ }
185
+ function phaseCount(phase) {
186
+ const n = phase.llmCalls.length + phase.toolEvents.length + phase.evaluationEvents.length;
187
+ return n > 0 ? String(n) : "";
188
+ }
189
+ function PhaseDrilldownBody({ phase }) {
190
+ switch (phase.phase) {
191
+ case "HANDLE":
192
+ return /* @__PURE__ */ jsx(HandleBody, { calls: phase.llmCalls, ctx: phase.providerAccesses });
193
+ case "PLAN":
194
+ return /* @__PURE__ */ jsx(PlanBody, { calls: phase.llmCalls });
195
+ case "ACTION":
196
+ return /* @__PURE__ */ jsx(ActionBody, { events: phase.toolEvents });
197
+ case "EVALUATE":
198
+ return /* @__PURE__ */ jsx(EvaluateBody, { calls: phase.llmCalls, events: phase.evaluationEvents });
199
+ }
200
+ }
201
+ function preview(text, max = 160) {
202
+ const trimmed = text.trim();
203
+ if (trimmed.length <= max) return trimmed;
204
+ return `${trimmed.slice(0, max)}...`;
205
+ }
206
+ function HandleBody({
207
+ calls,
208
+ ctx
209
+ }) {
210
+ const respond = calls.find(
211
+ (c) => (c.stepType || c.purpose || "").toLowerCase() === "should_respond"
212
+ );
213
+ const decision = respond ? extractShouldRespondDecision(respond) : null;
214
+ const providers = [
215
+ ...new Set(ctx.map((p) => p.providerName).filter(Boolean))
216
+ ];
217
+ if (!decision && providers.length === 0) {
218
+ return /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", dim: true, children: "no handle activity" });
219
+ }
220
+ return /* @__PURE__ */ jsxs(VStack, { gap: 1, children: [
221
+ decision ? /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
222
+ /* @__PURE__ */ jsx(Text, { bold: true, children: decision.decision }),
223
+ decision.reasoning ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", grow: 1, children: preview(decision.reasoning) }) : null
224
+ ] }) : null,
225
+ providers.length > 0 ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: `ctx: ${providers.join(", ")}` }) : null
226
+ ] });
227
+ }
228
+ function PlanBody({ calls }) {
229
+ const last = calls[calls.length - 1];
230
+ if (!last) {
231
+ return /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", dim: true, children: "no plan yet" });
232
+ }
233
+ const text = preview(last.response);
234
+ return /* @__PURE__ */ jsxs(VStack, { gap: 1, children: [
235
+ last.actionType ? /* @__PURE__ */ jsx(Text, { bold: true, children: last.actionType }) : null,
236
+ text ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: text }) : null
237
+ ] });
238
+ }
239
+ function ActionBody({ events }) {
240
+ if (events.length === 0) {
241
+ return /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", dim: true, children: "no actions" });
242
+ }
243
+ return /* @__PURE__ */ jsx(List, { gap: 1, children: events.map((e) => {
244
+ const name = e.actionName || e.toolName || e.name || "action";
245
+ const tone = toolTone(e);
246
+ return /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", agent: `tool-${e.id}`, children: [
247
+ /* @__PURE__ */ jsx(Text, { tone, bold: true, children: toolMark(e) }),
248
+ /* @__PURE__ */ jsx(Text, { grow: 1, wrap: false, children: name }),
249
+ typeof e.durationMs === "number" ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: `${e.durationMs}ms` }) : null,
250
+ e.error ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "danger", wrap: false, children: preview(e.error, 40) }) : null
251
+ ] }, e.id);
252
+ }) });
253
+ }
254
+ function toolTone(e) {
255
+ if (e.type === "tool_error" || e.error || e.success === false)
256
+ return "danger";
257
+ if (e.type === "tool_result" || e.status === "completed" || e.success === true)
258
+ return "success";
259
+ if (e.status === "skipped") return "warning";
260
+ return "primary";
261
+ }
262
+ function toolMark(e) {
263
+ if (e.type === "tool_error" || e.error || e.success === false) return "x";
264
+ if (e.type === "tool_result" || e.status === "completed" || e.success === true)
265
+ return "+";
266
+ if (e.status === "skipped") return "-";
267
+ return "*";
268
+ }
269
+ function EvaluateBody({
270
+ calls,
271
+ events
272
+ }) {
273
+ if (events.length === 0 && calls.length === 0) {
274
+ return /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", dim: true, children: "no evaluation" });
275
+ }
276
+ return /* @__PURE__ */ jsx(List, { gap: 1, children: events.map((e) => {
277
+ const name = e.evaluatorName || e.name || "evaluator";
278
+ const tone = e.error || e.success === false ? "danger" : e.success === true || e.status === "completed" ? "success" : e.status === "skipped" ? "warning" : "primary";
279
+ return /* @__PURE__ */ jsxs(VStack, { gap: 0, agent: `eval-${e.id}`, children: [
280
+ /* @__PURE__ */ jsxs(HStack, { gap: 1, align: "center", children: [
281
+ /* @__PURE__ */ jsx(Text, { tone, grow: 1, wrap: false, children: name }),
282
+ e.decision ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: e.decision }) : null
283
+ ] }),
284
+ e.thought ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "muted", children: preview(e.thought) }) : null,
285
+ e.error ? /* @__PURE__ */ jsx(Text, { style: "caption", tone: "danger", children: preview(e.error, 80) }) : null
286
+ ] }, e.id);
287
+ }) });
288
+ }
289
+ export {
290
+ EMPTY_TRAJECTORY_SNAPSHOT,
291
+ TrajectoryLoggerSpatialView
292
+ };
293
+ //# sourceMappingURL=TrajectoryLoggerSpatialView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/TrajectoryLoggerSpatialView.tsx"],"sourcesContent":["/**\n * TrajectoryLoggerSpatialView — the trajectory inspector authored once with the\n * spatial vocabulary, so it renders correctly wherever it is displayed:\n *\n * - GUI / XR - mounted in `<SpatialSurface>` (DOM; XR scales up).\n * - TUI - rendered to real terminal lines by the agent terminal, via\n * `registerSpatialTerminalView` (see `register-terminal-view.tsx`).\n *\n * It is purely presentational (a snapshot + an action callback in, primitives\n * out) and imports only the cross-modality primitives plus type-only views of\n * the trajectory wire shapes, so it is safe to render in the Node agent process\n * where the terminal lives (no browser/runtime import, no polling hook).\n */\n\nimport {\n Button,\n Card,\n Divider,\n HStack,\n List,\n type SpatialTone,\n Text,\n VStack,\n} from \"@elizaos/ui/spatial\";\nimport type {\n UIEvaluationEvent,\n UILlmCall,\n UIProviderAccess,\n UIToolEvent,\n} from \"../api-client.js\";\nimport type { PhaseName, PhaseStatus, PhaseSummary } from \"../phases.js\";\nimport { extractShouldRespondDecision, PHASES } from \"../phases.js\";\n\nexport type Slot = \"now\" | \"last\";\n\n/** One trajectory track: its phase tabs plus a recording/empty indicator. */\nexport interface TrajectoryTrack {\n /** True once the agent has captured at least one turn for this slot. */\n hasTrajectory: boolean;\n /** Phase summaries in canonical order (HANDLE / PLAN / ACTION / EVALUATE). */\n phases: PhaseSummary[];\n}\n\nexport interface TrajectorySnapshot {\n /** False while the first poll is still in flight. */\n ready: boolean;\n /** Whether the active (\"now\") trajectory is currently recording. */\n recording: boolean;\n /**\n * True when the trajectory routes are not mounted on this surface (the\n * provider plugin is absent). Distinct from `error`: the view shows a calm\n * \"unavailable on this surface\" message instead of the strips.\n */\n unavailable?: boolean;\n /** Fetch error from the trajectories endpoint, if any. */\n error?: string | null;\n /** In-flight trajectory track. */\n now: TrajectoryTrack;\n /** Last completed trajectory track. */\n last: TrajectoryTrack;\n /** Which phase tab (if any) is expanded into its drilldown body. */\n selected?: { slot: Slot; phase: PhaseName } | null;\n}\n\nexport interface TrajectoryLoggerSpatialViewProps {\n snapshot: TrajectorySnapshot;\n /** Dispatch by agent id: `back`, `select:<slot>:<phase>`, `refresh`. */\n onAction?: (action: string) => void;\n}\n\nconst EMPTY_TRACK: TrajectoryTrack = {\n hasTrajectory: false,\n phases: PHASES.map((phase) => ({\n phase,\n status: \"idle\",\n summary: null,\n llmCalls: [],\n providerAccesses: [],\n toolEvents: [],\n evaluationEvents: [],\n })),\n};\n\nexport const EMPTY_TRAJECTORY_SNAPSHOT: TrajectorySnapshot = {\n ready: false,\n recording: false,\n unavailable: false,\n error: null,\n now: EMPTY_TRACK,\n last: EMPTY_TRACK,\n selected: null,\n};\n\nfunction statusTone(status: PhaseStatus): SpatialTone {\n switch (status) {\n case \"active\":\n return \"primary\";\n case \"done\":\n return \"success\";\n case \"error\":\n return \"danger\";\n case \"skipped\":\n return \"warning\";\n default:\n return \"muted\";\n }\n}\n\n/** ASCII status marker (avoid East-Asian ambiguous glyphs in the terminal). */\nfunction statusMark(status: PhaseStatus): string {\n switch (status) {\n case \"active\":\n return \"*\";\n case \"done\":\n return \"+\";\n case \"error\":\n return \"x\";\n case \"skipped\":\n return \"-\";\n default:\n return \".\";\n }\n}\n\nexport function TrajectoryLoggerSpatialView({\n snapshot,\n onAction,\n}: TrajectoryLoggerSpatialViewProps) {\n const selected = resolveSelected(snapshot);\n return (\n <Card gap={1} padding={1}>\n <HStack gap={1} align=\"center\">\n <Button\n variant=\"ghost\"\n tone=\"default\"\n agent=\"back\"\n onPress={() => onAction?.(\"back\")}\n >\n Back\n </Button>\n <Text style=\"caption\" tone=\"muted\" grow={1}>\n route\n </Text>\n {snapshot.unavailable ? null : !snapshot.ready ? (\n <Text style=\"caption\" tone=\"muted\">\n loading\n </Text>\n ) : (\n <Text\n style=\"caption\"\n tone={snapshot.recording ? \"danger\" : \"muted\"}\n bold={snapshot.recording}\n >\n {snapshot.recording ? \"[*] recording\" : \"[ ] idle\"}\n </Text>\n )}\n </HStack>\n\n {snapshot.unavailable ? (\n <Text tone=\"muted\" style=\"caption\" dim>\n Trajectory logging unavailable on this surface\n </Text>\n ) : (\n <>\n {snapshot.error ? (\n <Text tone=\"danger\" style=\"caption\">\n {snapshot.error}\n </Text>\n ) : null}\n\n <PhaseStrip\n live\n slot=\"now\"\n track={snapshot.now}\n selectedPhase={selected?.slot === \"now\" ? selected.phase : null}\n onSelect={(phase) => onAction?.(`select:now:${phase}`)}\n />\n <PhaseStrip\n live={false}\n slot=\"last\"\n track={snapshot.last}\n selectedPhase={selected?.slot === \"last\" ? selected.phase : null}\n onSelect={(phase) => onAction?.(`select:last:${phase}`)}\n />\n\n {selected.summary ? (\n <VStack gap={1}>\n <Divider\n label={`${selected.slot === \"now\" ? \"now\" : \"last\"} / ${selected.summary.phase}`}\n />\n <PhaseDrilldownBody phase={selected.summary} />\n </VStack>\n ) : null}\n </>\n )}\n </Card>\n );\n}\n\nfunction resolveSelected(snapshot: TrajectorySnapshot): {\n slot: Slot;\n phase: PhaseName;\n summary: PhaseSummary | null;\n} {\n const sel = snapshot.selected ?? null;\n if (!sel) return { slot: \"now\", phase: \"HANDLE\", summary: null };\n const track = sel.slot === \"now\" ? snapshot.now : snapshot.last;\n const summary = track.phases.find((p) => p.phase === sel.phase) ?? null;\n return { slot: sel.slot, phase: sel.phase, summary };\n}\n\nfunction PhaseStrip({\n live,\n slot,\n track,\n selectedPhase,\n onSelect,\n}: {\n live: boolean;\n slot: Slot;\n track: TrajectoryTrack;\n selectedPhase: PhaseName | null;\n onSelect: (phase: PhaseName) => void;\n}) {\n const recording = live && track.hasTrajectory;\n const lastDone = track.phases.reduce(\n (acc, p, i) => (p.status !== \"idle\" ? i : acc),\n -1,\n );\n const total = track.phases.length;\n // Borderless labeled section (no nested box). The divider carries the\n // now/last label; recording state shows through the phase statuses.\n return (\n <VStack gap={1} agent={`strip-${slot}`}>\n <Divider label={live ? \"now\" : \"last\"} />\n <Text\n style=\"caption\"\n tone={recording ? \"primary\" : \"muted\"}\n align=\"center\"\n >\n {!track.hasTrajectory ? \"no turn yet\" : progressBar(lastDone, total)}\n </Text>\n <List gap={0}>\n {track.phases.map((p) => (\n <HStack\n key={p.phase}\n gap={1}\n align=\"center\"\n agent={`phase-${slot}-${p.phase}`}\n >\n <Text tone={statusTone(p.status)} bold>\n {statusMark(p.status)}\n </Text>\n <Text bold={selectedPhase === p.phase} width=\"30%\" wrap={false}>\n {p.phase}\n </Text>\n <Text style=\"caption\" tone=\"muted\" grow={1} wrap={false}>\n {p.summary ?? p.status}\n </Text>\n <Button\n variant={selectedPhase === p.phase ? \"solid\" : \"ghost\"}\n tone={statusTone(p.status)}\n agent={`select-${slot}-${p.phase}`}\n onPress={() => onSelect(p.phase)}\n >\n {phaseCount(p) || \"open\"}\n </Button>\n </HStack>\n ))}\n </List>\n </VStack>\n );\n}\n\nfunction progressBar(lastDone: number, total: number): string {\n if (total <= 0) return \"\";\n const filled = Math.max(0, lastDone + 1);\n return `[${\"=\".repeat(filled)}${\"-\".repeat(Math.max(0, total - filled))}]`;\n}\n\nfunction phaseCount(phase: PhaseSummary): string {\n const n =\n phase.llmCalls.length +\n phase.toolEvents.length +\n phase.evaluationEvents.length;\n return n > 0 ? String(n) : \"\";\n}\n\nfunction PhaseDrilldownBody({ phase }: { phase: PhaseSummary }) {\n switch (phase.phase) {\n case \"HANDLE\":\n return <HandleBody calls={phase.llmCalls} ctx={phase.providerAccesses} />;\n case \"PLAN\":\n return <PlanBody calls={phase.llmCalls} />;\n case \"ACTION\":\n return <ActionBody events={phase.toolEvents} />;\n case \"EVALUATE\":\n return (\n <EvaluateBody calls={phase.llmCalls} events={phase.evaluationEvents} />\n );\n }\n}\n\nfunction preview(text: string, max = 160): string {\n const trimmed = text.trim();\n if (trimmed.length <= max) return trimmed;\n return `${trimmed.slice(0, max)}...`;\n}\n\nfunction HandleBody({\n calls,\n ctx,\n}: {\n calls: UILlmCall[];\n ctx: UIProviderAccess[];\n}) {\n const respond = calls.find(\n (c) => (c.stepType || c.purpose || \"\").toLowerCase() === \"should_respond\",\n );\n const decision = respond ? extractShouldRespondDecision(respond) : null;\n const providers = [\n ...new Set(ctx.map((p) => p.providerName).filter(Boolean)),\n ];\n if (!decision && providers.length === 0) {\n return (\n <Text style=\"caption\" tone=\"muted\" dim>\n no handle activity\n </Text>\n );\n }\n return (\n <VStack gap={1}>\n {decision ? (\n <HStack gap={1} align=\"center\">\n <Text bold>{decision.decision}</Text>\n {decision.reasoning ? (\n <Text style=\"caption\" tone=\"muted\" grow={1}>\n {preview(decision.reasoning)}\n </Text>\n ) : null}\n </HStack>\n ) : null}\n {providers.length > 0 ? (\n <Text style=\"caption\" tone=\"muted\">\n {`ctx: ${providers.join(\", \")}`}\n </Text>\n ) : null}\n </VStack>\n );\n}\n\nfunction PlanBody({ calls }: { calls: UILlmCall[] }) {\n const last = calls[calls.length - 1];\n if (!last) {\n return (\n <Text style=\"caption\" tone=\"muted\" dim>\n no plan yet\n </Text>\n );\n }\n const text = preview(last.response);\n return (\n <VStack gap={1}>\n {last.actionType ? <Text bold>{last.actionType}</Text> : null}\n {text ? (\n <Text style=\"caption\" tone=\"muted\">\n {text}\n </Text>\n ) : null}\n </VStack>\n );\n}\n\nfunction ActionBody({ events }: { events: UIToolEvent[] }) {\n if (events.length === 0) {\n return (\n <Text style=\"caption\" tone=\"muted\" dim>\n no actions\n </Text>\n );\n }\n return (\n <List gap={1}>\n {events.map((e) => {\n const name = e.actionName || e.toolName || e.name || \"action\";\n const tone = toolTone(e);\n return (\n <HStack key={e.id} gap={1} align=\"center\" agent={`tool-${e.id}`}>\n <Text tone={tone} bold>\n {toolMark(e)}\n </Text>\n <Text grow={1} wrap={false}>\n {name}\n </Text>\n {typeof e.durationMs === \"number\" ? (\n <Text style=\"caption\" tone=\"muted\">\n {`${e.durationMs}ms`}\n </Text>\n ) : null}\n {e.error ? (\n <Text style=\"caption\" tone=\"danger\" wrap={false}>\n {preview(e.error, 40)}\n </Text>\n ) : null}\n </HStack>\n );\n })}\n </List>\n );\n}\n\nfunction toolTone(e: UIToolEvent): SpatialTone {\n if (e.type === \"tool_error\" || e.error || e.success === false)\n return \"danger\";\n if (\n e.type === \"tool_result\" ||\n e.status === \"completed\" ||\n e.success === true\n )\n return \"success\";\n if (e.status === \"skipped\") return \"warning\";\n return \"primary\";\n}\n\nfunction toolMark(e: UIToolEvent): string {\n if (e.type === \"tool_error\" || e.error || e.success === false) return \"x\";\n if (\n e.type === \"tool_result\" ||\n e.status === \"completed\" ||\n e.success === true\n )\n return \"+\";\n if (e.status === \"skipped\") return \"-\";\n return \"*\";\n}\n\nfunction EvaluateBody({\n calls,\n events,\n}: {\n calls: UILlmCall[];\n events: UIEvaluationEvent[];\n}) {\n if (events.length === 0 && calls.length === 0) {\n return (\n <Text style=\"caption\" tone=\"muted\" dim>\n no evaluation\n </Text>\n );\n }\n return (\n <List gap={1}>\n {events.map((e) => {\n const name = e.evaluatorName || e.name || \"evaluator\";\n const tone =\n e.error || e.success === false\n ? \"danger\"\n : e.success === true || e.status === \"completed\"\n ? \"success\"\n : e.status === \"skipped\"\n ? \"warning\"\n : \"primary\";\n return (\n <VStack key={e.id} gap={0} agent={`eval-${e.id}`}>\n <HStack gap={1} align=\"center\">\n <Text tone={tone as SpatialTone} grow={1} wrap={false}>\n {name}\n </Text>\n {e.decision ? (\n <Text style=\"caption\" tone=\"muted\">\n {e.decision}\n </Text>\n ) : null}\n </HStack>\n {e.thought ? (\n <Text style=\"caption\" tone=\"muted\">\n {preview(e.thought)}\n </Text>\n ) : null}\n {e.error ? (\n <Text style=\"caption\" tone=\"danger\">\n {preview(e.error, 80)}\n </Text>\n ) : null}\n </VStack>\n );\n })}\n </List>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * TrajectoryLoggerView - the single GUI/XR data wrapper for the Trajectory
3
+ * Logger surface.
4
+ *
5
+ * It owns the live trajectory data (the 700ms polling hook + the selected-phase
6
+ * drilldown state) and renders the one presentational
7
+ * {@link TrajectoryLoggerSpatialView} inside a {@link SpatialSurface}. Omitting
8
+ * the `modality` prop lets `SpatialSurface` auto-detect GUI vs XR via
9
+ * `window.__elizaXRContext`, so the SAME component serves both surfaces. The TUI
10
+ * surface renders the same `TrajectoryLoggerSpatialView` through the terminal
11
+ * registry (see `register-terminal-view.tsx`).
12
+ */
13
+ import type { OverlayAppContext } from "@elizaos/ui";
14
+ export interface TrajectoryLoggerViewProps {
15
+ /**
16
+ * Optional host-supplied "back" handler. When the view is mounted as a
17
+ * full-screen overlay the host passes its `exitToApps`; the bundle/manifest
18
+ * mount renders it without props and Back falls back to the navigation bus.
19
+ */
20
+ exitToApps?: OverlayAppContext["exitToApps"];
21
+ }
22
+ export declare function TrajectoryLoggerView({ exitToApps, }?: TrajectoryLoggerViewProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=TrajectoryLoggerView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrajectoryLoggerView.d.ts","sourceRoot":"","sources":["../../src/components/TrajectoryLoggerView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAwBrD,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;CAC9C;AAED,wBAAgB,oBAAoB,CAAC,EACnC,UAAU,GACX,GAAE,yBAA8B,2CAoDhC"}
@@ -0,0 +1,2 @@
1
+ export declare function interact(capability: string, params?: Record<string, unknown>): Promise<unknown>;
2
+ //# sourceMappingURL=TrajectoryLoggerView.interact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrajectoryLoggerView.interact.d.ts","sourceRoot":"","sources":["../../src/components/TrajectoryLoggerView.interact.ts"],"names":[],"mappings":"AAMA,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CAqClB"}