@rynx-ai/server 0.1.11-beta.1 → 0.1.11-beta.3

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.
@@ -7,8 +7,8 @@
7
7
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
8
8
  <link rel="icon" type="image/png" href="/favicon.png" />
9
9
  <title>rynx · control</title>
10
- <script type="module" crossorigin src="/assets/index-Dlywgy58.js"></script>
11
- <link rel="stylesheet" crossorigin href="/assets/index-CnVtOmLv.css">
10
+ <script type="module" crossorigin src="/assets/index-BnX7NWJX.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-CUoWRX2i.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
@@ -1,20 +1,12 @@
1
- /**
2
- * Daemon-owned application service for the first Remote Runtime Session slice.
3
- *
4
- * This service deliberately has no HTTP, Koa, WebSocket, or Direct-binding
5
- * knowledge. Durable records, live state, events, and interruption remain owned
6
- * by the daemon process and arrive through narrow injected ports. Local and
7
- * Direct adapters can therefore expose the same behavior without copying state
8
- * into a Control Plane database.
9
- */
10
- import { type AgentRuntimeId, type AgentSpec, type ConversationRuntime, type SessionProviderId, type ReasoningEffort, type RuntimeUserInput, type SessionBus, type SessionLogStore, type SessionRegistry } from "@rynx-ai/core";
11
- import type { SequencedSessionEvent, SessionInteractionResolution, SessionItem, UserContentPart } from "@rynx-ai/protocol";
1
+ import { type AdmissionReservation, type AgentRuntimeId, type ConversationRuntime, type ResolvedExecutionSnapshot, type SessionWorkspaceSnapshot, type SessionProviderId, type MachineSessionRecord, type ReasoningEffort, type RuntimeUserInput, type SessionBus, type SessionLogStore, type SessionRegistry } from "@rynx-ai/core";
2
+ import type { SequencedSessionEvent, SessionEvent, SessionInteractionResolution, SessionItem, UserContentPart } from "@rynx-ai/protocol";
12
3
  import type { RemoteRuntimeSessionResourceDeleteParams, RemoteRuntimeSessionResourceDeleteResult, RemoteRuntimeSessionResourceGetParams, RemoteRuntimeSessionResourceGetResult, RemoteRuntimeSessionResourcePolicyResult, RemoteRuntimeSessionResourceReadParams, RemoteRuntimeSessionResourceReadResult, RemoteRuntimeSessionResourceUploadBeginParams, RemoteRuntimeSessionResourceUploadBeginResult, RemoteRuntimeSessionResourceUploadChunkParams, RemoteRuntimeSessionResourceUploadChunkResult, RemoteRuntimeSessionResourceUploadCommitParams, RemoteRuntimeSessionResourceUploadCommitResult } from "@rynx-ai/protocol/remote-runtime-rpc";
13
4
  import type { ControlAgentSummary, ControlSessionInteractionResolveDisposition, ControlSessionRuntimeSnapshot } from "@rynx-ai/protocol/control";
14
5
  import { type RemoteRuntimeSessionInterruptResult, type RemoteRuntimeSessionLaunchOptionsListResult, type RemoteRuntimeSessionListParams, type RemoteRuntimeSessionListResult, type RemoteRuntimeSessionSnapshotParams } from "@rynx-ai/protocol/remote-runtime-rpc";
15
- import { type CodexRuntimeStatus, type CodexSessionStore, type InjectOutcome } from "@rynx-ai/runtime";
6
+ import type { CodexRuntimeStatus, InjectOutcome } from "@rynx-ai/runtime";
16
7
  export interface MachineSessionRuntimeStatePort {
17
8
  snapshot(sessionId: string): ControlSessionRuntimeSnapshot;
9
+ beginResponseHandoff?(sessionId: string, responseId: string): () => void;
18
10
  remove?(sessionId: string): void;
19
11
  }
20
12
  export interface MachineSessionInterruptPort {
@@ -63,23 +55,17 @@ export interface MachineSessionResourcePort {
63
55
  }
64
56
  export interface MachineSessionRunnerPort {
65
57
  ensureLiveSession(sessionId: string, options?: {
66
- cwd?: string;
67
58
  cols?: number;
68
59
  rows?: number;
69
- runtime?: AgentRuntimeId;
70
- reasoningEffort?: ReasoningEffort;
71
- agentName?: string;
72
- agentSpec?: AgentSpec;
60
+ workspace?: SessionWorkspaceSnapshot;
61
+ execution?: ResolvedExecutionSnapshot;
73
62
  }): Promise<boolean>;
74
63
  /** Start the Provider TUI pane without waiting for its native thread to bind. */
75
64
  startLiveSession?(sessionId: string, options?: {
76
- cwd?: string;
77
65
  cols?: number;
78
66
  rows?: number;
79
- runtime?: AgentRuntimeId;
80
- reasoningEffort?: ReasoningEffort;
81
- agentName?: string;
82
- agentSpec?: AgentSpec;
67
+ workspace?: SessionWorkspaceSnapshot;
68
+ execution?: ResolvedExecutionSnapshot;
83
69
  }): Promise<boolean>;
84
70
  lastLiveSessionError?(sessionId: string): string | undefined;
85
71
  injectMessage(sessionId: string, input: RuntimeUserInput | string): Promise<InjectOutcome>;
@@ -87,15 +73,69 @@ export interface MachineSessionRunnerPort {
87
73
  resolveInteraction(sessionId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<{
88
74
  disposition: ControlSessionInteractionResolveDisposition;
89
75
  }>;
76
+ /** Internal Provider fork. RunnerManager fences both source and target before
77
+ * invoking `beforeProviderFork`, then commits the native Provider context. */
78
+ forkSession?(sourceSessionId: string, targetSessionId: string, options: {
79
+ workspace: SessionWorkspaceSnapshot;
80
+ execution: ResolvedExecutionSnapshot;
81
+ beforeProviderFork: () => Promise<void>;
82
+ }): Promise<{
83
+ ok: true;
84
+ } | {
85
+ ok: false;
86
+ message: string;
87
+ }>;
90
88
  /** Backend-free readiness probe for launch options and direct Provider creation. */
91
89
  getStatus?(options: {
92
90
  runtime: AgentRuntimeId;
93
91
  }): Promise<CodexRuntimeStatus>;
94
92
  }
93
+ export type MachineSessionForkOperationState = "reserved" | "completed" | "target_deleted";
94
+ export interface MachineSessionForkOperationRecord {
95
+ operationId: string;
96
+ requestHash: string;
97
+ sourceSessionId: string;
98
+ targetSessionId: string;
99
+ title?: string;
100
+ forkPosition?: number;
101
+ state: MachineSessionForkOperationState;
102
+ error?: string;
103
+ }
104
+ /** Durable idempotency + atomic Session/history/resource publication boundary.
105
+ * The daemon implementation owns SQLite and resource files; the application
106
+ * service never exposes a target before this port commits it. */
107
+ export interface MachineSessionForkStorePort {
108
+ claim(input: {
109
+ operationId: string;
110
+ requestHash: string;
111
+ sourceSessionId: string;
112
+ title?: string;
113
+ }): MachineSessionForkOperationRecord | Promise<MachineSessionForkOperationRecord>;
114
+ commit(input: {
115
+ operationId: string;
116
+ target: MachineSessionRecord;
117
+ items: SessionItem[];
118
+ }): void | Promise<void>;
119
+ /** Publish a fork already performed inside a live Provider TUI. Unlike
120
+ * `commit`, this has no caller-supplied idempotency operation because the
121
+ * Provider-created target Session id is itself the durable identity. */
122
+ publishNativeFork(input: {
123
+ sourceSessionId: string;
124
+ target: MachineSessionRecord;
125
+ items: SessionItem[];
126
+ }): void | Promise<void>;
127
+ markError(operationId: string, error: string): void | Promise<void>;
128
+ listReserved(): MachineSessionForkOperationRecord[] | Promise<MachineSessionForkOperationRecord[]>;
129
+ hasReservedSource(sessionId: string): boolean | Promise<boolean>;
130
+ markTargetDeleted(sessionId: string): void | Promise<void>;
131
+ }
95
132
  export interface MachineSessionServicePorts {
96
133
  registry: Pick<SessionRegistry, "create" | "get" | "list" | "setTitle" | "remove">;
97
134
  log: Pick<SessionLogStore, "list" | "listSessions" | "snapshot" | "deleteSession">;
98
135
  events: Pick<SessionBus, "subscribe"> & Partial<Pick<SessionBus, "close">>;
136
+ /** Canonical persistence + fan-out for user turns accepted before a native
137
+ * Terminal has finished starting. */
138
+ publishEvent?: (sessionId: string, event: SessionEvent) => void | Promise<void>;
99
139
  runtimeState: MachineSessionRuntimeStatePort;
100
140
  interruption: MachineSessionInterruptPort;
101
141
  /** External Session-owned resources fenced before and finalized after deletion. */
@@ -111,9 +151,23 @@ export interface MachineSessionServicePorts {
111
151
  /** Native Session execution belongs to the target daemon, never the caller. */
112
152
  execution?: {
113
153
  runtime: Pick<ConversationRuntime, "resolveRuntime">;
154
+ resolve(input: {
155
+ agent?: string;
156
+ provider?: SessionProviderId;
157
+ model?: string;
158
+ reasoningEffort?: ReasoningEffort;
159
+ cwd: string;
160
+ }): Promise<ResolvedExecutionSnapshot>;
114
161
  runner: MachineSessionRunnerPort;
115
- sessionStore?: Pick<CodexSessionStore, "get">;
116
162
  };
163
+ /** Resolve a temporary Project selection, or create a Session-only fallback directory. */
164
+ workspace?: {
165
+ resolve(projectId?: string): Promise<SessionWorkspaceSnapshot>;
166
+ /** Remove an unbound Session-only allocation after creation fails. Project
167
+ * directories are never passed to this hook. */
168
+ discardUnbound?(workspace: SessionWorkspaceSnapshot): Promise<void>;
169
+ };
170
+ forks?: MachineSessionForkStorePort;
117
171
  }
118
172
  export interface MachineSessionServiceOptions {
119
173
  /** Maximum summaries returned in one list page. */
@@ -128,6 +182,11 @@ export interface MachineSessionServiceOptions {
128
182
  directoryScanLimit?: number;
129
183
  /** Delay between setup-readiness retries for durable pending messages. */
130
184
  pendingMessageRetryMs?: number;
185
+ /** Dynamic daemon-wide admission fence used during process replacement. */
186
+ admissionOpen?: () => boolean;
187
+ /** Atomically reserves one work-producing admission until it is rejected or
188
+ * has become visible in the daemon activity projection. */
189
+ admissionReserve?: () => AdmissionReservation | undefined;
131
190
  }
132
191
  export type MachineSessionListInput = RemoteRuntimeSessionListParams;
133
192
  export interface MachineSessionListPage extends RemoteRuntimeSessionListResult {
@@ -148,6 +207,7 @@ interface MachineSessionCreateOptions {
148
207
  model?: string;
149
208
  reasoningEffort?: ReasoningEffort;
150
209
  title?: string;
210
+ projectId?: string;
151
211
  }
152
212
  export type MachineSessionCreateInput = MachineSessionCreateOptions & ({
153
213
  agent: string;
@@ -159,6 +219,20 @@ export type MachineSessionCreateInput = MachineSessionCreateOptions & ({
159
219
  export interface MachineSessionCreateResult {
160
220
  sessionId: string;
161
221
  }
222
+ export interface MachineSessionForkInput {
223
+ sourceSessionId: string;
224
+ operationId: string;
225
+ title?: string;
226
+ }
227
+ export interface MachineSessionForkResult {
228
+ sessionId: string;
229
+ disposition: "created" | "replayed";
230
+ }
231
+ export interface MachineSessionNativeRotationInput {
232
+ sourceSessionId: string;
233
+ targetSessionId: string;
234
+ kind: "clear" | "fork";
235
+ }
162
236
  export interface MachineSessionMessageResult {
163
237
  ok: true;
164
238
  injected: true;
@@ -209,8 +283,11 @@ export declare class MachineSessionService {
209
283
  private readonly snapshotPageMaxBytes;
210
284
  private readonly directoryScanLimit;
211
285
  private readonly pendingMessageRetryMs;
286
+ private readonly admissionOpen;
287
+ private readonly admissionReserve;
212
288
  private readonly pendingDeliveries;
213
289
  private readonly cancelledPendingDeliveries;
290
+ private readonly forkTasks;
214
291
  constructor(ports: MachineSessionServicePorts, options?: MachineSessionServiceOptions);
215
292
  list(input?: MachineSessionListInput): Promise<MachineSessionListPage>;
216
293
  snapshot(input: MachineSessionSnapshotInput): Promise<MachineSessionSnapshotPage>;
@@ -231,8 +308,21 @@ export declare class MachineSessionService {
231
308
  launchOptions(): Promise<RemoteRuntimeSessionLaunchOptionsListResult>;
232
309
  /** Create target-owned Session identity from one Agent preset or direct Provider. */
233
310
  create(input: MachineSessionCreateInput): Promise<MachineSessionCreateResult>;
311
+ private createAdmitted;
312
+ /** Create one independent Session at the source's stable Provider/canonical
313
+ * boundary. Project and Agent selectors are intentionally absent: the target
314
+ * receives exact copies of the source's already-frozen snapshots. */
315
+ fork(input: MachineSessionForkInput): Promise<MachineSessionForkResult>;
316
+ private forkAdmitted;
317
+ /** Publish a Provider TUI `/clear` or `/fork` after its native binding has
318
+ * already been persisted. The source snapshots remain the only workspace and
319
+ * execution authority; Provider events cannot alter them during rotation. */
320
+ recordNativeRotation(input: MachineSessionNativeRotationInput): Promise<void>;
321
+ private performFork;
322
+ private assertForkableSource;
234
323
  /** Inject one turn through the target daemon's native single-writer runner. */
235
324
  sendMessage(sessionIdInput: string, messageInput: string | MachineSessionMessageInput): Promise<MachineSessionMessageResult>;
325
+ private sendMessageAdmitted;
236
326
  resourcePolicy(sessionIdInput: string): RemoteRuntimeSessionResourcePolicyResult;
237
327
  beginResourceUpload(input: RemoteRuntimeSessionResourceUploadBeginParams): Promise<RemoteRuntimeSessionResourceUploadBeginResult>;
238
328
  writeResourceUploadChunk(input: RemoteRuntimeSessionResourceUploadChunkParams): Promise<RemoteRuntimeSessionResourceUploadChunkResult>;
@@ -244,13 +334,17 @@ export declare class MachineSessionService {
244
334
  * delivery worker starts the pane now, waits for a real native thread, then
245
335
  * injects exactly once. `failed` is fenced as outcome_unknown and never retried. */
246
336
  enqueueMessage(sessionIdInput: string, messageInput: string): Promise<MachineSessionMessageEnqueueResult>;
337
+ private enqueueMessageAdmitted;
247
338
  /** Explicitly restore the target daemon's live runner without starting a turn. */
248
339
  startTerminal(sessionIdInput: string): Promise<MachineSessionTerminalStartResult>;
340
+ private startTerminalAdmitted;
249
341
  private ensureLiveSession;
250
342
  private liveSessionRequest;
251
343
  resolveInteraction(sessionIdInput: string, interactionIdInput: string, resolution: SessionInteractionResolution): Promise<MachineSessionInteractionResult>;
252
344
  delete(sessionIdInput: string): Promise<MachineSessionDeleteResult>;
253
345
  private requireAgents;
346
+ private reserveAdmission;
347
+ private withAdmission;
254
348
  private requireResources;
255
349
  private requireResourceSession;
256
350
  private resumePendingDeliveries;
@@ -259,6 +353,10 @@ export declare class MachineSessionService {
259
353
  private runtimeReadiness;
260
354
  private probeRuntimeReadiness;
261
355
  private requireExecution;
356
+ private requireWorkspace;
357
+ private requireForks;
358
+ private assertNotForkReserved;
359
+ private resumeReservedForks;
262
360
  }
263
361
  /** One-line title derived from the first user message; no model call. */
264
362
  export declare function synthesizeSessionTitle(message: string, limit?: number): string;