@kortix/sdk 0.10.16 → 0.12.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 +114 -62
- package/dist/browser/cache/idb-sync-cache-key.d.ts +2 -0
- package/dist/browser/cache/idb-sync-cache-key.d.ts.map +1 -0
- package/dist/browser/cache/idb-sync-cache-key.js +7 -0
- package/dist/browser/cache/idb-sync-cache-key.js.map +1 -0
- package/dist/browser/cache/idb-sync-cache.d.ts +3 -3
- package/dist/browser/cache/idb-sync-cache.d.ts.map +1 -1
- package/dist/browser/cache/idb-sync-cache.js +49 -26
- package/dist/browser/cache/idb-sync-cache.js.map +1 -1
- package/dist/browser/session-sync/session-cache-ownership.d.ts +36 -0
- package/dist/browser/session-sync/session-cache-ownership.d.ts.map +1 -0
- package/dist/browser/session-sync/session-cache-ownership.js +66 -0
- package/dist/browser/session-sync/session-cache-ownership.js.map +1 -0
- package/dist/browser/session-sync/session-sync-registry.d.ts +9 -4
- package/dist/browser/session-sync/session-sync-registry.d.ts.map +1 -1
- package/dist/browser/session-sync/session-sync-registry.js +111 -29
- package/dist/browser/session-sync/session-sync-registry.js.map +1 -1
- package/dist/browser/session-sync/session-transcript-cache.d.ts +55 -0
- package/dist/browser/session-sync/session-transcript-cache.d.ts.map +1 -0
- package/dist/browser/session-sync/session-transcript-cache.js +69 -0
- package/dist/browser/session-sync/session-transcript-cache.js.map +1 -0
- package/dist/core/client/kortix.d.ts +198 -24
- package/dist/core/client/kortix.d.ts.map +1 -1
- package/dist/core/client/kortix.js +112 -20
- package/dist/core/client/kortix.js.map +1 -1
- package/dist/core/http/api-client.d.ts.map +1 -1
- package/dist/core/http/api-client.js +48 -68
- package/dist/core/http/api-client.js.map +1 -1
- package/dist/core/rest/platform-client/host-boundary.d.ts +121 -0
- package/dist/core/rest/platform-client/host-boundary.d.ts.map +1 -0
- package/dist/core/rest/platform-client/host-boundary.js +243 -0
- package/dist/core/rest/platform-client/host-boundary.js.map +1 -0
- package/dist/core/rest/platform-client/index.d.ts +1 -0
- package/dist/core/rest/platform-client/index.d.ts.map +1 -1
- package/dist/core/rest/platform-client/index.js +1 -0
- package/dist/core/rest/platform-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/access.d.ts +1 -2
- package/dist/core/rest/projects-client/access.d.ts.map +1 -1
- package/dist/core/rest/projects-client/access.js +9 -6
- package/dist/core/rest/projects-client/access.js.map +1 -1
- package/dist/core/rest/projects-client/account-lifecycle.d.ts +22 -0
- package/dist/core/rest/projects-client/account-lifecycle.d.ts.map +1 -0
- package/dist/core/rest/projects-client/account-lifecycle.js +26 -0
- package/dist/core/rest/projects-client/account-lifecycle.js.map +1 -0
- package/dist/core/rest/projects-client/admin-providers.d.ts +10 -0
- package/dist/core/rest/projects-client/admin-providers.d.ts.map +1 -0
- package/dist/core/rest/projects-client/admin-providers.js +34 -0
- package/dist/core/rest/projects-client/admin-providers.js.map +1 -0
- package/dist/core/rest/projects-client/agent-config.d.ts +17 -2
- package/dist/core/rest/projects-client/agent-config.d.ts.map +1 -1
- package/dist/core/rest/projects-client/agent-config.js +43 -2
- package/dist/core/rest/projects-client/agent-config.js.map +1 -1
- package/dist/core/rest/projects-client/agent-scope.d.ts +4 -0
- package/dist/core/rest/projects-client/agent-scope.d.ts.map +1 -1
- package/dist/core/rest/projects-client/agent-scope.js +34 -1
- package/dist/core/rest/projects-client/agent-scope.js.map +1 -1
- package/dist/core/rest/projects-client/audit.d.ts +34 -0
- package/dist/core/rest/projects-client/audit.d.ts.map +1 -1
- package/dist/core/rest/projects-client/audit.js +49 -4
- package/dist/core/rest/projects-client/audit.js.map +1 -1
- package/dist/core/rest/projects-client/billing.d.ts +101 -0
- package/dist/core/rest/projects-client/billing.d.ts.map +1 -1
- package/dist/core/rest/projects-client/billing.js +42 -0
- package/dist/core/rest/projects-client/billing.js.map +1 -1
- package/dist/core/rest/projects-client/channels.d.ts +8 -27
- package/dist/core/rest/projects-client/channels.d.ts.map +1 -1
- package/dist/core/rest/projects-client/channels.js +12 -23
- package/dist/core/rest/projects-client/channels.js.map +1 -1
- package/dist/core/rest/projects-client/connectors.d.ts +234 -24
- package/dist/core/rest/projects-client/connectors.d.ts.map +1 -1
- package/dist/core/rest/projects-client/connectors.js +114 -15
- package/dist/core/rest/projects-client/connectors.js.map +1 -1
- package/dist/core/rest/projects-client/gateway.d.ts +1 -0
- package/dist/core/rest/projects-client/gateway.d.ts.map +1 -1
- package/dist/core/rest/projects-client/gateway.js.map +1 -1
- package/dist/core/rest/projects-client/iam.d.ts +509 -0
- package/dist/core/rest/projects-client/iam.d.ts.map +1 -0
- package/dist/core/rest/projects-client/iam.js +301 -0
- package/dist/core/rest/projects-client/iam.js.map +1 -0
- package/dist/core/rest/projects-client/index.d.ts +7 -0
- package/dist/core/rest/projects-client/index.d.ts.map +1 -1
- package/dist/core/rest/projects-client/index.js +7 -0
- package/dist/core/rest/projects-client/index.js.map +1 -1
- package/dist/core/rest/projects-client/marketplace-catalog.d.ts +9 -2
- package/dist/core/rest/projects-client/marketplace-catalog.d.ts.map +1 -1
- package/dist/core/rest/projects-client/marketplace-catalog.js +7 -0
- package/dist/core/rest/projects-client/marketplace-catalog.js.map +1 -1
- package/dist/core/rest/projects-client/policies.d.ts +18 -0
- package/dist/core/rest/projects-client/policies.d.ts.map +1 -1
- package/dist/core/rest/projects-client/policies.js.map +1 -1
- package/dist/core/rest/projects-client/presentations.d.ts +12 -0
- package/dist/core/rest/projects-client/presentations.d.ts.map +1 -0
- package/dist/core/rest/projects-client/presentations.js +9 -0
- package/dist/core/rest/projects-client/presentations.js.map +1 -0
- package/dist/core/rest/projects-client/projects.d.ts +62 -10
- package/dist/core/rest/projects-client/projects.d.ts.map +1 -1
- package/dist/core/rest/projects-client/projects.js +14 -7
- package/dist/core/rest/projects-client/projects.js.map +1 -1
- package/dist/core/rest/projects-client/public-voice-join.d.ts +59 -0
- package/dist/core/rest/projects-client/public-voice-join.d.ts.map +1 -0
- package/dist/core/rest/projects-client/public-voice-join.js +64 -0
- package/dist/core/rest/projects-client/public-voice-join.js.map +1 -0
- package/dist/core/rest/projects-client/referrals.d.ts +53 -0
- package/dist/core/rest/projects-client/referrals.d.ts.map +1 -0
- package/dist/core/rest/projects-client/referrals.js +27 -0
- package/dist/core/rest/projects-client/referrals.js.map +1 -0
- package/dist/core/rest/projects-client/sandbox.d.ts +50 -0
- package/dist/core/rest/projects-client/sandbox.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sandbox.js.map +1 -1
- package/dist/core/rest/projects-client/session-costs.d.ts +102 -0
- package/dist/core/rest/projects-client/session-costs.d.ts.map +1 -0
- package/dist/core/rest/projects-client/session-costs.js +25 -0
- package/dist/core/rest/projects-client/session-costs.js.map +1 -0
- package/dist/core/rest/projects-client/session-sandbox.d.ts.map +1 -1
- package/dist/core/rest/projects-client/session-sandbox.js +1 -0
- package/dist/core/rest/projects-client/session-sandbox.js.map +1 -1
- package/dist/core/rest/projects-client/sessions.d.ts +143 -18
- package/dist/core/rest/projects-client/sessions.d.ts.map +1 -1
- package/dist/core/rest/projects-client/sessions.js +43 -1
- package/dist/core/rest/projects-client/sessions.js.map +1 -1
- package/dist/core/rest/projects-client/setup-links.d.ts +37 -0
- package/dist/core/rest/projects-client/setup-links.d.ts.map +1 -1
- package/dist/core/rest/projects-client/setup-links.js +11 -0
- package/dist/core/rest/projects-client/setup-links.js.map +1 -1
- package/dist/core/session/index.d.ts +2 -0
- package/dist/core/session/index.d.ts.map +1 -1
- package/dist/core/session/index.js +2 -0
- package/dist/core/session/index.js.map +1 -1
- package/dist/core/session/presentation.d.ts +12 -0
- package/dist/core/session/presentation.d.ts.map +1 -0
- package/dist/core/session/presentation.js +70 -0
- package/dist/core/session/presentation.js.map +1 -0
- package/dist/core/session/preview-auth.d.ts +32 -0
- package/dist/core/session/preview-auth.d.ts.map +1 -0
- package/dist/core/session/preview-auth.js +53 -0
- package/dist/core/session/preview-auth.js.map +1 -0
- package/dist/core/session/rewind.d.ts +18 -0
- package/dist/core/session/rewind.d.ts.map +1 -0
- package/dist/core/session/rewind.js +17 -0
- package/dist/core/session/rewind.js.map +1 -0
- package/dist/core/session/server-store/url-helpers.d.ts.map +1 -1
- package/dist/core/session/server-store/url-helpers.js +5 -3
- package/dist/core/session/server-store/url-helpers.js.map +1 -1
- package/dist/core/session/url.d.ts +43 -0
- package/dist/core/session/url.d.ts.map +1 -1
- package/dist/core/session/url.js +81 -0
- package/dist/core/session/url.js.map +1 -1
- package/dist/core/session-sync/session-sync-controller.d.ts +40 -1
- package/dist/core/session-sync/session-sync-controller.d.ts.map +1 -1
- package/dist/core/session-sync/session-sync-controller.js +161 -6
- package/dist/core/session-sync/session-sync-controller.js.map +1 -1
- package/dist/core/stream/fetch-sse.d.ts +23 -0
- package/dist/core/stream/fetch-sse.d.ts.map +1 -0
- package/dist/core/stream/fetch-sse.js +119 -0
- package/dist/core/stream/fetch-sse.js.map +1 -0
- package/dist/core/turns/state.d.ts.map +1 -1
- package/dist/core/turns/state.js +11 -4
- package/dist/core/turns/state.js.map +1 -1
- package/dist/core/turns/types.d.ts +6 -0
- package/dist/core/turns/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/kortix.esm.min.js +19 -16
- package/dist/kortix.global.js +19 -16
- package/dist/node/server.d.ts +14 -0
- package/dist/node/server.d.ts.map +1 -1
- package/dist/node/server.js +42 -0
- package/dist/node/server.js.map +1 -1
- package/dist/react/agent-selection-scope.d.ts +8 -0
- package/dist/react/agent-selection-scope.d.ts.map +1 -0
- package/dist/react/agent-selection-scope.js +4 -0
- package/dist/react/agent-selection-scope.js.map +1 -0
- package/dist/react/index.d.ts +12 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +12 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/initial-session-pin.d.ts +8 -0
- package/dist/react/initial-session-pin.d.ts.map +1 -0
- package/dist/react/initial-session-pin.js +4 -0
- package/dist/react/initial-session-pin.js.map +1 -0
- package/dist/react/model-flatten.d.ts +8 -0
- package/dist/react/model-flatten.d.ts.map +1 -1
- package/dist/react/model-flatten.js +1 -0
- package/dist/react/model-flatten.js.map +1 -1
- package/dist/react/opencode.d.ts +25 -2
- package/dist/react/opencode.d.ts.map +1 -1
- package/dist/react/opencode.js +24 -1
- package/dist/react/opencode.js.map +1 -1
- package/dist/react/provider-selection.d.ts +1 -0
- package/dist/react/provider-selection.d.ts.map +1 -1
- package/dist/react/provider-selection.js +22 -0
- package/dist/react/provider-selection.js.map +1 -1
- package/dist/react/run-pty-command.d.ts +5 -0
- package/dist/react/run-pty-command.d.ts.map +1 -0
- package/dist/react/run-pty-command.js +42 -0
- package/dist/react/run-pty-command.js.map +1 -0
- package/dist/react/runtime-actions.d.ts +51 -0
- package/dist/react/runtime-actions.d.ts.map +1 -0
- package/dist/react/runtime-actions.js +105 -0
- package/dist/react/runtime-actions.js.map +1 -0
- package/dist/react/session-agent-name-guard.d.ts +16 -0
- package/dist/react/session-agent-name-guard.d.ts.map +1 -0
- package/dist/react/session-agent-name-guard.js +22 -0
- package/dist/react/session-agent-name-guard.js.map +1 -0
- package/dist/react/session-title-sync.d.ts +23 -0
- package/dist/react/session-title-sync.d.ts.map +1 -0
- package/dist/react/session-title-sync.js +85 -0
- package/dist/react/session-title-sync.js.map +1 -0
- package/dist/react/use-admin-accounts.d.ts +122 -0
- package/dist/react/use-admin-accounts.d.ts.map +1 -0
- package/dist/react/use-admin-accounts.js +146 -0
- package/dist/react/use-admin-accounts.js.map +1 -0
- package/dist/react/use-admin-analytics.d.ts +332 -0
- package/dist/react/use-admin-analytics.d.ts.map +1 -0
- package/dist/react/use-admin-analytics.js +518 -0
- package/dist/react/use-admin-analytics.js.map +1 -0
- package/dist/react/use-admin-billing.d.ts +27 -0
- package/dist/react/use-admin-billing.d.ts.map +1 -0
- package/dist/react/use-admin-billing.js +61 -0
- package/dist/react/use-admin-billing.js.map +1 -0
- package/dist/react/use-admin-feedback.d.ts +119 -0
- package/dist/react/use-admin-feedback.d.ts.map +1 -0
- package/dist/react/use-admin-feedback.js +148 -0
- package/dist/react/use-admin-feedback.js.map +1 -0
- package/dist/react/use-admin-sandboxes.d.ts +157 -0
- package/dist/react/use-admin-sandboxes.d.ts.map +1 -0
- package/dist/react/use-admin-sandboxes.js +145 -0
- package/dist/react/use-admin-sandboxes.js.map +1 -0
- package/dist/react/use-authenticated-preview-url.d.ts +24 -0
- package/dist/react/use-authenticated-preview-url.d.ts.map +1 -0
- package/dist/react/use-authenticated-preview-url.js +137 -0
- package/dist/react/use-authenticated-preview-url.js.map +1 -0
- package/dist/react/use-canonical-opencode-session.d.ts +4 -0
- package/dist/react/use-canonical-opencode-session.d.ts.map +1 -1
- package/dist/react/use-canonical-opencode-session.js +9 -4
- package/dist/react/use-canonical-opencode-session.js.map +1 -1
- package/dist/react/use-model-defaults.d.ts +22 -0
- package/dist/react/use-model-defaults.d.ts.map +1 -0
- package/dist/react/use-model-defaults.js +104 -0
- package/dist/react/use-model-defaults.js.map +1 -0
- package/dist/react/use-model-store.d.ts +6 -14
- package/dist/react/use-model-store.d.ts.map +1 -1
- package/dist/react/use-model-store.js +41 -52
- package/dist/react/use-model-store.js.map +1 -1
- package/dist/react/use-opencode-events/handle-event.d.ts.map +1 -1
- package/dist/react/use-opencode-events/handle-event.js +103 -41
- package/dist/react/use-opencode-events/handle-event.js.map +1 -1
- package/dist/react/use-opencode-events/index.d.ts +3 -1
- package/dist/react/use-opencode-events/index.d.ts.map +1 -1
- package/dist/react/use-opencode-events/index.js +6 -2
- package/dist/react/use-opencode-events/index.js.map +1 -1
- package/dist/react/use-opencode-local.d.ts.map +1 -1
- package/dist/react/use-opencode-local.js +10 -1
- package/dist/react/use-opencode-local.js.map +1 -1
- package/dist/react/use-opencode-sessions/agents.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/agents.js +5 -3
- package/dist/react/use-opencode-sessions/agents.js.map +1 -1
- package/dist/react/use-opencode-sessions/commands.d.ts +7 -2
- package/dist/react/use-opencode-sessions/commands.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/commands.js +13 -9
- package/dist/react/use-opencode-sessions/commands.js.map +1 -1
- package/dist/react/use-opencode-sessions/keys.d.ts +3 -1
- package/dist/react/use-opencode-sessions/keys.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/keys.js +2 -0
- package/dist/react/use-opencode-sessions/keys.js.map +1 -1
- package/dist/react/use-opencode-sessions/provider-load-plan.d.ts +6 -0
- package/dist/react/use-opencode-sessions/provider-load-plan.d.ts.map +1 -0
- package/dist/react/use-opencode-sessions/provider-load-plan.js +4 -0
- package/dist/react/use-opencode-sessions/provider-load-plan.js.map +1 -0
- package/dist/react/use-opencode-sessions/providers.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/providers.js +39 -27
- package/dist/react/use-opencode-sessions/providers.js.map +1 -1
- package/dist/react/use-opencode-sessions/sessions.d.ts +1 -1
- package/dist/react/use-opencode-sessions/sessions.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/sessions.js +18 -9
- package/dist/react/use-opencode-sessions/sessions.js.map +1 -1
- package/dist/react/use-opencode-sessions/shared.d.ts +3 -2
- package/dist/react/use-opencode-sessions/shared.d.ts.map +1 -1
- package/dist/react/use-opencode-sessions/shared.js +6 -3
- package/dist/react/use-opencode-sessions/shared.js.map +1 -1
- package/dist/react/use-opencode-sessions/sharing.js +2 -2
- package/dist/react/use-opencode-sessions/sharing.js.map +1 -1
- package/dist/react/use-ops-overview.d.ts +64 -0
- package/dist/react/use-ops-overview.d.ts.map +1 -0
- package/dist/react/use-ops-overview.js +16 -0
- package/dist/react/use-ops-overview.js.map +1 -0
- package/dist/react/use-session-model-selection.d.ts +15 -0
- package/dist/react/use-session-model-selection.d.ts.map +1 -0
- package/dist/react/use-session-model-selection.js +27 -0
- package/dist/react/use-session-model-selection.js.map +1 -0
- package/dist/react/use-session-sync.d.ts +13 -1
- package/dist/react/use-session-sync.d.ts.map +1 -1
- package/dist/react/use-session-sync.js +87 -17
- package/dist/react/use-session-sync.js.map +1 -1
- package/dist/react/use-session.d.ts +72 -1
- package/dist/react/use-session.d.ts.map +1 -1
- package/dist/react/use-session.js +222 -32
- package/dist/react/use-session.js.map +1 -1
- package/dist/react/use-system-status.d.ts +39 -0
- package/dist/react/use-system-status.d.ts.map +1 -0
- package/dist/react/use-system-status.js +68 -0
- package/dist/react/use-system-status.js.map +1 -0
- package/dist/react/use-teams-installations.d.ts +36 -0
- package/dist/react/use-teams-installations.d.ts.map +1 -0
- package/dist/react/use-teams-installations.js +94 -0
- package/dist/react/use-teams-installations.js.map +1 -0
- package/dist/react/use-tunnel.d.ts +120 -0
- package/dist/react/use-tunnel.d.ts.map +1 -0
- package/dist/react/use-tunnel.js +268 -0
- package/dist/react/use-tunnel.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @kortix/sdk
|
|
2
2
|
|
|
3
3
|
The **single, opinionated data layer** for the Kortix agent platform. One typed
|
|
4
|
-
client wraps both the **Kortix REST API** and the **
|
|
4
|
+
client wraps both the **Kortix REST API** and the **agent runtime** so a
|
|
5
5
|
host app — web, mobile, reference — imports **only `@kortix/sdk`** and never
|
|
6
6
|
`@opencode-ai/sdk` directly. (The no-raw-`backendApi`/`authenticatedFetch` rule
|
|
7
7
|
below is the target state, not yet fully true of apps/web — see Rules of the
|
|
@@ -24,9 +24,12 @@ npm install @kortix/sdk
|
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
```ts
|
|
27
|
-
import { createKortix } from
|
|
27
|
+
import { createKortix } from "@kortix/sdk";
|
|
28
28
|
|
|
29
|
-
const kortix = createKortix({
|
|
29
|
+
const kortix = createKortix({
|
|
30
|
+
backendUrl: "https://api.kortix.com/v1",
|
|
31
|
+
getToken,
|
|
32
|
+
});
|
|
30
33
|
await kortix.projects.list();
|
|
31
34
|
```
|
|
32
35
|
|
|
@@ -53,10 +56,10 @@ no build step required:
|
|
|
53
56
|
`@kortix/sdk` is the canonical entry — everything framework-free lives there.
|
|
54
57
|
Three others exist, each for a reason that fits in one sentence:
|
|
55
58
|
|
|
56
|
-
| Entry
|
|
57
|
-
|
|
58
|
-
| `@kortix/sdk/react`
|
|
59
|
-
| `@kortix/sdk/server`
|
|
59
|
+
| Entry | Why it can't live at root |
|
|
60
|
+
| ------------------------ | --------------------------- |
|
|
61
|
+
| `@kortix/sdk/react` | React is a peer dependency |
|
|
62
|
+
| `@kortix/sdk/server` | imports `node:async_hooks` |
|
|
60
63
|
| `@kortix/sdk/internal/*` | unsupported, outside semver |
|
|
61
64
|
|
|
62
65
|
Older subpaths (`@kortix/sdk/projects-client`, `/turns`, …) still work and are
|
|
@@ -70,32 +73,71 @@ table for the full list (20 of them).
|
|
|
70
73
|
## Quick start
|
|
71
74
|
|
|
72
75
|
```ts
|
|
73
|
-
import { createKortix } from
|
|
76
|
+
import { createKortix } from "@kortix/sdk";
|
|
74
77
|
|
|
75
78
|
const kortix = createKortix({
|
|
76
|
-
backendUrl:
|
|
77
|
-
getToken: () =>
|
|
79
|
+
backendUrl: "https://api.kortix.com/v1",
|
|
80
|
+
getToken: () =>
|
|
81
|
+
supabase.auth
|
|
82
|
+
.getSession()
|
|
83
|
+
.then((s) => s.data.session?.access_token ?? null),
|
|
78
84
|
});
|
|
79
85
|
|
|
80
86
|
// Projects
|
|
81
87
|
const projects = await kortix.projects.list();
|
|
82
|
-
const detail
|
|
83
|
-
await kortix.project(pid).secrets.upsert({ name:
|
|
88
|
+
const detail = await kortix.project(pid).detail();
|
|
89
|
+
await kortix.project(pid).secrets.upsert({ name: "STRIPE_API_KEY", value });
|
|
84
90
|
const visibleSessions = await kortix.project(pid).sessions.list();
|
|
85
|
-
const projectInventory = await kortix
|
|
91
|
+
const projectInventory = await kortix
|
|
92
|
+
.project(pid)
|
|
93
|
+
.sessions.list({ scope: "project" }); // manager only
|
|
94
|
+
const warm = await kortix.project(pid).sessions.ensureWarm();
|
|
95
|
+
await kortix
|
|
96
|
+
.project(pid)
|
|
97
|
+
.sessions.claimWarm({ session_id: warm.session.session_id });
|
|
86
98
|
|
|
87
99
|
// Sessions (id-bound handle)
|
|
88
100
|
const s = kortix.session(pid, sid);
|
|
89
|
-
await s.
|
|
101
|
+
const cost = await s.cost(); // reads finalized LLM + compute cost; no runtime start
|
|
102
|
+
await s.send("Build me a widget"); // provisions/resumes if needed, then prompts
|
|
103
|
+
await s.rewind(userMessageId); // stages a reversible rollback on this session
|
|
104
|
+
await s.restoreRewind(); // restores the removed path before the next prompt
|
|
90
105
|
await s.previews();
|
|
91
106
|
|
|
92
|
-
// Lower level: the typed
|
|
107
|
+
// Lower level: the typed OpenCode REST compatibility client for THIS sandbox.
|
|
93
108
|
// `.runtime` throws until the runtime is resolved, and the runtime is keyed by
|
|
94
109
|
// the OpenCode session id (NOT the Kortix `sid`) — resolve both via ensureReady.
|
|
95
110
|
const { opencodeSessionId } = await s.ensureReady();
|
|
96
111
|
await s.runtime.session.prompt({ sessionID: opencodeSessionId, parts });
|
|
97
112
|
```
|
|
98
113
|
|
|
114
|
+
For OpenCode REST sessions, `send()` reads the persisted session model and
|
|
115
|
+
agent before the first prompt on a handle. This prevents a snapshot-inherited
|
|
116
|
+
OpenCode session from reusing stale snapshot defaults. A per-call choice
|
|
117
|
+
overrides a `setModel()` or `setAgent()` choice. A handle choice overrides the
|
|
118
|
+
persisted session default.
|
|
119
|
+
|
|
120
|
+
### React runtime
|
|
121
|
+
|
|
122
|
+
`useSession(projectId, sessionId)` opens the OpenCode REST runtime returned by
|
|
123
|
+
`POST /start`. The hook owns messages, rewind and restore, cancellation,
|
|
124
|
+
commands, permissions, and questions. Hosts do not construct runtime routes.
|
|
125
|
+
|
|
126
|
+
A server-rendered host can seed a known OpenCode pin while `/start` runs:
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
useSession(projectId, sessionId, {
|
|
130
|
+
initialOpenCodeSessionId: persistedSession.opencode_session_id,
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Use only a pin that the host authorized for the same `(projectId, sessionId)`.
|
|
135
|
+
The seed hydrates cached content. It does not choose the runtime identity.
|
|
136
|
+
The pin returned by `/start` always replaces a stale seed. The SDK also scopes
|
|
137
|
+
OpenCode query and synchronization controllers to the sandbox runtime. Two
|
|
138
|
+
sandboxes cannot share browser cache state when a snapshot exposes the same
|
|
139
|
+
OpenCode id during adoption.
|
|
140
|
+
|
|
99
141
|
## The facade surface
|
|
100
142
|
|
|
101
143
|
`createKortix(config)` returns one client. The table below is illustrative, not
|
|
@@ -104,13 +146,13 @@ exhaustive — see `API-MAP.md` for the full per-domain surface:
|
|
|
104
146
|
| namespace | what |
|
|
105
147
|
|---|---|
|
|
106
148
|
| `kortix.projects` | list · get · detail · create · provision · update · archive · llmCatalog · modelPicker · sandboxTemplates · sessions (+ more: `listForAccount`, `sandboxHealth`, `createSession`) |
|
|
107
|
-
| `kortix.accounts` | list · get · create · members · invites · `tokens.{list,create,revoke}` (account-scoped CLI PATs, `kortix_pat_…`) · `audit.{log,export,webhooks.*}` (
|
|
108
|
-
| `kortix.billing` | entitlement/usage reads: `accountState` · `accountStateMinimal` · `transactions` · `transactionsSummary` · `creditBreakdown` · `usageHistory` · `tierConfigurations` — plus a curated mutation surface: `checkout.{createSession,confirmSession}` · `subscription.{createPortalSession,cancel,reactivate,scheduleDowngrade,cancelScheduledChange,prorationPreview}` · `credits.{purchase,autoTopupSettings,configureAutoTopup}` |
|
|
149
|
+
| `kortix.accounts` | list · get · create · members · invites · `tokens.{list,create,revoke}` (account-scoped CLI PATs, `kortix_pat_…`) · `audit.{log,export,webhooks.*}` (filterable project/session reconstruction log) (+ more: `updateName`, `leave`, `invite`, `removeMember`, `updateMemberRole`) |
|
|
150
|
+
| `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}` |
|
|
109
151
|
| `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` |
|
|
110
152
|
| `kortix.validateToken()` | pasted-API-key validation helper — `GET /accounts/me`, never throws, resolves `{valid, identity?, error?}` |
|
|
111
153
|
| `kortix.project(id)` | id-bound handle: `.secrets` · `.access` · `.connectors` · `.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`) |
|
|
112
|
-
| `kortix.session(pid, sid)` | id-bound handle: lifecycle (`get`/`update`/`delete`/`start`/`restart`/`stop`/`setSharing`/`previews`/`commit`/`publicShares`/`ensureReady`) · `send`/`abort`/`setModel`/`setAgent`
|
|
113
|
-
| `kortix.runtime()` | the
|
|
154
|
+
| `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
|
+
| `kortix.runtime()` | the OpenCode v2 compatibility client for the active sandbox; use a session-scoped handle in multi-tenant code |
|
|
114
156
|
|
|
115
157
|
Runnable, self-contained scripts for the highest-value flows live in
|
|
116
158
|
[`examples/`](./examples): list projects with a PAT, send + stream, the
|
|
@@ -125,7 +167,7 @@ to the agent only as one `KORTIX_SESSION_CONTEXT` JSON envelope:
|
|
|
125
167
|
|
|
126
168
|
```ts
|
|
127
169
|
await kortix.project(projectId).sessions.create({
|
|
128
|
-
runtime_context: { workspace_id:
|
|
170
|
+
runtime_context: { workspace_id: "org_123", locale: "de" },
|
|
129
171
|
});
|
|
130
172
|
```
|
|
131
173
|
|
|
@@ -136,27 +178,27 @@ credential endpoint, and pass only the non-secret profile id at session create:
|
|
|
136
178
|
```ts
|
|
137
179
|
const project = kortix.project(projectId);
|
|
138
180
|
const profile = await project.connectors.profiles.reconcile({
|
|
139
|
-
connector_alias:
|
|
140
|
-
owner_type:
|
|
181
|
+
connector_alias: "customer-data",
|
|
182
|
+
owner_type: "external",
|
|
141
183
|
owner_id: wrapperUserId,
|
|
142
|
-
label:
|
|
184
|
+
label: "Customer data",
|
|
143
185
|
metadata: { tenant_ref: wrapperTenantReference },
|
|
144
186
|
});
|
|
145
187
|
|
|
146
188
|
// Omit `auth` when creating to apply source-advertised authentication.
|
|
147
189
|
const auth = await project.connectors.auth.discover({
|
|
148
|
-
slug:
|
|
149
|
-
provider:
|
|
150
|
-
spec:
|
|
190
|
+
slug: "hubspot",
|
|
191
|
+
provider: "postman",
|
|
192
|
+
spec: "https://github.com/HubSpot/HubSpot-public-api-spec-collection",
|
|
151
193
|
});
|
|
152
194
|
await project.connectors.profiles.updateCredential(profile.profile_id, {
|
|
153
195
|
value: shortLivedCapability,
|
|
154
|
-
kind:
|
|
196
|
+
kind: "secret",
|
|
155
197
|
});
|
|
156
198
|
await project.sessions.create({
|
|
157
|
-
runtime_context: { locale:
|
|
199
|
+
runtime_context: { locale: "de" },
|
|
158
200
|
connector_bindings: {
|
|
159
|
-
|
|
201
|
+
"customer-data": { profile_id: profile.profile_id },
|
|
160
202
|
},
|
|
161
203
|
});
|
|
162
204
|
```
|
|
@@ -167,8 +209,8 @@ token:
|
|
|
167
209
|
|
|
168
210
|
```ts
|
|
169
211
|
const profile = await project.connectors.profiles.reconcileMember({
|
|
170
|
-
connector_alias:
|
|
171
|
-
label:
|
|
212
|
+
connector_alias: "gmail",
|
|
213
|
+
label: "My Gmail",
|
|
172
214
|
});
|
|
173
215
|
await project.connectors.profiles.pipedreamConnect(profile.profile_id);
|
|
174
216
|
// Complete OAuth, then:
|
|
@@ -186,7 +228,8 @@ restart. Credentials are encrypted server-side and are never returned, placed
|
|
|
186
228
|
in `KORTIX_SESSION_CONTEXT`, or injected into the sandbox environment. Raw env
|
|
187
229
|
and MCP configuration are not session-create inputs.
|
|
188
230
|
|
|
189
|
-
`session.stream()` is a thin facade over the
|
|
231
|
+
For OpenCode REST sessions, `session.stream()` is a thin facade over the
|
|
232
|
+
framework-free `openEventStream`
|
|
190
233
|
primitive (also exported directly, for hosts that want to manage the client
|
|
191
234
|
themselves): it resolves THIS handle's own runtime (`ensureReady()`), connects
|
|
192
235
|
to that runtime's SSE endpoint, and hands you a `close()`-able handle. No React
|
|
@@ -202,6 +245,8 @@ const handle = await kortix.session(pid, sid).stream({
|
|
|
202
245
|
handle.close();
|
|
203
246
|
```
|
|
204
247
|
|
|
248
|
+
`session.stream()` emits OpenCode v2 events. Use `useSession()` in React.
|
|
249
|
+
|
|
205
250
|
`@kortix/sdk/react`'s `useOpenCodeEventStream` uses the exact same primitive
|
|
206
251
|
under the hood — it just also writes into the React Query cache.
|
|
207
252
|
|
|
@@ -219,12 +264,12 @@ in-flight request.
|
|
|
219
264
|
it statically imports `node:async_hooks`) fixes this with `AsyncLocalStorage`:
|
|
220
265
|
|
|
221
266
|
```ts
|
|
222
|
-
import { createScopedKortix } from
|
|
267
|
+
import { createScopedKortix } from "@kortix/sdk/server";
|
|
223
268
|
|
|
224
269
|
// Express/Hono/Bun.serve — any per-request handler. One scoped client PER
|
|
225
270
|
// REQUEST; each end user's token stays isolated to that request's own async
|
|
226
271
|
// call tree, even across `await`s, even under concurrency.
|
|
227
|
-
app.get(
|
|
272
|
+
app.get("/projects", async (req, res) => {
|
|
228
273
|
const kortix = createScopedKortix({
|
|
229
274
|
backendUrl: process.env.KORTIX_API_URL!,
|
|
230
275
|
getToken: async () => resolveKortixTokenFor(req), // per-end-user PAT/token
|
|
@@ -240,7 +285,7 @@ it never writes the process-global singleton. For middleware-style wrapping of
|
|
|
240
285
|
an entire request body instead, use the lower-level primitive:
|
|
241
286
|
|
|
242
287
|
```ts
|
|
243
|
-
import { runWithKortix } from
|
|
288
|
+
import { runWithKortix } from "@kortix/sdk/server";
|
|
244
289
|
|
|
245
290
|
app.use(async (req, res, next) => {
|
|
246
291
|
await runWithKortix(
|
|
@@ -271,8 +316,8 @@ renderer for **every** part kind at compile time, so a new part type is a
|
|
|
271
316
|
build error at your call site instead of a silent drop in production:
|
|
272
317
|
|
|
273
318
|
```tsx
|
|
274
|
-
import { renderParts, type PartRenderers } from
|
|
275
|
-
import { classifyTurn } from
|
|
319
|
+
import { renderParts, type PartRenderers } from "@kortix/sdk/react";
|
|
320
|
+
import { classifyTurn } from "@kortix/sdk/turns";
|
|
276
321
|
|
|
277
322
|
const renderers: PartRenderers<React.ReactNode> = {
|
|
278
323
|
text: (p) => <Markdown>{p.text}</Markdown>,
|
|
@@ -283,16 +328,21 @@ const renderers: PartRenderers<React.ReactNode> = {
|
|
|
283
328
|
patch: (p) => <DiffStat files={p.fileCount} />,
|
|
284
329
|
retry: (p) => <Note>{`retrying (attempt ${p.attempt})`}</Note>,
|
|
285
330
|
compaction: () => <Note>context compacted</Note>,
|
|
286
|
-
snapshot: () => null,
|
|
287
|
-
agent: () => null,
|
|
288
|
-
step: () => null,
|
|
289
|
-
unknown: () => null,
|
|
331
|
+
snapshot: () => null, // internal checkpoint hash — nothing to show
|
|
332
|
+
agent: () => null, // inline @mention, already in the sibling text
|
|
333
|
+
step: () => null, // model-step bookkeeping
|
|
334
|
+
unknown: () => null, // forward-compat: newer server than client
|
|
290
335
|
};
|
|
291
336
|
|
|
292
337
|
function Turn({ message }: { message: MessageWithParts }) {
|
|
293
338
|
const { parts, error, isEmpty } = classifyTurn(message);
|
|
294
339
|
if (isEmpty && !error) return null;
|
|
295
|
-
return
|
|
340
|
+
return (
|
|
341
|
+
<>
|
|
342
|
+
{renderParts(parts, renderers)}
|
|
343
|
+
{error && <TurnFailed {...error} />}
|
|
344
|
+
</>
|
|
345
|
+
);
|
|
296
346
|
}
|
|
297
347
|
```
|
|
298
348
|
|
|
@@ -331,17 +381,19 @@ The canonical server-side wrapper shape — catch a 402 and pass the payload
|
|
|
331
381
|
through to your own client for re-billing, instead of leaking a Kortix error:
|
|
332
382
|
|
|
333
383
|
```ts
|
|
334
|
-
import { ApiError, AuthError, BillingError } from
|
|
384
|
+
import { ApiError, AuthError, BillingError } from "@kortix/sdk";
|
|
335
385
|
|
|
336
386
|
try {
|
|
337
387
|
await kortix.session(pid, sid).send(prompt);
|
|
338
388
|
} catch (err) {
|
|
339
389
|
if (err instanceof BillingError) {
|
|
340
390
|
// 402 — surface the upgrade/cost payload under YOUR billing story.
|
|
341
|
-
return res.status(402).json({ reason:
|
|
391
|
+
return res.status(402).json({ reason: "quota", detail: err.detail });
|
|
342
392
|
}
|
|
343
|
-
if (err instanceof AuthError)
|
|
344
|
-
|
|
393
|
+
if (err instanceof AuthError)
|
|
394
|
+
return res.status(401).json({ error: "not authenticated" });
|
|
395
|
+
if (err instanceof ApiError)
|
|
396
|
+
return res.status(err.status ?? 502).json({ error: err.message });
|
|
345
397
|
throw err;
|
|
346
398
|
}
|
|
347
399
|
```
|
|
@@ -364,19 +416,19 @@ Stable, tree-shakeable surfaces (also reachable via the facade). Not exhaustive
|
|
|
364
416
|
`./sandbox-connection-store`, `./opencode-pending-store`, `./session/url`,
|
|
365
417
|
`./idb-sync-cache`):
|
|
366
418
|
|
|
367
|
-
| import
|
|
368
|
-
|
|
369
|
-
| `@kortix/sdk`
|
|
370
|
-
| `@kortix/sdk/server`
|
|
371
|
-
| `@kortix/sdk/react`
|
|
372
|
-
| `@kortix/sdk/turns`
|
|
373
|
-
| `@kortix/sdk/files`
|
|
374
|
-
| `@kortix/sdk/session`
|
|
375
|
-
| `@kortix/sdk/opencode-client`
|
|
376
|
-
| `@kortix/sdk/projects-client`
|
|
377
|
-
| `@kortix/sdk/auth`
|
|
378
|
-
| `@kortix/sdk/api-client`
|
|
379
|
-
| `@kortix/sdk/server-store` · `@kortix/sdk/sync-store` | active-sandbox state · live message/part/status store
|
|
419
|
+
| import | provides |
|
|
420
|
+
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
421
|
+
| `@kortix/sdk` | `createKortix`, `configureKortix`, `files`, the error classes, `classifyPart`/`classifyTurn`, `narrowChatEvent`, `openEventStream`, domain result types |
|
|
422
|
+
| `@kortix/sdk/server` | **Node/Bun only** — `runWithKortix`, `createScopedKortix`, `getScopedConfig` (per-request config isolation; see "Kortix as a Backend") |
|
|
423
|
+
| `@kortix/sdk/react` | every `useOpenCode*` hook + providers (reactive data), `useSession`, `useChatTurns`/`renderParts`, domain hooks (`useProjectSecrets`/`useProjectTriggers`/`useChangeRequests`) |
|
|
424
|
+
| `@kortix/sdk/turns` | framework-free part/turn classification (`classifyPart`, `classifyTurn`, `toolInfo`, turn grouping/cost helpers) |
|
|
425
|
+
| `@kortix/sdk/files` | workspace file ops (daemon `/file` + `/find`): `listFiles`, `readFile`, `readBlob`, `getFileStatus`, `findFiles`, `findText`, `uploadFile`, `deleteFile`, `mkdir`, `renameFile`, … |
|
|
426
|
+
| `@kortix/sdk/session` | a session's runtime surface — `getSessionHealth`/`isRuntimeReady` + proxy/preview URL builders (`rewriteLocalhostUrl`, `proxyLocalhostUrl`, `detectLocalhostUrls`, …) + preview-auth helpers. **No "sandbox" in the public surface** — a session owns its runtime |
|
|
427
|
+
| `@kortix/sdk/opencode-client` | `getClient`, `getClientForUrl` + the **full opencode v2 type surface** (`Event`, `Part`, `Message`, `Session`, `Pty`, `Config`, …) |
|
|
428
|
+
| `@kortix/sdk/projects-client` | the raw REST functions (the facade wraps these) |
|
|
429
|
+
| `@kortix/sdk/auth` | `authenticatedFetch`, token accessors |
|
|
430
|
+
| `@kortix/sdk/api-client` | the raw `backendApi` primitive — host code should go through the facade or another subpath module instead of calling this directly |
|
|
431
|
+
| `@kortix/sdk/server-store` · `@kortix/sdk/sync-store` | active-sandbox state · live message/part/status store |
|
|
380
432
|
|
|
381
433
|
## Configuration
|
|
382
434
|
|
|
@@ -432,6 +484,6 @@ pnpm --filter @kortix/sdk typecheck # package + examples/ (examples/tsconfig.js
|
|
|
432
484
|
pnpm --filter @kortix/sdk test # facade, files, react hooks, turns, transcript, session url/health, projects-client domains
|
|
433
485
|
```
|
|
434
486
|
|
|
435
|
-
See **`API-MAP.md`** for the complete endpoint catalogue
|
|
436
|
-
and
|
|
437
|
-
release.
|
|
487
|
+
See **`API-MAP.md`** for the complete endpoint catalogue. It covers the Kortix
|
|
488
|
+
REST API and OpenCode REST runtime. See **`CHANGELOG.md`** for
|
|
489
|
+
per-release changes.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idb-sync-cache-key.d.ts","sourceRoot":"","sources":["../../../src/browser/cache/idb-sync-cache-key.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,MAAM,CAKR"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function buildSessionCacheKey(userScope, openCodeSessionId, kortixSessionScope) {
|
|
2
|
+
if (!kortixSessionScope) {
|
|
3
|
+
return `${userScope}:session:${openCodeSessionId}`;
|
|
4
|
+
}
|
|
5
|
+
return `${userScope}:kortix-session:${encodeURIComponent(kortixSessionScope)}`;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=idb-sync-cache-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idb-sync-cache-key.js","sourceRoot":"","sources":["../../../src/browser/cache/idb-sync-cache-key.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAClC,SAAiB,EACjB,iBAAyB,EACzB,kBAA2B;IAE3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,OAAO,GAAG,SAAS,YAAY,iBAAiB,EAAE,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,SAAS,mBAAmB,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,CAAC;AACjF,CAAC"}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* Schema: one object store "sessions" keyed by cacheKey, each entry holds
|
|
6
6
|
* { cacheKey, userId, sessionId, messages, parts, updatedAt }.
|
|
7
7
|
*/
|
|
8
|
-
export declare function saveSessionToIDB(sessionId: string, messages: any[], parts: Record<string, any[]
|
|
8
|
+
export declare function saveSessionToIDB(sessionId: string, messages: any[], parts: Record<string, any[]>, kortixSessionScope?: string): Promise<void>;
|
|
9
9
|
export declare function flushIDBWrites(): Promise<void>;
|
|
10
|
-
export declare function loadSessionFromIDB(sessionId: string): Promise<{
|
|
10
|
+
export declare function loadSessionFromIDB(sessionId: string, kortixSessionScope?: string): Promise<{
|
|
11
11
|
messages: any[];
|
|
12
12
|
parts: Record<string, any[]>;
|
|
13
13
|
} | null>;
|
|
14
14
|
export declare function loadAllSessionIdsFromIDB(): Promise<string[]>;
|
|
15
|
-
export declare function deleteSessionFromIDB(sessionId: string): Promise<void>;
|
|
15
|
+
export declare function deleteSessionFromIDB(sessionId: string, kortixSessionScope?: string): Promise<void>;
|
|
16
16
|
export declare function clearSessionIDBCache(): Promise<void>;
|
|
17
17
|
export declare function pruneIDBCache(): Promise<void>;
|
|
18
18
|
//# sourceMappingURL=idb-sync-cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idb-sync-cache.d.ts","sourceRoot":"","sources":["../../../src/browser/cache/idb-sync-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"idb-sync-cache.d.ts","sourceRoot":"","sources":["../../../src/browser/cache/idb-sync-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmHH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,GAAG,EAAE,EACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAC5B,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAgB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAK9C;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;CAAE,GAAG,IAAI,CAAC,CA4BnE;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBlE;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAa1D;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BnD"}
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
* { cacheKey, userId, sessionId, messages, parts, updatedAt }.
|
|
7
7
|
*/
|
|
8
8
|
import { platformConfig } from '../../core/http/config.js';
|
|
9
|
-
|
|
9
|
+
import { buildSessionCacheKey } from './idb-sync-cache-key.js';
|
|
10
|
+
const DB_NAME = 'kortix-session-cache';
|
|
10
11
|
const DB_VERSION = 2;
|
|
11
|
-
const STORE_NAME =
|
|
12
|
+
const STORE_NAME = 'sessions';
|
|
12
13
|
const MAX_CACHED_SESSIONS = 50;
|
|
13
14
|
const MAX_SESSION_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
14
15
|
async function getCurrentCacheScope() {
|
|
@@ -20,16 +21,13 @@ async function getCurrentCacheScope() {
|
|
|
20
21
|
return null;
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
function buildCacheKey(scope, sessionId) {
|
|
24
|
-
return `${scope}:session:${sessionId}`;
|
|
25
|
-
}
|
|
26
24
|
let dbPromise = null;
|
|
27
25
|
function openDB() {
|
|
28
26
|
if (dbPromise)
|
|
29
27
|
return dbPromise;
|
|
30
28
|
dbPromise = new Promise((resolve, reject) => {
|
|
31
|
-
if (typeof indexedDB ===
|
|
32
|
-
reject(new Error(
|
|
29
|
+
if (typeof indexedDB === 'undefined') {
|
|
30
|
+
reject(new Error('IndexedDB not available'));
|
|
33
31
|
return;
|
|
34
32
|
}
|
|
35
33
|
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
|
@@ -39,7 +37,7 @@ function openDB() {
|
|
|
39
37
|
db.deleteObjectStore(STORE_NAME);
|
|
40
38
|
}
|
|
41
39
|
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
42
|
-
db.createObjectStore(STORE_NAME, { keyPath:
|
|
40
|
+
db.createObjectStore(STORE_NAME, { keyPath: 'cacheKey' });
|
|
43
41
|
}
|
|
44
42
|
};
|
|
45
43
|
req.onsuccess = () => resolve(req.result);
|
|
@@ -53,17 +51,25 @@ function openDB() {
|
|
|
53
51
|
const pendingWrites = new Map();
|
|
54
52
|
let flushTimer = null;
|
|
55
53
|
const FLUSH_INTERVAL_MS = 500;
|
|
54
|
+
// The caps below are only real if something enforces them. Prune once per page
|
|
55
|
+
// load, off the back of the first flush, so the cache cannot grow forever
|
|
56
|
+
// without any host having to remember to call it.
|
|
57
|
+
let prunedThisLoad = false;
|
|
56
58
|
async function flushPendingWrites() {
|
|
57
59
|
flushTimer = null;
|
|
58
60
|
if (pendingWrites.size === 0)
|
|
59
61
|
return;
|
|
62
|
+
if (!prunedThisLoad) {
|
|
63
|
+
prunedThisLoad = true;
|
|
64
|
+
void pruneIDBCache();
|
|
65
|
+
}
|
|
60
66
|
const batch = new Map(pendingWrites);
|
|
61
67
|
pendingWrites.clear();
|
|
62
68
|
try {
|
|
63
69
|
const db = await openDB();
|
|
64
|
-
const tx = db.transaction(STORE_NAME,
|
|
70
|
+
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
65
71
|
const store = tx.objectStore(STORE_NAME);
|
|
66
|
-
for (const [cacheKey, { scope, sessionId, messages, parts }] of batch) {
|
|
72
|
+
for (const [cacheKey, { scope, sessionId, kortixSessionScope, messages, parts }] of batch) {
|
|
67
73
|
const partsForSession = {};
|
|
68
74
|
for (const msg of messages) {
|
|
69
75
|
if (parts[msg.id]) {
|
|
@@ -74,6 +80,7 @@ async function flushPendingWrites() {
|
|
|
74
80
|
cacheKey,
|
|
75
81
|
userId: scope,
|
|
76
82
|
sessionId,
|
|
83
|
+
kortixSessionScope,
|
|
77
84
|
messages,
|
|
78
85
|
parts: partsForSession,
|
|
79
86
|
updatedAt: Date.now(),
|
|
@@ -88,12 +95,18 @@ async function flushPendingWrites() {
|
|
|
88
95
|
// Non-critical
|
|
89
96
|
}
|
|
90
97
|
}
|
|
91
|
-
export async function saveSessionToIDB(sessionId, messages, parts) {
|
|
98
|
+
export async function saveSessionToIDB(sessionId, messages, parts, kortixSessionScope) {
|
|
92
99
|
const scope = await getCurrentCacheScope();
|
|
93
100
|
if (!scope)
|
|
94
101
|
return;
|
|
95
|
-
const cacheKey =
|
|
96
|
-
pendingWrites.set(cacheKey, {
|
|
102
|
+
const cacheKey = buildSessionCacheKey(scope, sessionId, kortixSessionScope);
|
|
103
|
+
pendingWrites.set(cacheKey, {
|
|
104
|
+
scope,
|
|
105
|
+
sessionId,
|
|
106
|
+
kortixSessionScope,
|
|
107
|
+
messages,
|
|
108
|
+
parts,
|
|
109
|
+
});
|
|
97
110
|
if (!flushTimer) {
|
|
98
111
|
flushTimer = setTimeout(flushPendingWrites, FLUSH_INTERVAL_MS);
|
|
99
112
|
}
|
|
@@ -104,25 +117,32 @@ export function flushIDBWrites() {
|
|
|
104
117
|
}
|
|
105
118
|
return flushPendingWrites();
|
|
106
119
|
}
|
|
107
|
-
export async function loadSessionFromIDB(sessionId) {
|
|
120
|
+
export async function loadSessionFromIDB(sessionId, kortixSessionScope) {
|
|
108
121
|
try {
|
|
109
122
|
const scope = await getCurrentCacheScope();
|
|
110
123
|
if (!scope)
|
|
111
124
|
return null;
|
|
112
125
|
const db = await openDB();
|
|
113
|
-
const tx = db.transaction(STORE_NAME,
|
|
126
|
+
const tx = db.transaction(STORE_NAME, 'readonly');
|
|
114
127
|
const store = tx.objectStore(STORE_NAME);
|
|
115
|
-
const req = store.get(
|
|
128
|
+
const req = store.get(buildSessionCacheKey(scope, sessionId, kortixSessionScope));
|
|
116
129
|
const result = await new Promise((resolve, reject) => {
|
|
117
130
|
req.onsuccess = () => resolve(req.result);
|
|
118
131
|
req.onerror = () => reject(req.error);
|
|
119
132
|
});
|
|
120
133
|
if (!result)
|
|
121
134
|
return null;
|
|
122
|
-
if (result.userId !== scope
|
|
135
|
+
if (result.userId !== scope)
|
|
123
136
|
return null;
|
|
137
|
+
if (kortixSessionScope) {
|
|
138
|
+
if (result.kortixSessionScope !== kortixSessionScope)
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
else if (result.sessionId !== sessionId) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
124
144
|
if (Date.now() - result.updatedAt > MAX_SESSION_AGE_MS) {
|
|
125
|
-
deleteSessionFromIDB(sessionId);
|
|
145
|
+
deleteSessionFromIDB(sessionId, kortixSessionScope);
|
|
126
146
|
return null;
|
|
127
147
|
}
|
|
128
148
|
return { messages: result.messages, parts: result.parts };
|
|
@@ -137,7 +157,7 @@ export async function loadAllSessionIdsFromIDB() {
|
|
|
137
157
|
if (!scope)
|
|
138
158
|
return [];
|
|
139
159
|
const db = await openDB();
|
|
140
|
-
const tx = db.transaction(STORE_NAME,
|
|
160
|
+
const tx = db.transaction(STORE_NAME, 'readonly');
|
|
141
161
|
const store = tx.objectStore(STORE_NAME);
|
|
142
162
|
const req = store.getAll();
|
|
143
163
|
const entries = await new Promise((resolve, reject) => {
|
|
@@ -150,14 +170,14 @@ export async function loadAllSessionIdsFromIDB() {
|
|
|
150
170
|
return [];
|
|
151
171
|
}
|
|
152
172
|
}
|
|
153
|
-
export async function deleteSessionFromIDB(sessionId) {
|
|
173
|
+
export async function deleteSessionFromIDB(sessionId, kortixSessionScope) {
|
|
154
174
|
try {
|
|
155
175
|
const scope = await getCurrentCacheScope();
|
|
156
176
|
if (!scope)
|
|
157
177
|
return;
|
|
158
178
|
const db = await openDB();
|
|
159
|
-
const tx = db.transaction(STORE_NAME,
|
|
160
|
-
tx.objectStore(STORE_NAME).delete(
|
|
179
|
+
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
180
|
+
tx.objectStore(STORE_NAME).delete(buildSessionCacheKey(scope, sessionId, kortixSessionScope));
|
|
161
181
|
}
|
|
162
182
|
catch {
|
|
163
183
|
// ignore
|
|
@@ -171,7 +191,7 @@ export async function clearSessionIDBCache() {
|
|
|
171
191
|
flushTimer = null;
|
|
172
192
|
}
|
|
173
193
|
const db = await openDB();
|
|
174
|
-
const tx = db.transaction(STORE_NAME,
|
|
194
|
+
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
175
195
|
tx.objectStore(STORE_NAME).clear();
|
|
176
196
|
}
|
|
177
197
|
catch {
|
|
@@ -181,7 +201,7 @@ export async function clearSessionIDBCache() {
|
|
|
181
201
|
export async function pruneIDBCache() {
|
|
182
202
|
try {
|
|
183
203
|
const db = await openDB();
|
|
184
|
-
const tx = db.transaction(STORE_NAME,
|
|
204
|
+
const tx = db.transaction(STORE_NAME, 'readwrite');
|
|
185
205
|
const store = tx.objectStore(STORE_NAME);
|
|
186
206
|
const req = store.getAll();
|
|
187
207
|
const entries = await new Promise((resolve, reject) => {
|
|
@@ -189,16 +209,19 @@ export async function pruneIDBCache() {
|
|
|
189
209
|
req.onerror = () => reject(req.error);
|
|
190
210
|
});
|
|
191
211
|
const now = Date.now();
|
|
212
|
+
// Delete by `cacheKey` — it is the store's keyPath. Deleting by `sessionId`
|
|
213
|
+
// matched no record, so prune silently kept every entry forever and the
|
|
214
|
+
// 50-session / 7-day caps were never enforced.
|
|
192
215
|
const stale = entries.filter((e) => now - e.updatedAt > MAX_SESSION_AGE_MS);
|
|
193
216
|
for (const e of stale) {
|
|
194
|
-
store.delete(e.
|
|
217
|
+
store.delete(e.cacheKey);
|
|
195
218
|
}
|
|
196
219
|
const fresh = entries
|
|
197
220
|
.filter((e) => now - e.updatedAt <= MAX_SESSION_AGE_MS)
|
|
198
221
|
.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
199
222
|
if (fresh.length > MAX_CACHED_SESSIONS) {
|
|
200
223
|
for (const e of fresh.slice(MAX_CACHED_SESSIONS)) {
|
|
201
|
-
store.delete(e.
|
|
224
|
+
store.delete(e.cacheKey);
|
|
202
225
|
}
|
|
203
226
|
}
|
|
204
227
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idb-sync-cache.js","sourceRoot":"","sources":["../../../src/browser/cache/idb-sync-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"idb-sync-cache.js","sourceRoot":"","sources":["../../../src/browser/cache/idb-sync-cache.ts"],"names":[],"mappings":"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"}
|