@hydraharness/harness-client-runtime 0.0.0-stage → 0.1.1-rc.7
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/LICENSE +21 -0
- package/README.md +96 -2
- package/lib/client.js +10964 -0
- package/lib/index.js +6 -0
- package/lib/invariant.js +36 -0
- package/lib/types/client/agents/scope.d.ts +35 -0
- package/lib/types/client/contract/conversation.d.ts +242 -0
- package/lib/types/client/contract/session.d.ts +97 -0
- package/lib/types/client/contract/sessions-port.d.ts +55 -0
- package/lib/types/client/contract/sessions.d.ts +164 -0
- package/lib/types/client/contract/settings-scope.d.ts +79 -0
- package/lib/types/client/contract/store.d.ts +90 -0
- package/lib/types/client/contract/workspaces.d.ts +102 -0
- package/lib/types/client/conversation/definition-registry.d.ts +30 -0
- package/lib/types/client/conversation/event-registry.d.ts +27 -0
- package/lib/types/client/conversation/view-registry.d.ts +15 -0
- package/lib/types/client/index.d.ts +128 -0
- package/lib/types/client/ordered-baseline.d.ts +12 -0
- package/lib/types/client/sessions/assistant-timing.d.ts +34 -0
- package/lib/types/client/sessions/context-provenance.d.ts +58 -0
- package/lib/types/client/sessions/conversation-assembler.d.ts +107 -0
- package/lib/types/client/sessions/conversation-context.d.ts +22 -0
- package/lib/types/client/sessions/conversation-location-index.d.ts +70 -0
- package/lib/types/client/sessions/conversation-versions.d.ts +25 -0
- package/lib/types/client/sessions/conversation.d.ts +422 -0
- package/lib/types/client/sessions/failure-display.d.ts +7 -0
- package/lib/types/client/sessions/lineage.d.ts +47 -0
- package/lib/types/client/sessions/manager.d.ts +300 -0
- package/lib/types/client/sessions/notifier.d.ts +35 -0
- package/lib/types/client/sessions/partial.d.ts +40 -0
- package/lib/types/client/sessions/pending.d.ts +55 -0
- package/lib/types/client/sessions/projection-store.d.ts +111 -0
- package/lib/types/client/sessions/provide.d.ts +79 -0
- package/lib/types/client/sessions/queue-mirror.d.ts +33 -0
- package/lib/types/client/sessions/remotes.d.ts +10 -0
- package/lib/types/client/sessions/request-inspection.d.ts +74 -0
- package/lib/types/client/sessions/service.d.ts +415 -0
- package/lib/types/client/sessions/session.d.ts +287 -0
- package/lib/types/client/sessions/steering-history.d.ts +23 -0
- package/lib/types/client/sessions/subagent-lineage.d.ts +24 -0
- package/lib/types/client/sessions/tool-call-tree.d.ts +45 -0
- package/lib/types/client/slots.d.ts +191 -0
- package/lib/types/client/time-zone.d.ts +8 -0
- package/lib/types/client/workspaces/manager.d.ts +182 -0
- package/lib/types/client/workspaces/path.d.ts +17 -0
- package/lib/types/client/workspaces/service.d.ts +179 -0
- package/lib/types/client/workspaces/workspace.d.ts +65 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +94 -3
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import type { Context } from '@hydraharness/cordis';
|
|
2
|
+
import type { AttachmentIdType, ImageAttachmentRef, VideoAttachmentRef } from '@hydraharness/harness-attachment';
|
|
3
|
+
import type { IApiClient, MessageId, MuxFrame, PromptContentPart, QueueAction, RpcId, RpcResult, SessionId, SubagentAddress } from '@hydraharness/harness-api-remotes/client';
|
|
4
|
+
import type { SessionFace } from '../contract/session.ts';
|
|
5
|
+
import type { ConversationRuntime } from './conversation-assembler.ts';
|
|
6
|
+
import type { ConversationSnapshot } from './conversation.ts';
|
|
7
|
+
import type { RemoteResult } from '@hydraharness/harness-typert-protocol';
|
|
8
|
+
import type { SessionRemotes } from './remotes.ts';
|
|
9
|
+
import { ProjectionValueStore } from './projection-store.ts';
|
|
10
|
+
/** Messages requested per history page. */
|
|
11
|
+
export declare const PAGE_MESSAGES = 50;
|
|
12
|
+
/** Manager-owned observers of a Session object's local state edges. */
|
|
13
|
+
export interface SessionOptions {
|
|
14
|
+
/** Catalog-discovered address selecting non-activating subagent transport. */
|
|
15
|
+
address?: SubagentAddress;
|
|
16
|
+
/** Whether the exact direct parent Agent was live at the latest catalog read. */
|
|
17
|
+
parentAvailable?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* First ACCEPTED prompt on a blank session (fires at most once, on the
|
|
20
|
+
* prompt RPC's success response): the manager mirrors the blank→false flip
|
|
21
|
+
* into its list row so the session surfaces without waiting for a host
|
|
22
|
+
* frame. Acceptance is the flip point because it proves the user message
|
|
23
|
+
* is in the host log; a rejected first prompt keeps the session blank
|
|
24
|
+
* (hidden, still reusable by connectWorkspace).
|
|
25
|
+
*/
|
|
26
|
+
onEngaged?(session: Session): void;
|
|
27
|
+
/**
|
|
28
|
+
* Manager-owned projection value store to adopt (frames route through the
|
|
29
|
+
* manager and values outlive instantiation); omitted, the Session owns a
|
|
30
|
+
* private store (bare object-layer construction).
|
|
31
|
+
*/
|
|
32
|
+
projections?: ProjectionValueStore;
|
|
33
|
+
/** Runtime registries used by this Session-owned Conversation assembler. */
|
|
34
|
+
conversation?: ConversationRuntime;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Owns a session's event window, derived conversation state, and observable
|
|
38
|
+
* snapshot. React bindings remain outside this data layer. Features see only
|
|
39
|
+
* the {@link SessionFace} slice (ISession verbs + the snapshot source); the
|
|
40
|
+
* remaining public members are manager/runtime entry points.
|
|
41
|
+
*/
|
|
42
|
+
export declare class Session implements SessionFace {
|
|
43
|
+
readonly sessionId: SessionId;
|
|
44
|
+
private readonly api;
|
|
45
|
+
private readonly remote;
|
|
46
|
+
private readonly options;
|
|
47
|
+
private events;
|
|
48
|
+
/** Wire views aligned with `events` by index (envelope-level annotations; undefined = no view).
|
|
49
|
+
* Kept parallel rather than merged so `events` stays the raw log slice (model-visible ⟺ logged). */
|
|
50
|
+
private views;
|
|
51
|
+
private baseSeq;
|
|
52
|
+
private versioned;
|
|
53
|
+
private hasMore;
|
|
54
|
+
private openState;
|
|
55
|
+
private openError;
|
|
56
|
+
private openPromise;
|
|
57
|
+
/** Bumped by resync to invalidate an in-flight doOpen: a reconnect must rebuild, never adopt
|
|
58
|
+
* a pre-disconnect open whose history request is already doomed. Stale doOpen
|
|
59
|
+
* passes drop all writes once the generation moves on. */
|
|
60
|
+
private openGeneration;
|
|
61
|
+
private loadingOlder;
|
|
62
|
+
private pending;
|
|
63
|
+
private pendingRev;
|
|
64
|
+
private pendingCache;
|
|
65
|
+
/** Authoritative stream-only inbox snapshot; pending work never hits history. */
|
|
66
|
+
private readonly queueMirror;
|
|
67
|
+
/** Session-owned business Context engine over the contiguous raw window. */
|
|
68
|
+
private readonly conversation;
|
|
69
|
+
private running;
|
|
70
|
+
private address;
|
|
71
|
+
private parentAvailable;
|
|
72
|
+
/**
|
|
73
|
+
* Sticky send marker, private input of the composerPhase derivation: set
|
|
74
|
+
* synchronously before prompt()'s first await, never reset — the blank →
|
|
75
|
+
* engaging edge of the phase machine (see ComposerPhase).
|
|
76
|
+
*/
|
|
77
|
+
private promptAttempted;
|
|
78
|
+
/** A first accepted prompt stays in the engaging phase until its turn is observable. */
|
|
79
|
+
private firstPromptPendingTurn;
|
|
80
|
+
/** Empty-log mirror (see ConversationSnapshot.blank); unknown bare sessions begin conservatively blank. */
|
|
81
|
+
private blankBit;
|
|
82
|
+
private removed;
|
|
83
|
+
private promptError;
|
|
84
|
+
private lastAgentError;
|
|
85
|
+
/** Live events buffered during open/resync and stitched by sequence once history lands. */
|
|
86
|
+
private liveBuffer;
|
|
87
|
+
/** Gap repair in flight; live events detour to the buffer until the tail page lands. */
|
|
88
|
+
private stitching;
|
|
89
|
+
/** subscribed.lastSeq baseline (gap detection; null when no subscribed frame arrived — degrade to the liveBuffer dedup path). */
|
|
90
|
+
private subscribedLastSeq;
|
|
91
|
+
/**
|
|
92
|
+
* Per-session projection value store (push model; see the session-projection
|
|
93
|
+
* subsystem page, docs/subsystems/session-projection.md): finished whole
|
|
94
|
+
* values computed on the host, seeded by the tail page's
|
|
95
|
+
* projections block and updated by `session/projection` frames under the
|
|
96
|
+
* one higher-seq-wins rule. Keys are read via `projections.faceOf(key)`
|
|
97
|
+
* (the useProjection resolution face); the conversation snapshot never
|
|
98
|
+
* carries projection values, and no client-side domain folding exists.
|
|
99
|
+
* Manager-owned when constructed through SessionManager (frames route and
|
|
100
|
+
* the store outlives instantiation, the title-snapshot precedent); a bare
|
|
101
|
+
* construction gets a private store.
|
|
102
|
+
*/
|
|
103
|
+
readonly projections: ProjectionValueStore;
|
|
104
|
+
private snapshotCache;
|
|
105
|
+
private readonly notifier;
|
|
106
|
+
/**
|
|
107
|
+
* Agent-scoped cordis context, bound once by SessionRuntime when it
|
|
108
|
+
* mints the scope (the client mirror of the host Agent's loopCtx). The
|
|
109
|
+
* Session dispatches its own scoped events through it; undefined means
|
|
110
|
+
* unbound (bare object-layer construction) or already pruned — both skip
|
|
111
|
+
* dispatch-dependent behavior rather than fail.
|
|
112
|
+
*/
|
|
113
|
+
private actx;
|
|
114
|
+
/**
|
|
115
|
+
* @param sessionId - Host session identity (client sessions are always Host-born).
|
|
116
|
+
* @param api - shared wire client.
|
|
117
|
+
* @param remote - generated Remote namespaces this session calls.
|
|
118
|
+
* @param options - optional manager-owned state observers.
|
|
119
|
+
*/
|
|
120
|
+
constructor(sessionId: SessionId, api: IApiClient, remote: SessionRemotes, options?: SessionOptions);
|
|
121
|
+
/**
|
|
122
|
+
* Bind the Agent-scoped context minted by SessionRuntime (single write;
|
|
123
|
+
* a second bind is a wiring error and throws). Direction stays one-way at
|
|
124
|
+
* this binding boundary: consumers still reach the Session via `sessions.sessionOf`,
|
|
125
|
+
* while the Session holds its own dispatch point (host Agent.loopCtx
|
|
126
|
+
* mirror).
|
|
127
|
+
* @param actx - the agent's scoped context.
|
|
128
|
+
*/
|
|
129
|
+
bindScope(actx: Context): void;
|
|
130
|
+
/** Release the bound scope at prune time (a later rebind accompanies a freshly minted scope). */
|
|
131
|
+
unbindScope(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Send (queue/steer passed through 1:1); failures land in the snapshot's promptError.
|
|
134
|
+
* @param content - text plus browser-owned temporary image uploads.
|
|
135
|
+
* @param mode - queue appends after the current turn; steer interrupts it.
|
|
136
|
+
* @returns the prompt result (also mirrored into promptError on failure).
|
|
137
|
+
*/
|
|
138
|
+
prompt(content: PromptContentPart[], mode: 'queue' | 'steer', signal?: AbortSignal): Promise<RpcResult<{
|
|
139
|
+
accepted: true;
|
|
140
|
+
}>>;
|
|
141
|
+
/**
|
|
142
|
+
* Resolve image or video bytes referenced by this session.
|
|
143
|
+
* @param attachmentId - opaque id found in the folded session log.
|
|
144
|
+
* @returns the authenticated reference and decoded bytes.
|
|
145
|
+
*/
|
|
146
|
+
readAttachment(attachmentId: AttachmentIdType): Promise<RpcResult<{
|
|
147
|
+
attachment: ImageAttachmentRef | VideoAttachmentRef;
|
|
148
|
+
data: Uint8Array;
|
|
149
|
+
}>>;
|
|
150
|
+
/** Apply one operation to a still-pending queue occurrence. */
|
|
151
|
+
updateQueue(itemId: MessageId, action: QueueAction): Promise<RpcResult<{
|
|
152
|
+
accepted: true;
|
|
153
|
+
}>>;
|
|
154
|
+
/**
|
|
155
|
+
* Stop the active turn while the Host preserves pending inbox work; failures
|
|
156
|
+
* land in promptError (same error-strip display slot). A continuable
|
|
157
|
+
* subagent address routes through `subagent.interrupt`, whose durable
|
|
158
|
+
* parent-address authority works without a live parent Agent; a one-shot
|
|
159
|
+
* address stays uncancellable (the UI offers no stop action, so this arm is
|
|
160
|
+
* defensive).
|
|
161
|
+
* @returns the cancel result.
|
|
162
|
+
*/
|
|
163
|
+
cancel(): Promise<RpcResult<{
|
|
164
|
+
accepted: true;
|
|
165
|
+
}>>;
|
|
166
|
+
/**
|
|
167
|
+
* Rename: contract session.rename 1:1. On success settle the 'title'
|
|
168
|
+
* projection cell from the response's `{title, seq}` under the store's
|
|
169
|
+
* higher-seq-wins rule (the push frame arriving later is a no-op replay),
|
|
170
|
+
* so the list row and any useProjection('title') reader update without
|
|
171
|
+
* waiting for the mux frame.
|
|
172
|
+
* @param title - raw title text (the host normalizes acceptance).
|
|
173
|
+
* @returns the rename result (normalized accepted title + title event seq).
|
|
174
|
+
*/
|
|
175
|
+
rename(title: string): Promise<RpcResult<{
|
|
176
|
+
title: string;
|
|
177
|
+
seq: number;
|
|
178
|
+
}>>;
|
|
179
|
+
/**
|
|
180
|
+
* Execute one slash-command line against this session's agent — pure
|
|
181
|
+
* admission semantics (the host executor durably logs the lifecycle;
|
|
182
|
+
* outcomes render as flow nodes, never as a response echo).
|
|
183
|
+
* @param line - the full command line, leading slash included.
|
|
184
|
+
* @returns the admission result, or the error branch on transport failure.
|
|
185
|
+
*/
|
|
186
|
+
command(line: string): Promise<RemoteResult<{
|
|
187
|
+
matched: boolean;
|
|
188
|
+
}>>;
|
|
189
|
+
/** First open: pull the tail page (idempotent — in-flight/already-open returns the existing promise). */
|
|
190
|
+
open(): Promise<void>;
|
|
191
|
+
/** Page up: pull one earlier page with the window's first seq as beforeSeq and prepend. */
|
|
192
|
+
loadOlder(): Promise<void>;
|
|
193
|
+
/** Reconnect rebuild (manager calls this on onConnected for instances that were opened):
|
|
194
|
+
* reset the window and rerun open; pending waits for the baseline replay. Invalidates any
|
|
195
|
+
* in-flight open first — its history request rode the dead connection and must not settle
|
|
196
|
+
* the fresh generation into 'error'. */
|
|
197
|
+
resync(): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* uSES subscription entry.
|
|
200
|
+
* @param listener - change callback.
|
|
201
|
+
* @returns the unsubscribe function.
|
|
202
|
+
*/
|
|
203
|
+
subscribe(listener: () => void): () => void;
|
|
204
|
+
/**
|
|
205
|
+
* Cached conversation snapshot (rebuilt lazily when dirty with no listeners).
|
|
206
|
+
* @returns the cached reference (stable until the next flush).
|
|
207
|
+
*/
|
|
208
|
+
getSnapshot(): ConversationSnapshot;
|
|
209
|
+
/**
|
|
210
|
+
* Mux frame arrival (the dispatch switch).
|
|
211
|
+
* @param rpcId - the frame envelope id (the respond backfill key for requested frames).
|
|
212
|
+
* @param frame - the routed frame.
|
|
213
|
+
*/
|
|
214
|
+
handleMuxEnvelope(rpcId: RpcId, frame: MuxFrame): void;
|
|
215
|
+
/**
|
|
216
|
+
* Running-bit relay from the host stream (list entry and snapshot stay consistent).
|
|
217
|
+
* @param running - the new running state.
|
|
218
|
+
*/
|
|
219
|
+
handleRunning(running: boolean): void;
|
|
220
|
+
/**
|
|
221
|
+
* Install or clear the catalog-discovered transport address. A changed
|
|
222
|
+
* address rebuilds an already-open window through its new history route.
|
|
223
|
+
* @param address - direct parent/child address, or undefined for ordinary transport.
|
|
224
|
+
* @param parentAvailable - latest exact-parent availability hint.
|
|
225
|
+
*/
|
|
226
|
+
configureSubagent(address: SubagentAddress | undefined, parentAvailable?: boolean): void;
|
|
227
|
+
/**
|
|
228
|
+
* Update only the parent availability hint from a catalog refresh.
|
|
229
|
+
* @param available - whether the exact direct parent is live.
|
|
230
|
+
*/
|
|
231
|
+
handleSubagentParentAvailable(available: boolean): void;
|
|
232
|
+
/**
|
|
233
|
+
* Blank-bit relay from the authoritative summary source (list baseline and
|
|
234
|
+
* the session-added frame). Monotone: once any signal (local first send,
|
|
235
|
+
* running flip, an earlier summary) cleared it, a stale true never
|
|
236
|
+
* re-blanks.
|
|
237
|
+
* @param blank - the summary's derived empty-log bit.
|
|
238
|
+
*/
|
|
239
|
+
handleBlank(blank: boolean): void;
|
|
240
|
+
/** host/session-removed relay: flag the snapshot (instance survives — resident-instance rule). */
|
|
241
|
+
handleRemoved(): void;
|
|
242
|
+
/**
|
|
243
|
+
* host/agent-error relay: the only outlet for live failures with no turn position.
|
|
244
|
+
* @param message - the stringified error.
|
|
245
|
+
*/
|
|
246
|
+
handleAgentError(message: string): void;
|
|
247
|
+
/** No-op because session instances remain resident. */
|
|
248
|
+
dispose(): void;
|
|
249
|
+
/** Rebuild the current window after a low-frequency Definition or view registration change. */
|
|
250
|
+
rebuildConversationRegistry(): void;
|
|
251
|
+
/** Requested-frame arrival: the wait enters the pending map under its own key. */
|
|
252
|
+
private mint;
|
|
253
|
+
/** Authoritative resolved-frame settlement: mark, then drop from the pending map. */
|
|
254
|
+
private settle;
|
|
255
|
+
/** @param generation - openGeneration at launch; every await re-checks it and a stale pass
|
|
256
|
+
* drops all writes (resync superseded this open — its outcome belongs to a dead connection). */
|
|
257
|
+
private doOpen;
|
|
258
|
+
/** Install the history window + stitch the liveBuffer (seq is the sole dedup key).
|
|
259
|
+
* Stitching MUST NOT route through acceptLiveEvent: openState is still 'loading' here
|
|
260
|
+
* (doOpen flips it after install), so recursing would push every buffered event straight
|
|
261
|
+
* back into liveBuffer where nothing ever drains it — a silent drop loop.
|
|
262
|
+
* A carried projections block seeds the value store (higher seq wins, so a stale
|
|
263
|
+
* baseline cannot overwrite a newer push frame); the window events themselves are
|
|
264
|
+
* never folded — the host is the only computation site. */
|
|
265
|
+
private installWindow;
|
|
266
|
+
/** Seq-guarded append shared by stitching and the open-state live path. */
|
|
267
|
+
private appendLive;
|
|
268
|
+
/** Land a live session/event (open/repair in flight -> buffer; overlapping seq -> drop;
|
|
269
|
+
* a seq gap -> buffer + tail-page repull instead of appending a hole (a gap is an
|
|
270
|
+
* expected reconnect-window artifact, repaired by refetch). The window stays one contiguous
|
|
271
|
+
* raw range, which lets Conversation Definitions correlate every recorded event between its
|
|
272
|
+
* ends and lets a compaction checkpoint resolve its cited summary event. */
|
|
273
|
+
private acceptLiveEvent;
|
|
274
|
+
/** Route assembler cadence into the Session's existing microtask/RAF notifier. */
|
|
275
|
+
private scheduleConversation;
|
|
276
|
+
/** Resync-lite: repull the tail page and stitch the liveBuffer through the shared
|
|
277
|
+
* installWindow path. No openState transition — the UI keeps the current window (no loading
|
|
278
|
+
* flash); events arriving meanwhile detour to liveBuffer via the stitching flag. */
|
|
279
|
+
private repairGap;
|
|
280
|
+
private windowTailSeq;
|
|
281
|
+
/** A control received after the history cut requires a newer selected transcript. */
|
|
282
|
+
private currentHistory;
|
|
283
|
+
private buildSnapshot;
|
|
284
|
+
/** Select ordinary or addressed history transport from the stored browser fact. */
|
|
285
|
+
private history;
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Reconstruct durable steering identity from the event-sourced agent inbox. */
|
|
2
|
+
import type { SessionEvent } from '@hydraharness/harness-session/types';
|
|
3
|
+
/**
|
|
4
|
+
* Incrementally identifies `user/message` events claimed from the next-step
|
|
5
|
+
* inbox. The agent loop records all admitted input as `user/message`; the
|
|
6
|
+
* preceding `agent/inbox/spliced` events preserve whether it came from the
|
|
7
|
+
* queued-turn list or the next-step list.
|
|
8
|
+
*/
|
|
9
|
+
export declare class SteeringHistory {
|
|
10
|
+
private readonly inbox;
|
|
11
|
+
private readonly claimedNextStep;
|
|
12
|
+
/** Clear all replay state before rebuilding a history window. */
|
|
13
|
+
reset(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Apply one event and report whether it is a durable human steering message.
|
|
16
|
+
* @param event - next raw session event in sequence order.
|
|
17
|
+
* @returns true only for a user-origin message previously claimed from `next-step`.
|
|
18
|
+
*/
|
|
19
|
+
apply(event: SessionEvent): boolean;
|
|
20
|
+
/** Replay one host-validated inbox splice. */
|
|
21
|
+
private applySplice;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=steering-history.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure subagent-lineage aggregation over the retained session-list mirror.
|
|
3
|
+
* Ordinary forks terminate propagation so each visible session owns only its
|
|
4
|
+
* uninterrupted subagent subtree.
|
|
5
|
+
* @module @hydraharness/harness-client-runtime/client/sessions/subagent-lineage
|
|
6
|
+
*/
|
|
7
|
+
import type { SessionId } from '@hydraharness/harness-api-remotes/client';
|
|
8
|
+
import type { SessionSummary } from './service.ts';
|
|
9
|
+
/** Descendant counts projected for one possible parent session. */
|
|
10
|
+
export interface SubagentDescendantSummary {
|
|
11
|
+
/** All descendants connected through uninterrupted subagent-origin lineage. */
|
|
12
|
+
readonly count: number;
|
|
13
|
+
/** Descendants whose exact session summary is currently running. */
|
|
14
|
+
readonly runningCount: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Index every subagent descendant under each ancestor it reaches through an
|
|
18
|
+
* uninterrupted subagent-origin chain. Cycles fail soft and orphan owners
|
|
19
|
+
* remain harmless map keys until their summaries arrive.
|
|
20
|
+
* @param summaries - retained session summaries keyed by id.
|
|
21
|
+
* @returns descendant totals and running totals keyed by possible parent id.
|
|
22
|
+
*/
|
|
23
|
+
export declare function indexSubagentDescendants(summaries: Readonly<Record<SessionId, SessionSummary>>): ReadonlyMap<SessionId, SubagentDescendantSummary>;
|
|
24
|
+
//# sourceMappingURL=subagent-lineage.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { SessionEvent } from '@hydraharness/harness-session/types';
|
|
2
|
+
import type { ConversationNode, RunningToolCall } from './conversation.ts';
|
|
3
|
+
/** Fixed wire-safety ceiling for every recursive Tool call consumer. */
|
|
4
|
+
export declare const MAX_TOOL_CALL_TREE_DEPTH = 256;
|
|
5
|
+
/**
|
|
6
|
+
* Owns Code Dispatch pairing and projects its private parent index into the
|
|
7
|
+
* recursive Tool call contract exposed by conversation snapshots.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ToolCallTree {
|
|
10
|
+
private readonly childrenByParent;
|
|
11
|
+
private readonly depthByCall;
|
|
12
|
+
private readonly projectedByCall;
|
|
13
|
+
private revision;
|
|
14
|
+
private nodesCache;
|
|
15
|
+
private runningCache;
|
|
16
|
+
/** Forget all event-derived child calls before replaying a new window. */
|
|
17
|
+
reset(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Fold one event when it belongs to the Code Dispatch lifecycle.
|
|
20
|
+
* @param event - Session event from the current live or history window.
|
|
21
|
+
* @returns Whether the event was consumed as a child-call lifecycle event.
|
|
22
|
+
*/
|
|
23
|
+
apply(event: SessionEvent): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Attach recursively projected children to all settled roots in a node list.
|
|
26
|
+
* @param nodes - Cache-stable base conversation nodes.
|
|
27
|
+
* @returns The original list when no root changed, otherwise a structurally shared list.
|
|
28
|
+
*/
|
|
29
|
+
projectNodes(nodes: readonly ConversationNode[]): readonly ConversationNode[];
|
|
30
|
+
/**
|
|
31
|
+
* Attach recursively projected children to all running root calls.
|
|
32
|
+
* @param calls - Cache-stable base running calls.
|
|
33
|
+
* @returns The original list when no root changed, otherwise a structurally shared list.
|
|
34
|
+
*/
|
|
35
|
+
projectRunningCalls(calls: readonly RunningToolCall[]): readonly RunningToolCall[];
|
|
36
|
+
private projectBlock;
|
|
37
|
+
/**
|
|
38
|
+
* Accept an edge only when every recursive consumer can traverse it safely.
|
|
39
|
+
* Host-minted ids exclude cycles and current bindings emit one level; a
|
|
40
|
+
* malformed wire/history edge is consumed without hiding the rest of the session.
|
|
41
|
+
*/
|
|
42
|
+
private acceptEdge;
|
|
43
|
+
private wouldCreateCycle;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=tool-call-tree.d.ts.map
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlotRegistry: the cordis Service layer of the slot system over the pure
|
|
3
|
+
* SlotCore (ui-slots owns registration semantics, the declaration ledger,
|
|
4
|
+
* the load-time validations, and the unload cascade). This layer owns what
|
|
5
|
+
* needs the runtime: the 'slots/changed' event bridge, register and
|
|
6
|
+
* declaration injection through the caller's ctx.effect (fiber unload
|
|
7
|
+
* collects both), the renderer installation contract (install()/renderSlot('root') +
|
|
8
|
+
* the SlotRendererHost face), and the store INSTANCE axis — handle x scope
|
|
9
|
+
* key -> create/cache, dropped with the last holding entry, session instances
|
|
10
|
+
* cleared (with persisted state) on scope death.
|
|
11
|
+
*/
|
|
12
|
+
import { Service } from '@hydraharness/cordis';
|
|
13
|
+
import type { Context } from '@hydraharness/cordis';
|
|
14
|
+
import { SlotCore } from '@hydraharness/harness-client-ui-slots';
|
|
15
|
+
import type { LiveSlotNode, LocaleFace, OwnerOf, SlotMap, SlotRenderer, SlotSpec, StoredEntry } from '@hydraharness/harness-client-ui-slots';
|
|
16
|
+
declare module '@hydraharness/harness-client-ui-slots' {
|
|
17
|
+
interface SlotMap {
|
|
18
|
+
/**
|
|
19
|
+
* The built-in render-tree root hole (seeded by SlotCore): the one slot the
|
|
20
|
+
* shell itself renders, and the ancestor of every other seat. OCCUPIED by
|
|
21
|
+
* ui-layout's AppFrame, which declares the sidebar, conversation, details,
|
|
22
|
+
* and shell.overlay seats inside it.
|
|
23
|
+
*
|
|
24
|
+
* DO NOT register here. This is a single slot, so a second entry does not
|
|
25
|
+
* sit beside the frame — it shadows it, and a dynamically registered entry
|
|
26
|
+
* is assigned a lower priority than the shipped one, which makes it the
|
|
27
|
+
* winner: the page would render your component alone, with every seat the
|
|
28
|
+
* frame declares gone. For a surface of your own that floats over the whole
|
|
29
|
+
* app, register into `shell.overlay` instead (a list slot: additive, and
|
|
30
|
+
* click-through until your entry opts into pointer events).
|
|
31
|
+
*/
|
|
32
|
+
'root': {
|
|
33
|
+
kind: 'single';
|
|
34
|
+
scope: 'root';
|
|
35
|
+
owner: RootOwnerProps;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Root owner share: the shell supplies nothing — the frame is inject-assembled. */
|
|
40
|
+
export interface RootOwnerProps {
|
|
41
|
+
children?: never;
|
|
42
|
+
}
|
|
43
|
+
/** One synchronous effect installed while an injected slot declaration is live. */
|
|
44
|
+
type SlotInjectionEffect = (() => void) | Iterable<() => void, void, void>;
|
|
45
|
+
/** cordis Service layer of the slot system; see the module doc for the split with SlotCore. */
|
|
46
|
+
export declare class SlotRegistry extends Service {
|
|
47
|
+
private readonly _core;
|
|
48
|
+
/** Store-instance axis: handle -> mounted scope, refcount, resolved instances. */
|
|
49
|
+
private readonly _stores;
|
|
50
|
+
private _renderer;
|
|
51
|
+
private _locale;
|
|
52
|
+
private _host;
|
|
53
|
+
/**
|
|
54
|
+
* @param ctx - owning root context.
|
|
55
|
+
*/
|
|
56
|
+
constructor(ctx: Context);
|
|
57
|
+
/**
|
|
58
|
+
* The single registration API. The typed face IS the core's register
|
|
59
|
+
* (both overloads reused verbatim — one authority, no structural copy;
|
|
60
|
+
* see SlotCore.register for children declaration, store seat, inject
|
|
61
|
+
* face, load-time validation, and the unload cascade). This layer adds:
|
|
62
|
+
* disposal through the caller's ctx.effect (fiber unload = cascade),
|
|
63
|
+
* exclusive-factory minting (`store: createXxxStore` becomes a per-entry
|
|
64
|
+
* handle), the registrant diagnostics stamp, and store-instance lifecycle
|
|
65
|
+
* on the entry axis.
|
|
66
|
+
*
|
|
67
|
+
* Declared here, implemented by prototype assignment below the class: it
|
|
68
|
+
* MUST stay a prototype method (never an instance arrow) — the cordis
|
|
69
|
+
* service proxy binds `this.ctx` to the CALLER's context at call time,
|
|
70
|
+
* which is what routes the effect (and the unload cascade) into the
|
|
71
|
+
* caller's fiber. An arrow property would freeze `this` to the service's
|
|
72
|
+
* own root ctx and silently break per-plugin disposal.
|
|
73
|
+
*/
|
|
74
|
+
readonly register: SlotCore['register'];
|
|
75
|
+
/**
|
|
76
|
+
* Install an effect for each declaration lifetime of a slot. The callback
|
|
77
|
+
* runs synchronously when the declaration already exists; otherwise it runs
|
|
78
|
+
* inside the declaring `register()` call after the declaration is committed.
|
|
79
|
+
* Collapse disposes the effect and a later declaration runs it again.
|
|
80
|
+
* Callback effects are synchronous disposers; iterable effects install
|
|
81
|
+
* transactionally and dispose in reverse order. The controller belongs to
|
|
82
|
+
* the caller's fiber, so plugin unload cancels a pending wait and removes any
|
|
83
|
+
* active contribution.
|
|
84
|
+
*
|
|
85
|
+
* @param key - declared SlotMap key to depend on.
|
|
86
|
+
* @param callback - creates one disposer or an iterable of disposers.
|
|
87
|
+
* @returns idempotent disposer for the wait and active effect.
|
|
88
|
+
* @throws callback setup failures synchronously when the slot is already declared.
|
|
89
|
+
*/
|
|
90
|
+
inject(key: keyof SlotMap & string, callback: () => SlotInjectionEffect): () => void;
|
|
91
|
+
/**
|
|
92
|
+
* Install the shell's renderer (ui-renderer's createSlotRenderer product).
|
|
93
|
+
* Boot-once: a second install throws. Runs through the caller's ctx.effect,
|
|
94
|
+
* so shell fiber unload uninstalls the renderer.
|
|
95
|
+
* @param renderer - the outlet machinery implementing SlotRenderer.
|
|
96
|
+
*/
|
|
97
|
+
install(renderer: SlotRenderer): void;
|
|
98
|
+
/**
|
|
99
|
+
* Install the locale face backing the `t` standard seat (the locale
|
|
100
|
+
* plugin's product; same boot-once discipline as the renderer install).
|
|
101
|
+
* Runs through the caller's ctx.effect, so the installing fiber's unload
|
|
102
|
+
* uninstalls the face.
|
|
103
|
+
* @param face - namespace binder + revision observable.
|
|
104
|
+
*/
|
|
105
|
+
installLocale(face: LocaleFace): void;
|
|
106
|
+
/**
|
|
107
|
+
* The single ctx-level render entry: the shell renders 'root'; every other
|
|
108
|
+
* key renders inside components through the props renderSlot face. All
|
|
109
|
+
* three guards are fail-loud boot-order checks, no fallback.
|
|
110
|
+
* @param key - must be 'root' (runtime-enforced for dynamically composed callers).
|
|
111
|
+
* @param owner - owner share for the root entry (the shell supplies {}).
|
|
112
|
+
* @returns the rendered root tree.
|
|
113
|
+
*/
|
|
114
|
+
renderSlot<K extends keyof SlotMap & string>(key: K, owner: OwnerOf<K>): ReturnType<SlotRenderer['renderRoot']>;
|
|
115
|
+
/**
|
|
116
|
+
* Drop the per-session store instances of a dead session (the sessions
|
|
117
|
+
* service calls this on scope teardown; root-scoped records are untouched).
|
|
118
|
+
* Persisted state goes with the session — a never-rendered dead session can
|
|
119
|
+
* still own keys from an earlier page load, so the instance is materialized
|
|
120
|
+
* transiently just to clear storage (no-op for unpersisted stores).
|
|
121
|
+
* @param sessionId - the torn-down session.
|
|
122
|
+
*/
|
|
123
|
+
pruneStoreScope(sessionId: string): void;
|
|
124
|
+
/**
|
|
125
|
+
* Snapshot entries for a key (render-erased view; stable reference between mutations).
|
|
126
|
+
* @param key - SlotMap key.
|
|
127
|
+
* @returns registered entries.
|
|
128
|
+
*/
|
|
129
|
+
entries(key: keyof SlotMap & string): readonly StoredEntry[];
|
|
130
|
+
/**
|
|
131
|
+
* Shadowing winners per cell for a key: the first live (non-abdicated)
|
|
132
|
+
* entry of each cell in priority order — what outlets render; chain keys
|
|
133
|
+
* pass through unchanged (election consumes every entry). The raw
|
|
134
|
+
* {@link SlotsService.entries} view stays the inspection surface. Fresh
|
|
135
|
+
* array per call, not a uSES getSnapshot source.
|
|
136
|
+
* @param key - SlotMap key.
|
|
137
|
+
* @returns the winning entry per occupied cell.
|
|
138
|
+
*/
|
|
139
|
+
entriesOfSlot(key: keyof SlotMap & string): readonly StoredEntry[];
|
|
140
|
+
/**
|
|
141
|
+
* Export the current JSON-safe Slot declaration tree for read-only inspection.
|
|
142
|
+
* @param root - exact live Slot root; omitted returns all roots.
|
|
143
|
+
* @returns selected Slot trees.
|
|
144
|
+
*/
|
|
145
|
+
snapshot(root?: string): LiveSlotNode[];
|
|
146
|
+
/**
|
|
147
|
+
* Observe entry boundary crashes (every render-time entry failure the
|
|
148
|
+
* boundaries contain, abdicating or not) — the supervision seam for
|
|
149
|
+
* plugins mirroring contribution health. Fires synchronously per report,
|
|
150
|
+
* after the registry mutated for abdicating crashes. Callers own the
|
|
151
|
+
* disposer (wire it through ctx.effect for fiber-lifetime cleanup, as with
|
|
152
|
+
* {@link SlotsService.subscribe}).
|
|
153
|
+
* @param fn - called with the slot key, the crashed entry, the crash
|
|
154
|
+
* cause, and `abdicated`: whether the crash retired the entry from its cell.
|
|
155
|
+
* @returns unsubscribe.
|
|
156
|
+
*/
|
|
157
|
+
onEntryError(fn: (key: string, entry: StoredEntry, error: unknown, info: {
|
|
158
|
+
abdicated: boolean;
|
|
159
|
+
}) => void): () => void;
|
|
160
|
+
/**
|
|
161
|
+
* Look up a declared spec (register-declared or the built-in 'root').
|
|
162
|
+
* @param key - SlotMap key.
|
|
163
|
+
* @returns spec or undefined.
|
|
164
|
+
*/
|
|
165
|
+
spec<K extends keyof SlotMap & string>(key: K): SlotSpec<SlotMap[K]> | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Subscribe to a key's registration changes (microtask-batched).
|
|
168
|
+
* @param key - SlotMap key.
|
|
169
|
+
* @param fn - change callback.
|
|
170
|
+
* @returns unsubscribe.
|
|
171
|
+
*/
|
|
172
|
+
subscribe(key: keyof SlotMap & string, fn: () => void): () => void;
|
|
173
|
+
/**
|
|
174
|
+
* Version counter for uSES pairing.
|
|
175
|
+
* @param key - SlotMap key.
|
|
176
|
+
* @returns current version.
|
|
177
|
+
*/
|
|
178
|
+
getVersion(key: keyof SlotMap & string): number;
|
|
179
|
+
/** Delegating registration path: factory minting + registrant stamp + core write + instance-axis bookkeeping. */
|
|
180
|
+
private _register;
|
|
181
|
+
/** Build once after both object-layer services mount; per-session provide bundles still resolve lazily. */
|
|
182
|
+
private hostFace;
|
|
183
|
+
/** Resolve (create or reuse) the store instance for a registered handle under a scope key. */
|
|
184
|
+
private resolveStore;
|
|
185
|
+
/** Bind (or re-reference) a handle on the axis; cross-scope conflicts already threw in the core. */
|
|
186
|
+
private _acquire;
|
|
187
|
+
/** Drop one reference; the last holder's unload drops the record (instances go with it — engine stores need no explicit dispose). */
|
|
188
|
+
private _release;
|
|
189
|
+
}
|
|
190
|
+
export {};
|
|
191
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Browser-owned time-zone sampling for prompt RPC provenance. */
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the current browser IANA zone for one outbound operation.
|
|
4
|
+
* @returns The browser-provided canonical zone.
|
|
5
|
+
* @throws when the runtime cannot provide a non-empty zone.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolvedClientTimeZone(): string;
|
|
8
|
+
//# sourceMappingURL=time-zone.d.ts.map
|