@opengeni/react 0.1.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.
- package/README.md +141 -0
- package/dist/index.d.ts +897 -0
- package/dist/index.js +3013 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
- package/src/approvals.ts +86 -0
- package/src/client.ts +52 -0
- package/src/commands/index.ts +17 -0
- package/src/commands/registry.ts +236 -0
- package/src/commands/types.ts +88 -0
- package/src/components/chat-composer.tsx +619 -0
- package/src/components/command-palette.tsx +94 -0
- package/src/components/fleet-tile.tsx +72 -0
- package/src/components/message-timeline.tsx +416 -0
- package/src/components/session-status.tsx +92 -0
- package/src/hooks/internal.ts +236 -0
- package/src/hooks/use-billing-usage.ts +51 -0
- package/src/hooks/use-composer.ts +213 -0
- package/src/hooks/use-environments.ts +118 -0
- package/src/hooks/use-file-attachments.ts +135 -0
- package/src/hooks/use-goal.ts +154 -0
- package/src/hooks/use-packs.ts +101 -0
- package/src/hooks/use-scheduled-tasks.ts +29 -0
- package/src/hooks/use-session-control.ts +85 -0
- package/src/hooks/use-session-events.ts +130 -0
- package/src/hooks/use-session.ts +33 -0
- package/src/hooks/use-slash-commands.ts +366 -0
- package/src/hooks/use-turn-queue.ts +229 -0
- package/src/hooks/use-workspace-sessions.ts +30 -0
- package/src/hooks/use-workspaces.ts +66 -0
- package/src/index.ts +115 -0
- package/src/lib/cn.ts +7 -0
- package/src/lib/format.ts +84 -0
- package/src/provider.tsx +57 -0
- package/src/timeline.ts +632 -0
- package/styles/index.css +157 -0
- package/styles/tokens.css +111 -0
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @opengeni/react
|
|
2
|
+
|
|
3
|
+
React hooks and styled components for OpenGeni, built on
|
|
4
|
+
[`@opengeni/sdk`](../sdk): live session streaming, a chat composer, a message
|
|
5
|
+
timeline that renders streaming deltas / tool calls / spawned-worker status,
|
|
6
|
+
session status badges, and fleet tiles for workspace overviews.
|
|
7
|
+
|
|
8
|
+
Design-system-first: every visual decision routes through CSS-variable tokens
|
|
9
|
+
(`styles/tokens.css`) — color, typography, radius, shadow, motion. Dark mode is
|
|
10
|
+
the first-class default; light is an opt-in via `data-og-theme="light"` on any
|
|
11
|
+
ancestor. Components are styled with Tailwind v4 utilities mapped onto the
|
|
12
|
+
tokens, Radix primitives for behavior, and Motion for state-communicating
|
|
13
|
+
animation. Override the tokens to rebrand everything.
|
|
14
|
+
|
|
15
|
+
## Install & styles
|
|
16
|
+
|
|
17
|
+
The package ships TypeScript source plus two CSS entries. In your Tailwind v4
|
|
18
|
+
entry CSS:
|
|
19
|
+
|
|
20
|
+
```css
|
|
21
|
+
@import "tailwindcss";
|
|
22
|
+
@import "@opengeni/react/styles.css";
|
|
23
|
+
@source "../node_modules/@opengeni/react/src";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
(`@source` lets Tailwind compile the utilities used inside the components.
|
|
27
|
+
Consuming only the tokens without Tailwind? Import
|
|
28
|
+
`@opengeni/react/tokens.css` and use the `--og-*` variables directly.)
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { OpenGeniClient } from "@opengeni/sdk";
|
|
34
|
+
import {
|
|
35
|
+
ChatComposer,
|
|
36
|
+
MessageTimeline,
|
|
37
|
+
OpenGeniProvider,
|
|
38
|
+
SessionStatus,
|
|
39
|
+
useComposer,
|
|
40
|
+
useSessionEvents,
|
|
41
|
+
} from "@opengeni/react";
|
|
42
|
+
|
|
43
|
+
const client = new OpenGeniClient({ baseUrl: "/api/opengeni" }); // proxy through your API
|
|
44
|
+
|
|
45
|
+
function OpsChannel({ sessionId }: { sessionId: string }) {
|
|
46
|
+
const { timeline, sessionStatus } = useSessionEvents(sessionId);
|
|
47
|
+
const composer = useComposer(sessionId);
|
|
48
|
+
return (
|
|
49
|
+
<div className="flex h-full flex-col">
|
|
50
|
+
{sessionStatus ? <SessionStatus status={sessionStatus} /> : null}
|
|
51
|
+
<MessageTimeline items={timeline} status={sessionStatus} className="min-h-0 flex-1" />
|
|
52
|
+
<ChatComposer composer={composer} status={sessionStatus} />
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function App() {
|
|
58
|
+
return (
|
|
59
|
+
<OpenGeniProvider client={client} workspaceId={workspaceId}>
|
|
60
|
+
<OpsChannel sessionId={sessionId} />
|
|
61
|
+
</OpenGeniProvider>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Hooks
|
|
67
|
+
|
|
68
|
+
- `useSessionEvents(sessionId)` — live stream + replay on the SDK's
|
|
69
|
+
exactly-once/ordered event delivery; returns the raw `events`, the projected
|
|
70
|
+
`timeline`, the latest `sessionStatus`, and the connection state. Updates are
|
|
71
|
+
batched per animation-frame-ish window so long replays stay smooth.
|
|
72
|
+
- `useComposer(sessionId, { sendExtras, defaultMode })` — draft/send/interrupt
|
|
73
|
+
state plus the compose-time **queue-vs-steer** choice (`mode`/`setMode`,
|
|
74
|
+
default `"queue"`): queue stacks the message behind the running turn, steer
|
|
75
|
+
interrupts and injects it now. Drafts survive failed sends; each draft
|
|
76
|
+
reuses one `clientEventId` across retries so the server dedupes.
|
|
77
|
+
`sendExtras` (object or function evaluated at send time) merges
|
|
78
|
+
resources/tools/model/reasoningEffort into every message. All human input is
|
|
79
|
+
plain chat text by design; approvals flow as control events
|
|
80
|
+
(`useSessionControl`), not bespoke widgets.
|
|
81
|
+
- `useTurnQueue(sessionId, { events })` — the live turn queue: `queue` (queued
|
|
82
|
+
turns in execution order), `activeTurn`, and optimistic `editTurn` /
|
|
83
|
+
`reorderTurns` / `removeTurn` that reconcile with the server (failed
|
|
84
|
+
mutations roll back via refetch). Live-updates on `turn.*` events — pass the
|
|
85
|
+
`events` log from `useSessionEvents` to reuse its stream, or let it tail the
|
|
86
|
+
session itself.
|
|
87
|
+
- `useGoal(sessionId, { events })` — goal state + autonomy counters
|
|
88
|
+
(`autoContinuations`, `noProgressStreak`) with `pause(rationale?)` /
|
|
89
|
+
`resume()`. Goal-less sessions yield `goal: null`. Live-updates on `goal.*`
|
|
90
|
+
events.
|
|
91
|
+
- `useSessionControl(sessionId)` — `interrupt(reason?)` and
|
|
92
|
+
`approve`/`reject(approvalId, message?)` for `requires_action` approvals.
|
|
93
|
+
- `useSession(sessionId)` — fetch one session (optional polling).
|
|
94
|
+
- `useWorkspaceSessions()` / `useScheduledTasks()` — workspace lists for
|
|
95
|
+
fleet/manager views (optional polling).
|
|
96
|
+
- `useEnvironments()` — workspace environments with create/update/remove and
|
|
97
|
+
write-only `setVariable`/`deleteVariable` (values never come back on reads).
|
|
98
|
+
- `usePacks()` — capability packs + installations with
|
|
99
|
+
register/enable/remove and `installationFor(packId)`.
|
|
100
|
+
- `useWorkspaces()` — the caller's workspaces with create/update (client-only;
|
|
101
|
+
not bound to the provider's workspace).
|
|
102
|
+
- `useBillingUsage({ accountId?, workspaceId? })` — credit balance + recent
|
|
103
|
+
usage events for billing meters (client-only, optional polling).
|
|
104
|
+
|
|
105
|
+
All workspace-scoped hooks resolve the client/workspace from
|
|
106
|
+
`<OpenGeniProvider>` or accept `{ client, workspaceId }` per call
|
|
107
|
+
(`useWorkspaces`/`useBillingUsage` need only the client). They depend on
|
|
108
|
+
`SessionClientLike` — a structural slice of `OpenGeniClient` — so proxy-backed
|
|
109
|
+
or scripted clients work unchanged.
|
|
110
|
+
|
|
111
|
+
## Timeline projection
|
|
112
|
+
|
|
113
|
+
`buildTimeline(events)` is a pure, tested reducer from the raw event log to
|
|
114
|
+
renderable items (user/agent messages with streaming flags, tool calls matched
|
|
115
|
+
to outputs, `session_create`/`session_send_message` calls promoted to worker
|
|
116
|
+
items, sandbox operations with command output, goal markers, status changes,
|
|
117
|
+
notices). User messages carry their attached `resources` and requested `tools`
|
|
118
|
+
so consumers can render attachment chips. `groupTimeline` clusters consecutive
|
|
119
|
+
activity for collapsed display. Use them directly if you want custom rendering
|
|
120
|
+
with the same semantics.
|
|
121
|
+
|
|
122
|
+
## Components
|
|
123
|
+
|
|
124
|
+
- `ChatComposer` — auto-growing textarea, Enter-to-send (IME-safe), stop
|
|
125
|
+
control while a turn runs, inline error recovery. Slots for app chrome:
|
|
126
|
+
`controlsStart` (footer controls like model pickers / attach buttons),
|
|
127
|
+
`header` (e.g. attachment chips above the field), and `onPaste`
|
|
128
|
+
(paste-image-to-attach).
|
|
129
|
+
- `MessageTimeline` — the session timeline with stick-to-bottom scrolling, a
|
|
130
|
+
"jump to latest" affordance, streaming caret, collapsible activity clusters,
|
|
131
|
+
and worker cards (wire `onOpenSession` to drill into a worker). Pass
|
|
132
|
+
`renderMessageText` to plug a markdown renderer.
|
|
133
|
+
- `SessionStatus` / `StatusDot` — status badges; live states breathe.
|
|
134
|
+
- `FleetTile` — one session in a fleet grid: title, status, model, recency.
|
|
135
|
+
|
|
136
|
+
## Demo harness
|
|
137
|
+
|
|
138
|
+
`bun run demo` (from this package) serves a harness that drives the real hooks
|
|
139
|
+
and components against a scripted mock client — a manager ops-channel narrative
|
|
140
|
+
with streaming, tool calls, and a worker spawn, plus fleet and scheduled-task
|
|
141
|
+
views and a dark/light toggle. `bun run demo:build` is part of the repo gate.
|