@littlebigbrain/client 0.14.0 → 0.16.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/dist/client.d.ts +46 -43
- package/dist/client.js +62 -71
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/namespaces.d.ts +79 -18
- package/dist/namespaces.js +128 -22
- package/dist/schema.d.ts +11634 -6173
- package/dist/transport.d.ts +17 -2
- package/dist/transport.js +14 -0
- package/dist/types.d.ts +21 -1
- package/dist/types.js +21 -2
- package/dist/workflows.d.ts +207 -0
- package/dist/workflows.js +518 -0
- package/package.json +1 -1
package/dist/transport.d.ts
CHANGED
|
@@ -7,8 +7,13 @@ export interface CallOptions {
|
|
|
7
7
|
maxRetries?: number;
|
|
8
8
|
/** Override the client's deadline-based retry budget (ms) for this request. */
|
|
9
9
|
retryBudgetMs?: number;
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Override retry safety classification. Read-only POST namespaces set this
|
|
12
|
+
* automatically. `true` retries a `429`, a `5xx` and a network failure;
|
|
13
|
+
* `"rate_limited"` retries only a retryable `429`, which the server returns
|
|
14
|
+
* before it runs the request.
|
|
15
|
+
*/
|
|
16
|
+
retry?: boolean | "rate_limited";
|
|
12
17
|
/** Abort the request and suppress any further retries. */
|
|
13
18
|
signal?: AbortSignal;
|
|
14
19
|
/** Additional request headers. Values override SDK defaults intentionally. */
|
|
@@ -50,6 +55,16 @@ export type Query = Record<string, QueryValue>;
|
|
|
50
55
|
export declare function sleep(ms: number): Promise<void>;
|
|
51
56
|
export declare function retryableStatus(status: number): boolean;
|
|
52
57
|
export declare function retryAllowed(method: string, idempotencyKey?: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Whether a request's retry classification covers a network failure.
|
|
60
|
+
* `"rate_limited"` does not: the request may have run on the server.
|
|
61
|
+
*/
|
|
62
|
+
export declare function retriesNetworkFailure(retry: boolean | "rate_limited"): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Whether a request's retry classification covers a retryable status.
|
|
65
|
+
* `"rate_limited"` covers only `429`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function retriesStatus(retry: boolean | "rate_limited", status: number): boolean;
|
|
53
68
|
/** Parse a Retry-After delta-seconds or HTTP-date value, capped at one minute. */
|
|
54
69
|
export declare function parseRetryAfterMs(value: string | null | undefined, nowMs?: number): number | undefined;
|
|
55
70
|
/**
|
package/dist/transport.js
CHANGED
|
@@ -69,6 +69,20 @@ export function retryAllowed(method, idempotencyKey) {
|
|
|
69
69
|
upper === "OPTIONS" ||
|
|
70
70
|
idempotencyKey !== undefined);
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Whether a request's retry classification covers a network failure.
|
|
74
|
+
* `"rate_limited"` does not: the request may have run on the server.
|
|
75
|
+
*/
|
|
76
|
+
export function retriesNetworkFailure(retry) {
|
|
77
|
+
return retry === true;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Whether a request's retry classification covers a retryable status.
|
|
81
|
+
* `"rate_limited"` covers only `429`.
|
|
82
|
+
*/
|
|
83
|
+
export function retriesStatus(retry, status) {
|
|
84
|
+
return retry === "rate_limited" ? status === 429 : retry;
|
|
85
|
+
}
|
|
72
86
|
const MAX_RETRY_AFTER_MS = 60_000;
|
|
73
87
|
/** Parse a Retry-After delta-seconds or HTTP-date value, capped at one minute. */
|
|
74
88
|
export function parseRetryAfterMs(value, nowMs = Date.now()) {
|
package/dist/types.d.ts
CHANGED
|
@@ -138,12 +138,25 @@ export interface SparqlResultsJson {
|
|
|
138
138
|
boolean?: boolean;
|
|
139
139
|
}
|
|
140
140
|
/** Parsed SPARQL results: the head vars, the ASK boolean (or null), the raw
|
|
141
|
-
* typed bindings,
|
|
141
|
+
* typed bindings, the bindings flattened to `{ variable: lexicalValue }`, and
|
|
142
|
+
* the served snapshot (or null). */
|
|
142
143
|
export interface SparqlResults {
|
|
143
144
|
vars: string[];
|
|
144
145
|
boolean: boolean | null;
|
|
145
146
|
bindings: Record<string, SparqlTerm>[];
|
|
146
147
|
rows: Record<string, string>[];
|
|
148
|
+
/**
|
|
149
|
+
* The snapshot the rows were read from, for an eventual or pinned
|
|
150
|
+
* (`as_of_commit_seq`) read: `served_at_seq` is that commit. `null` for a
|
|
151
|
+
* plain strong read.
|
|
152
|
+
*/
|
|
153
|
+
snapshot: Schemas["SnapshotView"] | null;
|
|
154
|
+
/**
|
|
155
|
+
* What the server measured for the request: timings, reads, plan counters
|
|
156
|
+
* and the join order with estimates. Present only when the request set
|
|
157
|
+
* `profile: true`.
|
|
158
|
+
*/
|
|
159
|
+
profile?: Schemas["SparqlQueryProfile"];
|
|
147
160
|
}
|
|
148
161
|
/**
|
|
149
162
|
* Parse a {@link Schemas.SparqlTextResponse} (whose `results` field carries the
|
|
@@ -151,6 +164,13 @@ export interface SparqlResults {
|
|
|
151
164
|
* `{ variable: lexicalValue }` rows — the form most callers want, so they never
|
|
152
165
|
* have to `JSON.parse` and zip `head.vars` with binding values by hand.
|
|
153
166
|
*/
|
|
167
|
+
/**
|
|
168
|
+
* Send `profile` only when it is `true`. An answer without the field is the
|
|
169
|
+
* default, and a server that predates `profile` refuses unknown body fields.
|
|
170
|
+
*/
|
|
171
|
+
export declare function profileBody<B extends {
|
|
172
|
+
profile?: boolean;
|
|
173
|
+
}>(body: B, profile?: boolean): B;
|
|
154
174
|
export declare function parseSparqlResults(response: Schemas["SparqlTextResponse"]): SparqlResults;
|
|
155
175
|
export declare function firstPatternVariable(patterns: Schemas["AnalyticTriplePattern"][]): string;
|
|
156
176
|
export declare function attributeFilter(filter: AttributeFilter, defaultVar: string): Schemas["SparqlFilter"];
|
package/dist/types.js
CHANGED
|
@@ -4,15 +4,34 @@
|
|
|
4
4
|
* `{ variable: lexicalValue }` rows — the form most callers want, so they never
|
|
5
5
|
* have to `JSON.parse` and zip `head.vars` with binding values by hand.
|
|
6
6
|
*/
|
|
7
|
+
/**
|
|
8
|
+
* Send `profile` only when it is `true`. An answer without the field is the
|
|
9
|
+
* default, and a server that predates `profile` refuses unknown body fields.
|
|
10
|
+
*/
|
|
11
|
+
export function profileBody(body, profile) {
|
|
12
|
+
const { profile: bodyProfile, ...rest } = body;
|
|
13
|
+
return (bodyProfile ?? profile) === true
|
|
14
|
+
? { ...rest, profile: true }
|
|
15
|
+
: rest;
|
|
16
|
+
}
|
|
7
17
|
export function parseSparqlResults(response) {
|
|
8
18
|
const doc = JSON.parse(response.results);
|
|
9
19
|
const vars = doc.head?.vars ?? [];
|
|
20
|
+
const snapshot = response.snapshot ?? null;
|
|
21
|
+
const profile = response.profile ? { profile: response.profile } : {};
|
|
10
22
|
if (typeof doc.boolean === "boolean") {
|
|
11
|
-
return {
|
|
23
|
+
return {
|
|
24
|
+
vars,
|
|
25
|
+
boolean: doc.boolean,
|
|
26
|
+
bindings: [],
|
|
27
|
+
rows: [],
|
|
28
|
+
snapshot,
|
|
29
|
+
...profile,
|
|
30
|
+
};
|
|
12
31
|
}
|
|
13
32
|
const bindings = doc.results?.bindings ?? [];
|
|
14
33
|
const rows = bindings.map((binding) => Object.fromEntries(Object.entries(binding).map(([name, term]) => [name, term.value])));
|
|
15
|
-
return { vars, boolean: null, bindings, rows };
|
|
34
|
+
return { vars, boolean: null, bindings, rows, snapshot, ...profile };
|
|
16
35
|
}
|
|
17
36
|
export function firstPatternVariable(patterns) {
|
|
18
37
|
for (const pattern of patterns) {
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import type { LbbClient, Schemas } from "./client.js";
|
|
2
|
+
import type { CallOptions } from "./transport.js";
|
|
3
|
+
type Turn = Schemas["WorkflowTurn"];
|
|
4
|
+
type Instance = Schemas["WorkflowInstance"];
|
|
5
|
+
/** A permanent handler/replay error; ordinary thrown errors retry up to max_attempts. */
|
|
6
|
+
export declare class WorkflowError extends Error {
|
|
7
|
+
}
|
|
8
|
+
export interface WorkflowResult<S, R = unknown, M = unknown> {
|
|
9
|
+
state: S;
|
|
10
|
+
result?: R;
|
|
11
|
+
continuation?: {
|
|
12
|
+
message: M;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface WorkflowStepOptions {
|
|
16
|
+
kind?: "step" | "model" | "tool";
|
|
17
|
+
/** Per-attempt execution limit, independent of worker lease renewal (default 5 minutes). */
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
/** Require explicit progress from the operation, independent of worker liveness. */
|
|
20
|
+
heartbeatTimeoutMs?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface WorkflowStepContext {
|
|
23
|
+
effectId: string;
|
|
24
|
+
signal: AbortSignal;
|
|
25
|
+
/** Last progress checkpoint from a previous attempt, or null. */
|
|
26
|
+
checkpoint: unknown;
|
|
27
|
+
heartbeat(details: unknown, options?: {
|
|
28
|
+
checkpoint?: unknown;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export type WorkflowSignalResult<T> = {
|
|
32
|
+
received: true;
|
|
33
|
+
value: T;
|
|
34
|
+
} | {
|
|
35
|
+
received: false;
|
|
36
|
+
value: null;
|
|
37
|
+
};
|
|
38
|
+
export interface WorkflowContext {
|
|
39
|
+
readonly signal: AbortSignal;
|
|
40
|
+
readonly workflowId: string;
|
|
41
|
+
readonly messageId: string;
|
|
42
|
+
readonly turn: number;
|
|
43
|
+
/** Sequential named effects only. Pass effectId to the external service as its idempotency key. */
|
|
44
|
+
step<T>(key: string, effect: (context: WorkflowStepContext) => Promise<T>, options?: WorkflowStepOptions): Promise<T>;
|
|
45
|
+
/** Wait without holding a worker; signals can arrive before registration. */
|
|
46
|
+
waitForSignal<T = unknown>(key: string, options: {
|
|
47
|
+
name: string;
|
|
48
|
+
timeoutMs: number;
|
|
49
|
+
}): Promise<WorkflowSignalResult<T>>;
|
|
50
|
+
/** Checkpoint and release the worker until the timer is due. */
|
|
51
|
+
sleep(key: string, milliseconds: number): Promise<void>;
|
|
52
|
+
/** Commit state and append a new message at the inbox tail in one transaction. */
|
|
53
|
+
continue<S, M>(state: S, message: M): WorkflowResult<S, never, M>;
|
|
54
|
+
}
|
|
55
|
+
interface RegisteredWorkflow {
|
|
56
|
+
name: string;
|
|
57
|
+
version: string;
|
|
58
|
+
initialState: unknown;
|
|
59
|
+
execute(ctx: WorkflowContext, state: unknown, message: unknown): Promise<WorkflowResult<unknown>>;
|
|
60
|
+
}
|
|
61
|
+
export interface WorkflowDefinition<S, M> extends RegisteredWorkflow {
|
|
62
|
+
initialState: S;
|
|
63
|
+
start(client: LbbClient, id: string, options?: {
|
|
64
|
+
leaseMs?: number;
|
|
65
|
+
maxAttempts?: number;
|
|
66
|
+
}): Promise<WorkflowHandle<M>>;
|
|
67
|
+
}
|
|
68
|
+
/** Define a version-pinned message handler. Put I/O, clock reads and randomness inside ctx.step. */
|
|
69
|
+
export declare function workflow<S, M, R = unknown>(definition: {
|
|
70
|
+
name: string;
|
|
71
|
+
version: string;
|
|
72
|
+
initialState: S;
|
|
73
|
+
onMessage(ctx: WorkflowContext, state: S, message: M): Promise<WorkflowResult<S, R, M>>;
|
|
74
|
+
}): WorkflowDefinition<S, M>;
|
|
75
|
+
export declare class WorkflowHandle<M = unknown> {
|
|
76
|
+
private readonly api;
|
|
77
|
+
readonly id: string;
|
|
78
|
+
constructor(api: WorkflowNamespace, id: string);
|
|
79
|
+
status(options?: CallOptions): Promise<Instance>;
|
|
80
|
+
/** Reuse id when retrying the same message, including after a client restart. */
|
|
81
|
+
send(message: M, options: {
|
|
82
|
+
id: string;
|
|
83
|
+
} & CallOptions): Promise<Turn>;
|
|
84
|
+
/** Deliver an approval, callback or other event to a specific run, including while it waits. */
|
|
85
|
+
signal(name: string, value: unknown, options: {
|
|
86
|
+
turn: number;
|
|
87
|
+
id: string;
|
|
88
|
+
} & CallOptions): Promise<Turn>;
|
|
89
|
+
history(options?: {
|
|
90
|
+
after?: number;
|
|
91
|
+
limit?: number;
|
|
92
|
+
} & CallOptions): Promise<{
|
|
93
|
+
next_after?: number | null;
|
|
94
|
+
turns: import("./schema.js").components["schemas"]["WorkflowTurn"][];
|
|
95
|
+
}>;
|
|
96
|
+
pause(options?: CallOptions): Promise<{
|
|
97
|
+
completed_turns: number;
|
|
98
|
+
created_at_ms: number;
|
|
99
|
+
current_turn?: null | import("./schema.js").components["schemas"]["WorkflowTurn"];
|
|
100
|
+
history_pruned_through?: number;
|
|
101
|
+
history_through: number;
|
|
102
|
+
id: string;
|
|
103
|
+
pending_messages: number;
|
|
104
|
+
sequence: number;
|
|
105
|
+
state: unknown;
|
|
106
|
+
status: import("./schema.js").components["schemas"]["WorkflowInstanceStatus"];
|
|
107
|
+
updated_at_ms: number;
|
|
108
|
+
version: string;
|
|
109
|
+
workflow_type: string;
|
|
110
|
+
}>;
|
|
111
|
+
resume(options?: CallOptions): Promise<{
|
|
112
|
+
completed_turns: number;
|
|
113
|
+
created_at_ms: number;
|
|
114
|
+
current_turn?: null | import("./schema.js").components["schemas"]["WorkflowTurn"];
|
|
115
|
+
history_pruned_through?: number;
|
|
116
|
+
history_through: number;
|
|
117
|
+
id: string;
|
|
118
|
+
pending_messages: number;
|
|
119
|
+
sequence: number;
|
|
120
|
+
state: unknown;
|
|
121
|
+
status: import("./schema.js").components["schemas"]["WorkflowInstanceStatus"];
|
|
122
|
+
updated_at_ms: number;
|
|
123
|
+
version: string;
|
|
124
|
+
workflow_type: string;
|
|
125
|
+
}>;
|
|
126
|
+
retry(turn: number, options?: CallOptions): Promise<{
|
|
127
|
+
completed_turns: number;
|
|
128
|
+
created_at_ms: number;
|
|
129
|
+
current_turn?: null | import("./schema.js").components["schemas"]["WorkflowTurn"];
|
|
130
|
+
history_pruned_through?: number;
|
|
131
|
+
history_through: number;
|
|
132
|
+
id: string;
|
|
133
|
+
pending_messages: number;
|
|
134
|
+
sequence: number;
|
|
135
|
+
state: unknown;
|
|
136
|
+
status: import("./schema.js").components["schemas"]["WorkflowInstanceStatus"];
|
|
137
|
+
updated_at_ms: number;
|
|
138
|
+
version: string;
|
|
139
|
+
workflow_type: string;
|
|
140
|
+
}>;
|
|
141
|
+
cancelTurn(turn: number, options?: CallOptions): Promise<{
|
|
142
|
+
completed_turns: number;
|
|
143
|
+
created_at_ms: number;
|
|
144
|
+
current_turn?: null | import("./schema.js").components["schemas"]["WorkflowTurn"];
|
|
145
|
+
history_pruned_through?: number;
|
|
146
|
+
history_through: number;
|
|
147
|
+
id: string;
|
|
148
|
+
pending_messages: number;
|
|
149
|
+
sequence: number;
|
|
150
|
+
state: unknown;
|
|
151
|
+
status: import("./schema.js").components["schemas"]["WorkflowInstanceStatus"];
|
|
152
|
+
updated_at_ms: number;
|
|
153
|
+
version: string;
|
|
154
|
+
workflow_type: string;
|
|
155
|
+
}>;
|
|
156
|
+
}
|
|
157
|
+
export declare class WorkflowNamespace {
|
|
158
|
+
private readonly client;
|
|
159
|
+
constructor(client: LbbClient);
|
|
160
|
+
handle<M = unknown>(id: string): WorkflowHandle<M>;
|
|
161
|
+
start<S, M>(definition: WorkflowDefinition<S, M>, id: string, options?: {
|
|
162
|
+
leaseMs?: number;
|
|
163
|
+
maxAttempts?: number;
|
|
164
|
+
}): Promise<WorkflowHandle<M>>;
|
|
165
|
+
create(request: Schemas["WorkflowInstanceCreateRequest"], options?: CallOptions): Promise<Instance>;
|
|
166
|
+
get(id: string, options?: CallOptions): Promise<Instance>;
|
|
167
|
+
list(options?: {
|
|
168
|
+
after?: string;
|
|
169
|
+
limit?: number;
|
|
170
|
+
} & CallOptions): Promise<Schemas["WorkflowInstanceListResponse"]>;
|
|
171
|
+
send(workflowId: string, message: unknown, options: {
|
|
172
|
+
id: string;
|
|
173
|
+
} & CallOptions): Promise<Turn>;
|
|
174
|
+
signal(workflowId: string, name: string, value: unknown, options: {
|
|
175
|
+
turn: number;
|
|
176
|
+
id: string;
|
|
177
|
+
} & CallOptions): Promise<Turn>;
|
|
178
|
+
history(id: string, options?: {
|
|
179
|
+
after?: number;
|
|
180
|
+
limit?: number;
|
|
181
|
+
} & CallOptions): Promise<Schemas["WorkflowTurnHistoryResponse"]>;
|
|
182
|
+
control(id: string, action: Schemas["WorkflowInstanceAction"], turn?: number, options?: CallOptions): Promise<Instance>;
|
|
183
|
+
/**
|
|
184
|
+
* Delete an instance with its turns and history. `deleted` is false when
|
|
185
|
+
* no instance had the id, or when a retry finished an earlier delete.
|
|
186
|
+
* The id can be created again once this returns.
|
|
187
|
+
*/
|
|
188
|
+
deleteInstance(id: string, options?: CallOptions): Promise<Schemas["WorkflowInstanceDeleteResponse"]>;
|
|
189
|
+
}
|
|
190
|
+
/** One turn at a time per worker; run additional worker processes for concurrency. */
|
|
191
|
+
export declare class WorkflowWorker {
|
|
192
|
+
private readonly client;
|
|
193
|
+
private readonly definitions;
|
|
194
|
+
private readonly options;
|
|
195
|
+
constructor(client: LbbClient, definitions: readonly RegisteredWorkflow[], options: {
|
|
196
|
+
worker: string;
|
|
197
|
+
});
|
|
198
|
+
run(options: {
|
|
199
|
+
signal: AbortSignal;
|
|
200
|
+
}): Promise<void>;
|
|
201
|
+
runOnce(options?: {
|
|
202
|
+
signal?: AbortSignal;
|
|
203
|
+
waitMs?: number;
|
|
204
|
+
}): Promise<boolean>;
|
|
205
|
+
private execute;
|
|
206
|
+
}
|
|
207
|
+
export {};
|