@getorrery/client 0.0.0-stage → 0.2.2
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 +38 -2
- package/dist/anim.d.ts +23 -0
- package/dist/channel.d.ts +24 -0
- package/dist/chunk-P3UGNLD6.js +135 -0
- package/dist/chunk-RQUTHT7N.js +1551 -0
- package/dist/cloud-events.d.ts +94 -0
- package/dist/cloud-events.js +14 -0
- package/dist/conformance-node.d.ts +11 -0
- package/dist/conformance.d.ts +58 -0
- package/dist/events.d.ts +173 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +112 -0
- package/dist/kept.d.ts +82 -0
- package/dist/node.d.ts +11 -0
- package/dist/node.js +175 -0
- package/dist/session.d.ts +210 -0
- package/dist/store.d.ts +277 -0
- package/dist/transport-http.d.ts +37 -0
- package/dist/transport-ws.d.ts +68 -0
- package/dist/transport.d.ts +138 -0
- package/dist/workspace.d.ts +66 -0
- package/package.json +56 -3
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orrery Cloud's event stream (platform decision 0024, plan 14 "Events"):
|
|
3
|
+
* `GET /api/v1/events` as Server-Sent Events, account-scoped. Each event names
|
|
4
|
+
* what changed (ids and a version, never content); a client re-reads it
|
|
5
|
+
* through the routes it already uses. `reset` means refresh everything.
|
|
6
|
+
*
|
|
7
|
+
* - [`SseParser`]: `text/event-stream` text in, events out, chunk by chunk
|
|
8
|
+
* (the ADE feeds it what its Rust side reads; a browser feeds it `fetch`'s body).
|
|
9
|
+
* - [`cloudEvents`]: the `fetch`-streaming client (headers, so not `EventSource`):
|
|
10
|
+
* the token in `Authorization`, never the query, and `Last-Event-ID` to resume.
|
|
11
|
+
* - [`backoffMs`]: the reconnect delay, 1 s doubling to 30 s.
|
|
12
|
+
*
|
|
13
|
+
* Browser-safe: `fetch`, `ReadableStream` and `TextDecoder` only.
|
|
14
|
+
*/
|
|
15
|
+
/** One server-sent event. `event` is `message` when the block named none. */
|
|
16
|
+
export interface SseEvent {
|
|
17
|
+
id?: string;
|
|
18
|
+
event: string;
|
|
19
|
+
data: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* An incremental `text/event-stream` parser (the WHATWG rules that matter
|
|
23
|
+
* here): `\n`, `\r\n` or `\r` end a line, a blank line ends an event, `:` lines
|
|
24
|
+
* are comments (Cloud's `: ping`), `data:` lines join with `\n`, `id:` is kept
|
|
25
|
+
* as [`lastEventId`] for the reconnect.
|
|
26
|
+
*/
|
|
27
|
+
export declare class SseParser {
|
|
28
|
+
/** The last `id:` seen: what `Last-Event-ID` sends back. */
|
|
29
|
+
lastEventId: string | undefined;
|
|
30
|
+
private buffer;
|
|
31
|
+
private event;
|
|
32
|
+
private data;
|
|
33
|
+
private id;
|
|
34
|
+
/** Feed text; get the events it completed. */
|
|
35
|
+
push(text: string): SseEvent[];
|
|
36
|
+
private line;
|
|
37
|
+
}
|
|
38
|
+
/** What a Cloud event names (plan 14 "Events"). Unknown kinds are dropped by [`cloudEventOf`]. */
|
|
39
|
+
export type CloudEvent = {
|
|
40
|
+
kind: "machine";
|
|
41
|
+
machine_id: string;
|
|
42
|
+
host_id?: string;
|
|
43
|
+
version?: number;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "host";
|
|
46
|
+
host_id: string;
|
|
47
|
+
version?: number;
|
|
48
|
+
} | {
|
|
49
|
+
kind: "session";
|
|
50
|
+
session_id: string;
|
|
51
|
+
machine_id: string;
|
|
52
|
+
change: "started" | "state" | "title" | "ended" | "deleted" | string;
|
|
53
|
+
version?: number;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "lease";
|
|
56
|
+
session_id: string;
|
|
57
|
+
machine_id: string;
|
|
58
|
+
epoch: number;
|
|
59
|
+
handoff_id?: string;
|
|
60
|
+
version?: number;
|
|
61
|
+
} | {
|
|
62
|
+
kind: "config";
|
|
63
|
+
keys: string[];
|
|
64
|
+
machine_id?: string;
|
|
65
|
+
version?: number;
|
|
66
|
+
} | {
|
|
67
|
+
kind: "reset";
|
|
68
|
+
};
|
|
69
|
+
/** An SSE event as a [`CloudEvent`], or `null` for a kind or body this client does not know. */
|
|
70
|
+
export declare function cloudEventOf(e: SseEvent): CloudEvent | null;
|
|
71
|
+
/** The wait before reconnect attempt `attempt` (0-based): 1 s, 2 s, 4 s … at most 30 s. */
|
|
72
|
+
export declare function backoffMs(attempt: number, firstMs?: number, maxMs?: number): number;
|
|
73
|
+
/** `GET /events` refused: `status` 401 means sign in again. */
|
|
74
|
+
export declare class CloudEventsError extends Error {
|
|
75
|
+
readonly status: number;
|
|
76
|
+
constructor(message: string, status: number);
|
|
77
|
+
}
|
|
78
|
+
export interface CloudEventsOptions {
|
|
79
|
+
/** `https://cloud/api/v1/events`. */
|
|
80
|
+
url: string;
|
|
81
|
+
/** A person or client token: sent as `Authorization: Bearer`. */
|
|
82
|
+
token: string;
|
|
83
|
+
/** Resume after this event (`Last-Event-ID`). */
|
|
84
|
+
lastEventId?: string;
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
/** `fetch` (the global one when absent). */
|
|
87
|
+
fetch?: typeof fetch;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Read Cloud's event stream until it ends, the signal aborts, or it breaks
|
|
91
|
+
* (thrown). Every event carries the `id` to resume from. A refusal throws a
|
|
92
|
+
* [`CloudEventsError`] with the status.
|
|
93
|
+
*/
|
|
94
|
+
export declare function cloudEvents(options: CloudEventsOptions): AsyncGenerator<SseEvent>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fixture runner's disk half: Node only, exported from `@getorrery/client/node`.
|
|
3
|
+
*/
|
|
4
|
+
import { type Scenario } from "./conformance.js";
|
|
5
|
+
export * from "./conformance.js";
|
|
6
|
+
/** Where the fixtures live, relative to this package. */
|
|
7
|
+
export declare function fixturesDir(): string;
|
|
8
|
+
/** Load one scenario file. Throws naming the file and the line. */
|
|
9
|
+
export declare function load(path: string): Scenario;
|
|
10
|
+
/** Load every `*.jsonl` scenario in a directory, sorted by name. */
|
|
11
|
+
export declare function loadAll(dir?: string): Scenario[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fixture runner, shared by every TypeScript client.
|
|
3
|
+
*
|
|
4
|
+
* Browser-safe: this half parses a scenario from its text and replays it.
|
|
5
|
+
* Reading the fixtures from disk (`load`, `loadAll`, `fixturesDir`) is in
|
|
6
|
+
* `@getorrery/client/node`; a browser bundles the files' text instead.
|
|
7
|
+
*
|
|
8
|
+
* `sdk-ts` runs these and so does Ink (plan 09c). The **same files** the Rust
|
|
9
|
+
* SDK runs: a scenario only one language checks is a scenario that has stopped
|
|
10
|
+
* being a contract.
|
|
11
|
+
*/
|
|
12
|
+
import { type Frame } from "./events.js";
|
|
13
|
+
import { type StoreState, SurfaceStore } from "./store.js";
|
|
14
|
+
/** One line of a scenario. */
|
|
15
|
+
export type Step = {
|
|
16
|
+
kind: "event";
|
|
17
|
+
frame: Frame;
|
|
18
|
+
}
|
|
19
|
+
/** A frame this build cannot even parse. It still consumes its `seq`. */
|
|
20
|
+
| {
|
|
21
|
+
kind: "unknown";
|
|
22
|
+
seq: number;
|
|
23
|
+
what: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "expect";
|
|
26
|
+
state: StoreState;
|
|
27
|
+
};
|
|
28
|
+
/** One fixture file. */
|
|
29
|
+
export interface Scenario {
|
|
30
|
+
name: string;
|
|
31
|
+
path: string;
|
|
32
|
+
steps: Step[];
|
|
33
|
+
}
|
|
34
|
+
/** Parse one scenario from its text. Throws naming the file and the line. */
|
|
35
|
+
export declare function parse(text: string, name: string, path?: string): Scenario;
|
|
36
|
+
/** The frames of a scenario, in order: what a fixture-backed fake connection plays. */
|
|
37
|
+
export declare function framesOf(scenario: Scenario): Frame[];
|
|
38
|
+
/**
|
|
39
|
+
* How many scenarios there are — the whole set, exactly.
|
|
40
|
+
*
|
|
41
|
+
* The twin of `orrery_client::conformance::SCENARIO_COUNT`. Every client
|
|
42
|
+
* asserts this number rather than a floor of its own; two floors is how
|
|
43
|
+
* fixtures get deleted and only one suite notices.
|
|
44
|
+
*
|
|
45
|
+
* It counts the `*.jsonl` files in `clients/conformance` and nothing below it:
|
|
46
|
+
* `conformance/streams/` holds `ModelEvent` scripts for the fixture provider,
|
|
47
|
+
* not AG-UI scenarios for a renderer, and `loadAll` is deliberately not
|
|
48
|
+
* recursive.
|
|
49
|
+
*/
|
|
50
|
+
export declare const SCENARIO_COUNT = 68;
|
|
51
|
+
/** Every checkpoint in a scenario, with the store as it stood at each. */
|
|
52
|
+
export declare function checkpoints(scenario: Scenario): Array<{
|
|
53
|
+
index: number;
|
|
54
|
+
actual: StoreState;
|
|
55
|
+
expected: StoreState;
|
|
56
|
+
}>;
|
|
57
|
+
/** Replay a scenario and hand back the store it produced. */
|
|
58
|
+
export declare function replay(scenario: Scenario): SurfaceStore;
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The AG-UI events this client understands, and the frame that carries our seq.
|
|
3
|
+
*
|
|
4
|
+
* The tags come from `@ag-ui/core`'s own `EventType`, not from a list retyped
|
|
5
|
+
* here: that is what makes "an existing AG-UI client works unmodified" checkable
|
|
6
|
+
* rather than asserted. The surface half comes from `@getorrery/protocol`, which is
|
|
7
|
+
* generated from `orrery-proto`. Nothing in this file is a hand-written frame
|
|
8
|
+
* type.
|
|
9
|
+
*/
|
|
10
|
+
import { EventType } from "@ag-ui/core";
|
|
11
|
+
import type { Outcome, SurfaceKind } from "@getorrery/protocol";
|
|
12
|
+
/** The `Custom` name a consent prompt rides under. */
|
|
13
|
+
export declare const CONSENT_REQUEST = "orrery.consent.request";
|
|
14
|
+
/** The `Custom` name a consent resolution rides under. */
|
|
15
|
+
export declare const CONSENT_RESOLVED = "orrery.consent.resolved";
|
|
16
|
+
/** The `Custom` name a turn's cancellation rides under. */
|
|
17
|
+
export declare const TURN_CANCELLED = "orrery.turn.cancelled";
|
|
18
|
+
/**
|
|
19
|
+
* The `Custom` name a placement rides under (decisions 0086, 0088): the
|
|
20
|
+
* `Placed` fields, its `surface`, and `text`, its text form, for a client that
|
|
21
|
+
* draws no panes. The store does not keep it; the UI document holds the same.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PLACED = "orrery.placed";
|
|
24
|
+
/** The `Custom` name a placement's removal rides under: `{id, owner}`. */
|
|
25
|
+
export declare const UNPLACED = "orrery.unplaced";
|
|
26
|
+
/**
|
|
27
|
+
* One RFC 6902 op, and nothing else (harness decision 0072): a stock AG-UI
|
|
28
|
+
* client drops a delta holding an op it does not know. Streamed text is an
|
|
29
|
+
* `add` onto `…/kind/chunks`, which the store folds into `kind.value`.
|
|
30
|
+
*/
|
|
31
|
+
export type PatchOp = {
|
|
32
|
+
op: "replace";
|
|
33
|
+
path: string;
|
|
34
|
+
value: unknown;
|
|
35
|
+
} | {
|
|
36
|
+
op: "add";
|
|
37
|
+
path: string;
|
|
38
|
+
value: unknown;
|
|
39
|
+
} | {
|
|
40
|
+
op: "remove";
|
|
41
|
+
path: string;
|
|
42
|
+
};
|
|
43
|
+
/** An AG-UI event, as `orrery-agui` encodes it. */
|
|
44
|
+
export type AguiEvent = {
|
|
45
|
+
type: typeof EventType.RUN_STARTED;
|
|
46
|
+
threadId: string;
|
|
47
|
+
runId: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: typeof EventType.RUN_FINISHED;
|
|
50
|
+
threadId: string;
|
|
51
|
+
runId: string;
|
|
52
|
+
result?: unknown;
|
|
53
|
+
outcome?: {
|
|
54
|
+
type: string;
|
|
55
|
+
};
|
|
56
|
+
usage?: unknown[];
|
|
57
|
+
} | {
|
|
58
|
+
type: typeof EventType.RUN_ERROR;
|
|
59
|
+
message: string;
|
|
60
|
+
code?: string | null;
|
|
61
|
+
result?: unknown;
|
|
62
|
+
usage?: unknown[];
|
|
63
|
+
} | {
|
|
64
|
+
type: typeof EventType.STEP_STARTED;
|
|
65
|
+
stepName: string;
|
|
66
|
+
} | {
|
|
67
|
+
type: typeof EventType.STEP_FINISHED;
|
|
68
|
+
stepName: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: typeof EventType.TEXT_MESSAGE_START;
|
|
71
|
+
messageId: string;
|
|
72
|
+
role: string;
|
|
73
|
+
/** The extension segment this message belongs to (decision 0076 §3). */
|
|
74
|
+
subagentRunId?: string;
|
|
75
|
+
} | {
|
|
76
|
+
type: typeof EventType.TEXT_MESSAGE_CONTENT;
|
|
77
|
+
messageId: string;
|
|
78
|
+
delta: string;
|
|
79
|
+
} | {
|
|
80
|
+
type: typeof EventType.TEXT_MESSAGE_END;
|
|
81
|
+
messageId: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: typeof EventType.TOOL_CALL_START;
|
|
84
|
+
toolCallId: string;
|
|
85
|
+
toolCallName: string;
|
|
86
|
+
parentMessageId?: string;
|
|
87
|
+
subagentRunId?: string;
|
|
88
|
+
} | {
|
|
89
|
+
type: typeof EventType.TOOL_CALL_ARGS;
|
|
90
|
+
toolCallId: string;
|
|
91
|
+
delta: string;
|
|
92
|
+
} | {
|
|
93
|
+
type: typeof EventType.TOOL_CALL_END;
|
|
94
|
+
toolCallId: string;
|
|
95
|
+
} | {
|
|
96
|
+
type: typeof EventType.TOOL_CALL_RESULT;
|
|
97
|
+
messageId: string;
|
|
98
|
+
toolCallId: string;
|
|
99
|
+
content: string;
|
|
100
|
+
outcome?: Outcome;
|
|
101
|
+
} | {
|
|
102
|
+
type: typeof EventType.REASONING_START;
|
|
103
|
+
messageId: string;
|
|
104
|
+
timestamp?: number;
|
|
105
|
+
} | {
|
|
106
|
+
type: typeof EventType.REASONING_MESSAGE_START;
|
|
107
|
+
messageId: string;
|
|
108
|
+
role: string;
|
|
109
|
+
} | {
|
|
110
|
+
type: typeof EventType.REASONING_MESSAGE_CONTENT;
|
|
111
|
+
messageId: string;
|
|
112
|
+
delta: string;
|
|
113
|
+
} | {
|
|
114
|
+
type: typeof EventType.REASONING_MESSAGE_END;
|
|
115
|
+
messageId: string;
|
|
116
|
+
} | {
|
|
117
|
+
type: typeof EventType.REASONING_END;
|
|
118
|
+
messageId: string;
|
|
119
|
+
timestamp?: number;
|
|
120
|
+
} | {
|
|
121
|
+
type: typeof EventType.SUBAGENT_STARTED;
|
|
122
|
+
subagentRunId: string;
|
|
123
|
+
/** `<ext>.model` or `<ext>.agent`. */
|
|
124
|
+
name: string;
|
|
125
|
+
description?: string;
|
|
126
|
+
parentToolCallId?: string;
|
|
127
|
+
} | {
|
|
128
|
+
type: typeof EventType.SUBAGENT_FINISHED;
|
|
129
|
+
subagentRunId: string;
|
|
130
|
+
result?: unknown;
|
|
131
|
+
outcome?: {
|
|
132
|
+
type: string;
|
|
133
|
+
};
|
|
134
|
+
} | {
|
|
135
|
+
type: typeof EventType.SUBAGENT_ERROR;
|
|
136
|
+
subagentRunId: string;
|
|
137
|
+
message: string;
|
|
138
|
+
code?: string | null;
|
|
139
|
+
} | {
|
|
140
|
+
type: typeof EventType.STATE_SNAPSHOT;
|
|
141
|
+
snapshot: unknown;
|
|
142
|
+
} | {
|
|
143
|
+
type: typeof EventType.STATE_DELTA;
|
|
144
|
+
delta: PatchOp[];
|
|
145
|
+
} | {
|
|
146
|
+
type: typeof EventType.CUSTOM;
|
|
147
|
+
name: string;
|
|
148
|
+
value: Record<string, unknown>;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* An AG-UI event with our `seq` on it.
|
|
152
|
+
*
|
|
153
|
+
* `seq` is assigned once, per session, at the differ's output — never per
|
|
154
|
+
* connection — so it is on the frame rather than implied by the order a socket
|
|
155
|
+
* happened to deliver things in. `mergedFrom` is the first seq a coalesced
|
|
156
|
+
* frame stands for, without which a merge and a lost frame look the same.
|
|
157
|
+
*/
|
|
158
|
+
export type Frame = AguiEvent & {
|
|
159
|
+
seq: number;
|
|
160
|
+
merged_from?: number;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* A frame as it arrives, made a [`Frame`]: Orrery's extras ride in AG-UI's
|
|
164
|
+
* `metadata.orrery` on the wire (`seq`, `merged_from`, a tool result's
|
|
165
|
+
* `outcome`, a failed run's `result`) and sit beside the event here. A frame
|
|
166
|
+
* recorded with them beside the event already passes through. `null` when it
|
|
167
|
+
* carries no `seq`, so is not a frame.
|
|
168
|
+
*/
|
|
169
|
+
export declare function frameOf(raw: unknown): Frame | null;
|
|
170
|
+
/** The first sequence number a frame accounts for. */
|
|
171
|
+
export declare function firstSeq(frame: Frame): number;
|
|
172
|
+
/** A surface kind we can still name after a patch has been applied to it. */
|
|
173
|
+
export type Kind = SurfaceKind;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@getorrery/client` — an AG-UI session and a `SurfaceStore`. Pure data, no drawing.
|
|
3
|
+
*
|
|
4
|
+
* The same two types as `clients/sdk-rs`, against the same conformance fixtures.
|
|
5
|
+
* The session half sits on stock `@ag-ui/client`, which is what makes "existing
|
|
6
|
+
* AG-UI clients work unmodified" a thing this repo checks rather than claims.
|
|
7
|
+
*
|
|
8
|
+
* ## Browser-safe
|
|
9
|
+
*
|
|
10
|
+
* This entry imports nothing from `node:` (checked by `test/entry.test.ts`), so
|
|
11
|
+
* a web page, the ADE's webview and a phone bundle it as is. What needs Node —
|
|
12
|
+
* the `orrery-client/1` channel over `ORRERY_ENDPOINT`, and reading the
|
|
13
|
+
* conformance fixtures from disk — is `@getorrery/client/node`.
|
|
14
|
+
*
|
|
15
|
+
* ## Transports
|
|
16
|
+
*
|
|
17
|
+
* `AguiSession` runs over a [`Transport`]: HTTP + SSE (`orrery serve` today)
|
|
18
|
+
* or WebSocket (the node's listener and the relay, one frame per message).
|
|
19
|
+
*
|
|
20
|
+
* ## A client never writes state
|
|
21
|
+
*
|
|
22
|
+
* AG-UI's shared state is bidirectional by design; ours is not. `StateSnapshot`
|
|
23
|
+
* and `StateDelta` flow outward only, and an edit a person makes arrives back as
|
|
24
|
+
* an `intent` the kernel validates. Anyone porting a component that expects to
|
|
25
|
+
* write state directly needs to know that.
|
|
26
|
+
*
|
|
27
|
+
* Implementation plan: `harness/docs/plans/08-protocol-transport.md`
|
|
28
|
+
*/
|
|
29
|
+
export * from "./events.js";
|
|
30
|
+
export * from "./anim.js";
|
|
31
|
+
export * from "./store.js";
|
|
32
|
+
export * from "./transport.js";
|
|
33
|
+
export { HttpSseTransport, type HttpTransportOptions, sse } from "./transport-http.js";
|
|
34
|
+
export { WebSocketTransport, type WebSocketCtor, type WebSocketLike, type WebSocketTransportOptions, } from "./transport-ws.js";
|
|
35
|
+
export * from "./session.js";
|
|
36
|
+
export * from "./workspace.js";
|
|
37
|
+
export * from "./kept.js";
|
|
38
|
+
export * from "./cloud-events.js";
|
|
39
|
+
export * as conformance from "./conformance.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGUI_PROTOCOL_VERSION,
|
|
3
|
+
ANIM,
|
|
4
|
+
AguiSession,
|
|
5
|
+
CONSENT_REQUEST,
|
|
6
|
+
CONSENT_RESOLVED,
|
|
7
|
+
ControlError,
|
|
8
|
+
DETACHED_TURN,
|
|
9
|
+
FrameHub,
|
|
10
|
+
HttpSseTransport,
|
|
11
|
+
MAX_FILE_BYTES,
|
|
12
|
+
MAX_MESSAGE_BYTES,
|
|
13
|
+
MOVED,
|
|
14
|
+
NOTICES,
|
|
15
|
+
OUT_OF_ORDER,
|
|
16
|
+
PLACED,
|
|
17
|
+
SESSION_CHANGES,
|
|
18
|
+
STATE_CHANGED,
|
|
19
|
+
SurfaceStore,
|
|
20
|
+
TURN_CANCELLED,
|
|
21
|
+
UNPLACED,
|
|
22
|
+
USER_MESSAGE,
|
|
23
|
+
WORKSPACE_COMMIT,
|
|
24
|
+
WORKSPACE_PUSH,
|
|
25
|
+
WORKSPACE_READ,
|
|
26
|
+
WORKSPACE_READ_CAP_BYTES,
|
|
27
|
+
WebSocketTransport,
|
|
28
|
+
afterOf,
|
|
29
|
+
choosingLine,
|
|
30
|
+
conformance_exports,
|
|
31
|
+
filePart,
|
|
32
|
+
firstSeq,
|
|
33
|
+
formatAddress,
|
|
34
|
+
frameOf,
|
|
35
|
+
framesOf,
|
|
36
|
+
keptTranscript,
|
|
37
|
+
movedOf,
|
|
38
|
+
parseAddress,
|
|
39
|
+
parseAnim,
|
|
40
|
+
parseEndpoint,
|
|
41
|
+
readKept,
|
|
42
|
+
resumeFrom,
|
|
43
|
+
sse,
|
|
44
|
+
thoughtMs,
|
|
45
|
+
workspaceCommit,
|
|
46
|
+
workspaceErrorCode,
|
|
47
|
+
workspacePush,
|
|
48
|
+
workspaceRead,
|
|
49
|
+
workspaceRequest
|
|
50
|
+
} from "./chunk-RQUTHT7N.js";
|
|
51
|
+
import {
|
|
52
|
+
CloudEventsError,
|
|
53
|
+
SseParser,
|
|
54
|
+
backoffMs,
|
|
55
|
+
cloudEventOf,
|
|
56
|
+
cloudEvents
|
|
57
|
+
} from "./chunk-P3UGNLD6.js";
|
|
58
|
+
export {
|
|
59
|
+
AGUI_PROTOCOL_VERSION,
|
|
60
|
+
ANIM,
|
|
61
|
+
AguiSession,
|
|
62
|
+
CONSENT_REQUEST,
|
|
63
|
+
CONSENT_RESOLVED,
|
|
64
|
+
CloudEventsError,
|
|
65
|
+
ControlError,
|
|
66
|
+
DETACHED_TURN,
|
|
67
|
+
FrameHub,
|
|
68
|
+
HttpSseTransport,
|
|
69
|
+
MAX_FILE_BYTES,
|
|
70
|
+
MAX_MESSAGE_BYTES,
|
|
71
|
+
MOVED,
|
|
72
|
+
NOTICES,
|
|
73
|
+
OUT_OF_ORDER,
|
|
74
|
+
PLACED,
|
|
75
|
+
SESSION_CHANGES,
|
|
76
|
+
STATE_CHANGED,
|
|
77
|
+
SseParser,
|
|
78
|
+
SurfaceStore,
|
|
79
|
+
TURN_CANCELLED,
|
|
80
|
+
UNPLACED,
|
|
81
|
+
USER_MESSAGE,
|
|
82
|
+
WORKSPACE_COMMIT,
|
|
83
|
+
WORKSPACE_PUSH,
|
|
84
|
+
WORKSPACE_READ,
|
|
85
|
+
WORKSPACE_READ_CAP_BYTES,
|
|
86
|
+
WebSocketTransport,
|
|
87
|
+
afterOf,
|
|
88
|
+
backoffMs,
|
|
89
|
+
choosingLine,
|
|
90
|
+
cloudEventOf,
|
|
91
|
+
cloudEvents,
|
|
92
|
+
conformance_exports as conformance,
|
|
93
|
+
filePart,
|
|
94
|
+
firstSeq,
|
|
95
|
+
formatAddress,
|
|
96
|
+
frameOf,
|
|
97
|
+
framesOf,
|
|
98
|
+
keptTranscript,
|
|
99
|
+
movedOf,
|
|
100
|
+
parseAddress,
|
|
101
|
+
parseAnim,
|
|
102
|
+
parseEndpoint,
|
|
103
|
+
readKept,
|
|
104
|
+
resumeFrom,
|
|
105
|
+
sse,
|
|
106
|
+
thoughtMs,
|
|
107
|
+
workspaceCommit,
|
|
108
|
+
workspaceErrorCode,
|
|
109
|
+
workspacePush,
|
|
110
|
+
workspaceRead,
|
|
111
|
+
workspaceRequest
|
|
112
|
+
};
|
package/dist/kept.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A session kept in Orrery Cloud (platform decision 0013, plan 12 step 2):
|
|
3
|
+
* the client's three-part cursor, reading the kept log a page at a time, and
|
|
4
|
+
* what the log reads as while its machine is offline.
|
|
5
|
+
*
|
|
6
|
+
* The wire is `GET /api/v1/sessions/:id/log?after=<epoch>,<seq>` (plan 12,
|
|
7
|
+
* "Wire"). Pure data: the caller fetches pages, this decides what to ask for
|
|
8
|
+
* and what is new.
|
|
9
|
+
*/
|
|
10
|
+
/** Where a client is in a session's history (decision 0013 §6). */
|
|
11
|
+
export interface SessionCursor {
|
|
12
|
+
/** The lease epoch the frames were read under (Cloud's `epoch`). */
|
|
13
|
+
epoch?: number;
|
|
14
|
+
/** The last kept entry read from Cloud, `(epoch, seq)` with `epoch` above. */
|
|
15
|
+
entrySeq?: number;
|
|
16
|
+
/** The last live frame's `seq`, from the node's ring. */
|
|
17
|
+
frameSeq?: number;
|
|
18
|
+
}
|
|
19
|
+
/** One kept entry, decrypted: a row of the node's `sessions.db`. */
|
|
20
|
+
export interface KeptEntry {
|
|
21
|
+
epoch: number;
|
|
22
|
+
seq: number;
|
|
23
|
+
/** `branch`, `turn`, `entry` or `event`. */
|
|
24
|
+
kind: string;
|
|
25
|
+
/** `<kind>:<id or seq>`. */
|
|
26
|
+
key: string;
|
|
27
|
+
hash: string;
|
|
28
|
+
at: number;
|
|
29
|
+
body: unknown;
|
|
30
|
+
}
|
|
31
|
+
/** One page of `GET /sessions/:id/log`. */
|
|
32
|
+
export interface KeptPage {
|
|
33
|
+
session_id: string;
|
|
34
|
+
machine_id: string;
|
|
35
|
+
epoch: number;
|
|
36
|
+
lease: "held" | "expired";
|
|
37
|
+
entries: KeptEntry[];
|
|
38
|
+
next: {
|
|
39
|
+
epoch: number;
|
|
40
|
+
seq: number;
|
|
41
|
+
} | null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* How to (re)attach. Within one epoch, resume from the node's ring after
|
|
45
|
+
* `frameSeq`. When the epoch moved (a handoff, a node that restarted or was
|
|
46
|
+
* replaced), the frames held are partial: drop them and read the history
|
|
47
|
+
* again (decision 0013 §6).
|
|
48
|
+
*/
|
|
49
|
+
export declare function resumeFrom(cursor: SessionCursor, epoch: number | undefined): {
|
|
50
|
+
since?: number;
|
|
51
|
+
replay: boolean;
|
|
52
|
+
};
|
|
53
|
+
/** The `after=` of a cursor: `<epoch>,<entry_seq>`, or nothing to read from the start. */
|
|
54
|
+
export declare function afterOf(cursor: SessionCursor): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Read the kept log after `cursor` until `next` is null. An entry already in
|
|
57
|
+
* `seen` (by `(epoch, seq)`) is skipped, so pages, polls and a re-read never
|
|
58
|
+
* draw one twice. Returns the new entries and the cursor past them.
|
|
59
|
+
*/
|
|
60
|
+
export declare function readKept(page: (after: string | undefined) => Promise<KeptPage>, cursor: SessionCursor, seen: Set<string>): Promise<{
|
|
61
|
+
entries: KeptEntry[];
|
|
62
|
+
cursor: SessionCursor;
|
|
63
|
+
page: KeptPage | null;
|
|
64
|
+
}>;
|
|
65
|
+
/** What a kept log reads as: one item per message, reasoning or tool call. */
|
|
66
|
+
export type KeptItem = {
|
|
67
|
+
role: "user" | "assistant" | "thinking";
|
|
68
|
+
text: string;
|
|
69
|
+
key: string;
|
|
70
|
+
} | {
|
|
71
|
+
role: "tool";
|
|
72
|
+
name: string;
|
|
73
|
+
call: string;
|
|
74
|
+
ok: boolean | null;
|
|
75
|
+
key: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The transcript of kept `turn` entries, the way `orrery replay` reads the
|
|
79
|
+
* same rows: the person's words, the model's prose and reasoning, each tool
|
|
80
|
+
* call and how it settled. Runs, settings and events are not drawn.
|
|
81
|
+
*/
|
|
82
|
+
export declare function keptTranscript(entries: readonly KeptEntry[]): KeptItem[];
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@getorrery/client/node` — everything in `@getorrery/client`, plus what only runs
|
|
3
|
+
* in Node:
|
|
4
|
+
*
|
|
5
|
+
* - [`connectClient`]: `orrery-client/1` over `ORRERY_ENDPOINT` (a local pipe
|
|
6
|
+
* or stdio, through `@getorrery/ext`), for a client the host spawned;
|
|
7
|
+
* - `conformance.load` / `loadAll` / `fixturesDir`: the fixtures, from disk.
|
|
8
|
+
*/
|
|
9
|
+
export * from "./index.js";
|
|
10
|
+
export * from "./channel.js";
|
|
11
|
+
export * as conformance from "./conformance-node.js";
|