@kortix/sdk 0.12.4 → 0.12.6
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 +80 -15
- package/dist/browser/session-sync/session-transcript-cache.d.ts +17 -0
- package/dist/browser/session-sync/session-transcript-cache.d.ts.map +1 -1
- package/dist/browser/session-sync/session-transcript-cache.js +14 -2
- package/dist/browser/session-sync/session-transcript-cache.js.map +1 -1
- package/dist/browser/stores/sync-store.d.ts +86 -2
- package/dist/browser/stores/sync-store.d.ts.map +1 -1
- package/dist/browser/stores/sync-store.js +386 -33
- package/dist/browser/stores/sync-store.js.map +1 -1
- package/dist/core/client/kortix.d.ts +87 -54
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +67 -21
- package/dist/core/client/kortix.js.map +1 -1
- package/dist/core/http/api-client.d.ts +19 -1
- package/dist/core/http/api-client.d.ts.map +1 -1
- package/dist/core/http/api-client.js +79 -21
- package/dist/core/http/api-client.js.map +1 -1
- package/dist/core/http/auth.d.ts.map +1 -1
- package/dist/core/http/auth.js +6 -4
- package/dist/core/http/auth.js.map +1 -1
- package/dist/core/http/config.d.ts +4 -0
- package/dist/core/http/config.d.ts.map +1 -1
- package/dist/core/http/config.js.map +1 -1
- package/dist/core/rest/platform-client/host-boundary.js +2 -2
- package/dist/core/rest/platform-client/host-boundary.js.map +1 -1
- package/dist/core/rest/projects-client/access.d.ts +1 -1
- package/dist/core/rest/projects-client/agent-config.d.ts +1 -1
- package/dist/core/rest/projects-client/agent-config.d.ts.map +1 -1
- package/dist/core/rest/projects-client/apps.d.ts +216 -0
- package/dist/core/rest/projects-client/apps.d.ts.map +1 -0
- package/dist/core/rest/projects-client/apps.js +105 -0
- package/dist/core/rest/projects-client/apps.js.map +1 -0
- package/dist/core/rest/projects-client/audit.js +1 -1
- package/dist/core/rest/projects-client/audit.js.map +1 -1
- package/dist/core/rest/projects-client/billing.d.ts +7 -0
- package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
- package/dist/core/rest/projects-client/billing.js.map +1 -1
- package/dist/core/rest/projects-client/channels.d.ts +7 -6
- package/dist/core/rest/projects-client/channels.d.ts.map +1 -1
- package/dist/core/rest/projects-client/channels.js +12 -2
- package/dist/core/rest/projects-client/channels.js.map +1 -1
- package/dist/core/rest/projects-client/connectors.d.ts +133 -98
- package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
- package/dist/core/rest/projects-client/connectors.js +199 -119
- package/dist/core/rest/projects-client/connectors.js.map +1 -1
- package/dist/core/rest/projects-client/files.d.ts.map +1 -1
- package/dist/core/rest/projects-client/files.js +7 -1
- package/dist/core/rest/projects-client/files.js.map +1 -1
- package/dist/core/rest/projects-client/index.d.ts +1 -0
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +1 -0
- package/dist/core/rest/projects-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/policies.js +3 -3
- package/dist/core/rest/projects-client/policies.js.map +1 -1
- package/dist/core/rest/projects-client/projects.d.ts +47 -1
- package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
- package/dist/core/rest/projects-client/projects.js +12 -0
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/secrets.d.ts +55 -3
- package/dist/core/rest/projects-client/secrets.d.ts.map +1 -1
- package/dist/core/rest/projects-client/secrets.js +14 -4
- package/dist/core/rest/projects-client/secrets.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +8 -16
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +1 -1
- package/dist/core/rest/projects-client/sessions.js.map +1 -1
- package/dist/core/session/index.d.ts +1 -0
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js +1 -0
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/preview-probe.d.ts +76 -0
- package/dist/core/session/preview-probe.d.ts.map +1 -0
- package/dist/core/session/preview-probe.js +97 -0
- package/dist/core/session/preview-probe.js.map +1 -0
- package/dist/core/turns/classify.js +1 -1
- package/dist/core/turns/errors.js +1 -1
- package/dist/core/turns/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/kortix.esm.min.js +19 -19
- package/dist/kortix.global.js +19 -19
- package/dist/platform/auth-core.d.ts +2 -1
- package/dist/platform/auth-core.d.ts.map +1 -1
- package/dist/platform/auth-core.js +10 -1
- package/dist/platform/auth-core.js.map +1 -1
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/invalidate-project.d.ts +76 -0
- package/dist/react/invalidate-project.d.ts.map +1 -0
- package/dist/react/invalidate-project.js +72 -0
- package/dist/react/invalidate-project.js.map +1 -0
- package/dist/react/provider-refresh.d.ts.map +1 -1
- package/dist/react/provider-refresh.js +12 -3
- package/dist/react/provider-refresh.js.map +1 -1
- package/dist/react/query-contracts.d.ts +112 -0
- package/dist/react/query-contracts.d.ts.map +1 -0
- package/dist/react/query-contracts.js +100 -0
- package/dist/react/query-contracts.js.map +1 -0
- package/dist/react/query-keys.d.ts +251 -0
- package/dist/react/query-keys.d.ts.map +1 -0
- package/dist/react/query-keys.js +249 -0
- package/dist/react/query-keys.js.map +1 -0
- package/dist/react/session-title-sync.d.ts.map +1 -1
- package/dist/react/session-title-sync.js +14 -4
- package/dist/react/session-title-sync.js.map +1 -1
- package/dist/react/use-admin-accounts.d.ts +85 -0
- package/dist/react/use-admin-accounts.d.ts.map +1 -1
- package/dist/react/use-admin-accounts.js +100 -0
- package/dist/react/use-admin-accounts.js.map +1 -1
- package/dist/react/use-admin-activity-analytics.d.ts +91 -0
- package/dist/react/use-admin-activity-analytics.d.ts.map +1 -0
- package/dist/react/use-admin-activity-analytics.js +83 -0
- package/dist/react/use-admin-activity-analytics.js.map +1 -0
- package/dist/react/use-admin-projects.d.ts +50 -0
- package/dist/react/use-admin-projects.d.ts.map +1 -0
- package/dist/react/use-admin-projects.js +28 -0
- package/dist/react/use-admin-projects.js.map +1 -0
- package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
- package/dist/react/use-canonical-opencode-session.js +12 -7
- package/dist/react/use-canonical-opencode-session.js.map +1 -1
- package/dist/react/use-gateway-catalog-sync.d.ts.map +1 -1
- package/dist/react/use-gateway-catalog-sync.js +5 -2
- package/dist/react/use-gateway-catalog-sync.js.map +1 -1
- package/dist/react/use-model-defaults.d.ts.map +1 -1
- package/dist/react/use-model-defaults.js +3 -1
- package/dist/react/use-model-defaults.js.map +1 -1
- package/dist/react/use-model-enablement.d.ts.map +1 -1
- package/dist/react/use-model-enablement.js +6 -2
- package/dist/react/use-model-enablement.js.map +1 -1
- package/dist/react/use-opencode-events/handle-event.d.ts +6 -0
- package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
- package/dist/react/use-opencode-events/handle-event.js +3 -3
- package/dist/react/use-opencode-events/handle-event.js.map +1 -1
- package/dist/react/use-opencode-events/helpers.d.ts +27 -1
- package/dist/react/use-opencode-events/helpers.d.ts.map +1 -1
- package/dist/react/use-opencode-events/helpers.js +31 -6
- package/dist/react/use-opencode-events/helpers.js.map +1 -1
- package/dist/react/use-opencode-events/index.d.ts.map +1 -1
- package/dist/react/use-opencode-events/index.js +8 -0
- package/dist/react/use-opencode-events/index.js.map +1 -1
- package/dist/react/use-opencode-sessions/agents.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/agents.js +10 -1
- package/dist/react/use-opencode-sessions/agents.js.map +1 -1
- package/dist/react/use-opencode-sessions/messages.d.ts +19 -3
- package/dist/react/use-opencode-sessions/messages.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/messages.js +28 -55
- package/dist/react/use-opencode-sessions/messages.js.map +1 -1
- package/dist/react/use-opencode-sessions/providers.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/providers.js +9 -2
- package/dist/react/use-opencode-sessions/providers.js.map +1 -1
- package/dist/react/use-project-apps.d.ts +410 -0
- package/dist/react/use-project-apps.d.ts.map +1 -0
- package/dist/react/use-project-apps.js +98 -0
- package/dist/react/use-project-apps.js.map +1 -0
- package/dist/react/use-project-config.d.ts +7 -0
- package/dist/react/use-project-config.d.ts.map +1 -1
- package/dist/react/use-project-config.js +14 -4
- package/dist/react/use-project-config.js.map +1 -1
- package/dist/react/use-project-models.d.ts.map +1 -1
- package/dist/react/use-project-models.js +8 -2
- package/dist/react/use-project-models.js.map +1 -1
- package/dist/react/use-project-name.d.ts +23 -0
- package/dist/react/use-project-name.d.ts.map +1 -0
- package/dist/react/use-project-name.js +44 -0
- package/dist/react/use-project-name.js.map +1 -0
- package/dist/react/use-project-secrets.d.ts +29 -2
- package/dist/react/use-project-secrets.d.ts.map +1 -1
- package/dist/react/use-project-secrets.js +8 -2
- package/dist/react/use-project-secrets.js.map +1 -1
- package/dist/react/use-project-session.d.ts +40 -0
- package/dist/react/use-project-session.d.ts.map +1 -0
- package/dist/react/use-project-session.js +49 -0
- package/dist/react/use-project-session.js.map +1 -0
- package/dist/react/use-project-triggers.d.ts +4 -2
- package/dist/react/use-project-triggers.d.ts.map +1 -1
- package/dist/react/use-project-triggers.js +7 -2
- package/dist/react/use-project-triggers.js.map +1 -1
- package/dist/react/use-session-sync.d.ts +1 -2
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +17 -40
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session.d.ts.map +1 -1
- package/dist/react/use-session.js +18 -16
- package/dist/react/use-session.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,6 +33,31 @@ const kortix = createKortix({
|
|
|
33
33
|
await kortix.projects.list();
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
### Call external systems through Connectors
|
|
37
|
+
|
|
38
|
+
Use one six-method data plane for every Connector provider. A user token binds
|
|
39
|
+
the project explicitly. An agent-minted session token already carries its
|
|
40
|
+
project scope, so it can use the top-level fallback.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const connectors = projectId
|
|
44
|
+
? kortix.project(projectId).connectors
|
|
45
|
+
: kortix.connectors;
|
|
46
|
+
|
|
47
|
+
await connectors.catalog();
|
|
48
|
+
await connectors.tools();
|
|
49
|
+
await connectors.search('send email');
|
|
50
|
+
await connectors.describe('gmail.send_email');
|
|
51
|
+
await connectors.call('gmail.send_email', { to, subject, body });
|
|
52
|
+
await connectors.uploadAttachment(bytes, {
|
|
53
|
+
filename: 'invoice.pdf',
|
|
54
|
+
contentType: 'application/pdf',
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A Connector defines callable tools. A Connection stores one authorization for
|
|
59
|
+
that Connector. Credentials remain server-side and never enter the sandbox.
|
|
60
|
+
|
|
36
61
|
## No bundler, no framework
|
|
37
62
|
|
|
38
63
|
The published package ships a browser IIFE bundle alongside its ESM `dist/` —
|
|
@@ -86,7 +111,19 @@ const kortix = createKortix({
|
|
|
86
111
|
// Projects
|
|
87
112
|
const projects = await kortix.projects.list();
|
|
88
113
|
const detail = await kortix.project(pid).detail();
|
|
89
|
-
await kortix.project(pid).secrets.upsert({
|
|
114
|
+
await kortix.project(pid).secrets.upsert({
|
|
115
|
+
name: "LOCAL_TOOL_TOKEN",
|
|
116
|
+
value,
|
|
117
|
+
strategy: "runtime",
|
|
118
|
+
consumer: "sandbox",
|
|
119
|
+
});
|
|
120
|
+
await kortix.project(pid).secrets.upsert({
|
|
121
|
+
identifier: "anthropic-primary",
|
|
122
|
+
name: "ANTHROPIC_API_KEY",
|
|
123
|
+
value: providerKey,
|
|
124
|
+
strategy: "broker",
|
|
125
|
+
consumer: "llm_gateway",
|
|
126
|
+
});
|
|
90
127
|
const visibleSessions = await kortix.project(pid).sessions.list();
|
|
91
128
|
const projectInventory = await kortix
|
|
92
129
|
.project(pid)
|
|
@@ -111,6 +148,28 @@ const { opencodeSessionId } = await s.ensureReady();
|
|
|
111
148
|
await s.runtime.session.prompt({ sessionID: opencodeSessionId, parts });
|
|
112
149
|
```
|
|
113
150
|
|
|
151
|
+
### Apps
|
|
152
|
+
|
|
153
|
+
`kortix.project(projectId).apps` deploys immutable App versions behind one stable URL. New Apps use `private` access. Apps is an experimental project feature, so API operations return `404` until a project manager enables it.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const apps = kortix.project(projectId).apps;
|
|
157
|
+
const app = await apps.create({ slug: 'docs', name: 'Docs' });
|
|
158
|
+
const artifact = await apps.artifacts.uploadArchive(tarGzBytes);
|
|
159
|
+
await apps.deployments.create(app.app_id, {
|
|
160
|
+
artifact_id: artifact.artifact_id,
|
|
161
|
+
source: { kind: 'static', spa: true },
|
|
162
|
+
});
|
|
163
|
+
await apps.access.update(app.app_id, {
|
|
164
|
+
mode: 'restricted',
|
|
165
|
+
member_ids: [memberId],
|
|
166
|
+
group_ids: [groupId],
|
|
167
|
+
});
|
|
168
|
+
const browserSession = await apps.access.session(app.app_id);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Access modes are `private`, `project`, `restricted`, `public`, and `password`. An access session exchanges a five-minute URL for an eight-hour, host-only cookie. A stopped or idle App resumes on the same public request. Transient machine requests receive `202 app_starting` and `Retry-After: 3`.
|
|
172
|
+
|
|
114
173
|
For OpenCode REST sessions, `send()` reads the persisted session model and
|
|
115
174
|
agent before the first prompt on a handle. This prevents a snapshot-inherited
|
|
116
175
|
OpenCode session from reusing stale snapshot defaults. A per-call choice
|
|
@@ -150,7 +209,8 @@ exhaustive — see `API-MAP.md` for the full per-domain surface:
|
|
|
150
209
|
| `kortix.billing` | entitlement/usage reads: `accountState` · `accountStateMinimal` · `transactions` · `transactionsSummary` · `creditBreakdown` · `usageHistory` · `usageRollup` · `sessionCosts.{list,get}` · `tierConfigurations` — plus a curated mutation surface: `checkout.{createSession,confirmSession}` · `subscription.{createPortalSession,cancel,reactivate,scheduleDowngrade,cancelScheduledChange,prorationPreview}` · `credits.{purchase,autoTopupSettings,configureAutoTopup}` |
|
|
151
210
|
| `kortix.marketplace` | public marketplace catalog browse + sources (not project-scoped): `items` · `item` · `itemFile` · `marketplaces` · `featured` · `sources.{list,add,remove}` — distinct from the install-scoped `project(id).marketplace` |
|
|
152
211
|
| `kortix.validateToken()` | pasted-API-key validation helper — `GET /accounts/me`, never throws, resolves `{valid, identity?, error?}` |
|
|
153
|
-
| `kortix.
|
|
212
|
+
| `kortix.connectors` | Connector data plane for an agent-minted session token: `catalog` · `tools` · `search` · `describe` · `call` · `uploadAttachment` |
|
|
213
|
+
| `kortix.project(id)` | id-bound handle: `.apps` (stable serverless App URLs, access, artifacts, deployments, logs, rollback, start/stop) · `.secrets` · `.access` · `.connectors` (data plane + configuration + Connections) · `.policies` · `.triggers` · `.files` · `.git` · `.changeRequests` (incl. `requestChanges`) · `.sessions` · `.tokens` (project-scoped CLI PATs — the `KORTIX_TOKEN` shape) · `.marketplace` / `.registry` (install/update/remove catalog items) · `.setupLinks.{requestSecret,requestConnector}` (agent-minted secret-entry / connector links) · `.validateManifest` · `.gitToken` · `.setDefaultAgent(name)` · `.session(sid)` (+ more namespaces: `.review`, `.approvals`, `.gateway` (incl. `.routing` and `.playground`), `.channels`, `.modelDefaults`, `.sandbox`) |
|
|
154
214
|
| `kortix.session(pid, sid)` | id-bound handle: lifecycle (`get`/`update`/`delete`/`start`/`restart`/`stop`/`setSharing`/`previews`/`commit`/`publicShares`/`ensureReady`) · finalized `cost()` · `send`/`abort`/`rewind`/`restoreRewind`/`setModel`/`setAgent` · `transcript()` · `.files` · runtime URL helpers (`health`/`previewUrl`/`proxyUrl`) · OpenCode REST compatibility escape hatches: `stream()` and `.runtime` |
|
|
155
215
|
| `kortix.runtime()` | the OpenCode v2 compatibility client for the active sandbox; use a session-scoped handle in multi-tenant code |
|
|
156
216
|
|
|
@@ -172,12 +232,12 @@ await kortix.project(projectId).sessions.create({
|
|
|
172
232
|
```
|
|
173
233
|
|
|
174
234
|
Do not put credentials in this map. For a white-label/backend wrapper, create an
|
|
175
|
-
operator-managed connection
|
|
176
|
-
credential endpoint, and pass only the non-secret
|
|
235
|
+
operator-managed connection, store its credential through the dedicated
|
|
236
|
+
credential endpoint, and pass only the non-secret connection id at session create:
|
|
177
237
|
|
|
178
238
|
```ts
|
|
179
239
|
const project = kortix.project(projectId);
|
|
180
|
-
const
|
|
240
|
+
const connection = await project.connectors.connections.reconcile({
|
|
181
241
|
connector_alias: "customer-data",
|
|
182
242
|
owner_type: "external",
|
|
183
243
|
owner_id: wrapperUserId,
|
|
@@ -191,39 +251,39 @@ const auth = await project.connectors.auth.discover({
|
|
|
191
251
|
provider: "postman",
|
|
192
252
|
spec: "https://github.com/HubSpot/HubSpot-public-api-spec-collection",
|
|
193
253
|
});
|
|
194
|
-
await project.connectors.
|
|
254
|
+
await project.connectors.connections.updateCredential(connection.connection_id, {
|
|
195
255
|
value: shortLivedCapability,
|
|
196
256
|
kind: "secret",
|
|
197
257
|
});
|
|
198
258
|
await project.sessions.create({
|
|
199
259
|
runtime_context: { locale: "de" },
|
|
200
260
|
connector_bindings: {
|
|
201
|
-
"customer-data": {
|
|
261
|
+
"customer-data": { connection_id: connection.connection_id },
|
|
202
262
|
},
|
|
203
263
|
});
|
|
204
264
|
```
|
|
205
265
|
|
|
206
266
|
For bring-your-own authorization, each logged-in member creates their own
|
|
207
|
-
|
|
267
|
+
connection without supplying an owner id; Kortix derives ownership from the bearer
|
|
208
268
|
token:
|
|
209
269
|
|
|
210
270
|
```ts
|
|
211
|
-
const
|
|
271
|
+
const connection = await project.connectors.connections.reconcileMember({
|
|
212
272
|
connector_alias: "gmail",
|
|
213
273
|
label: "My Gmail",
|
|
214
274
|
});
|
|
215
|
-
await project.connectors.
|
|
275
|
+
await project.connectors.connections.pipedreamConnect(connection.connection_id);
|
|
216
276
|
// Complete OAuth, then:
|
|
217
|
-
await project.connectors.
|
|
277
|
+
await project.connectors.connections.pipedreamFinalize(connection.connection_id);
|
|
218
278
|
await project.sessions.create({
|
|
219
|
-
connector_bindings: { gmail: {
|
|
279
|
+
connector_bindings: { gmail: { connection_id: connection.connection_id } },
|
|
220
280
|
});
|
|
221
281
|
```
|
|
222
282
|
|
|
223
|
-
Member
|
|
283
|
+
Member connections are owner-only even for project managers, and sessions using
|
|
224
284
|
one must remain private. Project defaults remain shared; external/agent/subject
|
|
225
|
-
|
|
226
|
-
and resolved on every
|
|
285
|
+
connections remain operator-managed. Every connection is project/connector scoped
|
|
286
|
+
and resolved on every Connector request, so revocation takes effect without a
|
|
227
287
|
restart. Credentials are encrypted server-side and are never returned, placed
|
|
228
288
|
in `KORTIX_SESSION_CONTEXT`, or injected into the sandbox environment. Raw env
|
|
229
289
|
and MCP configuration are not session-create inputs.
|
|
@@ -438,6 +498,7 @@ Stable, tree-shakeable surfaces (also reachable via the facade). Not exhaustive
|
|
|
438
498
|
interface KortixPlatformConfig {
|
|
439
499
|
backendUrl: string;
|
|
440
500
|
getToken: () => Promise<string | null>;
|
|
501
|
+
clientSource?: 'api' | 'cli' | 'mobile' | 'web';
|
|
441
502
|
getUserId?: () => Promise<string | null>;
|
|
442
503
|
billingEnabled?: boolean;
|
|
443
504
|
sandboxId?: string | null;
|
|
@@ -448,6 +509,10 @@ interface KortixPlatformConfig {
|
|
|
448
509
|
}
|
|
449
510
|
```
|
|
450
511
|
|
|
512
|
+
Set `clientSource` when a non-web host needs its requests separated in the
|
|
513
|
+
centralized audit log. The SDK sends the validated value as request metadata.
|
|
514
|
+
Actor identity and permissions still come from the bearer token.
|
|
515
|
+
|
|
451
516
|
The SDK is host-agnostic: no Next.js / web coupling in the core. The host injects
|
|
452
517
|
its token getter and toast/notify sinks; the SDK does the rest. Today that's proven
|
|
453
518
|
in React DOM (`apps/web` and the `apps/whitelabel-demo` reference app are the
|
|
@@ -38,10 +38,27 @@ export declare function toHydrateEntries(transcript: CachedTranscript): Array<{
|
|
|
38
38
|
* store holds anything for this session — from SSE, an optimistic send, or a
|
|
39
39
|
* completed reconcile — it outranks whatever is on disk, so hydrating again
|
|
40
40
|
* could only ever move the transcript backwards.
|
|
41
|
+
*
|
|
42
|
+
* With exactly one exception, and it is not hypothetical: a session whose agent
|
|
43
|
+
* is still running when the store evicts it. Eviction deletes the key; the
|
|
44
|
+
* agent's next SSE frame puts it straight back, holding only what streamed
|
|
45
|
+
* after the eviction. The store "has" the session, but what it has is strictly
|
|
46
|
+
* less than the disk copy, so standing down leaves the user with a fragment and
|
|
47
|
+
* a `loadOlder` for their own history. `hydrate` merges rather than replaces —
|
|
48
|
+
* it never drops a message the store has that the incoming set lacks, and for
|
|
49
|
+
* text parts it keeps whichever side has more — so painting the disk copy under
|
|
50
|
+
* a live fragment restores the history without touching the live tail.
|
|
41
51
|
*/
|
|
42
52
|
export declare function shouldHydrateFromCache(input: {
|
|
43
53
|
storeHasSession: boolean;
|
|
44
54
|
cachedMessageCount: number;
|
|
55
|
+
/**
|
|
56
|
+
* The store's entry for this session is a post-eviction fragment. From
|
|
57
|
+
* `useSyncStore.wasTranscriptEvicted`, which also reports false the moment a
|
|
58
|
+
* send goes in flight — repainting under one would retire the message the
|
|
59
|
+
* user just typed.
|
|
60
|
+
*/
|
|
61
|
+
storeSessionWasEvicted?: boolean;
|
|
45
62
|
}): boolean;
|
|
46
63
|
/**
|
|
47
64
|
* Read this session's cached transcript. Resolves to null when there is no
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-transcript-cache.d.ts","sourceRoot":"","sources":["../../../src/browser/session-sync/session-transcript-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAIhE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAC/B;AAED,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,MAAM,GAChB,gBAAgB,GAAG,IAAI,CASzB;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,gBAAgB,GAC3B,KAAK,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAIzC;AAED
|
|
1
|
+
{"version":3,"file":"session-transcript-cache.d.ts","sourceRoot":"","sources":["../../../src/browser/session-sync/session-transcript-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAIhE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAC/B;AAED,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,MAAM,GAChB,gBAAgB,GAAG,IAAI,CASzB;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,gBAAgB,GAC3B,KAAK,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CAIzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAIV;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIlC;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,IAAI,CAAC,CAIf"}
|
|
@@ -42,11 +42,23 @@ export function toHydrateEntries(transcript) {
|
|
|
42
42
|
* store holds anything for this session — from SSE, an optimistic send, or a
|
|
43
43
|
* completed reconcile — it outranks whatever is on disk, so hydrating again
|
|
44
44
|
* could only ever move the transcript backwards.
|
|
45
|
+
*
|
|
46
|
+
* With exactly one exception, and it is not hypothetical: a session whose agent
|
|
47
|
+
* is still running when the store evicts it. Eviction deletes the key; the
|
|
48
|
+
* agent's next SSE frame puts it straight back, holding only what streamed
|
|
49
|
+
* after the eviction. The store "has" the session, but what it has is strictly
|
|
50
|
+
* less than the disk copy, so standing down leaves the user with a fragment and
|
|
51
|
+
* a `loadOlder` for their own history. `hydrate` merges rather than replaces —
|
|
52
|
+
* it never drops a message the store has that the incoming set lacks, and for
|
|
53
|
+
* text parts it keeps whichever side has more — so painting the disk copy under
|
|
54
|
+
* a live fragment restores the history without touching the live tail.
|
|
45
55
|
*/
|
|
46
56
|
export function shouldHydrateFromCache(input) {
|
|
47
|
-
if (input.
|
|
57
|
+
if (input.cachedMessageCount <= 0)
|
|
48
58
|
return false;
|
|
49
|
-
|
|
59
|
+
if (!input.storeHasSession)
|
|
60
|
+
return true;
|
|
61
|
+
return input.storeSessionWasEvicted === true;
|
|
50
62
|
}
|
|
51
63
|
/**
|
|
52
64
|
* Read this session's cached transcript. Resolves to null when there is no
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-transcript-cache.js","sourceRoot":"","sources":["../../../src/browser/session-sync/session-transcript-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAY/E;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAA2B,EAC3B,SAAiB;IAEjB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,EAAE;YAAE,SAAS;QAC3B,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,gBAAgB,CAC9B,UAA4B;IAE5B,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;SAC/B,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;SAClC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACxF,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"session-transcript-cache.js","sourceRoot":"","sources":["../../../src/browser/session-sync/session-transcript-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAY/E;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAA2B,EAC3B,SAAiB;IAEjB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,EAAE;YAAE,SAAS;QAC3B,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,gBAAgB,CAC9B,UAA4B;IAE5B,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;SAC/B,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;SAClC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACxF,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAUtC;IACC,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,KAAK,CAAC,sBAAsB,KAAK,IAAI,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,SAAiB,EACjB,kBAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;AAClE,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,qBAAqB,CACnC,KAA2B,EAC3B,SAAiB,EACjB,kBAA2B;IAE3B,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1C,OAAO,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;AAChG,CAAC"}
|
|
@@ -13,9 +13,40 @@ interface SyncState {
|
|
|
13
13
|
applyEvent: (event: OpenCodeEvent) => void;
|
|
14
14
|
upsertMessage: (sessionID: string, message: Message) => void;
|
|
15
15
|
removeMessage: (sessionID: string, messageID: string) => void;
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* `sessionID` is optional. Omitted, the deltaActiveParts guard below reads
|
|
18
|
+
* `part.sessionID` directly. Pass it explicitly whenever the caller already
|
|
19
|
+
* resolved a more trustworthy session id than the wire part carries — see
|
|
20
|
+
* the `message.part.updated` handler in `applyEvent`, which falls back to
|
|
21
|
+
* scanning every session's message list specifically because
|
|
22
|
+
* `part.sessionID` can be absent on the wire. Without this parameter that
|
|
23
|
+
* resolved id has nowhere to go, and the guard silently no-ops for exactly
|
|
24
|
+
* the malformed events it exists to protect against.
|
|
25
|
+
*
|
|
26
|
+
* Kept optional (not merged into `part`, not required) because `upsertPart`
|
|
27
|
+
* has real callers outside this file (`apps/web` via `useSessionStateStore`)
|
|
28
|
+
* that only ever pass `(messageID, part)` — this stays source-compatible
|
|
29
|
+
* with them.
|
|
30
|
+
*/
|
|
31
|
+
upsertPart: (messageID: string, part: Part, sessionID?: string) => void;
|
|
17
32
|
removePart: (messageID: string, partID: string) => void;
|
|
18
|
-
|
|
33
|
+
/**
|
|
34
|
+
* `sessionID` is a new REQUIRED leading parameter (was `(messageID, partID,
|
|
35
|
+
* field, delta)`) — a breaking arity change for anyone calling this action
|
|
36
|
+
* directly. Deliberate, not silent: the only caller of `applyPartDelta` in
|
|
37
|
+
* this repo is this file's own `applyEvent` (`message.part.delta` case),
|
|
38
|
+
* which already has a reliable `sessionID` on the event itself — no
|
|
39
|
+
* "resolve it from an unreliable field" case like `upsertPart` above.
|
|
40
|
+
* Kept required, not optional-with-fallback, because there is no
|
|
41
|
+
* `part.sessionID`-equivalent to fall back to here that wouldn't be a
|
|
42
|
+
* guess. Verified no other in-repo caller exists (`apps/web`, `apps/mobile`
|
|
43
|
+
* both use their own stores/methods, not this one). This action is exported
|
|
44
|
+
* on `useSyncStore` (`./sync-store`, `./internal/sync-store`), which makes
|
|
45
|
+
* it technically part of the published surface, so an out-of-repo consumer
|
|
46
|
+
* calling it directly would fail to compile — that needs a semver-relevant
|
|
47
|
+
* callout in the next release notes.
|
|
48
|
+
*/
|
|
49
|
+
applyPartDelta: (sessionID: string, messageID: string, partID: string, field: string, delta: string) => void;
|
|
19
50
|
setStatus: (sessionID: string, status: SessionStatus) => void;
|
|
20
51
|
setDiff: (sessionID: string, diffs: FileDiff[]) => void;
|
|
21
52
|
setTodo: (sessionID: string, todos: Todo[]) => void;
|
|
@@ -39,6 +70,59 @@ interface SyncState {
|
|
|
39
70
|
* whose first prompt the server hasn't registered yet. */
|
|
40
71
|
hasOptimisticMessages: (sessionID: string) => boolean;
|
|
41
72
|
clearSession: (sessionID: string) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Take a hold on `sessionID`'s transcript for one mounted consumer, and get
|
|
75
|
+
* back the release for it. The session's data stays resident until every
|
|
76
|
+
* hold is released; see {@link DETACHED_SESSION_LIMIT} for what happens
|
|
77
|
+
* after that.
|
|
78
|
+
*
|
|
79
|
+
* Returning the release rather than exposing a separate `releaseSession`
|
|
80
|
+
* makes the pairing structural — a caller cannot take a hold without
|
|
81
|
+
* receiving the matching release, and a React effect returns it directly:
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* useEffect(() => useSyncStore.getState().retainSession(id), [id]);
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* Same shape as `retainSessionSyncController` in session-sync-registry.ts.
|
|
88
|
+
* The release is idempotent: calling it twice drops one hold, not two.
|
|
89
|
+
*/
|
|
90
|
+
retainSession: (sessionID: string) => () => void;
|
|
91
|
+
/**
|
|
92
|
+
* True when this session's `messages` entry — if it has one at all — is a
|
|
93
|
+
* post-eviction fragment rather than the transcript.
|
|
94
|
+
*
|
|
95
|
+
* Eviction deletes the key, and `use-session-sync.ts` reads its absence as
|
|
96
|
+
* "the disk copy may repaint". A session whose agent is still running defeats
|
|
97
|
+
* that on its own: its SSE frames put the key back within a second or two,
|
|
98
|
+
* holding only what streamed after the eviction, so the user came back to the
|
|
99
|
+
* fragment and had to `loadOlder` for everything before it.
|
|
100
|
+
*
|
|
101
|
+
* Answering this at the store is what makes the repaint decision correct
|
|
102
|
+
* without dropping any event — dropping events for a session nobody has
|
|
103
|
+
* mounted would blind the spawn-tool preview of a child session, which has no
|
|
104
|
+
* reconcile of its own and is fed by SSE alone.
|
|
105
|
+
*
|
|
106
|
+
* Goes false again the moment anything re-establishes the session:
|
|
107
|
+
* `hydrate` (the repaint, or a reconcile), `clearSession`, `optimisticAdd`.
|
|
108
|
+
*/
|
|
109
|
+
wasTranscriptEvicted: (sessionID: string) => boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Join this session's messages with their parts, memoized on the identity of
|
|
112
|
+
* the arrays it read.
|
|
113
|
+
*
|
|
114
|
+
* Every consumer selects through here — `useSessionSync` and
|
|
115
|
+
* `useOpenCodeMessages` alike. It has to be one shared memo rather than one
|
|
116
|
+
* per hook: `getMessages` rebuilds via `.map()` on every call, so a raw
|
|
117
|
+
* selector returns a new array each time, fails `useSyncExternalStore`'s
|
|
118
|
+
* `Object.is` check and re-renders forever. The memo previously existed
|
|
119
|
+
* TWICE, once in each hook file, and neither copy was dropped when a
|
|
120
|
+
* session's data was — so an evicted transcript stayed reachable through
|
|
121
|
+
* whichever memo still held its rows. Keeping it in the store, next to the
|
|
122
|
+
* eviction that invalidates it, is what makes that impossible rather than
|
|
123
|
+
* merely fixed.
|
|
124
|
+
*/
|
|
125
|
+
buildSessionMessages: (sessionID: string, msgs: Message[] | undefined, parts: Record<string, Part[]>) => MessageWithParts[];
|
|
42
126
|
hydrate: (sessionID: string, msgs: Array<{
|
|
43
127
|
info: Message;
|
|
44
128
|
parts: Part[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/sync-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,OAAO,EACP,KAAK,IAAI,aAAa,EACtB,IAAI,EAEJ,aAAa,EAEb,IAAI,EACJ,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKnF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AAC/B,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAe/C,UAAU,SAAS;IAElB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAG9B,UAAU,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3C,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-store.d.ts","sourceRoot":"","sources":["../../../src/browser/stores/sync-store.ts"],"names":[],"mappings":"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"}
|