@opengeni/react 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/{chunk-AVPU5PMC.js → chunk-F4CFWKVI.js} +332 -64
  2. package/dist/chunk-F4CFWKVI.js.map +1 -0
  3. package/dist/chunk-GQN2QIR2.js +3767 -0
  4. package/dist/chunk-GQN2QIR2.js.map +1 -0
  5. package/dist/{chunk-I3BJZIG5.js → chunk-HIWPQYWI.js} +2 -120
  6. package/dist/chunk-HIWPQYWI.js.map +1 -0
  7. package/dist/chunk-M7X4JZOD.js +121 -0
  8. package/dist/chunk-M7X4JZOD.js.map +1 -0
  9. package/dist/{chunk-SHOFILHJ.js → chunk-MP6237JB.js} +570 -984
  10. package/dist/chunk-MP6237JB.js.map +1 -0
  11. package/dist/chunk-OZDLELJQ.js +937 -0
  12. package/dist/chunk-OZDLELJQ.js.map +1 -0
  13. package/dist/{chunk-RDPDU4TA.js → chunk-TMH6HZWF.js} +3 -3
  14. package/dist/{chunk-6XUS5VFM.js → chunk-YU5PGUK7.js} +6 -4
  15. package/dist/{chunk-6XUS5VFM.js.map → chunk-YU5PGUK7.js.map} +1 -1
  16. package/dist/{composer-BXb0Q1HF.d.ts → composer-DoC4veX1.d.ts} +4 -75
  17. package/dist/composer.d.ts +2 -1
  18. package/dist/composer.js +4 -3
  19. package/dist/index.d.ts +14 -259
  20. package/dist/index.js +1016 -5140
  21. package/dist/index.js.map +1 -1
  22. package/dist/machines.js +3 -2
  23. package/dist/session-Du_FsrZ1.d.ts +264 -0
  24. package/dist/session-ui-BqQDH7YV.d.ts +183 -0
  25. package/dist/session-ui.d.ts +7 -0
  26. package/dist/session-ui.js +17 -0
  27. package/dist/session-ui.js.map +1 -0
  28. package/dist/session.d.ts +3 -1
  29. package/dist/session.js +26 -9
  30. package/dist/use-file-attachments-C0kpHrs9.d.ts +76 -0
  31. package/dist/{session-BEvtFWhe.d.ts → use-turn-queue-3rkJwjFv.d.ts} +3 -185
  32. package/package.json +6 -2
  33. package/src/components/message-timeline.tsx +92 -52
  34. package/src/hooks/use-composer.ts +456 -69
  35. package/src/hooks/use-file-attachments.ts +1 -1
  36. package/src/hooks/use-goal.ts +1 -1
  37. package/src/hooks/use-session-events.ts +5 -0
  38. package/src/hooks/use-session-lineage.ts +1 -1
  39. package/src/hooks/use-session.ts +9 -6
  40. package/src/session-ui.ts +13 -0
  41. package/src/session.ts +15 -0
  42. package/src/timeline/activity-rail.tsx +1 -1
  43. package/dist/chunk-AVPU5PMC.js.map +0 -1
  44. package/dist/chunk-I3BJZIG5.js.map +0 -1
  45. package/dist/chunk-SHOFILHJ.js.map +0 -1
  46. /package/dist/{chunk-RDPDU4TA.js.map → chunk-TMH6HZWF.js.map} +0 -0
package/dist/machines.js CHANGED
@@ -24,9 +24,10 @@ import {
24
24
  healthPulses,
25
25
  pointsFor,
26
26
  useMachines
27
- } from "./chunk-6XUS5VFM.js";
27
+ } from "./chunk-YU5PGUK7.js";
28
28
  import "./chunk-TK7G6XLT.js";
29
- import "./chunk-I3BJZIG5.js";
29
+ import "./chunk-HIWPQYWI.js";
30
+ import "./chunk-M7X4JZOD.js";
30
31
  export {
31
32
  CONNECTION_STATUS_META,
32
33
  ConnectionDot,
@@ -0,0 +1,264 @@
1
+ import { C as ClientOverride, E as EmbeddedSessionClientOverride, e as EmbeddedSessionMcpApprovalPolicyClientOverride, f as EmbeddedHumanInputClientOverride } from './session-context-rgrfElMl.js';
2
+ import { Session, SessionEvent, StreamConnectionState, SessionStatus, SessionGoal, SessionControlResponse, SessionMcpServerMetadata, SessionMcpApprovalPolicy, UpdateSessionMcpApprovalPolicyResponse, SessionLineageResponse, HumanInputQuestion, SessionHumanInputRequest, SubmitHumanInputResponseRequest } from '@opengeni/sdk';
3
+ import { S as SessionEventFeedOptions } from './use-composer-BnEzheSk.js';
4
+ import { e as TimelineItem, d as TimelineGroup } from './use-turn-queue-3rkJwjFv.js';
5
+ import './use-file-attachments-C0kpHrs9.js';
6
+
7
+ type UseSessionOptions = ClientOverride & SessionEventFeedOptions & {
8
+ /** Re-fetch on an interval (ms). Off by default — pair with `useSessionEvents` for live status. */
9
+ pollIntervalMs?: number | undefined;
10
+ };
11
+ type UseSessionResult = {
12
+ session: Session | null;
13
+ loading: boolean;
14
+ error: Error | null;
15
+ refresh: () => Promise<void>;
16
+ /** Manually rename the session (PATCH, source='user'). Returns the updated session, or null on failure. */
17
+ updateTitle: (title: string) => Promise<Session | null>;
18
+ /** True while a rename is in flight. */
19
+ updating: boolean;
20
+ mutationError: Error | null;
21
+ clearMutationError: () => void;
22
+ };
23
+ /** Event types that change the session title (auto + cross-client renames). */
24
+ declare function isTitleEvent(event: Pick<SessionEvent, "type">): boolean;
25
+ /** Fetch one session (with optional polling), live-patching its title on `session.title_set`. */
26
+ declare function useSession(sessionId: string | null | undefined, options?: UseSessionOptions): UseSessionResult;
27
+
28
+ type SessionEventsConnectionState = StreamConnectionState | "idle" | "ended" | "error";
29
+ type UseSessionEventsOptions = EmbeddedSessionClientOverride & {
30
+ /** Resume after this sequence (exclusive). Nonzero keeps full replay/resume semantics. */
31
+ after?: number | undefined;
32
+ /** Load a bounded tail by default, or opt back into full replay from `after`. */
33
+ replay?: "windowed" | "full" | undefined;
34
+ /** Pause the stream without unmounting (e.g. hidden tab). Defaults to true. */
35
+ enabled?: boolean | undefined;
36
+ };
37
+ type UseSessionEventsResult = {
38
+ /** Replayed + live events, ordered by sequence, no gaps, no duplicates. */
39
+ events: SessionEvent[];
40
+ /** Projected, renderable timeline (memoized over `events`). */
41
+ timeline: TimelineItem[];
42
+ /** Latest session status observed in the event log, if any. */
43
+ sessionStatus: SessionStatus | null;
44
+ connectionState: SessionEventsConnectionState;
45
+ /** Highest sequence seen so far (0 before the first event). */
46
+ lastSequence: number;
47
+ /** Exact serialized bytes retained in the current browser event window. */
48
+ windowBytes: number;
49
+ /** Whether older delivered events were evicted from the browser window. */
50
+ windowTruncated: boolean;
51
+ /** True until the initial tail window has been applied (windowed mode). */
52
+ initialLoading: boolean;
53
+ /** Whether older durable events are available before the current window. */
54
+ hasOlder: boolean;
55
+ /** True while an older window is being fetched. */
56
+ loadingOlder: boolean;
57
+ /** Prepend an older density-bounded window; resolves true when more remain. */
58
+ loadOlder: () => Promise<boolean>;
59
+ error: Error | null;
60
+ };
61
+ declare const SESSION_EVENT_BROWSER_MAX_BYTES: number;
62
+ declare const SESSION_EVENT_BROWSER_MAX_COUNT = 10000;
63
+ declare const SESSION_EVENT_BROWSER_SINGLE_EVENT_MAX_BYTES: number;
64
+ declare const SESSION_EVENT_BROWSER_PENDING_MAX_BYTES: number;
65
+ declare const SESSION_EVENT_BROWSER_PENDING_MAX_COUNT = 256;
66
+ type BrowserSessionEventWindow = {
67
+ events: SessionEvent[];
68
+ bytes: number;
69
+ truncated: boolean;
70
+ };
71
+ /**
72
+ * Live-stream a session's event log with replay-by-sequence, reconnect, and
73
+ * batched React updates. Fresh loads default to a bounded tail window; pass
74
+ * `replay: "full"` or a nonzero `after` for the previous full replay path.
75
+ */
76
+ declare function useSessionEvents(sessionId: string | null | undefined, options?: UseSessionEventsOptions): UseSessionEventsResult;
77
+ /**
78
+ * Keep one direction-aware count+byte-bounded browser window. Live/default
79
+ * accumulation retains the newest suffix; backward paging retains the oldest
80
+ * prefix so newly fetched history cannot be immediately evicted. This is
81
+ * deliberately separate from durable history and transport paging: when a
82
+ * backward page evicts the live tail, the hook reconnects from the retained
83
+ * high-water mark while preserving the highest-ever-observed sequence
84
+ * separately. The source event remains durable in PostgreSQL throughout.
85
+ */
86
+ declare function boundBrowserSessionEventWindow(events: readonly SessionEvent[], options?: {
87
+ maxBytes?: number;
88
+ maxCount?: number;
89
+ direction?: "newest" | "oldest";
90
+ }): BrowserSessionEventWindow;
91
+
92
+ /** Event types that change the session goal (set/updated/completed/paused/...). */
93
+ declare function isGoalEvent(event: Pick<SessionEvent, "type">): boolean;
94
+ type UseGoalOptions = ClientOverride & SessionEventFeedOptions & {
95
+ /** Optional safety-net polling (ms). Off by default — event refreshes drive updates. */
96
+ pollIntervalMs?: number | undefined;
97
+ };
98
+ type UseGoalResult = {
99
+ /** The session goal, or null when the session has none. */
100
+ goal: SessionGoal | null;
101
+ /** Convenience flags over `goal.status`. */
102
+ isActive: boolean;
103
+ isPaused: boolean;
104
+ isCompleted: boolean;
105
+ loading: boolean;
106
+ error: Error | null;
107
+ refresh: () => Promise<void>;
108
+ /** Pause the goal loop (PATCH status=paused). */
109
+ pause: (rationale?: string) => Promise<SessionGoal | null>;
110
+ /** Resume a paused goal: resets counters and re-arms continuations. */
111
+ resume: () => Promise<SessionGoal | null>;
112
+ /** Clear the session goal; goal-less sessions remain a successful no-op. */
113
+ clearGoal: () => Promise<void>;
114
+ /** Alias for `clearGoal`. */
115
+ deleteGoal: () => Promise<void>;
116
+ /** True while a pause/resume/clear is in flight. */
117
+ updating: boolean;
118
+ mutationError: Error | null;
119
+ clearMutationError: () => void;
120
+ };
121
+ /**
122
+ * The session's goal: state, the autonomy counters (`autoContinuations`,
123
+ * `noProgressStreak`), and pause/resume control. A goal-less session yields
124
+ * `goal: null` (the 404 is absorbed). Live-updates on goal, turn, session,
125
+ * control, and system-update events — pass `options.events` from
126
+ * `useSessionEvents` to reuse its stream.
127
+ */
128
+ declare function useGoal(sessionId: string | null | undefined, options?: UseGoalOptions): UseGoalResult;
129
+
130
+ type UseSessionControlOptions = EmbeddedSessionClientOverride;
131
+ type UseSessionControlResult = {
132
+ pause: (reason?: string) => Promise<SessionControlResponse | null>;
133
+ resume: (reason?: string) => Promise<SessionControlResponse | null>;
134
+ controlling: boolean;
135
+ /** Approve a pending `requires_action` approval. */
136
+ approve: (approvalId: string, message?: string) => Promise<SessionEvent | null>;
137
+ /** Reject a pending `requires_action` approval. */
138
+ reject: (approvalId: string, message?: string) => Promise<SessionEvent | null>;
139
+ /** True while an approval decision is in flight. */
140
+ responding: boolean;
141
+ error: Error | null;
142
+ clearError: () => void;
143
+ };
144
+ /**
145
+ * Session pause/resume and approval decisions. Pair with
146
+ * `useSessionEvents` (for `session.requiresAction` payloads carrying the
147
+ * `approvalId`) to render an approval bar.
148
+ */
149
+ declare function useSessionControl(sessionId: string | null | undefined, options?: UseSessionControlOptions): UseSessionControlResult;
150
+
151
+ declare function isSessionMcpApprovalPolicyEvent(event: Pick<SessionEvent, "type" | "payload">, serverId?: string): boolean;
152
+ type UseSessionMcpApprovalPolicyOptions = EmbeddedSessionMcpApprovalPolicyClientOverride & SessionEventFeedOptions & {
153
+ /** Optional safety-net polling (ms). Off by default; policy events drive refreshes. */
154
+ pollIntervalMs?: number | undefined;
155
+ };
156
+ type UseSessionMcpApprovalPolicyResult = {
157
+ server: SessionMcpServerMetadata | null;
158
+ policy: SessionMcpApprovalPolicy | null;
159
+ loading: boolean;
160
+ error: Error | null;
161
+ refresh: () => Promise<void>;
162
+ update: (policy: SessionMcpApprovalPolicy) => Promise<UpdateSessionMcpApprovalPolicyResponse | null>;
163
+ updating: boolean;
164
+ clearError: () => void;
165
+ };
166
+ /**
167
+ * Read and update one existing session MCP server's approval policy. Updates
168
+ * become effective for the next claimed attempt; current work is unchanged.
169
+ */
170
+ declare function useSessionMcpApprovalPolicy(sessionId: string | null | undefined, serverId: string | null | undefined, options?: UseSessionMcpApprovalPolicyOptions): UseSessionMcpApprovalPolicyResult;
171
+
172
+ type UseSessionLineageOptions = ClientOverride & {
173
+ events?: SessionEvent[] | undefined;
174
+ /** Refresh interval (ms). Off by default. */
175
+ pollIntervalMs?: number | undefined;
176
+ enabled?: boolean | undefined;
177
+ };
178
+ type UseSessionLineageResult = {
179
+ lineage: SessionLineageResponse | null;
180
+ loading: boolean;
181
+ error: Error | null;
182
+ refresh: () => Promise<void>;
183
+ };
184
+ declare function isLineageRefreshEvent(event: SessionEvent): boolean;
185
+ /** Read the ancestors + descendant tree for one session. Data-only; no UI state. */
186
+ declare function useSessionLineage(sessionId: string | null | undefined, options?: UseSessionLineageOptions): UseSessionLineageResult;
187
+
188
+ type PendingApproval = {
189
+ /** The id to send back via `user.approvalDecision` (`approvalId`). */
190
+ id: string;
191
+ /** Tool/function name awaiting the decision. */
192
+ name: string;
193
+ arguments?: unknown;
194
+ /** The raw approval entry from the `session.requiresAction` payload. */
195
+ raw?: unknown;
196
+ };
197
+ /** The approvals carried by one `session.requiresAction` payload. */
198
+ declare function approvalsFromRequiresAction(payload: unknown): PendingApproval[];
199
+ /** The approvals still awaiting a decision after replaying `events` in order. */
200
+ declare function projectPendingApprovals(events: SessionEvent[]): PendingApproval[];
201
+
202
+ /** Minimal actionable request shape available from the durable event log. */
203
+ type PendingHumanInputRequest = {
204
+ id: string;
205
+ turnId: string | null;
206
+ questions: HumanInputQuestion[];
207
+ allowSkip: boolean;
208
+ expiresAt: string | null;
209
+ };
210
+ /** Parse one generic `session.humanInput.requested` event defensively. */
211
+ declare function humanInputRequestFromEvent(event: Pick<SessionEvent, "type" | "payload" | "turnId">): PendingHumanInputRequest | null;
212
+ /**
213
+ * Fold a durable event log into the structured requests that are actionable
214
+ * now. Responses remove one request; a terminal owning turn clears any
215
+ * unresolved requests that died with it. Replaying history cannot resurrect a
216
+ * previously answered card.
217
+ */
218
+ declare function projectPendingHumanInputRequests(events: SessionEvent[]): PendingHumanInputRequest[];
219
+
220
+ /** Events that can create, settle, or invalidate an actionable request. */
221
+ declare function isHumanInputEvent(event: Pick<SessionEvent, "type">): boolean;
222
+ type UseHumanInputRequestsOptions = EmbeddedHumanInputClientOverride & SessionEventFeedOptions & {
223
+ /** Optional safety-net polling. Durable events drive refresh by default. */
224
+ pollIntervalMs?: number | undefined;
225
+ };
226
+ type UseHumanInputRequestsResult = {
227
+ requests: SessionHumanInputRequest[];
228
+ loading: boolean;
229
+ error: Error | null;
230
+ refresh: () => Promise<void>;
231
+ respond: (requestId: string, response: SubmitHumanInputResponseRequest) => Promise<SessionEvent | null>;
232
+ respondingRequestId: string | null;
233
+ mutationError: Error | null;
234
+ clearMutationError: () => void;
235
+ };
236
+ /**
237
+ * Authoritative structured-human-input hook. The server's pending-request
238
+ * table is the read model; events only trigger reconciliation. This lets an
239
+ * embedded host use the same primitive with a shared event feed or its own SDK
240
+ * proxy without rebuilding request lifecycle logic.
241
+ */
242
+ declare function useHumanInputRequests(sessionId: string | null | undefined, options?: UseHumanInputRequestsOptions): UseHumanInputRequestsResult;
243
+
244
+ /** Readable label for a tool call, without leaking an MCP server prefix. */
245
+ declare function toolDisplayName(name: string): string;
246
+ declare function buildTimeline(events: SessionEvent[]): TimelineItem[];
247
+ /**
248
+ * Whether the session's most recent turn ended in credit exhaustion — the
249
+ * terminal credit state apps key their "add credits" affordances on. Derived
250
+ * from the LAST turn-end event (completed/failed/cancelled): a later turn that
251
+ * settles any other way (someone topped up and kept working) clears it.
252
+ */
253
+ declare function creditExhaustedFromEvents(events: SessionEvent[]): boolean;
254
+ /** The latest session status carried in the event log, if any. */
255
+ declare function sessionStatusFromEvents(events: SessionEvent[]): SessionStatus | null;
256
+ declare function groupTimeline(items: TimelineItem[]): TimelineGroup[];
257
+ /**
258
+ * Find a session id in orchestration tool arguments or output. Handles raw
259
+ * objects, JSON strings, and MCP tool results (`{ content: [{ type: "text",
260
+ * text: "{...}" }], structuredContent? }`).
261
+ */
262
+ declare function extractSessionRef(value: unknown, depth?: number): string | null;
263
+
264
+ export { isGoalEvent as A, type BrowserSessionEventWindow as B, isHumanInputEvent as C, isLineageRefreshEvent as D, isSessionMcpApprovalPolicyEvent as E, isTitleEvent as F, projectPendingApprovals as G, projectPendingHumanInputRequests as H, sessionStatusFromEvents as I, toolDisplayName as J, useGoal as K, useHumanInputRequests as L, useSession as M, useSessionControl as N, useSessionEvents as O, type PendingApproval as P, useSessionLineage as Q, useSessionMcpApprovalPolicy as R, SESSION_EVENT_BROWSER_MAX_BYTES as S, type UseGoalOptions as U, type PendingHumanInputRequest as a, SESSION_EVENT_BROWSER_MAX_COUNT as b, SESSION_EVENT_BROWSER_PENDING_MAX_BYTES as c, SESSION_EVENT_BROWSER_PENDING_MAX_COUNT as d, SESSION_EVENT_BROWSER_SINGLE_EVENT_MAX_BYTES as e, type SessionEventsConnectionState as f, type UseGoalResult as g, type UseHumanInputRequestsOptions as h, type UseHumanInputRequestsResult as i, type UseSessionControlOptions as j, type UseSessionControlResult as k, type UseSessionEventsOptions as l, type UseSessionEventsResult as m, type UseSessionLineageOptions as n, type UseSessionLineageResult as o, type UseSessionMcpApprovalPolicyOptions as p, type UseSessionMcpApprovalPolicyResult as q, type UseSessionOptions as r, type UseSessionResult as s, approvalsFromRequiresAction as t, boundBrowserSessionEventWindow as u, buildTimeline as v, creditExhaustedFromEvents as w, extractSessionRef as x, groupTimeline as y, humanInputRequestFromEvent as z };
@@ -0,0 +1,183 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SessionHumanInputRequest, SubmitHumanInputResponseRequest, HumanInputQuestion, HumanInputAnswer, SessionEvent, SessionStatus } from '@opengeni/sdk';
3
+ import { ReactNode, ComponentType } from 'react';
4
+ import { h as UseTurnQueueResult, f as ToolCallItem, e as TimelineItem, a as AgentMessageItem, i as UserMessageItem, b as AuthNeededItem } from './use-turn-queue-3rkJwjFv.js';
5
+ import { C as ComposerState } from './use-composer-BnEzheSk.js';
6
+
7
+ /** The sole human prompt queue: compact above Goal, Agents, and composer. */
8
+ type QueueSurfaceCommonProps = {
9
+ /** Focus the composer owned by this queue after checkout/removal. */
10
+ onRequestComposerFocus?: (() => void) | undefined;
11
+ };
12
+ type QueueSurfaceProps = (QueueSurfaceCommonProps & {
13
+ queue: UseTurnQueueResult;
14
+ composer: ComposerState;
15
+ readOnly?: false | undefined;
16
+ }) | (QueueSurfaceCommonProps & {
17
+ queue: UseTurnQueueResult;
18
+ composer?: undefined;
19
+ readOnly: true;
20
+ });
21
+
22
+ /** The sole human prompt queue: compact above Goal, Agents, and composer. */
23
+ declare const QueueSurface: (props: QueueSurfaceProps) => react_jsx_runtime.JSX.Element | null;
24
+
25
+ type HumanInputAnswerDraft = {
26
+ values: string[];
27
+ other: string;
28
+ otherSelected: boolean;
29
+ };
30
+ type HumanInputFormMessages = {
31
+ title: string;
32
+ description: string;
33
+ submit: string;
34
+ skip: string;
35
+ submitting: string;
36
+ other: string;
37
+ deadlineLabel: string;
38
+ formatDeadline: (value: string) => string;
39
+ required: string;
40
+ minLength: (count: number) => string;
41
+ maxLength: (count: number) => string;
42
+ otherRequired: string;
43
+ minSelections: (count: number) => string;
44
+ maxSelections: (count: number) => string;
45
+ };
46
+ declare const defaultHumanInputFormMessages: HumanInputFormMessages;
47
+ type HumanInputFormProps = {
48
+ request: Pick<SessionHumanInputRequest, "id" | "questions" | "allowSkip" | "expiresAt">;
49
+ onSubmit: (response: SubmitHumanInputResponseRequest) => void | Promise<void>;
50
+ submitting?: boolean | undefined;
51
+ error?: string | null | undefined;
52
+ title?: ReactNode;
53
+ description?: ReactNode;
54
+ submitLabel?: string | undefined;
55
+ skipLabel?: string | undefined;
56
+ messages?: Partial<HumanInputFormMessages> | undefined;
57
+ autoFocus?: boolean | undefined;
58
+ className?: string | undefined;
59
+ };
60
+ /**
61
+ * Styled but host-neutral renderer for one structured request. Hosts can use
62
+ * the headless `useHumanInputRequests` hook instead, or replace the title and
63
+ * description while retaining accessible field semantics and validation.
64
+ */
65
+ declare function HumanInputForm({ request, onSubmit, submitting, error, title, description, submitLabel, skipLabel, messages: messageOverrides, autoFocus, className, }: HumanInputFormProps): react_jsx_runtime.JSX.Element;
66
+ declare function answersFromDrafts(questions: HumanInputQuestion[], drafts: Record<string, HumanInputAnswerDraft>, messageOverrides?: Partial<HumanInputFormMessages>): {
67
+ answers: HumanInputAnswer[];
68
+ errors: Record<string, string>;
69
+ };
70
+
71
+ type ToolRendererProps = {
72
+ item: ToolCallItem;
73
+ };
74
+ type ToolRenderer = ComponentType<ToolRendererProps>;
75
+ /** A registry entry: which key it matches and the component that renders it. */
76
+ type ToolRegistryEntry = {
77
+ match: "rawType";
78
+ type: string;
79
+ render: ToolRenderer;
80
+ } | {
81
+ match: "name";
82
+ name: string;
83
+ render: ToolRenderer;
84
+ };
85
+ type ToolRegistry = {
86
+ /** Resolve the renderer for a call (never null — falls back to generic). */
87
+ resolve: (item: ToolCallItem) => ToolRenderer;
88
+ /** The generic fallback renderer. */
89
+ fallback: ToolRenderer;
90
+ };
91
+ type CreateToolRegistryOptions = {
92
+ /**
93
+ * Entries that take precedence over the built-ins. Earlier entries win, so a
94
+ * consumer can shadow a default renderer for the same key.
95
+ */
96
+ entries?: ToolRegistryEntry[] | undefined;
97
+ /** Replace the generic fallback used for unmatched tools. */
98
+ fallback?: ToolRenderer | undefined;
99
+ };
100
+ /** The `raw.type` of a projected tool call, when the provider item carries one. */
101
+ declare function rawTypeOf(item: ToolCallItem): string | null;
102
+ /**
103
+ * Build a tool registry from a set of entries and a fallback. The returned
104
+ * registry resolves in priority order: `raw.type` entries first, then `name`
105
+ * entries, then the fallback. Consumer `entries` are consulted before the
106
+ * built-in `baseEntries`, so they shadow defaults cleanly.
107
+ */
108
+ declare function createToolRegistry(baseEntries: ToolRegistryEntry[], baseFallback: ToolRenderer, options?: CreateToolRegistryOptions): ToolRegistry;
109
+
110
+ type MessageTimelineProps = {
111
+ /** Raw session events (projected internally) … */
112
+ events?: SessionEvent[] | undefined;
113
+ /** … or pre-projected items (e.g. from `useSessionEvents().timeline`). */
114
+ items?: TimelineItem[] | undefined;
115
+ /** Current session status; drives the live "working" indicator. */
116
+ status?: SessionStatus | null | undefined;
117
+ /** Plug a markdown renderer for message bodies (e.g. streamdown). */
118
+ renderMessageText?: ((text: string, item: AgentMessageItem | UserMessageItem) => ReactNode) | undefined;
119
+ /** Drill into a spawned worker session. */
120
+ onOpenSession?: ((sessionId: string) => void) | undefined;
121
+ /**
122
+ * Deep-link a memory row (a `memory.saved` / `memory.corrected` step) to its
123
+ * record in the host's memory pane. Opt-in, exactly like `onReconnect`: the
124
+ * library draws no "View in memory" affordance without a handler — the memory
125
+ * row is then non-interactive rich content. This is the switch that makes the
126
+ * deep-link a first-party OpenGeni capability without other SDK consumers
127
+ * opting into it. The app supplies it (it owns routing to the memory pane).
128
+ */
129
+ onMemoryClick?: ((memoryId: string) => void) | undefined;
130
+ /**
131
+ * Start the reconnect flow when a tool needs its connection reauthorized. The
132
+ * app supplies this (it owns the SDK client + workspace): it typically kicks
133
+ * off `startConnectionOAuth` and redirects, or routes to credential entry.
134
+ * Rejecting surfaces a calm inline error on the card; the library never draws
135
+ * a Reconnect button without a handler to run it.
136
+ */
137
+ onReconnect?: ((item: AuthNeededItem) => void | Promise<void>) | undefined;
138
+ /**
139
+ * Resolve a provider domain (from a reconnect card) to a logo URL the host
140
+ * serves itself — the app maps it through its catalog + `catalogAssetUrl`.
141
+ * Return null/undefined to fall back to a calm monogram. The library never
142
+ * fetches an off-origin favicon (CSP + privacy); an unresolved logo is a
143
+ * monogram, not an external image.
144
+ */
145
+ resolveProviderLogo?: ((providerDomain: string) => string | null | undefined) | undefined;
146
+ /**
147
+ * The tool-renderer registry that resolves how each tool call is drawn.
148
+ * Defaults to {@link defaultToolRegistry}; pass a registry from
149
+ * `createDefaultToolRegistry({ entries })` to add custom tool renderers.
150
+ */
151
+ toolRegistry?: ToolRegistry | undefined;
152
+ /** Follow new events when pinned to the bottom. Defaults to true. */
153
+ autoFollow?: boolean | undefined;
154
+ /** Older durable history exists above the current window (see useSessionEvents). */
155
+ hasOlder?: boolean | undefined;
156
+ /** An older window is being fetched; shows the quiet top shimmer. */
157
+ loadingOlder?: boolean | undefined;
158
+ /** Called when the reader nears the top and older history should backfill. */
159
+ onLoadOlder?: (() => void) | undefined;
160
+ emptyState?: ReactNode | undefined;
161
+ className?: string | undefined;
162
+ };
163
+ /**
164
+ * The session timeline: chat messages with streaming deltas, collapsed
165
+ * activity clusters (reasoning, tool calls, sandbox work), spawned-worker
166
+ * cards, goal markers, and status transitions. Owns stick-to-bottom scrolling
167
+ * with a "jump to latest" affordance when the reader scrolls back.
168
+ */
169
+ declare function MessageTimeline({ events, items, status, renderMessageText, onOpenSession, onMemoryClick, onReconnect, resolveProviderLogo, toolRegistry, autoFollow, hasOlder, loadingOlder, onLoadOlder, emptyState, className, }: MessageTimelineProps): react_jsx_runtime.JSX.Element;
170
+ /**
171
+ * Render one non-activity timeline item (chat message, status divider, goal
172
+ * landmark, notice). Exported so the component demo draws the EXACT same rows as
173
+ * the live app — no forked bubble/goal markup.
174
+ */
175
+ declare function TimelineRow({ item, renderMessageText, onReconnect, resolveProviderLogo, onOpenSession, }: {
176
+ item: TimelineItem;
177
+ renderMessageText?: ((text: string, item: AgentMessageItem | UserMessageItem) => ReactNode) | undefined;
178
+ onReconnect?: ((item: AuthNeededItem) => void | Promise<void>) | undefined;
179
+ resolveProviderLogo?: ((providerDomain: string) => string | null | undefined) | undefined;
180
+ onOpenSession?: ((sessionId: string) => void) | undefined;
181
+ }): react_jsx_runtime.JSX.Element | null;
182
+
183
+ export { type CreateToolRegistryOptions as C, type HumanInputAnswerDraft as H, MessageTimeline as M, QueueSurface as Q, type ToolRegistry as T, HumanInputForm as a, type HumanInputFormMessages as b, createToolRegistry as c, type HumanInputFormProps as d, type MessageTimelineProps as e, type QueueSurfaceProps as f, TimelineRow as g, type ToolRegistryEntry as h, type ToolRenderer as i, type ToolRendererProps as j, answersFromDrafts as k, defaultHumanInputFormMessages as l, rawTypeOf as r };
@@ -0,0 +1,7 @@
1
+ export { H as HumanInputAnswerDraft, a as HumanInputForm, b as HumanInputFormMessages, d as HumanInputFormProps, M as MessageTimeline, e as MessageTimelineProps, Q as QueueSurface, f as QueueSurfaceProps, g as TimelineRow } from './session-ui-BqQDH7YV.js';
2
+ import 'react/jsx-runtime';
3
+ import '@opengeni/sdk';
4
+ import 'react';
5
+ import './use-turn-queue-3rkJwjFv.js';
6
+ import './session-context-rgrfElMl.js';
7
+ import './use-composer-BnEzheSk.js';
@@ -0,0 +1,17 @@
1
+ import {
2
+ HumanInputForm,
3
+ MessageTimeline,
4
+ QueueSurface,
5
+ TimelineRow
6
+ } from "./chunk-GQN2QIR2.js";
7
+ import "./chunk-TK7G6XLT.js";
8
+ import "./chunk-OZDLELJQ.js";
9
+ import "./chunk-M7X4JZOD.js";
10
+ import "./chunk-YDNWMKXO.js";
11
+ export {
12
+ HumanInputForm,
13
+ MessageTimeline,
14
+ QueueSurface,
15
+ TimelineRow
16
+ };
17
+ //# sourceMappingURL=session-ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/session.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { E as ClientOverride, f as HumanInputClientOverride, a as HumanInputSessionClientLike, b as SessionClientLike, c as SessionMcpApprovalPolicyClientLike, e as SessionMcpApprovalPolicyClientOverride } from './session-context-rgrfElMl.js';
2
- export { A as ActivityItem, c as AgentMessageItem, e as AuthNeededItem, G as GoalItem, a0 as MemoryItem, N as NoticeItem, P as PendingApproval, f as PendingHumanInputRequest, Q as QueueMutationKind, R as ReasoningItem, k as SandboxItem, l as SessionEventsConnectionState, m as SessionStatusItem, n as TimelineGroup, b as TimelineItem, T as ToolCallItem, o as TurnEndItem, a as TurnOutcome, p as UseHumanInputRequestsOptions, q as UseHumanInputRequestsResult, r as UseSessionControlOptions, s as UseSessionControlResult, t as UseSessionEventsOptions, u as UseSessionEventsResult, v as UseSessionMcpApprovalPolicyOptions, w as UseSessionMcpApprovalPolicyResult, x as UseTurnQueueOptions, U as UseTurnQueueResult, d as UserMessageItem, a1 as WorkerCompletionItem, W as WorkerItem, y as approvalsFromRequiresAction, C as buildTimeline, D as creditExhaustedFromEvents, E as extractSessionRef, F as groupTimeline, H as humanInputRequestFromEvent, I as isHumanInputEvent, J as isSessionMcpApprovalPolicyEvent, K as isTurnQueueEvent, L as projectPendingApprovals, M as projectPendingHumanInputRequests, O as sessionStatusFromEvents, V as toolDisplayName, X as useHumanInputRequests, Y as useSessionControl, Z as useSessionEvents, _ as useSessionMcpApprovalPolicy, $ as useTurnQueue } from './session-BEvtFWhe.js';
2
+ export { P as PendingApproval, a as PendingHumanInputRequest, f as SessionEventsConnectionState, U as UseGoalOptions, g as UseGoalResult, h as UseHumanInputRequestsOptions, i as UseHumanInputRequestsResult, j as UseSessionControlOptions, k as UseSessionControlResult, l as UseSessionEventsOptions, m as UseSessionEventsResult, n as UseSessionLineageOptions, o as UseSessionLineageResult, p as UseSessionMcpApprovalPolicyOptions, q as UseSessionMcpApprovalPolicyResult, r as UseSessionOptions, s as UseSessionResult, t as approvalsFromRequiresAction, v as buildTimeline, w as creditExhaustedFromEvents, x as extractSessionRef, y as groupTimeline, z as humanInputRequestFromEvent, A as isGoalEvent, C as isHumanInputEvent, D as isLineageRefreshEvent, E as isSessionMcpApprovalPolicyEvent, F as isTitleEvent, G as projectPendingApprovals, H as projectPendingHumanInputRequests, I as sessionStatusFromEvents, J as toolDisplayName, K as useGoal, L as useHumanInputRequests, M as useSession, N as useSessionControl, O as useSessionEvents, Q as useSessionLineage, R as useSessionMcpApprovalPolicy } from './session-Du_FsrZ1.js';
3
3
  export { a as ComposerSendExtras, C as ComposerState, F as FILE_ONLY_MESSAGE_TEXT, U as UseComposerOptions, c as composeSendInput, s as shouldSteerOnKey, b as shouldSubmitOnKey, u as useComposer } from './use-composer-BnEzheSk.js';
4
+ export { F as FileAttachment, a as UseFileAttachmentsOptions, U as UseFileAttachmentsResult, u as useFileAttachments } from './use-file-attachments-C0kpHrs9.js';
5
+ export { A as ActivityItem, a as AgentMessageItem, b as AuthNeededItem, G as GoalItem, M as MemoryItem, N as NoticeItem, Q as QueueMutationKind, R as ReasoningItem, S as SandboxItem, c as SessionStatusItem, d as TimelineGroup, e as TimelineItem, f as ToolCallItem, g as TurnEndItem, T as TurnOutcome, U as UseTurnQueueOptions, h as UseTurnQueueResult, i as UserMessageItem, k as WorkerCompletionItem, W as WorkerItem, j as isTurnQueueEvent, u as useTurnQueue } from './use-turn-queue-3rkJwjFv.js';
4
6
  import '@opengeni/sdk';
package/dist/session.js CHANGED
@@ -1,31 +1,41 @@
1
1
  import {
2
2
  approvalsFromRequiresAction,
3
- buildTimeline,
4
- creditExhaustedFromEvents,
5
- extractSessionRef,
6
- groupTimeline,
7
3
  humanInputRequestFromEvent,
4
+ isGoalEvent,
8
5
  isHumanInputEvent,
6
+ isLineageRefreshEvent,
9
7
  isSessionMcpApprovalPolicyEvent,
8
+ isTitleEvent,
10
9
  isTurnQueueEvent,
11
10
  projectPendingApprovals,
12
11
  projectPendingHumanInputRequests,
13
- sessionStatusFromEvents,
14
- toolDisplayName,
12
+ useFileAttachments,
13
+ useGoal,
15
14
  useHumanInputRequests,
15
+ useSession,
16
16
  useSessionControl,
17
17
  useSessionEvents,
18
+ useSessionLineage,
18
19
  useSessionMcpApprovalPolicy,
19
20
  useTurnQueue
20
- } from "./chunk-SHOFILHJ.js";
21
+ } from "./chunk-MP6237JB.js";
21
22
  import {
22
23
  FILE_ONLY_MESSAGE_TEXT,
23
24
  composeSendInput,
24
25
  shouldSteerOnKey,
25
26
  shouldSubmitOnKey,
26
27
  useComposer
27
- } from "./chunk-AVPU5PMC.js";
28
- import "./chunk-I3BJZIG5.js";
28
+ } from "./chunk-F4CFWKVI.js";
29
+ import "./chunk-HIWPQYWI.js";
30
+ import {
31
+ buildTimeline,
32
+ creditExhaustedFromEvents,
33
+ extractSessionRef,
34
+ groupTimeline,
35
+ sessionStatusFromEvents,
36
+ toolDisplayName
37
+ } from "./chunk-OZDLELJQ.js";
38
+ import "./chunk-M7X4JZOD.js";
29
39
  export {
30
40
  FILE_ONLY_MESSAGE_TEXT,
31
41
  approvalsFromRequiresAction,
@@ -35,8 +45,11 @@ export {
35
45
  extractSessionRef,
36
46
  groupTimeline,
37
47
  humanInputRequestFromEvent,
48
+ isGoalEvent,
38
49
  isHumanInputEvent,
50
+ isLineageRefreshEvent,
39
51
  isSessionMcpApprovalPolicyEvent,
52
+ isTitleEvent,
40
53
  isTurnQueueEvent,
41
54
  projectPendingApprovals,
42
55
  projectPendingHumanInputRequests,
@@ -45,9 +58,13 @@ export {
45
58
  shouldSubmitOnKey,
46
59
  toolDisplayName,
47
60
  useComposer,
61
+ useFileAttachments,
62
+ useGoal,
48
63
  useHumanInputRequests,
64
+ useSession,
49
65
  useSessionControl,
50
66
  useSessionEvents,
67
+ useSessionLineage,
51
68
  useSessionMcpApprovalPolicy,
52
69
  useTurnQueue
53
70
  };
@@ -0,0 +1,76 @@
1
+ import { FileAsset, FileResourceRef } from '@opengeni/sdk';
2
+ import { C as ClientOverride } from './session-context-rgrfElMl.js';
3
+
4
+ type UseFileAttachmentsOptions = ClientOverride & {
5
+ /**
6
+ * Only files matching this predicate are accepted by {@link
7
+ * UseFileAttachmentsResult.addFromPaste} (the clipboard path). Defaults to
8
+ * `image/*` — the console's historical paste filter. {@link
9
+ * UseFileAttachmentsResult.addFiles} (the explicit picker / drop path)
10
+ * bypasses it.
11
+ */
12
+ pasteFilter?: ((file: File) => boolean) | undefined;
13
+ };
14
+ type FileAttachment = {
15
+ id: string;
16
+ name: string;
17
+ contentType: string;
18
+ sizeBytes: number;
19
+ status: "uploading" | "ready" | "failed";
20
+ /** The SDK `FileAsset` once the upload finishes. */
21
+ file?: FileAsset | undefined;
22
+ /** Object-URL for an inline preview; minted for `image/*` files only. */
23
+ previewUrl?: string | undefined;
24
+ error?: string | undefined;
25
+ };
26
+ type UseFileAttachmentsResult = {
27
+ attachments: FileAttachment[];
28
+ /**
29
+ * `FileResourceRef[]` for every attachment that finished uploading — feed
30
+ * straight into `useComposer`'s `sendExtras.resources`.
31
+ */
32
+ readyResources: FileResourceRef[];
33
+ /** True while any attachment is still uploading (drives progress UI). */
34
+ uploading: boolean;
35
+ /**
36
+ * True while any attachment still needs an explicit outcome: wait for an
37
+ * upload, retry a failure, or remove it. This is the loss-prevention send
38
+ * gate; failed cards must never be silently omitted from a message.
39
+ */
40
+ hasUnresolved: boolean;
41
+ /** Explicit picker / drop path — uploads every file, no filter. */
42
+ addFiles: (files: Iterable<File>) => void;
43
+ /** Clipboard path — applies `pasteFilter` (default `image/*`) then uploads. */
44
+ addFromPaste: (event: {
45
+ clipboardData: DataTransfer | null;
46
+ }) => void;
47
+ /** Restore already-ready server assets without recreating browser-local bytes. */
48
+ restoreReadyFiles: (files: Iterable<FileAsset>) => void;
49
+ /**
50
+ * Re-run the upload for a `failed` attachment, in place (same id, same
51
+ * source file). No-op for an id that isn't a known failed upload.
52
+ */
53
+ retry: (id: string) => void;
54
+ /** Remove one attachment; revokes its object-URL. */
55
+ remove: (id: string) => void;
56
+ /**
57
+ * Remove only finalized files whose durable ids were accepted by a send.
58
+ * Attachments added while that request was in flight remain queued for the
59
+ * next message.
60
+ */
61
+ removeReadyFiles: (fileIds: Iterable<string>) => void;
62
+ /** Remove all attachments and revoke every object-URL. */
63
+ clear: () => void;
64
+ };
65
+ /**
66
+ * Upload-and-track state for files attached to the next message. Owns the
67
+ * full client-side upload layer: a per-file `uploading | ready | failed`
68
+ * status machine driven by the SDK's `client.uploadFile`, object-URL image
69
+ * previews with create/revoke lifecycle, the `image/*` clipboard paste filter,
70
+ * and a `FileResourceRef[]` projection that drops straight into a message's
71
+ * `resources`. Workspace-scoped, so it resolves both client and workspace from
72
+ * the {@link OpenGeniProvider} (or a per-call `{ client, workspaceId }`).
73
+ */
74
+ declare function useFileAttachments(options?: UseFileAttachmentsOptions): UseFileAttachmentsResult;
75
+
76
+ export { type FileAttachment as F, type UseFileAttachmentsResult as U, type UseFileAttachmentsOptions as a, useFileAttachments as u };