@k9o/core 1.0.0 → 1.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/CHANGELOG.md +5 -71
- package/README.md +224 -32
- package/dist/{chunk-OE2MMUIG.js → chunk-2NDFTHUB.js} +2 -2
- package/dist/chunk-2NDFTHUB.js.map +1 -0
- package/dist/{chunk-2VSTF5UU.js → chunk-LJZ45UA2.js} +1 -1
- package/dist/chunk-LJZ45UA2.js.map +1 -0
- package/dist/{chunk-FVWKL5UQ.js → chunk-O2ZTV6YN.js} +2 -2
- package/dist/chunk-O2ZTV6YN.js.map +1 -0
- package/dist/envelope.d.ts +9 -9
- package/dist/http.d.ts +4 -4
- package/dist/http.js +2 -2
- package/dist/index.d.ts +163 -183
- package/dist/index.js +43 -44
- package/dist/index.js.map +1 -1
- package/dist/kerror.d.ts +2 -2
- package/dist/kerror.js +1 -1
- package/dist/types.d.ts +4 -6
- package/dist/url-grammar.d.ts +6 -6
- package/dist/url-grammar.js +2 -2
- package/package.json +4 -4
- package/src/audit.ts +6 -6
- package/src/compute/llms.ts +16 -16
- package/src/data/from.ts +12 -12
- package/src/envelope.ts +9 -9
- package/src/extensions-bridge.ts +7 -9
- package/src/functions.ts +8 -8
- package/src/gate-bridge.ts +2 -2
- package/src/http.ts +4 -4
- package/src/index.ts +17 -27
- package/src/internal/sse.ts +2 -2
- package/src/kerror.ts +2 -2
- package/src/me.ts +7 -8
- package/src/metadata.ts +13 -20
- package/src/migrations.ts +12 -12
- package/src/org.ts +19 -19
- package/src/orgs.ts +5 -5
- package/src/policies.ts +2 -2
- package/src/projects.ts +5 -5
- package/src/realtime.ts +16 -16
- package/src/retry.ts +1 -1
- package/src/storage-buckets.ts +1 -1
- package/src/studio/dashboards.ts +13 -13
- package/src/studio/index.ts +2 -2
- package/src/studio/workflows.ts +21 -21
- package/src/types.ts +4 -6
- package/src/url-grammar.ts +6 -6
- package/dist/chunk-2VSTF5UU.js.map +0 -1
- package/dist/chunk-FVWKL5UQ.js.map +0 -1
- package/dist/chunk-OE2MMUIG.js.map +0 -1
package/dist/kerror.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* gateway didn't return one).
|
|
18
18
|
* - `status` — HTTP status the gateway returned (or null for
|
|
19
19
|
* SDK-side construct-time errors like
|
|
20
|
-
* `K9O_INVALID_BASE_URL`
|
|
20
|
+
* `K9O_INVALID_BASE_URL`).
|
|
21
21
|
* - `requestId` — gateway-emitted trace ID for downstream correlation.
|
|
22
22
|
*
|
|
23
23
|
* Standalone `@k9o/gate` ships its own `GateError` for the Auth0-parity
|
|
@@ -63,7 +63,7 @@ declare class KError extends Error {
|
|
|
63
63
|
* Rehydrate a wire `KError` payload into a typed `KError` instance.
|
|
64
64
|
* Unlike `@k9o/gate.gateErrorFromWire`, `@k9o/core` does not maintain
|
|
65
65
|
* a hand-curated allow-list of known codes — the gateway's KError
|
|
66
|
-
* code-space is open-ended and curated centrally
|
|
66
|
+
* code-space is open-ended and curated centrally; the SDK
|
|
67
67
|
* preserves whatever code the gateway sends. Code-narrowing in caller
|
|
68
68
|
* code uses string-literal comparison against the well-known codes
|
|
69
69
|
* (e.g. `if (e.code === 'K9O_TIER_CAP_HIT')`).
|
package/dist/kerror.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -24,11 +24,10 @@
|
|
|
24
24
|
* - `baseUrl` — gateway host root (scheme + host; no path). **Optional**;
|
|
25
25
|
* defaults to the platform apex `https://api.k9o.io`.
|
|
26
26
|
* When it is the bare apex and `orgSlug` is set, the SDK composes the
|
|
27
|
-
* canonical org subdomain `https://<orgSlug>.api.k9o.io
|
|
28
|
-
* §7.1). Pass an explicit host to override — an explicit `<orgSlug>` subdomain,
|
|
27
|
+
* canonical org subdomain `https://<orgSlug>.api.k9o.io`. Pass an explicit host to override — an explicit `<orgSlug>` subdomain,
|
|
29
28
|
* or a self-hosted / Sovereign-Control host, or a dev host — used as-is.
|
|
30
29
|
* - `fetch` — custom fetch implementation (defaults to global)
|
|
31
|
-
* - `retryConfig` — retry/backoff config (reserved;
|
|
30
|
+
* - `retryConfig` — retry/backoff config (reserved; currently ships single-attempt)
|
|
32
31
|
* - `defaultHeaders` — headers merged into every request
|
|
33
32
|
*/
|
|
34
33
|
type CreateClientOptions = {
|
|
@@ -41,9 +40,8 @@ type CreateClientOptions = {
|
|
|
41
40
|
defaultHeaders?: Record<string, string> | undefined;
|
|
42
41
|
};
|
|
43
42
|
/**
|
|
44
|
-
* Retry config
|
|
45
|
-
*
|
|
46
|
-
* sub-cycle.
|
|
43
|
+
* Retry config. The type is reserved; the HTTP client currently makes a
|
|
44
|
+
* single attempt per request and does not yet honour this config.
|
|
47
45
|
*/
|
|
48
46
|
type RetryConfig = {
|
|
49
47
|
maxRetries: number;
|
package/dist/url-grammar.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* URL grammar
|
|
2
|
+
* URL grammar.
|
|
3
3
|
*
|
|
4
4
|
* Canonical URL shapes:
|
|
5
5
|
* - Member-plane (project-scoped): `<orgSlug>.api.k9o.io/@<projectSlug>/<sub-resource>/...`
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
* - Platform-plane (cross-org): `api.k9o.io/discovery/...` + `api.k9o.io/auth/...` etc.
|
|
8
8
|
*
|
|
9
9
|
* The `baseUrl` passed to `createClient` is the gateway host root —
|
|
10
|
-
* scheme + host (+ optional port)
|
|
11
|
-
* are rejected with `K9O_INVALID_BASE_URL
|
|
10
|
+
* scheme + host (+ optional port). Path-bearing baseUrls
|
|
11
|
+
* are rejected with `K9O_INVALID_BASE_URL`.
|
|
12
12
|
*
|
|
13
13
|
* The SDK constructs URLs by composing `baseUrl + path-from-builder`.
|
|
14
14
|
* Per-resource SDK methods use the builders below to assemble their
|
|
15
15
|
* `path` argument before handing to the HTTP client.
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
-
* Validate a `baseUrl
|
|
18
|
+
* Validate a `baseUrl`. Returns the normalised form
|
|
19
19
|
* (trailing-slash stripped) on success; throws `K9O_INVALID_BASE_URL`
|
|
20
20
|
* on any violation.
|
|
21
21
|
*
|
|
@@ -37,7 +37,7 @@ declare function validateBaseUrl(baseUrl: string): string;
|
|
|
37
37
|
* OPTIONAL — it defaults to the platform apex `https://api.k9o.io`. When the
|
|
38
38
|
* (validated) host is a bare apex in `K9O_ORG_DERIVABLE_APEXES` and `orgSlug`
|
|
39
39
|
* is supplied, the SDK composes the canonical org-subdomain wire root
|
|
40
|
-
* `https://<orgSlug>.<apex
|
|
40
|
+
* `https://<orgSlug>.<apex>`. An explicit `<orgSlug>` subdomain, a
|
|
41
41
|
* self-hosted / Sovereign host, or a dev host (anything not in that set)
|
|
42
42
|
* passes through unchanged — `orgSlug` is intentionally NOT validated or
|
|
43
43
|
* composed onto a non-apex host (fixed 2026-08-30: this used to silently
|
|
@@ -48,7 +48,7 @@ declare function validateBaseUrl(baseUrl: string): string;
|
|
|
48
48
|
declare function resolveBaseUrl(baseUrl: string | undefined, orgSlug?: string): string;
|
|
49
49
|
declare function validateSlug(slug: string, kind: "org" | "project"): void;
|
|
50
50
|
/**
|
|
51
|
-
* Build a project-scoped (member-plane) URL path per
|
|
51
|
+
* Build a project-scoped (member-plane) URL path per the URL grammar
|
|
52
52
|
* E.g. `projectPath('member-portal', 'collections/posts/documents')`
|
|
53
53
|
* → `/@member-portal/collections/posts/documents`.
|
|
54
54
|
*
|
package/dist/url-grammar.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@k9o/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Kilimanjaro platform SDK — createClient + data-plane + projects + migrations + functions + studio (workflows/dashboards) + compute.llms + realtime subscriptions + KError + meta accessor sugar. Composes with @k9o/gate (auth) and @k9o/extensions (extension consumption).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"url": "https://github.com/k9o-dev/sdk-typescript"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@k9o/gate": "1.
|
|
63
|
-
"@k9o/extensions": "1.
|
|
64
|
-
"@k9o/kibo": "1.
|
|
62
|
+
"@k9o/gate": "1.1.0",
|
|
63
|
+
"@k9o/extensions": "1.1.0",
|
|
64
|
+
"@k9o/kibo": "1.1.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"bun-types": "^1.1.0",
|
package/src/audit.ts
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* The endpoint accepts cursor-paginated reverse-chronological queries.
|
|
11
11
|
* `type` is the audit-event namespace (e.g. `data.write.access.insert`,
|
|
12
|
-
* `gate.signin.success`) per the
|
|
12
|
+
* `gate.signin.success`) per the event-name taxonomy +
|
|
13
13
|
* `feedback_error_code_namespace_boundary_and_prefix.md` cement.
|
|
14
14
|
*
|
|
15
15
|
* Returns audit events with full context payload — actorId / targetKind /
|
|
16
|
-
* targetId / payload / occurredAt / requestId / traceId
|
|
16
|
+
* targetId / payload / occurredAt / requestId / traceId.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { request, type HttpClientConfig } from "./http.ts";
|
|
@@ -21,11 +21,11 @@ import { projectPath } from "./url-grammar.ts";
|
|
|
21
21
|
import type { Envelope } from "./envelope.ts";
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
* Audit event record
|
|
24
|
+
* Audit event record `_sys.audit_log` shape.
|
|
25
25
|
*/
|
|
26
26
|
export type AuditEvent = {
|
|
27
27
|
id: string;
|
|
28
|
-
/** Dotted namespace
|
|
28
|
+
/** Dotted namespace (e.g. `data.write.access.insert`). */
|
|
29
29
|
type: string;
|
|
30
30
|
actorId: string | null;
|
|
31
31
|
targetKind: string | null;
|
|
@@ -68,7 +68,7 @@ export function makeAuditNamespace(config: HttpClientConfig) {
|
|
|
68
68
|
* Query the audit log. Returns reverse-chronological events matching
|
|
69
69
|
* all supplied filters (AND composition).
|
|
70
70
|
*
|
|
71
|
-
* Per
|
|
71
|
+
* Per RBAC: requires `AUDIT_READER` role minimum; Custodian-
|
|
72
72
|
* class roles inherit. Project-level audit is project-scoped (this
|
|
73
73
|
* endpoint); platform-level audit is admin-only (separate surface).
|
|
74
74
|
*/
|
|
@@ -84,7 +84,7 @@ export function makeAuditNamespace(config: HttpClientConfig) {
|
|
|
84
84
|
/**
|
|
85
85
|
* Convenience: live-tail recent events. Currently single-shot read
|
|
86
86
|
* with `since` defaulted to "1 minute ago"; subscription-mode tail
|
|
87
|
-
* (SSE) lands when the streaming layer ships
|
|
87
|
+
* (SSE) lands when the streaming layer ships pattern.
|
|
88
88
|
*/
|
|
89
89
|
async tail(opts?: { sinceMinutes?: number; limit?: number }): Promise<Envelope<ReadonlyArray<AuditEvent>>> {
|
|
90
90
|
const slug = requireProjectSlug(config);
|
package/src/compute/llms.ts
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
* Compute LLMs SDK — `client.compute.llms.*`.
|
|
3
3
|
*
|
|
4
4
|
* Compute LLMs registry. Curated 9-model library
|
|
5
|
-
*
|
|
5
|
+
* + 4-endpoint family + per-model tier-gating.
|
|
6
6
|
*
|
|
7
|
-
* Wire mapping (project-plane;
|
|
7
|
+
* Wire mapping (project-plane;):
|
|
8
8
|
* - list() → GET /@<slug>/compute/llms
|
|
9
9
|
* - read(modelId) → GET /@<slug>/compute/llms/<model-id>
|
|
10
10
|
* - invoke(modelId, ...) → POST /@<slug>/compute/llms/<model-id>/invoke
|
|
11
11
|
* - invokeStream(modelId,...) → POST /@<slug>/compute/llms/<model-id>/invoke-stream (SSE)
|
|
12
12
|
*
|
|
13
|
-
* Per
|
|
13
|
+
* Per RBAC: list/read against all cohort roles; invoke +
|
|
14
14
|
* invokeStream require PROJECT_AUTHOR or PROJECT_ADMIN (LLM cost gate).
|
|
15
|
-
* Per
|
|
15
|
+
* Per, surfaces K9O_LLM_PROVIDER_UNAVAILABLE (503) +
|
|
16
16
|
* reuses K9O_MODEL_NOT_DECLARED / K9O_TIER_FEATURE_GATED /
|
|
17
17
|
* K9O_AGENT_INFERENCE_TIMEOUT.
|
|
18
18
|
*/
|
|
@@ -22,7 +22,7 @@ import { projectPath } from "../url-grammar.ts";
|
|
|
22
22
|
import type { Envelope } from "../envelope.ts";
|
|
23
23
|
import { parseSseStream } from "../internal/sse.ts";
|
|
24
24
|
|
|
25
|
-
/** Curated 9-model closed enum at v2 launch
|
|
25
|
+
/** Curated 9-model closed enum at v2 launch (extensible v2.x). */
|
|
26
26
|
export type LLMModelId =
|
|
27
27
|
| "mistral-7b"
|
|
28
28
|
| "mistral-8x7b"
|
|
@@ -37,21 +37,21 @@ export type LLMModelId =
|
|
|
37
37
|
export type LLMProviderClass = "self-hosted" | "external";
|
|
38
38
|
export type LLMModality = "text-completion" | "text-completion+tool-use" | "embeddings";
|
|
39
39
|
|
|
40
|
-
/** Model metadata
|
|
40
|
+
/** Model metadata + (cost transparency). */
|
|
41
41
|
export type LLMModel = {
|
|
42
42
|
id: LLMModelId;
|
|
43
43
|
providerClass: LLMProviderClass;
|
|
44
44
|
modality: LLMModality;
|
|
45
|
-
/** Minimum tier gate
|
|
45
|
+
/** Minimum tier gate (e.g. "base-camp", "ascent", "ridge"). */
|
|
46
46
|
tierGate: string;
|
|
47
47
|
contextWindow: number;
|
|
48
48
|
capabilities: ReadonlyArray<string>;
|
|
49
|
-
/** Per-model token cost for cost-transparency
|
|
49
|
+
/** Per-model token cost for cost-transparency. */
|
|
50
50
|
costPerMillionInputTokens: number;
|
|
51
51
|
costPerMillionOutputTokens: number;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
/** Inference parameters
|
|
54
|
+
/** Inference parameters (passed through to provider). */
|
|
55
55
|
export type LLMInvokeParams = {
|
|
56
56
|
maxTokens?: number;
|
|
57
57
|
temperature?: number;
|
|
@@ -60,14 +60,14 @@ export type LLMInvokeParams = {
|
|
|
60
60
|
[key: string]: unknown;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
/** Synchronous inference response
|
|
63
|
+
/** Synchronous inference response `/invoke`. */
|
|
64
64
|
export type LLMResponse = {
|
|
65
65
|
completion: string;
|
|
66
66
|
tokensUsed: number;
|
|
67
67
|
latencyMs: number;
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
/** Streaming chunk
|
|
70
|
+
/** Streaming chunk `/invoke-stream` (SSE per-token). */
|
|
71
71
|
export type LLMStreamChunk = {
|
|
72
72
|
/** Incremental completion delta. */
|
|
73
73
|
delta: string;
|
|
@@ -82,7 +82,7 @@ export type LLMInvokeInput = {
|
|
|
82
82
|
params?: LLMInvokeParams;
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
/** Error code coined in
|
|
85
|
+
/** Error code coined in (others reused). */
|
|
86
86
|
export const LLM_ERROR_CODES = {
|
|
87
87
|
PROVIDER_UNAVAILABLE: "K9O_LLM_PROVIDER_UNAVAILABLE",
|
|
88
88
|
} as const;
|
|
@@ -96,7 +96,7 @@ function requireProjectSlug(config: HttpClientConfig): string {
|
|
|
96
96
|
|
|
97
97
|
export function makeLlmsNamespace(config: HttpClientConfig) {
|
|
98
98
|
return {
|
|
99
|
-
/** GET /@<slug>/compute/llms — list models available to the project tier
|
|
99
|
+
/** GET /@<slug>/compute/llms — list models available to the project tier. */
|
|
100
100
|
async list(opts?: { modality?: LLMModality; providerClass?: LLMProviderClass }): Promise<Envelope<ReadonlyArray<LLMModel>>> {
|
|
101
101
|
const slug = requireProjectSlug(config);
|
|
102
102
|
return request(config, { method: "GET", path: projectPath(slug, "compute/llms"), query: opts });
|
|
@@ -113,7 +113,7 @@ export function makeLlmsNamespace(config: HttpClientConfig) {
|
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
115
|
* POST /@<slug>/compute/llms/<model-id>/invoke — synchronous inference.
|
|
116
|
-
* Requires PROJECT_AUTHOR or PROJECT_ADMIN (LLM cost gate
|
|
116
|
+
* Requires PROJECT_AUTHOR or PROJECT_ADMIN (LLM cost gate).
|
|
117
117
|
*/
|
|
118
118
|
async invoke(modelId: LLMModelId | string, input: LLMInvokeInput): Promise<Envelope<LLMResponse>> {
|
|
119
119
|
const slug = requireProjectSlug(config);
|
|
@@ -126,7 +126,7 @@ export function makeLlmsNamespace(config: HttpClientConfig) {
|
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
128
|
* POST /@<slug>/compute/llms/<model-id>/invoke-stream — streaming
|
|
129
|
-
* inference (SSE; per-token delta for low-latency UX
|
|
129
|
+
* inference (SSE; per-token delta for low-latency UX).
|
|
130
130
|
* Returns an async iterable of `LLMStreamChunk` — caller writes
|
|
131
131
|
* `for await (const chunk of client.compute.llms.invokeStream(...))`.
|
|
132
132
|
* The SDK handles SSE framing internally per
|
|
@@ -148,7 +148,7 @@ export function makeLlmsNamespace(config: HttpClientConfig) {
|
|
|
148
148
|
|
|
149
149
|
export function makeComputeNamespace(config: HttpClientConfig) {
|
|
150
150
|
return {
|
|
151
|
-
/** LLM registry + inference — `client.compute.llms
|
|
151
|
+
/** LLM registry + inference — `client.compute.llms.*`. */
|
|
152
152
|
llms: makeLlmsNamespace(config),
|
|
153
153
|
};
|
|
154
154
|
}
|
package/src/data/from.ts
CHANGED
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
* - `from('posts').update({ title: '...' }).eq(...)` → PATCH /@<projectSlug>/data/posts/:id
|
|
15
15
|
* - `from('posts').delete().eq('id','rec_X')` → DELETE /@<projectSlug>/data/posts/:id
|
|
16
16
|
*
|
|
17
|
-
* Filters compose as AND
|
|
17
|
+
* Filters compose as AND; multiple chained `.eq()` /
|
|
18
18
|
* `.gt()` / etc. calls all attach to the query string.
|
|
19
19
|
*
|
|
20
|
-
* Pagination + counting
|
|
20
|
+
* Pagination + counting: `.limit(n)`, `.cursor(opaque)`,
|
|
21
21
|
* `.count('none' | 'exact' | 'estimated')`. The returned envelope's
|
|
22
22
|
* `meta.cursor.next` is the cursor for the next page.
|
|
23
23
|
*
|
|
24
|
-
* Per
|
|
24
|
+
* Per KError delivery: every terminal verb throws KError on
|
|
25
25
|
* non-2xx. Caller catches via `instanceof KError` + narrows on `.code`.
|
|
26
26
|
*/
|
|
27
27
|
|
|
@@ -136,7 +136,7 @@ class QueryBuilder {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
/**
|
|
139
|
-
* Total-count behaviour
|
|
139
|
+
* Total-count behaviour. `none` (default) skips the
|
|
140
140
|
* count query (cheapest); `exact` runs `SELECT COUNT(*)` (most
|
|
141
141
|
* expensive at scale); `estimated` reads from pg_stats (fast +
|
|
142
142
|
* approximate).
|
|
@@ -158,7 +158,7 @@ class QueryBuilder {
|
|
|
158
158
|
? `(${(f.value as ReadonlyArray<string | number>).join(",")})`
|
|
159
159
|
: String(f.value);
|
|
160
160
|
// Multiple filters on the same column are not currently supported via
|
|
161
|
-
// the simple key=value query map.
|
|
161
|
+
// the simple key=value query map. future cycles cover
|
|
162
162
|
// `.or()` / multi-filter — when those land the builder will switch
|
|
163
163
|
// to a serialisation that supports collisions.
|
|
164
164
|
q[f.column] = `${f.op}.${val}`;
|
|
@@ -190,7 +190,7 @@ class FromBuilder {
|
|
|
190
190
|
|
|
191
191
|
/**
|
|
192
192
|
* Insert one record. Returns the inserted record (with platform-
|
|
193
|
-
* generated `id` + `metadata`)
|
|
193
|
+
* generated `id` + `metadata`).
|
|
194
194
|
*/
|
|
195
195
|
async insert<T = unknown>(record: Partial<T>): Promise<Envelope<T>> {
|
|
196
196
|
return request<T>(this.config, {
|
|
@@ -256,9 +256,9 @@ class UpdateBuilder<T> extends QueryBuilder implements PromiseLike<Envelope<T>>
|
|
|
256
256
|
if (idFilter === undefined) {
|
|
257
257
|
throw new KError({
|
|
258
258
|
code: "K9O_INVALID_FIELD_VALUE",
|
|
259
|
-
message: "update() requires an `.eq('id', '...')` filter;
|
|
259
|
+
message: "update() requires an `.eq('id', '...')` filter; changing many rows in one call is not supported",
|
|
260
260
|
context: { collection: this.collection },
|
|
261
|
-
recommendation: "Chain `.eq('id', 'rec_…')` before awaiting the update;
|
|
261
|
+
recommendation: "Chain `.eq('id', 'rec_…')` before awaiting the update; to change several rows, call update once per id.",
|
|
262
262
|
});
|
|
263
263
|
}
|
|
264
264
|
return request<T>(this.config, {
|
|
@@ -289,9 +289,9 @@ class DeleteBuilder<T> extends QueryBuilder implements PromiseLike<Envelope<T>>
|
|
|
289
289
|
if (idFilter === undefined) {
|
|
290
290
|
throw new KError({
|
|
291
291
|
code: "K9O_INVALID_FIELD_VALUE",
|
|
292
|
-
message: "delete() requires an `.eq('id', '...')` filter;
|
|
292
|
+
message: "delete() requires an `.eq('id', '...')` filter; deleting many rows in one call is not supported",
|
|
293
293
|
context: { collection: this.collection },
|
|
294
|
-
recommendation: "Chain `.eq('id', 'rec_…')` before awaiting the delete;
|
|
294
|
+
recommendation: "Chain `.eq('id', 'rec_…')` before awaiting the delete; to delete several rows, call delete once per id.",
|
|
295
295
|
});
|
|
296
296
|
}
|
|
297
297
|
return request<T>(this.config, {
|
|
@@ -311,7 +311,7 @@ class DeleteBuilder<T> extends QueryBuilder implements PromiseLike<Envelope<T>>
|
|
|
311
311
|
/**
|
|
312
312
|
* Build the collection-records URL path. Requires `config.projectSlug`
|
|
313
313
|
* to be bound; member-plane resources route via the `/@<projectSlug>/...`
|
|
314
|
-
* prefix per
|
|
314
|
+
* prefix per the URL grammar.
|
|
315
315
|
*/
|
|
316
316
|
function collectionPath(config: HttpClientConfig, collection: string): string {
|
|
317
317
|
if (typeof config.projectSlug !== "string" || config.projectSlug.length === 0) {
|
|
@@ -323,7 +323,7 @@ function collectionPath(config: HttpClientConfig, collection: string): string {
|
|
|
323
323
|
});
|
|
324
324
|
}
|
|
325
325
|
validateSlug(config.projectSlug, "project");
|
|
326
|
-
// Validate collection name shape — same slug grammar
|
|
326
|
+
// Validate collection name shape — same slug grammar.
|
|
327
327
|
if (!/^[a-z][a-z0-9_-]{0,62}$/.test(collection)) {
|
|
328
328
|
throw new KError({
|
|
329
329
|
code: "K9O_INVALID_FIELD_VALUE",
|
package/src/envelope.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Standard
|
|
2
|
+
* Standard envelope + meta namespace types.
|
|
3
3
|
*
|
|
4
4
|
* The `meta` namespace surfaces structured per-namespace
|
|
5
5
|
* accessors (cursor / subscription / idempotency / warnings / cost /
|
|
@@ -24,7 +24,7 @@ export type Envelope<T> = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Cursor pagination accessor
|
|
27
|
+
* Cursor pagination accessor. `next` is the opaque cursor
|
|
28
28
|
* for the next page (null when no more); `totalCount` populated only
|
|
29
29
|
* when the caller passes `?count=exact` (otherwise undefined).
|
|
30
30
|
*/
|
|
@@ -34,7 +34,7 @@ export type MetaCursor = {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* Subscription delivery metadata
|
|
37
|
+
* Subscription delivery metadata. `isInitial` is true on
|
|
38
38
|
* the first batch of an initial-load subscription; false on subsequent
|
|
39
39
|
* live deltas.
|
|
40
40
|
*/
|
|
@@ -43,7 +43,7 @@ export type MetaSubscription = {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* Idempotency replay metadata
|
|
46
|
+
* Idempotency replay metadata. `replayed` is true when
|
|
47
47
|
* the gateway recognised a previously-seen idempotency key and returned
|
|
48
48
|
* the original response.
|
|
49
49
|
*/
|
|
@@ -52,7 +52,7 @@ export type MetaIdempotency = {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* Non-fatal warning shape
|
|
55
|
+
* Non-fatal warning shape. Surfaced on responses where
|
|
56
56
|
* the operation succeeded but the caller should know about caveats
|
|
57
57
|
* (e.g. tier-approaching-cap; deprecated field used).
|
|
58
58
|
*/
|
|
@@ -62,8 +62,8 @@ export type MetaWarning = {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
/**
|
|
65
|
-
* Cost metadata
|
|
66
|
-
* Field names
|
|
65
|
+
* Cost metadata — per-dimension consumption attribution.
|
|
66
|
+
* Field names (waypoints, storageGbHours, egress,
|
|
67
67
|
* apiCalls, vaultOps, etc.). Dimensions are sparsely populated and values
|
|
68
68
|
* may be scalars (e.g. `waypoints: 3`) or structured objects (e.g.
|
|
69
69
|
* `egress: { gb, zone }`, `vaultOps: { encrypt, decrypt, ... }`), so the
|
|
@@ -73,7 +73,7 @@ export type MetaWarning = {
|
|
|
73
73
|
export type MetaCost = Record<string, unknown>;
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
|
-
* Timing metadata
|
|
76
|
+
* Timing metadata. `totalMs` is the gateway-side wall-clock
|
|
77
77
|
* for the request.
|
|
78
78
|
*/
|
|
79
79
|
export type MetaTiming = {
|
|
@@ -81,7 +81,7 @@ export type MetaTiming = {
|
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
|
-
* Request-correlation metadata
|
|
84
|
+
* Request-correlation metadata. `requestId` is the
|
|
85
85
|
* gateway-emitted trace ID; surface in error reports for support.
|
|
86
86
|
*/
|
|
87
87
|
export type MetaContext = {
|
package/src/extensions-bridge.ts
CHANGED
|
@@ -7,14 +7,12 @@
|
|
|
7
7
|
* factory returning typed bindings for Trailblazer/Anchor/Keystone
|
|
8
8
|
* class extensions (baked in at SDK publish time). Circuit-class
|
|
9
9
|
* (Long Tail) extensions use the install-time `k9o codegen` tool
|
|
10
|
-
*
|
|
11
|
-
* per path (b).
|
|
10
|
+
* path (a) OR raw HTTP / vendor-SDK fallback per path (b).
|
|
12
11
|
*
|
|
13
|
-
* The bridge re-exports the factory directly — it is config-free
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* runtime; until then the re-export is a thin pass-through.
|
|
12
|
+
* The bridge re-exports the factory directly — it is config-free
|
|
13
|
+
* (extension stubs do not require HTTP routing yet). Once per-method dispatch
|
|
14
|
+
* ships, the bridge will thread baseUrl + auth into the extension runtime;
|
|
15
|
+
* until then the re-export is a thin pass-through.
|
|
18
16
|
*/
|
|
19
17
|
|
|
20
18
|
import { k9o as extensionsNamespace, type ExtensionSlug, type Extension } from "@k9o/extensions";
|
|
@@ -24,8 +22,8 @@ export { extensionsNamespace, type ExtensionSlug, type Extension };
|
|
|
24
22
|
/**
|
|
25
23
|
* Build the composed `client.extensions` namespace. Currently a thin
|
|
26
24
|
* re-export of the `@k9o/extensions` `k9o.extension(slug)` factory.
|
|
27
|
-
* Config-free
|
|
28
|
-
*
|
|
25
|
+
* Config-free for now; it will use the client HTTP config once runtime
|
|
26
|
+
* dispatch ships.
|
|
29
27
|
*/
|
|
30
28
|
export function makeExtensionsBridge() {
|
|
31
29
|
return {
|
package/src/functions.ts
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* - `delete(name)` → DELETE /@<slug>/functions/<name>
|
|
11
11
|
* - `invoke(name, payload)` → POST /@<slug>/functions/<name>/invoke
|
|
12
12
|
*
|
|
13
|
-
* Per
|
|
14
|
-
* function manifest. Per
|
|
13
|
+
* Per: deploy requires PROJECT_ADMIN; invoke authority is per
|
|
14
|
+
* function manifest. Per: deploy returns 202 with status
|
|
15
15
|
* `deploying`; the function is ready when status flips to `active`.
|
|
16
16
|
*/
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ import type { Envelope } from "./envelope.ts";
|
|
|
23
23
|
* Function record returned by gateway endpoints.
|
|
24
24
|
*/
|
|
25
25
|
export type FunctionRecord = {
|
|
26
|
-
/** `fn_<base62
|
|
26
|
+
/** `fn_<base62>`. */
|
|
27
27
|
id: string;
|
|
28
28
|
name: string;
|
|
29
29
|
runtime: "wasm" | "bun" | "node";
|
|
@@ -35,7 +35,7 @@ export type FunctionRecord = {
|
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Deploy input. The `code` field is the runtime bundle (base64-encoded
|
|
38
|
-
* WASM or JS source)
|
|
38
|
+
* WASM or JS source).
|
|
39
39
|
*/
|
|
40
40
|
export type DeployFunctionInput = {
|
|
41
41
|
name: string;
|
|
@@ -64,7 +64,7 @@ export function makeFunctionsNamespace(config: HttpClientConfig) {
|
|
|
64
64
|
});
|
|
65
65
|
},
|
|
66
66
|
|
|
67
|
-
/** List deployed functions (cursor pagination
|
|
67
|
+
/** List deployed functions (cursor pagination). */
|
|
68
68
|
async list(opts?: { limit?: number; cursor?: string; status?: FunctionRecord["status"] }): Promise<Envelope<ReadonlyArray<FunctionRecord>>> {
|
|
69
69
|
const slug = requireProjectSlug(config);
|
|
70
70
|
return request(config, {
|
|
@@ -83,7 +83,7 @@ export function makeFunctionsNamespace(config: HttpClientConfig) {
|
|
|
83
83
|
});
|
|
84
84
|
},
|
|
85
85
|
|
|
86
|
-
/** Retire a function. Returns confirmation; the function name enters a 24h cooldown
|
|
86
|
+
/** Retire a function. Returns confirmation; the function name enters a 24h cooldown. */
|
|
87
87
|
async delete(name: string): Promise<Envelope<{ retired: boolean; cooldownUntil: string }>> {
|
|
88
88
|
const slug = requireProjectSlug(config);
|
|
89
89
|
return request(config, {
|
|
@@ -97,8 +97,8 @@ export function makeFunctionsNamespace(config: HttpClientConfig) {
|
|
|
97
97
|
* verbatim; the gateway returns whatever the function returns wrapped
|
|
98
98
|
* in the standard envelope.
|
|
99
99
|
*
|
|
100
|
-
* Per
|
|
101
|
-
* function manifest). Per
|
|
100
|
+
* Per: invoke authority is per-function (declared in the
|
|
101
|
+
* function manifest). Per: streaming responses use the
|
|
102
102
|
* subscription/async-iterator pattern; this method covers the
|
|
103
103
|
* request-response variant only.
|
|
104
104
|
*/
|
package/src/gate-bridge.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Mode defaults to `native` for the composition path — Native is the
|
|
13
13
|
* mode that pairs with the broader Kilimanjaro billing model per
|
|
14
|
-
* `@k9o/gate/mode.ts
|
|
14
|
+
* `@k9o/gate/mode.ts`. Standalone customers should import
|
|
15
15
|
* `@k9o/gate` directly and call `createGateClient({ mode: 'standalone', ... })`.
|
|
16
16
|
*
|
|
17
17
|
* KError vs GateError alignment is still open.
|
|
@@ -28,7 +28,7 @@ import { KError } from "./kerror.ts";
|
|
|
28
28
|
* Build the composed `client.gate` namespace bound to the K9oClient's
|
|
29
29
|
* baseUrl + projectSlug. Requires `projectSlug` to be set on the
|
|
30
30
|
* client config — gate operations are inherently project-scoped per
|
|
31
|
-
*
|
|
31
|
+
* URL grammar.
|
|
32
32
|
*
|
|
33
33
|
* Returns `null` when projectSlug is not bound — the K9oClient may be
|
|
34
34
|
* constructed for org-plane operations only (e.g. `client.orgs.list()`
|
package/src/http.ts
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* - KError rehydration on non-2xx
|
|
12
12
|
* - Bearer token injection (from per-call override OR bound default)
|
|
13
13
|
* - Project context header (`x-k9o-project-slug`) injection when bound
|
|
14
|
-
* - Retry with exponential backoff per RetryConfig (see retry.ts) —
|
|
15
|
-
*
|
|
14
|
+
* - Retry with exponential backoff per RetryConfig (see retry.ts) — not available
|
|
15
|
+
* yet; requests are currently a single attempt
|
|
16
16
|
*
|
|
17
17
|
* The client is intentionally minimal — per-resource SDK methods compose
|
|
18
18
|
* the path + body + bearer themselves and hand to `request()`. This keeps
|
|
@@ -42,7 +42,7 @@ export type HttpClientConfig = {
|
|
|
42
42
|
fetch?: typeof globalThis.fetch | undefined;
|
|
43
43
|
/** Default headers merged into every request. */
|
|
44
44
|
defaultHeaders?: Record<string, string> | undefined;
|
|
45
|
-
/** Retry config
|
|
45
|
+
/** Retry config; idempotent methods only (GET/HEAD/OPTIONS/DELETE) — applied when transport fails or upstream returns 502/503/504/429. */
|
|
46
46
|
retryConfig?: RetryConfig | undefined;
|
|
47
47
|
};
|
|
48
48
|
|
|
@@ -176,7 +176,7 @@ export async function requestOnce<T>(
|
|
|
176
176
|
* `Response` on 2xx (caller consumes `response.body` as an SSE / chunked
|
|
177
177
|
* stream); throws `KError` on non-2xx, transport failures, or a missing
|
|
178
178
|
* body. Used by streaming surfaces — `client.compute.llms.invokeStream`
|
|
179
|
-
*
|
|
179
|
+
* + `client.realtime.subscribe` SSE transport.
|
|
180
180
|
*
|
|
181
181
|
* Unlike `request()`, this does NOT unwrap the JSON envelope or apply
|
|
182
182
|
* retry — streaming responses are consumed incrementally and retry on a
|