electric-ax 0.2.21 → 0.2.22

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.
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  const require_chunk = require('./chunk-BCwAaXi7.cjs');
3
- const require_entity_stream_db = require('./entity-stream-db-uLb8jOQA.cjs');
3
+ const require_entity_stream_db = require('./entity-stream-db-DJU-Famv.cjs');
4
4
  const __electric_ax_agents_runtime = require_chunk.__toESM(require("@electric-ax/agents-runtime"));
5
- const __durable_streams_state_db = require_chunk.__toESM(require("@durable-streams/state/db"));
6
5
  const react = require_chunk.__toESM(require("react"));
7
6
  const ink = require_chunk.__toESM(require("ink"));
8
7
  const __tanstack_react_db = require_chunk.__toESM(require("@tanstack/react-db"));
@@ -25,6 +24,159 @@ function formatTime(iso) {
25
24
  function truncate(s, max) {
26
25
  return s.length > max ? s.slice(0, max - 3) + `...` : s;
27
26
  }
27
+ function createMessageSendBody(text, opts) {
28
+ return {
29
+ ...opts?.key ? { key: opts.key } : {},
30
+ payload: { text }
31
+ };
32
+ }
33
+ const OPTIMISTIC_INBOX_ORDER_START = Number.MAX_SAFE_INTEGER - 1e6;
34
+ const SEND_TXID_TIMEOUT_MS = 1e4;
35
+ let optimisticInboxOrderIndex = OPTIMISTIC_INBOX_ORDER_START;
36
+ function nextOptimisticInboxOrderIndex() {
37
+ optimisticInboxOrderIndex += 1;
38
+ if (optimisticInboxOrderIndex >= Number.MAX_SAFE_INTEGER) optimisticInboxOrderIndex = OPTIMISTIC_INBOX_ORDER_START;
39
+ return optimisticInboxOrderIndex;
40
+ }
41
+ function createOptimisticInboxKey(pendingOrderIndex) {
42
+ return `optimistic-${Date.now()}-${pendingOrderIndex}`;
43
+ }
44
+ async function readSendTxid(res) {
45
+ const data = await res.json().catch(() => null);
46
+ const txid = data?.txid;
47
+ if (typeof txid === `string` || typeof txid === `number`) return String(txid);
48
+ throw new Error(`Send response did not include txid`);
49
+ }
50
+ function GutterLine({ prefix = `│ `, color, dimColor, children }) {
51
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ink.Box, {
52
+ width: "100%",
53
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
54
+ color,
55
+ dimColor,
56
+ children: prefix
57
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Box, {
58
+ flexGrow: 1,
59
+ flexShrink: 1,
60
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
61
+ color,
62
+ dimColor,
63
+ wrap: "wrap",
64
+ children
65
+ })
66
+ })]
67
+ });
68
+ }
69
+ function payloadText(payload) {
70
+ if (typeof payload === `string`) return payload;
71
+ if (typeof payload === `object` && payload !== null) {
72
+ const record = payload;
73
+ return typeof record.text === `string` ? record.text : JSON.stringify(payload);
74
+ }
75
+ return String(payload ?? ``);
76
+ }
77
+ function resultText(result) {
78
+ if (result === void 0) return void 0;
79
+ return typeof result === `string` ? result : JSON.stringify(result);
80
+ }
81
+ function isPlainObject(value) {
82
+ return typeof value === `object` && value !== null && !Array.isArray(value);
83
+ }
84
+ function timelineRowsToDisplayRows(rows) {
85
+ let userMessageCount = 0;
86
+ return rows.flatMap((row) => {
87
+ if (row.inbox) {
88
+ const section = {
89
+ kind: `user_message`,
90
+ from: row.inbox.from,
91
+ text: payloadText(row.inbox.payload),
92
+ timestamp: Date.parse(row.inbox.timestamp || ``) || Date.now(),
93
+ isInitial: userMessageCount === 0
94
+ };
95
+ userMessageCount++;
96
+ return [{
97
+ kind: `section`,
98
+ key: row.$key,
99
+ section
100
+ }];
101
+ }
102
+ if (row.wake) {
103
+ const timestamp = Date.parse(row.wake.payload.timestamp);
104
+ return [{
105
+ kind: `section`,
106
+ key: row.$key,
107
+ section: {
108
+ kind: `wake`,
109
+ payload: row.wake.payload,
110
+ timestamp: Number.isFinite(timestamp) ? timestamp : Date.now()
111
+ }
112
+ }];
113
+ }
114
+ if (row.run) return [{
115
+ kind: `run`,
116
+ key: row.$key,
117
+ run: row.run
118
+ }];
119
+ if (row.error) return [{
120
+ kind: `section`,
121
+ key: row.$key,
122
+ section: {
123
+ kind: `agent_response`,
124
+ items: [],
125
+ error: row.error.error_code ? `${row.error.error_code}: ${row.error.message}` : row.error.message
126
+ }
127
+ }];
128
+ return [];
129
+ });
130
+ }
131
+ function textContent(item) {
132
+ return typeof item?.content === `string` ? item.content : ``;
133
+ }
134
+ function compareTimelineOrderValues(left, right) {
135
+ if (typeof left === `number` && typeof right === `number`) return left - right;
136
+ return String(left).localeCompare(String(right));
137
+ }
138
+ function runItemKind(item) {
139
+ return item.text ? `text` : `toolCall`;
140
+ }
141
+ function runItemKey(item) {
142
+ return item.text?.key ?? item.toolCall?.key ?? ``;
143
+ }
144
+ function compareRunItems(left, right) {
145
+ const orderCompare = compareTimelineOrderValues(left.text?.order ?? left.toolCall?.order ?? `~`, right.text?.order ?? right.toolCall?.order ?? `~`);
146
+ if (orderCompare !== 0) return orderCompare;
147
+ const kindCompare = runItemKind(left).localeCompare(runItemKind(right));
148
+ if (kindCompare !== 0) return kindCompare;
149
+ return runItemKey(left).localeCompare(runItemKey(right));
150
+ }
151
+ function runItemsToContentItems(items) {
152
+ const contentItems = [];
153
+ for (const item of items) {
154
+ if (item.text) {
155
+ const content = textContent(item.text);
156
+ if (content.trim().length > 0) contentItems.push({
157
+ kind: `text`,
158
+ text: content
159
+ });
160
+ continue;
161
+ }
162
+ if (!item.toolCall) continue;
163
+ contentItems.push({
164
+ kind: `tool_call`,
165
+ toolCallId: item.toolCall.tool_call_id ?? item.toolCall.key,
166
+ toolName: item.toolCall.tool_name,
167
+ args: isPlainObject(item.toolCall.args) ? item.toolCall.args : {},
168
+ status: item.toolCall.status,
169
+ result: resultText(item.toolCall.result),
170
+ error: item.toolCall.error,
171
+ isError: item.toolCall.status === `failed`
172
+ });
173
+ }
174
+ return contentItems;
175
+ }
176
+ function runErrorsText(errors) {
177
+ const messages = errors.map((error) => error.error_code ? `${error.error_code}: ${error.message}` : error.message).filter(Boolean);
178
+ return messages.length > 0 ? messages.join(`; `) : void 0;
179
+ }
28
180
  function UserMessageView({ msg }) {
29
181
  const time = formatTime(msg.timestamp);
30
182
  const payload = msg.payload;
@@ -44,9 +196,9 @@ function UserMessageView({ msg }) {
44
196
  }), time ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
45
197
  dimColor: true,
46
198
  children: ` ${time}`
47
- }) : null] }), text.split(`\n`).map((line, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
199
+ }) : null] }), text.split(`\n`).map((line, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GutterLine, {
48
200
  color: "white",
49
- children: `│ ${line}`
201
+ children: line
50
202
  }, i))]
51
203
  });
52
204
  }
@@ -60,9 +212,9 @@ function AgentTextView({ text, accumulatedText, label }) {
60
212
  bold: true,
61
213
  color: "green",
62
214
  children: `┌ ${label ?? `assistant`}`
63
- }) }), lines.map((line, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
215
+ }) }), lines.map((line, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GutterLine, {
64
216
  color: "white",
65
- children: `│ ${line}${i === lines.length - 1 ? cursor : ``}`
217
+ children: `${line}${i === lines.length - 1 ? cursor : ``}`
66
218
  }, i))]
67
219
  });
68
220
  }
@@ -109,9 +261,10 @@ function ToolResultView({ result }) {
109
261
  const remaining = lines.length - maxLines;
110
262
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ink.Box, {
111
263
  flexDirection: "column",
112
- children: [shown.map((line, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
264
+ children: [shown.map((line, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GutterLine, {
265
+ prefix: " │ ",
113
266
  dimColor: true,
114
- children: ` │ ${truncate(line, 100)}`
267
+ children: truncate(line, 100)
115
268
  }, i)), remaining > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
116
269
  dimColor: true,
117
270
  children: ` │ ... ${remaining} more lines`
@@ -121,26 +274,29 @@ function ToolResultView({ result }) {
121
274
  function MessageInput({ db, baseUrl, entityUrl, identity, headers, disabled }) {
122
275
  const [value, setValue] = (0, react.useState)(``);
123
276
  const [error, setError] = (0, react.useState)(null);
124
- const sendAction = (0, react.useMemo)(() => (0, __durable_streams_state_db.createOptimisticAction)({
125
- onMutate: ({ text }) => {
277
+ const sendAction = (0, react.useMemo)(() => (0, __tanstack_react_db.createOptimisticAction)({
278
+ onMutate: ({ text, key, pendingOrderIndex }) => {
279
+ const now = new Date().toISOString();
126
280
  db.collections.inbox.insert({
127
- key: `optimistic-${Date.now()}`,
281
+ key,
282
+ _timeline_order: (0, __electric_ax_agents_runtime.createPendingTimelineOrder)(pendingOrderIndex),
128
283
  from: identity,
284
+ from_principal: identity,
129
285
  payload: { text },
130
- timestamp: new Date().toISOString()
286
+ timestamp: now,
287
+ mode: `immediate`,
288
+ status: `processed`,
289
+ processed_at: now
131
290
  });
132
291
  },
133
- mutationFn: async ({ text }) => {
292
+ mutationFn: async ({ text, key }) => {
134
293
  const res = await fetch(require_entity_stream_db.entityApiUrl(baseUrl, entityUrl, `/send`), {
135
294
  method: `POST`,
136
295
  headers: {
137
296
  "content-type": `application/json`,
138
297
  ...headers
139
298
  },
140
- body: JSON.stringify({
141
- from: identity,
142
- payload: { text }
143
- })
299
+ body: JSON.stringify(createMessageSendBody(text, { key }))
144
300
  });
145
301
  if (!res.ok) {
146
302
  const body = await res.text().catch(() => ``);
@@ -155,6 +311,7 @@ function MessageInput({ db, baseUrl, entityUrl, identity, headers, disabled }) {
155
311
  }
156
312
  throw new Error(message);
157
313
  }
314
+ await db.utils.awaitTxId(await readSendTxid(res), SEND_TXID_TIMEOUT_MS);
158
315
  }
159
316
  }), [
160
317
  db,
@@ -168,7 +325,12 @@ function MessageInput({ db, baseUrl, entityUrl, identity, headers, disabled }) {
168
325
  if (key.return) {
169
326
  if (value.trim()) {
170
327
  setError(null);
171
- const tx = sendAction({ text: value.trim() });
328
+ const pendingOrderIndex = nextOptimisticInboxOrderIndex();
329
+ const tx = sendAction({
330
+ text: value.trim(),
331
+ key: createOptimisticInboxKey(pendingOrderIndex),
332
+ pendingOrderIndex
333
+ });
172
334
  setValue(``);
173
335
  tx.isPersisted.promise.catch((err) => {
174
336
  setError(err.message);
@@ -206,6 +368,7 @@ function MessageInput({ db, baseUrl, entityUrl, identity, headers, disabled }) {
206
368
  function AgentResponseView({ section, label, isStreaming }) {
207
369
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ink.Box, {
208
370
  flexDirection: "column",
371
+ width: "100%",
209
372
  children: [
210
373
  section.items.map((item, i) => {
211
374
  if (item.kind === `text`) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentTextView, {
@@ -235,6 +398,31 @@ function AgentResponseView({ section, label, isStreaming }) {
235
398
  ]
236
399
  });
237
400
  }
401
+ function AgentRunView({ run, label, isStreaming }) {
402
+ const { data: items = [] } = (0, __tanstack_react_db.useLiveQuery)((q) => run.items ? q.from({ item: run.items }) : void 0, [run.items]);
403
+ const { data: errors = [] } = (0, __tanstack_react_db.useLiveQuery)((q) => run.errors ? q.from({ error: run.errors }) : void 0, [run.errors]);
404
+ const sortedItems = (0, react.useMemo)(() => [...items].sort(compareRunItems), [items]);
405
+ const runErrors = (0, react.useMemo)(() => runErrorsText(errors), [errors]);
406
+ const finishReason = run.status === `failed` && run.finish_reason ? `finish_reason=${run.finish_reason}` : void 0;
407
+ const section = (0, react.useMemo)(() => ({
408
+ kind: `agent_response`,
409
+ items: runItemsToContentItems(sortedItems),
410
+ ...run.status === `completed` && { done: true },
411
+ ...runErrors || finishReason ? { error: runErrors || finishReason } : {},
412
+ ...run.tokens && { tokens: run.tokens }
413
+ }), [
414
+ finishReason,
415
+ run.status,
416
+ run.tokens,
417
+ runErrors,
418
+ sortedItems
419
+ ]);
420
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentResponseView, {
421
+ section,
422
+ label,
423
+ isStreaming
424
+ });
425
+ }
238
426
  function wakeReason(section) {
239
427
  const { payload } = section;
240
428
  if (payload.timeout) return `timeout`;
@@ -267,64 +455,59 @@ function ObserveExitHotkey({ onExit }) {
267
455
  return null;
268
456
  }
269
457
  function ObserveView({ db, entityUrl, baseUrl, identity, headers }) {
270
- const timelineQuery = (0, react.useMemo)(() => (0, __electric_ax_agents_runtime.createEntityIncludesQuery)(db), [db]);
458
+ const timelineQuery = (0, react.useMemo)(() => (0, __electric_ax_agents_runtime.createEntityTimelineQuery)(db), [db]);
271
459
  const { data: timelineRows = [] } = (0, __tanstack_react_db.useLiveQuery)(timelineQuery, [timelineQuery]);
272
- const timelineData = (0, __electric_ax_agents_runtime.normalizeEntityTimelineData)(timelineRows[0] ?? {
273
- runs: [],
274
- inbox: [],
275
- wakes: [],
276
- signals: [],
277
- contextInserted: [],
278
- contextRemoved: [],
279
- entities: []
280
- });
281
- const typedRuns = timelineData.runs;
282
- const typedInbox = timelineData.inbox;
283
- const typedWakes = timelineData.wakes;
284
- const timeline = (0, react.useMemo)(() => (0, __electric_ax_agents_runtime.buildSections)(typedRuns, typedInbox, typedWakes), [
285
- typedRuns,
286
- typedInbox,
287
- typedWakes
288
- ]);
289
- const { data: stopped = [] } = (0, __tanstack_react_db.useLiveQuery)((q) => q.from({ entityStopped: db.collections.entityStopped }), [db]);
290
- const closed = stopped.length > 0;
460
+ const displayRows = (0, react.useMemo)(() => timelineRowsToDisplayRows(timelineRows), [timelineRows]);
461
+ const { data: entityStoppedRows = [] } = (0, __tanstack_react_db.useLiveQuery)((q) => q.from({ stopped: db.collections.entityStopped }), [db.collections.entityStopped]);
462
+ const closed = entityStoppedRows.length > 0;
291
463
  const lastAgentIndex = (0, react.useMemo)(() => {
292
- for (let i = timeline.length - 1; i >= 0; i--) if (timeline[i].kind === `agent_response`) return i;
464
+ for (let i = displayRows.length - 1; i >= 0; i--) {
465
+ const row = displayRows[i];
466
+ if (row.kind === `run` || row.kind === `section` && row.section.kind === `agent_response`) return i;
467
+ }
293
468
  return -1;
294
- }, [timeline]);
469
+ }, [displayRows]);
295
470
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ink.Box, {
296
471
  flexDirection: "column",
297
472
  children: [
298
473
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Box, {
299
474
  marginBottom: 1,
475
+ width: "100%",
300
476
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
301
477
  dimColor: true,
302
478
  children: `Observing ${entityUrl}${closed ? `` : ` (Ctrl+C to stop)`}`
303
479
  })
304
480
  }),
305
481
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ink.Box, {
482
+ width: "100%",
306
483
  borderStyle: "single",
307
484
  borderColor: "gray",
308
485
  flexDirection: "column",
309
486
  paddingX: 1,
310
487
  children: [
311
- timeline.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
488
+ displayRows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Text, {
312
489
  dimColor: true,
313
490
  children: "Waiting for events..."
314
491
  }) : null,
315
- timeline.map((section, i) => {
492
+ displayRows.map((row, i) => {
493
+ if (row.kind === `run`) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentRunView, {
494
+ run: row.run,
495
+ label: entityUrl,
496
+ isStreaming: !closed && i === lastAgentIndex && row.run.status !== `completed`
497
+ }, row.key);
498
+ const { section } = row;
316
499
  if (section.kind === `user_message`) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UserMessageView, { msg: {
317
500
  key: `timeline-${i}`,
318
501
  from: section.from ?? `user`,
319
502
  payload: { text: section.text },
320
503
  timestamp: new Date(section.timestamp).toISOString()
321
- } }, `msg-${i}`);
322
- if (section.kind === `wake`) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WakeView, { section }, `wake-${i}`);
504
+ } }, row.key);
505
+ if (section.kind === `wake`) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WakeView, { section }, row.key);
323
506
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AgentResponseView, {
324
507
  section,
325
508
  label: entityUrl,
326
509
  isStreaming: !closed && i === lastAgentIndex && !section.done
327
- }, `agent-${i}`);
510
+ }, row.key);
328
511
  }),
329
512
  closed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ink.Box, {
330
513
  marginTop: 1,
@@ -425,9 +608,15 @@ function renderObserve(opts) {
425
608
  exports.AgentTextView = AgentTextView
426
609
  exports.MessageInput = MessageInput
427
610
  exports.ObserveExitHotkey = ObserveExitHotkey
611
+ exports.ObserveView = ObserveView
428
612
  exports.ToolCallView = ToolCallView
429
613
  exports.ToolResultView = ToolResultView
430
614
  exports.UserMessageView = UserMessageView
615
+ exports.compareRunItems = compareRunItems
616
+ exports.createMessageSendBody = createMessageSendBody
431
617
  exports.formatTime = formatTime
432
618
  exports.renderObserve = renderObserve
619
+ exports.runItemKey = runItemKey
620
+ exports.runItemKind = runItemKind
621
+ exports.runItemsToContentItems = runItemsToContentItems
433
622
  exports.truncate = truncate
@@ -1,5 +1,5 @@
1
1
  import { EntityStreamDB } from "./entity-stream-db-BV4N31MR.cjs";
2
- import { EntityTimelineContentItem, MessageReceived } from "@electric-ax/agents-runtime";
2
+ import { EntityTimelineContentItem, EntityTimelineRunItem, MessageReceived } from "@electric-ax/agents-runtime";
3
3
  import React from "react";
4
4
 
5
5
  //#region src/observe-ui.d.ts
@@ -9,6 +9,18 @@ interface StreamingText {
9
9
  }
10
10
  declare function formatTime(iso: string | undefined): string;
11
11
  declare function truncate(s: string, max: number): string;
12
+ declare function createMessageSendBody(text: string, opts?: {
13
+ key?: string;
14
+ }): {
15
+ key?: string;
16
+ payload: {
17
+ text: string;
18
+ };
19
+ };
20
+ declare function runItemKind(item: EntityTimelineRunItem): `text` | `toolCall`;
21
+ declare function runItemKey(item: EntityTimelineRunItem): string;
22
+ declare function compareRunItems(left: EntityTimelineRunItem, right: EntityTimelineRunItem): number;
23
+ declare function runItemsToContentItems(items: Array<EntityTimelineRunItem>): Array<EntityTimelineContentItem>;
12
24
  declare function UserMessageView({
13
25
  msg
14
26
  }: {
@@ -55,6 +67,19 @@ declare function ObserveExitHotkey({
55
67
  }: {
56
68
  onExit: () => void;
57
69
  }): React.ReactElement | null;
70
+ declare function ObserveView({
71
+ db,
72
+ entityUrl,
73
+ baseUrl,
74
+ identity,
75
+ headers
76
+ }: {
77
+ db: EntityStreamDB;
78
+ entityUrl: string;
79
+ baseUrl: string;
80
+ identity: string;
81
+ headers?: Record<string, string>;
82
+ }): React.ReactElement;
58
83
  declare function renderObserve(opts: {
59
84
  entityUrl: string;
60
85
  baseUrl: string;
@@ -64,4 +89,4 @@ declare function renderObserve(opts: {
64
89
  }): void;
65
90
 
66
91
  //#endregion
67
- export { AgentTextView, MessageInput, ObserveExitHotkey, ToolCallView, ToolResultView, UserMessageView, formatTime, renderObserve, truncate };
92
+ export { AgentTextView, MessageInput, ObserveExitHotkey, ObserveView, ToolCallView, ToolResultView, UserMessageView, compareRunItems, createMessageSendBody, formatTime, renderObserve, runItemKey, runItemKind, runItemsToContentItems, truncate };
@@ -1,5 +1,5 @@
1
- import { EntityStreamDB } from "./entity-stream-db-BROzlu7p.js";
2
- import { EntityTimelineContentItem, MessageReceived } from "@electric-ax/agents-runtime";
1
+ import { EntityStreamDB } from "./entity-stream-db-DRQk9DHe.js";
2
+ import { EntityTimelineContentItem, EntityTimelineRunItem, MessageReceived } from "@electric-ax/agents-runtime";
3
3
  import React from "react";
4
4
 
5
5
  //#region src/observe-ui.d.ts
@@ -9,6 +9,18 @@ interface StreamingText {
9
9
  }
10
10
  declare function formatTime(iso: string | undefined): string;
11
11
  declare function truncate(s: string, max: number): string;
12
+ declare function createMessageSendBody(text: string, opts?: {
13
+ key?: string;
14
+ }): {
15
+ key?: string;
16
+ payload: {
17
+ text: string;
18
+ };
19
+ };
20
+ declare function runItemKind(item: EntityTimelineRunItem): `text` | `toolCall`;
21
+ declare function runItemKey(item: EntityTimelineRunItem): string;
22
+ declare function compareRunItems(left: EntityTimelineRunItem, right: EntityTimelineRunItem): number;
23
+ declare function runItemsToContentItems(items: Array<EntityTimelineRunItem>): Array<EntityTimelineContentItem>;
12
24
  declare function UserMessageView({
13
25
  msg
14
26
  }: {
@@ -55,6 +67,19 @@ declare function ObserveExitHotkey({
55
67
  }: {
56
68
  onExit: () => void;
57
69
  }): React.ReactElement | null;
70
+ declare function ObserveView({
71
+ db,
72
+ entityUrl,
73
+ baseUrl,
74
+ identity,
75
+ headers
76
+ }: {
77
+ db: EntityStreamDB;
78
+ entityUrl: string;
79
+ baseUrl: string;
80
+ identity: string;
81
+ headers?: Record<string, string>;
82
+ }): React.ReactElement;
58
83
  declare function renderObserve(opts: {
59
84
  entityUrl: string;
60
85
  baseUrl: string;
@@ -64,4 +89,4 @@ declare function renderObserve(opts: {
64
89
  }): void;
65
90
 
66
91
  //#endregion
67
- export { AgentTextView, MessageInput, ObserveExitHotkey, ToolCallView, ToolResultView, UserMessageView, formatTime, renderObserve, truncate };
92
+ export { AgentTextView, MessageInput, ObserveExitHotkey, ObserveView, ToolCallView, ToolResultView, UserMessageView, compareRunItems, createMessageSendBody, formatTime, renderObserve, runItemKey, runItemKind, runItemsToContentItems, truncate };