@north-light/crouter 0.3.282 → 0.3.284
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/api/client.d.ts +22 -4
- package/dist/api/client.js +34 -0
- package/dist/api/dto/broker-ops.d.ts +11 -0
- package/dist/api/dto/broker.d.ts +3 -8
- package/dist/api/dto/common.d.ts +1 -1
- package/dist/api/dto/messages.d.ts +2 -2
- package/dist/api/dto/node-outcomes.d.ts +80 -0
- package/dist/api/dto/node-outcomes.js +2 -0
- package/dist/api/dto/nodes.d.ts +9 -0
- package/dist/api/dto/profiles.d.ts +5 -0
- package/dist/api/dto/reports.d.ts +45 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/routes.d.ts +7 -0
- package/dist/api/routes.js +7 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +24 -3
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +31 -4
- package/dist/clients/attach/overlays/graph.d.ts +5 -0
- package/dist/clients/attach/overlays/graph.js +65 -47
- package/dist/clients/attach/overlays/pickers.js +8 -9
- package/dist/clients/attach/render/card-presentation.js +1 -1
- package/dist/clients/attach/viewer.js +1286 -1260
- package/dist/commands/api-client.js +22 -23
- package/dist/commands/node/create.js +38 -3
- package/dist/commands/node/inspect.js +3 -7
- package/dist/commands/node/message.js +3 -3
- package/dist/commands/node/outcome.d.ts +2 -0
- package/dist/commands/node/outcome.js +134 -0
- package/dist/commands/node.js +2 -1
- package/dist/commands/profile/pause.js +17 -14
- package/dist/commands/push.js +102 -1
- package/dist/commands/sys/__tests__/setup-core.test.js +4 -1
- package/dist/commands/sys/panels/broker-limits-panel.js +7 -1
- package/dist/commands/sys/panels/models-panel.js +2 -2
- package/dist/commands/sys/settings-shell.d.ts +1 -1
- package/dist/commands/sys/settings-shell.js +6 -0
- package/dist/commands/sys/settings.js +3 -3
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +2 -0
- package/dist/core/__tests__/fixtures/fake-engine.js +42 -4
- package/dist/core/__tests__/helpers/harness.d.ts +1 -0
- package/dist/core/__tests__/helpers/harness.js +9 -0
- package/dist/core/__tests__/integration/profile-pause.test.d.ts +1 -0
- package/dist/core/__tests__/integration/profile-pause.test.js +115 -0
- package/dist/core/__tests__/node-outcome.test.d.ts +1 -0
- package/dist/core/__tests__/node-outcome.test.js +184 -0
- package/dist/core/__tests__/revive-parked-fresh.test.js +13 -20
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +6 -2
- package/dist/core/__tests__/seam/dormancy-release.test.js +3 -3
- package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +1 -0
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +153 -0
- package/dist/core/bash-jobs.d.ts +6 -0
- package/dist/core/bash-jobs.js +22 -0
- package/dist/core/canvas/canvas.d.ts +41 -3
- package/dist/core/canvas/canvas.js +153 -39
- package/dist/core/canvas/crons.js +2 -1
- package/dist/core/canvas/index.d.ts +1 -0
- package/dist/core/canvas/index.js +1 -0
- package/dist/core/canvas/migrations.js +47 -0
- package/dist/core/canvas/node-outcome-deliveries.d.ts +80 -0
- package/dist/core/canvas/node-outcome-deliveries.js +163 -0
- package/dist/core/canvas/pid.d.ts +7 -0
- package/dist/core/canvas/pid.js +17 -0
- package/dist/core/canvas/render-source.js +2 -2
- package/dist/core/canvas/types.d.ts +42 -1
- package/dist/core/canvas/types.js +2 -1
- package/dist/core/config.d.ts +4 -1
- package/dist/core/config.js +25 -1
- package/dist/core/feed/feed.d.ts +8 -0
- package/dist/core/feed/feed.js +25 -4
- package/dist/core/feed/inbox.d.ts +5 -0
- package/dist/core/feed/inbox.js +13 -0
- package/dist/core/keybindings/catalog.d.ts +1 -1
- package/dist/core/keybindings/catalog.js +3 -0
- package/dist/core/profiles/manifest.d.ts +3 -1
- package/dist/core/profiles/manifest.js +6 -1
- package/dist/core/runtime/broker/daemon-ops.d.ts +3 -1
- package/dist/core/runtime/broker/daemon-ops.js +6 -0
- package/dist/core/runtime/broker/engine-drive.d.ts +2 -3
- package/dist/core/runtime/broker/engine-drive.js +74 -27
- package/dist/core/runtime/broker/frame-dispatch.js +1 -0
- package/dist/core/runtime/broker/read-ops.js +14 -0
- package/dist/core/runtime/broker/rebind.js +0 -7
- package/dist/core/runtime/broker-protocol.d.ts +1 -6
- package/dist/core/runtime/fleet.d.ts +7 -0
- package/dist/core/runtime/headless-pi.d.ts +13 -0
- package/dist/core/runtime/headless-pi.js +10 -2
- package/dist/core/runtime/lifecycle.d.ts +6 -1
- package/dist/core/runtime/lifecycle.js +50 -1
- package/dist/core/runtime/nodes.d.ts +5 -1
- package/dist/core/runtime/nodes.js +2 -1
- package/dist/core/runtime/outcome-document.d.ts +70 -0
- package/dist/core/runtime/outcome-document.js +97 -0
- package/dist/core/runtime/revive.js +16 -21
- package/dist/core/runtime/spawn.d.ts +5 -1
- package/dist/core/runtime/spawn.js +18 -7
- package/dist/core/runtime/stamp/channel.d.ts +3 -5
- package/dist/core/runtime/stamp/channel.js +3 -10
- package/dist/core/runtime/stop-guard.js +2 -2
- package/dist/core/runtime/structured-output.d.ts +24 -3
- package/dist/core/runtime/structured-output.js +42 -3
- package/dist/core/runtime/tmux-bindings.js +4 -0
- package/dist/core/runtime/warm-pool.d.ts +5 -2
- package/dist/core/runtime/warm-pool.js +5 -5
- package/dist/core/subscription-state.js +7 -5
- package/dist/core/substrate/render.js +10 -10
- package/dist/core/user-settings.d.ts +18 -1
- package/dist/core/user-settings.js +37 -0
- package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +1 -0
- package/dist/daemon/__tests__/node-deadline-lane.test.js +76 -0
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +1 -0
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +122 -0
- package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +1 -0
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +86 -0
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +86 -18
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +10 -1
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +159 -0
- package/dist/daemon/api/__tests__/submit-result.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/submit-result.test.js +214 -0
- package/dist/daemon/api/handlers/broker-ops.js +53 -24
- package/dist/daemon/api/handlers/canvas.js +2 -2
- package/dist/daemon/api/handlers/messages.js +12 -2
- package/dist/daemon/api/handlers/node-outcomes.d.ts +2 -0
- package/dist/daemon/api/handlers/node-outcomes.js +136 -0
- package/dist/daemon/api/handlers/nodes.js +67 -1
- package/dist/daemon/api/handlers/profiles.js +53 -1
- package/dist/daemon/api/handlers/reports.js +197 -33
- package/dist/daemon/api/map.d.ts +7 -2
- package/dist/daemon/api/map.js +78 -4
- package/dist/daemon/api/server.js +74 -7
- package/dist/daemon/crtrd.js +12 -0
- package/dist/daemon/fleet.d.ts +4 -8
- package/dist/daemon/fleet.js +48 -9
- package/dist/daemon/messaging/node-message.js +2 -1
- package/dist/daemon/node-outcome/deliver-outcome.d.ts +14 -0
- package/dist/daemon/node-outcome/deliver-outcome.js +155 -0
- package/dist/daemon/park-activity.d.ts +9 -0
- package/dist/daemon/park-activity.js +30 -0
- package/dist/daemon/park-pending.d.ts +10 -5
- package/dist/daemon/park-pending.js +18 -8
- package/dist/daemon/reconcilers/bash-deadline.js +6 -0
- package/dist/daemon/reconcilers/broker-supervision.d.ts +3 -7
- package/dist/daemon/reconcilers/broker-supervision.js +29 -33
- package/dist/daemon/reconcilers/node-deadline.d.ts +5 -0
- package/dist/daemon/reconcilers/node-deadline.js +82 -0
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +9 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +12 -3
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.d.ts +10 -0
- package/dist/daemon/reconcilers/node-outcome-delivery-lane.js +41 -0
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +66 -66
- package/dist/pi-extensions/canvas-structured-output.d.ts +9 -5
- package/dist/pi-extensions/canvas-structured-output.js +23 -297
- package/dist/shared/env.d.ts +8 -0
- package/dist/shared/env.js +14 -0
- package/dist/shared/generated-context.d.ts +3 -9
- package/dist/shared/generated-context.js +8 -16
- package/dist/types.d.ts +12 -0
- package/dist/types.js +1 -0
- package/package.json +9 -8
- package/runtime.lock.json +227 -383
package/dist/api/client.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { DaemonRestartDTO, HealthDTO, StatusDTO } from './dto/health.js';
|
|
2
2
|
import type { BashJobStatusDTO, BashJobStopResultDTO } from './dto/bash-jobs.js';
|
|
3
3
|
import type { ArtifactListDTO, ArtifactsQuery, ContextListDTO, CreateNodeRequest, ListNodesQuery, NodeDetailDTO, NodeMessagesPageDTO, NodeMessagesQuery, NodeSessionDTO, NodeSnapshotDTO, NodeSubjectDTO, NodeSummaryDTO, TranscriptDTO, TranscriptQuery } from './dto/nodes.js';
|
|
4
|
+
import type { NodeOutcomeResponseDTO, OutcomeDeliveryDTO, RegisterOutcomeDeliveryRequest } from './dto/node-outcomes.js';
|
|
4
5
|
import type { InterruptResultDTO, MessageResultDTO, SendMessageRequest } from './dto/messages.js';
|
|
5
|
-
import type { PushReportRequest, PushReportResultDTO, ReportDTO, ReportsQuery } from './dto/reports.js';
|
|
6
|
+
import type { PushReportRequest, PushReportResultDTO, ReportDTO, ReportsQuery, SubmitResultDTO, SubmitResultRequest } from './dto/reports.js';
|
|
6
7
|
import type { CloseRequest, CloseResultDTO, PromoteRequest, RelaunchRootResultDTO, ReviveRequest, ReviveResultDTO, WaitRequest, YieldRequest } from './dto/lifecycle.js';
|
|
7
8
|
import type { SubscribeRequest, SubscriptionDTO } from './dto/subscriptions.js';
|
|
8
9
|
import type { FocusDTO, RegisterFocusRequest, SetFocusPaneRequest } from './dto/focus.js';
|
|
9
10
|
import { type ArmCronRequest, type CancelCronQuery, type CronDTO, type CronRunDTO, type CronScopeQuery, type CronShowDTO, type ListCronsQuery, type PokeCronsResult } from './dto/crons.js';
|
|
10
11
|
import type { NodeConfigPatch } from './dto/config.js';
|
|
11
12
|
import type { AttachEnsureRequest, AttachEnsureResultDTO } from './dto/attach.js';
|
|
12
|
-
import type { DeleteProfileRequest, DeleteProfileResultDTO, EnsureProfileRequest, ProfileDTO, UpdateProfileMetadataRequest } from './dto/profiles.js';
|
|
13
|
+
import type { DeleteProfileRequest, DeleteProfileResultDTO, EnsureProfileRequest, ProfileDTO, ProfilePauseResultDTO, UpdateProfileMetadataRequest } from './dto/profiles.js';
|
|
13
14
|
import type { FilePeekDTO } from './dto/files.js';
|
|
14
15
|
import type { MemoryDocRefDTO } from './dto/memory.js';
|
|
15
16
|
import type { ChatInventoryDTO, ProspectiveChatInventoryDTO, ProspectiveChatInventoryQuery } from './dto/chat-inventory.js';
|
|
@@ -21,13 +22,15 @@ import type { CancelInboxTicketRequest, CanceledTicketResultDTO, InboxListDTO, I
|
|
|
21
22
|
import type { CreateHumanRequestDTO, CreateHumanRequestRequest, HumanRequestDTO, HumanRequestIdDTO, ReplaceHumanRequestRequest, RespondHumanRequestRequest, SettleHumanRequestRequest } from './dto/human-requests.js';
|
|
22
23
|
import type { AttentionCountsDTO, AttentionDTO, DashboardDTO, DashboardQuery, HistoryGrepQuery, HistoryGrepResultDTO, HistoryReadQuery, HistoryStatsQuery, HistoryStatsResultDTO, HistoryReadResultDTO, HistorySearchQuery, HistorySearchResultDTO, PruneRequest, PruneResultDTO, RebuildIndexResultDTO, RosterDTO, SnapshotDTO } from './dto/canvas.js';
|
|
23
24
|
import type { AbandonWorktreeRequest, AbandonWorktreeResultDTO, CloseWorktreeResultDTO, QuarantinedWorktreeDTO } from './dto/worktree.js';
|
|
24
|
-
import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerInboxCursorDirective, BrokerInboxCursorRequest, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerPersonaAckRequest, BrokerPersonaAckResultDTO, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest } from './dto/broker-ops.js';
|
|
25
|
+
import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerInboxCursorDirective, BrokerInboxCursorRequest, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerParkActivityResultDTO, BrokerParkCompleteRequest, BrokerPersonaAckRequest, BrokerPersonaAckResultDTO, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest } from './dto/broker-ops.js';
|
|
25
26
|
export interface CrtrClientOptions {
|
|
26
27
|
/** Unix socket path (default local transport). Exactly one of socketPath|baseUrl. */
|
|
27
28
|
socketPath?: string;
|
|
28
29
|
/** `http(s)://host:port` for TCP/remote transport. */
|
|
29
30
|
baseUrl?: string;
|
|
30
|
-
/** Extra headers
|
|
31
|
+
/** Extra headers, e.g. `{ authorization: 'Bearer <token>' }` when the target
|
|
32
|
+
* crtrd's TCP listener has `CRTRD_TOKEN` set (unix-socket transport is
|
|
33
|
+
* never checked, and a TCP daemon with no token set ignores this too). */
|
|
31
34
|
headers?: Record<string, string>;
|
|
32
35
|
/** Autostart on a cold socket (default true for socketPath, false for baseUrl). */
|
|
33
36
|
autostart?: boolean;
|
|
@@ -95,6 +98,16 @@ export declare class CrtrClient {
|
|
|
95
98
|
* latest/canonical reports and pending-human counts in the same response. */
|
|
96
99
|
listNodes(q?: ListNodesQuery): Promise<NodeSummaryDTO[]>;
|
|
97
100
|
getNode(id: string): Promise<NodeDetailDTO>;
|
|
101
|
+
/** Read a node outcome, optionally awaiting it for at most 25 seconds. This
|
|
102
|
+
* is a GET so the client can safely replay it across daemon handover. */
|
|
103
|
+
getNodeOutcome(id: string, { waitSeconds }?: {
|
|
104
|
+
waitSeconds?: number;
|
|
105
|
+
}): Promise<NodeOutcomeResponseDTO>;
|
|
106
|
+
/** Register or replace an armed target for terminal-outcome delivery. */
|
|
107
|
+
registerOutcomeDelivery(id: string, req: RegisterOutcomeDeliveryRequest): Promise<OutcomeDeliveryDTO>;
|
|
108
|
+
getOutcomeDelivery(id: string): Promise<OutcomeDeliveryDTO>;
|
|
109
|
+
/** Disarm an unsettled outcome-delivery registration. */
|
|
110
|
+
disarmOutcomeDelivery(id: string): Promise<void>;
|
|
98
111
|
listBashJobs(id: string): Promise<BashJobStatusDTO[]>;
|
|
99
112
|
stopBashJob(id: string, jobId: string): Promise<BashJobStopResultDTO>;
|
|
100
113
|
sendMessage(id: string, req: SendMessageRequest): Promise<MessageResultDTO>;
|
|
@@ -103,11 +116,14 @@ export declare class CrtrClient {
|
|
|
103
116
|
* revives a dormant target. */
|
|
104
117
|
interruptNode(id: string): Promise<InterruptResultDTO>;
|
|
105
118
|
pushReport(id: string, req: PushReportRequest): Promise<PushReportResultDTO>;
|
|
119
|
+
submitResult(id: string, req: SubmitResultRequest): Promise<SubmitResultDTO>;
|
|
106
120
|
forkNode(id: string): Promise<NodeDetailDTO>;
|
|
107
121
|
reviveNode(id: string, req?: ReviveRequest): Promise<ReviveResultDTO>;
|
|
108
122
|
relaunchRoot(id: string): Promise<RelaunchRootResultDTO>;
|
|
109
123
|
bindBrokerSession(id: string, req: BrokerSessionBoundRequest): Promise<BrokerSessionBoundResultDTO>;
|
|
110
124
|
settleBroker(id: string, req: BrokerSettleRequest): Promise<BrokerSettleDirective>;
|
|
125
|
+
completeBrokerPark(id: string, req: BrokerParkCompleteRequest): Promise<BrokerSettleDirective>;
|
|
126
|
+
recordBrokerParkActivity(id: string): Promise<BrokerParkActivityResultDTO>;
|
|
111
127
|
advanceBrokerInboxCursor(id: string, req: BrokerInboxCursorRequest): Promise<BrokerInboxCursorDirective>;
|
|
112
128
|
commitBrokerModel(id: string, req: BrokerModelCommitRequest): Promise<BrokerModelCommitResultDTO>;
|
|
113
129
|
brokerExtensionState(id: string): Promise<BrokerExtensionStateDTO>;
|
|
@@ -187,6 +203,8 @@ export declare class CrtrClient {
|
|
|
187
203
|
ensureProfile(name: string, req?: EnsureProfileRequest): Promise<ProfileDTO>;
|
|
188
204
|
listProfiles(): Promise<ProfileDTO[]>;
|
|
189
205
|
getProfile(name: string): Promise<ProfileDTO>;
|
|
206
|
+
pauseProfile(name: string): Promise<ProfilePauseResultDTO>;
|
|
207
|
+
resumeProfile(name: string): Promise<ProfilePauseResultDTO>;
|
|
190
208
|
/** Merge and remove entries in a profile's metadata map. */
|
|
191
209
|
updateProfileMetadata(name: string, req: UpdateProfileMetadataRequest): Promise<ProfileDTO>;
|
|
192
210
|
/** Force-delete or detach one profile by exact id or unique name. */
|
package/dist/api/client.js
CHANGED
|
@@ -104,6 +104,25 @@ export class CrtrClient {
|
|
|
104
104
|
getNode(id) {
|
|
105
105
|
return this.request('GET', routes.node(this.nodePath(id)));
|
|
106
106
|
}
|
|
107
|
+
/** Read a node outcome, optionally awaiting it for at most 25 seconds. This
|
|
108
|
+
* is a GET so the client can safely replay it across daemon handover. */
|
|
109
|
+
getNodeOutcome(id, { waitSeconds } = {}) {
|
|
110
|
+
if (waitSeconds !== undefined && (!Number.isInteger(waitSeconds) || waitSeconds < 0 || waitSeconds > 25)) {
|
|
111
|
+
throw new RangeError('waitSeconds must be an integer between 0 and 25');
|
|
112
|
+
}
|
|
113
|
+
return this.request('GET', withQuery(routes.nodeOutcome(this.nodePath(id)), { wait: waitSeconds }));
|
|
114
|
+
}
|
|
115
|
+
/** Register or replace an armed target for terminal-outcome delivery. */
|
|
116
|
+
registerOutcomeDelivery(id, req) {
|
|
117
|
+
return this.request('PUT', routes.nodeOutcomeDelivery(this.nodePath(id)), req);
|
|
118
|
+
}
|
|
119
|
+
getOutcomeDelivery(id) {
|
|
120
|
+
return this.request('GET', routes.nodeOutcomeDelivery(this.nodePath(id)));
|
|
121
|
+
}
|
|
122
|
+
/** Disarm an unsettled outcome-delivery registration. */
|
|
123
|
+
async disarmOutcomeDelivery(id) {
|
|
124
|
+
await this.request('DELETE', routes.nodeOutcomeDelivery(this.nodePath(id)));
|
|
125
|
+
}
|
|
107
126
|
listBashJobs(id) {
|
|
108
127
|
return this.request('GET', routes.nodeJobs(this.nodePath(id)));
|
|
109
128
|
}
|
|
@@ -122,6 +141,9 @@ export class CrtrClient {
|
|
|
122
141
|
pushReport(id, req) {
|
|
123
142
|
return this.request('POST', routes.nodeReports(this.nodePath(id)), req);
|
|
124
143
|
}
|
|
144
|
+
submitResult(id, req) {
|
|
145
|
+
return this.request('POST', routes.nodeResult(this.nodePath(id)), req);
|
|
146
|
+
}
|
|
125
147
|
forkNode(id) {
|
|
126
148
|
return this.request('POST', routes.nodeFork(this.nodePath(id)), {});
|
|
127
149
|
}
|
|
@@ -137,6 +159,12 @@ export class CrtrClient {
|
|
|
137
159
|
settleBroker(id, req) {
|
|
138
160
|
return this.request('POST', routes.nodeBrokerSettle(this.nodePath(id)), req);
|
|
139
161
|
}
|
|
162
|
+
completeBrokerPark(id, req) {
|
|
163
|
+
return this.request('POST', routes.nodeBrokerParkComplete(this.nodePath(id)), req);
|
|
164
|
+
}
|
|
165
|
+
recordBrokerParkActivity(id) {
|
|
166
|
+
return this.request('POST', routes.nodeBrokerParkActivity(this.nodePath(id)), {});
|
|
167
|
+
}
|
|
140
168
|
advanceBrokerInboxCursor(id, req) {
|
|
141
169
|
return this.request('POST', routes.nodeBrokerInboxCursor(this.nodePath(id)), req);
|
|
142
170
|
}
|
|
@@ -319,6 +347,12 @@ export class CrtrClient {
|
|
|
319
347
|
getProfile(name) {
|
|
320
348
|
return this.request('GET', routes.profile(name));
|
|
321
349
|
}
|
|
350
|
+
pauseProfile(name) {
|
|
351
|
+
return this.request('POST', routes.profilePause(name), {});
|
|
352
|
+
}
|
|
353
|
+
resumeProfile(name) {
|
|
354
|
+
return this.request('POST', routes.profileResume(name), {});
|
|
355
|
+
}
|
|
322
356
|
/** Merge and remove entries in a profile's metadata map. */
|
|
323
357
|
updateProfileMetadata(name, req) {
|
|
324
358
|
return this.request('PATCH', routes.profileMetadata(name), req);
|
|
@@ -36,6 +36,17 @@ export type BrokerSettleDirective = {
|
|
|
36
36
|
} | {
|
|
37
37
|
action: 'shutdown';
|
|
38
38
|
};
|
|
39
|
+
/** A main-engine input has won broker admission while a parking summary may be
|
|
40
|
+
* in flight. crtrd records it against the process-local pending marker before
|
|
41
|
+
* Pi begins the input, making parking completion and input admission atomic. */
|
|
42
|
+
export interface BrokerParkActivityResultDTO {
|
|
43
|
+
activity: 'recorded' | 'none';
|
|
44
|
+
}
|
|
45
|
+
/** `POST /v1/nodes/{id}/broker/park-complete` body. The isolated parking turn
|
|
46
|
+
* has ended; crtrd alone decides whether its pending park still applies. */
|
|
47
|
+
export interface BrokerParkCompleteRequest {
|
|
48
|
+
outcome: 'completed' | 'failed';
|
|
49
|
+
}
|
|
39
50
|
/** `POST /v1/nodes/{id}/broker/inbox-cursor` body. The watcher advances this
|
|
40
51
|
* only after Pi has settled every handoff through the supplied physical entry.
|
|
41
52
|
* `brokerPid` binds the commit to the broker generation crtrd currently owns. */
|
package/dist/api/dto/broker.d.ts
CHANGED
|
@@ -46,11 +46,6 @@ export interface BrokerWelcomeFrame<M = unknown> {
|
|
|
46
46
|
type: 'welcome';
|
|
47
47
|
snapshot?: BrokerWelcomeSnapshot<M>;
|
|
48
48
|
}
|
|
49
|
-
/** The presentation classification of the run whose native events follow. */
|
|
50
|
-
export interface BrokerTurnVisibilityFrame {
|
|
51
|
-
type: 'turn_visibility';
|
|
52
|
-
visibility: 'visible' | 'internal';
|
|
53
|
-
}
|
|
54
49
|
/**
|
|
55
50
|
* The crtrd broker `node_named` control frame — the node's generated name at the
|
|
56
51
|
* instant crtrd committed it.
|
|
@@ -76,12 +71,12 @@ export interface BrokerNodeNamedFrame {
|
|
|
76
71
|
editorLabel: string;
|
|
77
72
|
}
|
|
78
73
|
/**
|
|
79
|
-
* The broker-control frames a relay consumer reads: `welcome`
|
|
80
|
-
* `
|
|
74
|
+
* The broker-control frames a relay consumer reads: `welcome`, `error`, and
|
|
75
|
+
* `node_named`. The broker interleaves others (display_*, ack, …)
|
|
81
76
|
* under non-colliding `type` discriminants; a relay mapper drops those through its
|
|
82
77
|
* `default` arm untyped, so they are not enumerated here.
|
|
83
78
|
*/
|
|
84
|
-
export type BrokerControlFrame<M = unknown> = BrokerWelcomeFrame<M> |
|
|
79
|
+
export type BrokerControlFrame<M = unknown> = BrokerWelcomeFrame<M> | BrokerErrorFrame | BrokerNodeNamedFrame;
|
|
85
80
|
/**
|
|
86
81
|
* What the crtrd broker attach delivers to a relay consumer: the live engine
|
|
87
82
|
* event stream (`E` — pi's `AgentSessionEvent`, relayed verbatim) unioned with the
|
package/dist/api/dto/common.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export type ModeDTO = 'base' | 'orchestrator';
|
|
|
20
20
|
/** Why a node last stopped (mirrors the runtime `ExitIntent` union). */
|
|
21
21
|
export type ExitIntentDTO = 'done' | 'refresh' | 'idle-release' | 'parked' | null;
|
|
22
22
|
/** Why a terminal node ended (mirrors the runtime `TerminalReason` union). */
|
|
23
|
-
export type TerminalReasonDTO = 'finalized' | 'finished' | 'parked' | 'closed' | 'retired' | 'crashed' | 'stranded';
|
|
23
|
+
export type TerminalReasonDTO = 'finalized' | 'finished' | 'parked' | 'closed' | 'retired' | 'crashed' | 'stranded' | 'boot_failed' | 'crash_looped' | 'launch_failed' | 'context_overflow' | 'deadline_exceeded' | 'provider_fatal' | 'declined';
|
|
24
24
|
/** Inbox urgency tier for a delivered message (mirrors feed/inbox `InboxTier`). */
|
|
25
25
|
export type InboxTierDTO = 'critical' | 'urgent' | 'normal' | 'deferred';
|
|
26
26
|
/** Whether a node id is a safe single filesystem path segment. Re-declared here
|
|
@@ -36,8 +36,8 @@ export interface SendMessageRequest {
|
|
|
36
36
|
/** One-shot runtime cards for this turn only — never persisted. Delivered in
|
|
37
37
|
* array order, after `situational_card` and ahead of the body. */
|
|
38
38
|
context_cards?: RuntimeCardRequest[];
|
|
39
|
-
/** Raw JSON-schema string
|
|
40
|
-
* (`--output-schema`)
|
|
39
|
+
/** Raw JSON-schema string installing a one-off output schema before delivery
|
|
40
|
+
* (`--output-schema`); the target answers with `crtr push result`. Immediate only. */
|
|
41
41
|
output_schema?: string;
|
|
42
42
|
/** `'interactive'`: deliver via the target's LIVE broker engine (prompt/steer
|
|
43
43
|
* on its one serialized frame loop — the same ordering a tmux viewer gets)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { IsoTime, NodeIdDTO, NodeStatusDTO, TerminalReasonDTO } from './common.js';
|
|
2
|
+
import type { DeclinedResultDTO } from './reports.js';
|
|
3
|
+
export type OutcomeKindDTO = 'result' | 'failure';
|
|
4
|
+
/** Bounded diagnostics recorded for a failed node outcome. */
|
|
5
|
+
export interface NodeOutcomeDetailV1 {
|
|
6
|
+
schema: 'crtr.node-outcome-detail/v1';
|
|
7
|
+
message?: string;
|
|
8
|
+
fault_kind?: 'rate-limit' | 'overloaded' | 'connection' | 'auth' | 'protocol' | 'context-overflow' | 'other' | 'wedged' | 'model-not-found';
|
|
9
|
+
error_class?: 'rate_limit' | 'overloaded' | 'connection' | 'auth' | 'protocol' | 'context_overflow' | 'wedged' | 'model_not_found' | 'unknown';
|
|
10
|
+
respawn_failures?: number;
|
|
11
|
+
deadline?: {
|
|
12
|
+
deadline_at: string;
|
|
13
|
+
elapsed_ms: number;
|
|
14
|
+
};
|
|
15
|
+
/** Present only for reason `declined`: what the node gave `crtr push result --decline`. */
|
|
16
|
+
declined?: DeclinedResultDTO;
|
|
17
|
+
truncated?: true;
|
|
18
|
+
}
|
|
19
|
+
interface NodeOutcomeBaseDTO {
|
|
20
|
+
node_id: NodeIdDTO;
|
|
21
|
+
revision: number;
|
|
22
|
+
settled_at: IsoTime;
|
|
23
|
+
/** Canonical final report basename; set for kind='result' and for a declined structured result (kind='failure', reason='declined'); else null. */
|
|
24
|
+
final_report: string | null;
|
|
25
|
+
/** Absolute path of the canonical final report; null whenever `final_report` is. */
|
|
26
|
+
final_report_path: string | null;
|
|
27
|
+
/** Parsed context/result.json when the node ran under --output-schema; else null. */
|
|
28
|
+
structured_result: unknown | null;
|
|
29
|
+
/** Bounded diagnostics; null for kind='result'. */
|
|
30
|
+
detail: NodeOutcomeDetailV1 | null;
|
|
31
|
+
}
|
|
32
|
+
/** A settled outcome. Narrowing on `kind` then `reason` makes a declined
|
|
33
|
+
* structured result (`failure`/`declined`) a case a consumer must handle:
|
|
34
|
+
* only that case carries `declined`; every other outcome has it null. */
|
|
35
|
+
export type NodeOutcomeDTO = (NodeOutcomeBaseDTO & {
|
|
36
|
+
kind: 'result';
|
|
37
|
+
reason: TerminalReasonDTO;
|
|
38
|
+
declined: null;
|
|
39
|
+
}) | (NodeOutcomeBaseDTO & {
|
|
40
|
+
kind: 'failure';
|
|
41
|
+
reason: 'declined';
|
|
42
|
+
declined: DeclinedResultDTO;
|
|
43
|
+
}) | (NodeOutcomeBaseDTO & {
|
|
44
|
+
kind: 'failure';
|
|
45
|
+
reason: Exclude<TerminalReasonDTO, 'declined'>;
|
|
46
|
+
declined: null;
|
|
47
|
+
});
|
|
48
|
+
export interface NodeOutcomeResponseDTO {
|
|
49
|
+
node_id: NodeIdDTO;
|
|
50
|
+
state: 'pending' | 'settled';
|
|
51
|
+
outcome: NodeOutcomeDTO | null;
|
|
52
|
+
node_status: NodeStatusDTO;
|
|
53
|
+
deadline_at: IsoTime | null;
|
|
54
|
+
}
|
|
55
|
+
export interface RegisterOutcomeDeliveryRequest {
|
|
56
|
+
/** A name declared in the humanActions map of scope config. */
|
|
57
|
+
action: string;
|
|
58
|
+
/** Opaque, frozen at registration, echoed verbatim in the document. */
|
|
59
|
+
payload?: unknown;
|
|
60
|
+
}
|
|
61
|
+
export type OutcomeDeliveryStateDTO = 'armed' | 'pending' | 'running' | 'accepted' | 'permanent_failed';
|
|
62
|
+
export interface OutcomeDeliveryDTO {
|
|
63
|
+
node_id: NodeIdDTO;
|
|
64
|
+
state: OutcomeDeliveryStateDTO;
|
|
65
|
+
action: string;
|
|
66
|
+
attempt: number;
|
|
67
|
+
/** ISO-8601 time of the next retry, or null before the row is scheduled. */
|
|
68
|
+
next_attempt_at: IsoTime | null;
|
|
69
|
+
accepted_at: IsoTime | null;
|
|
70
|
+
permanent_failed_at: IsoTime | null;
|
|
71
|
+
last_failure: {
|
|
72
|
+
kind: string;
|
|
73
|
+
exit_code?: number;
|
|
74
|
+
signal?: string;
|
|
75
|
+
message?: string;
|
|
76
|
+
} | null;
|
|
77
|
+
created_at: IsoTime;
|
|
78
|
+
updated_at: IsoTime;
|
|
79
|
+
}
|
|
80
|
+
export {};
|
package/dist/api/dto/nodes.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Cursor, ExitIntentDTO, IsoTime, LifecycleDTO, ModeDTO, NodeIdDTO, NodeStatusDTO, TerminalReasonDTO } from './common.js';
|
|
2
2
|
import type { ReportDTO } from './reports.js';
|
|
3
|
+
import type { NodeOutcomeDTO, RegisterOutcomeDeliveryRequest } from './node-outcomes.js';
|
|
3
4
|
/** `GET /v1/nodes/{id}/subject` — the node-config subject substrate gate
|
|
4
5
|
* predicates evaluate against. Mirrors `NodeConfigSubject`; this narrow
|
|
5
6
|
* endpoint exists so a CLI process (the `memory read` leaf) can gate-check
|
|
@@ -51,6 +52,10 @@ export interface CreateNodeRequest {
|
|
|
51
52
|
situational_context?: string;
|
|
52
53
|
no_kickoff?: boolean;
|
|
53
54
|
output_schema?: string;
|
|
55
|
+
/** Wall-clock bound from spawn, e.g. "45m", "2h", "1h30m". Expiry cancels the node and synthesizes a failure outcome with reason 'deadline_exceeded'. */
|
|
56
|
+
deadline?: string;
|
|
57
|
+
/** Arm outcome delivery atomically with node birth. */
|
|
58
|
+
outcome_delivery?: RegisterOutcomeDeliveryRequest;
|
|
54
59
|
/** Spawn AT this exact node id instead of a runtime-minted one — format-
|
|
55
60
|
* validated and duplicate-rejected server-side (`NodeIdConflictError` →
|
|
56
61
|
* HTTP 409 `node_id_exists`). See `crtr node new --node-id`. */
|
|
@@ -80,6 +85,8 @@ export interface NodeSummaryDTO {
|
|
|
80
85
|
cwd: string;
|
|
81
86
|
host_kind: 'tmux' | 'broker' | null;
|
|
82
87
|
profile_id: string | null;
|
|
88
|
+
/** Whether the node's profile is currently paused. */
|
|
89
|
+
profile_paused: boolean;
|
|
83
90
|
parent: NodeIdDTO | null;
|
|
84
91
|
created: IsoTime;
|
|
85
92
|
intent: ExitIntentDTO;
|
|
@@ -96,6 +103,8 @@ export interface NodeSummaryDTO {
|
|
|
96
103
|
/** Basename of the canonical final report, or null when this node has not finalized. */
|
|
97
104
|
final_report: string | null;
|
|
98
105
|
finalized_at: IsoTime | null;
|
|
106
|
+
deadline_at: IsoTime | null;
|
|
107
|
+
outcome: NodeOutcomeDTO | null;
|
|
99
108
|
/** Present only when requested with `include=activity`. */
|
|
100
109
|
activity?: NodeActivityDTO;
|
|
101
110
|
}
|
|
@@ -28,6 +28,11 @@ export interface UpdateProfileMetadataRequest {
|
|
|
28
28
|
set?: Record<string, string>;
|
|
29
29
|
unset?: string[];
|
|
30
30
|
}
|
|
31
|
+
/** The daemon-owned result of pausing or resuming one profile. */
|
|
32
|
+
export interface ProfilePauseResultDTO {
|
|
33
|
+
profile_id: string;
|
|
34
|
+
paused_at: string | null;
|
|
35
|
+
}
|
|
31
36
|
/** `DELETE /v1/profiles/{name}` body. Destructive deletion is never implicit. */
|
|
32
37
|
export interface DeleteProfileRequest {
|
|
33
38
|
force: boolean;
|
|
@@ -31,6 +31,51 @@ export interface PushReportResultDTO {
|
|
|
31
31
|
/** Present only alongside `worktree_auto_dropped`: the checkout path dropped. */
|
|
32
32
|
worktree_auto_dropped_path?: string;
|
|
33
33
|
}
|
|
34
|
+
/** Why a node declined a structured result. `reason` is one plain sentence
|
|
35
|
+
* for a reader; `code` is an opaque token the requester classifies on and
|
|
36
|
+
* validates itself — crouter only carries it; `retryable` is the node's
|
|
37
|
+
* claim that the same request could succeed later. */
|
|
38
|
+
export interface DeclinedResultDTO {
|
|
39
|
+
reason: string;
|
|
40
|
+
code: string;
|
|
41
|
+
retryable: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** `POST /v1/nodes/{id}/result` body ({id} = the submitting node). Either the
|
|
44
|
+
* structured result to validate against the node's pending output schema —
|
|
45
|
+
* `value` must be present; any JSON value (including null) is legal input to
|
|
46
|
+
* validation — or a decline: `decline` is the reason sentence, `code` the
|
|
47
|
+
* requester-classified token, `retryable` the node's retry claim. A decline
|
|
48
|
+
* records a `failure` outcome with reason `declined` carrying all three and
|
|
49
|
+
* clears the request without validating anything. */
|
|
50
|
+
export type SubmitResultRequest = {
|
|
51
|
+
value: unknown;
|
|
52
|
+
} | {
|
|
53
|
+
decline: string;
|
|
54
|
+
code: string;
|
|
55
|
+
retryable: boolean;
|
|
56
|
+
};
|
|
57
|
+
/** Result of a structured-result submission (`crtr push result`). Terminal
|
|
58
|
+
* mode reuses the final-push machinery, so `transitioned` and the worktree
|
|
59
|
+
* auto-drop fields carry the same meaning as on PushReportResultDTO. */
|
|
60
|
+
export interface SubmitResultDTO {
|
|
61
|
+
/** Which request this answered: `terminal` finished the node; `oneoff` left it working. */
|
|
62
|
+
mode: 'terminal' | 'oneoff';
|
|
63
|
+
/** Absolute path of the recorded artifact: context/result.json for an
|
|
64
|
+
* answered request, context/declined.json for a declined one. */
|
|
65
|
+
result_path: string;
|
|
66
|
+
/** Present only when the request was declined. */
|
|
67
|
+
declined?: DeclinedResultDTO;
|
|
68
|
+
/** Absolute path of the report pushed alongside the result. */
|
|
69
|
+
report_path: string;
|
|
70
|
+
/** Subscriber node ids that received an inbox entry. */
|
|
71
|
+
notified: NodeIdDTO[];
|
|
72
|
+
transitioned?: {
|
|
73
|
+
from: string;
|
|
74
|
+
to: string;
|
|
75
|
+
};
|
|
76
|
+
worktree_auto_dropped?: boolean;
|
|
77
|
+
worktree_auto_dropped_path?: string;
|
|
78
|
+
}
|
|
34
79
|
/** `GET /v1/nodes/{id}/reports` query filters. */
|
|
35
80
|
export interface ReportsQuery {
|
|
36
81
|
tier?: ReportTierDTO;
|
package/dist/api/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from '../shared/generated-context.js';
|
|
|
7
7
|
export * from './dto/common.js';
|
|
8
8
|
export * from './dto/health.js';
|
|
9
9
|
export * from './dto/nodes.js';
|
|
10
|
+
export * from './dto/node-outcomes.js';
|
|
10
11
|
export * from './dto/bash-jobs.js';
|
|
11
12
|
export * from './dto/messages.js';
|
|
12
13
|
export * from './dto/reports.js';
|
package/dist/api/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from '../shared/generated-context.js';
|
|
|
8
8
|
export * from './dto/common.js';
|
|
9
9
|
export * from './dto/health.js';
|
|
10
10
|
export * from './dto/nodes.js';
|
|
11
|
+
export * from './dto/node-outcomes.js';
|
|
11
12
|
export * from './dto/bash-jobs.js';
|
|
12
13
|
export * from './dto/messages.js';
|
|
13
14
|
export * from './dto/reports.js';
|
package/dist/api/routes.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare const routes: {
|
|
|
8
8
|
readonly nodes: () => string;
|
|
9
9
|
readonly reviveAll: () => string;
|
|
10
10
|
readonly node: (id: string) => string;
|
|
11
|
+
readonly nodeOutcome: (id: string) => string;
|
|
12
|
+
readonly nodeOutcomeDelivery: (id: string) => string;
|
|
11
13
|
readonly nodeSnapshot: (id: string) => string;
|
|
12
14
|
readonly nodeSubject: (id: string) => string;
|
|
13
15
|
readonly nodeSession: (id: string) => string;
|
|
@@ -17,6 +19,7 @@ export declare const routes: {
|
|
|
17
19
|
readonly nodeContext: (id: string) => string;
|
|
18
20
|
readonly nodeArtifacts: (id: string) => string;
|
|
19
21
|
readonly nodeReports: (id: string) => string;
|
|
22
|
+
readonly nodeResult: (id: string) => string;
|
|
20
23
|
readonly nodeJobs: (id: string) => string;
|
|
21
24
|
readonly nodeJob: (id: string, jobId: string) => string;
|
|
22
25
|
readonly nodeMessages: (id: string) => string;
|
|
@@ -26,6 +29,8 @@ export declare const routes: {
|
|
|
26
29
|
readonly nodeRelaunchRoot: (id: string) => string;
|
|
27
30
|
readonly nodeBrokerSessionBound: (id: string) => string;
|
|
28
31
|
readonly nodeBrokerSettle: (id: string) => string;
|
|
32
|
+
readonly nodeBrokerParkComplete: (id: string) => string;
|
|
33
|
+
readonly nodeBrokerParkActivity: (id: string) => string;
|
|
29
34
|
readonly nodeBrokerInboxCursor: (id: string) => string;
|
|
30
35
|
readonly nodeBrokerModel: (id: string) => string;
|
|
31
36
|
readonly nodeBrokerExtensionState: (id: string) => string;
|
|
@@ -96,6 +101,8 @@ export declare const routes: {
|
|
|
96
101
|
readonly humanRequestCancel: (requestId: string) => string;
|
|
97
102
|
readonly profiles: () => string;
|
|
98
103
|
readonly profile: (name: string) => string;
|
|
104
|
+
readonly profilePause: (name: string) => string;
|
|
105
|
+
readonly profileResume: (name: string) => string;
|
|
99
106
|
readonly profileMetadata: (name: string) => string;
|
|
100
107
|
readonly modelAuths: () => string;
|
|
101
108
|
readonly modelAuth: (provider: string) => string;
|
package/dist/api/routes.js
CHANGED
|
@@ -23,6 +23,8 @@ export const routes = {
|
|
|
23
23
|
nodes: () => `${V}/nodes`,
|
|
24
24
|
reviveAll: () => `${V}/nodes/revive-all`,
|
|
25
25
|
node: (id) => `${V}/nodes/${id}`,
|
|
26
|
+
nodeOutcome: (id) => `${V}/nodes/${id}/outcome`,
|
|
27
|
+
nodeOutcomeDelivery: (id) => `${V}/nodes/${id}/outcome-delivery`,
|
|
26
28
|
// Node reads
|
|
27
29
|
nodeSnapshot: (id) => `${V}/nodes/${id}/snapshot`,
|
|
28
30
|
nodeSubject: (id) => `${V}/nodes/${id}/subject`,
|
|
@@ -33,6 +35,7 @@ export const routes = {
|
|
|
33
35
|
nodeContext: (id) => `${V}/nodes/${id}/context`,
|
|
34
36
|
nodeArtifacts: (id) => `${V}/nodes/${id}/artifacts`,
|
|
35
37
|
nodeReports: (id) => `${V}/nodes/${id}/reports`,
|
|
38
|
+
nodeResult: (id) => `${V}/nodes/${id}/result`,
|
|
36
39
|
nodeJobs: (id) => `${V}/nodes/${id}/jobs`,
|
|
37
40
|
nodeJob: (id, jobId) => `${V}/nodes/${id}/jobs/${jobId}`,
|
|
38
41
|
// Node messages / feed
|
|
@@ -44,6 +47,8 @@ export const routes = {
|
|
|
44
47
|
nodeRelaunchRoot: (id) => `${V}/nodes/${id}/relaunch-root`,
|
|
45
48
|
nodeBrokerSessionBound: (id) => `${V}/nodes/${id}/broker/session-bound`,
|
|
46
49
|
nodeBrokerSettle: (id) => `${V}/nodes/${id}/broker/settle`,
|
|
50
|
+
nodeBrokerParkComplete: (id) => `${V}/nodes/${id}/broker/park-complete`,
|
|
51
|
+
nodeBrokerParkActivity: (id) => `${V}/nodes/${id}/broker/park-activity`,
|
|
47
52
|
nodeBrokerInboxCursor: (id) => `${V}/nodes/${id}/broker/inbox-cursor`,
|
|
48
53
|
nodeBrokerModel: (id) => `${V}/nodes/${id}/broker/model`,
|
|
49
54
|
nodeBrokerExtensionState: (id) => `${V}/nodes/${id}/broker/extension-state`,
|
|
@@ -127,6 +132,8 @@ export const routes = {
|
|
|
127
132
|
// Profiles (deletion is daemon-owned because it crosses canvas state)
|
|
128
133
|
profiles: () => `${V}/profiles`,
|
|
129
134
|
profile: (name) => `${V}/profiles/${name}`,
|
|
135
|
+
profilePause: (name) => `${V}/profiles/${name}/pause`,
|
|
136
|
+
profileResume: (name) => `${V}/profiles/${name}/resume`,
|
|
130
137
|
profileMetadata: (name) => `${V}/profiles/${name}/metadata`,
|
|
131
138
|
// Model auth
|
|
132
139
|
modelAuths: () => `${V}/model-auth`,
|
|
@@ -405,6 +405,18 @@ async function streamProviderAttempt(state, providerId, model, context, options,
|
|
|
405
405
|
fetch: withAnthropicFallbackBeta(options?.fetch ?? globalThis.fetch),
|
|
406
406
|
}
|
|
407
407
|
: {}),
|
|
408
|
+
// Codex fast mode: the ChatGPT backend serves the turn at its priority
|
|
409
|
+
// tier. The wire value is `priority` (`fast` is rejected 400), and the
|
|
410
|
+
// response always echoes `service_tier: "default"` regardless — only
|
|
411
|
+
// generation timing shows whether it took effect.
|
|
412
|
+
...(providerId === OPENAI_CODEX_PROVIDER_ID && state.providerOptions?.[OPENAI_CODEX_PROVIDER_ID]?.fastMode === true
|
|
413
|
+
? {
|
|
414
|
+
onPayload: async (payload, payloadModel) => {
|
|
415
|
+
const callerPayload = await options?.onPayload?.(payload, payloadModel);
|
|
416
|
+
return { ...(callerPayload === undefined ? payload : callerPayload), service_tier: "priority" };
|
|
417
|
+
},
|
|
418
|
+
}
|
|
419
|
+
: {}),
|
|
408
420
|
onResponse: async (response, responseModel) => {
|
|
409
421
|
observedStatus = response.status;
|
|
410
422
|
if (response.status === 429 || response.status === 503) {
|
|
@@ -773,8 +785,12 @@ function parseCommand(args) {
|
|
|
773
785
|
function parseProvider(value) {
|
|
774
786
|
return isManagedProvider(value) ? value : undefined;
|
|
775
787
|
}
|
|
776
|
-
|
|
777
|
-
|
|
788
|
+
/** Merged config for the NODE's scope (its own cwd/profile), not this
|
|
789
|
+
* process's ambient one. */
|
|
790
|
+
function readTargetLaunchConfig(state, ctx) {
|
|
791
|
+
return readMergedLaunchConfig(ctx.cwd, configuredValue(state, 'profileId', 'CRTR_PROFILE_ID') || null);
|
|
792
|
+
}
|
|
793
|
+
function installDeclaredRouteProviders(state, pi, ctx, config) {
|
|
778
794
|
const providerIds = new Set(Object.values({ ...(config.modelRoutes ?? {}), ...(config.legacyModelRoutes ?? {}) }).map((route) => route.providerId));
|
|
779
795
|
for (const providerId of providerIds) {
|
|
780
796
|
if (isManagedProvider(providerId) || state.delegatedProviderStreams.has(providerId))
|
|
@@ -931,11 +947,16 @@ export function createProviderRotationExtension(options) {
|
|
|
931
947
|
});
|
|
932
948
|
pi.on("session_start", async (_event, ctx) => {
|
|
933
949
|
state.runtimeContext = ctx;
|
|
934
|
-
|
|
950
|
+
const config = readTargetLaunchConfig(state, ctx);
|
|
951
|
+
state.providerOptions = config.providerOptions;
|
|
952
|
+
installDeclaredRouteProviders(state, pi, ctx, config);
|
|
935
953
|
updateRotationStatus(state, ctx);
|
|
936
954
|
});
|
|
937
955
|
pi.on("before_agent_start", async (_event, ctx) => {
|
|
938
956
|
state.runtimeContext = ctx;
|
|
957
|
+
// Re-read per turn: this is what makes a provider-options toggle apply to
|
|
958
|
+
// a broker that is already running, on its next turn.
|
|
959
|
+
state.providerOptions = readTargetLaunchConfig(state, ctx).providerOptions;
|
|
939
960
|
const restored = await restoreHigherRankIfAvailable(state, pi, ctx);
|
|
940
961
|
if (restored && ctx.model && isManagedProvider(ctx.model.provider)) {
|
|
941
962
|
logRotation(`restored higher-ranked route ${ctx.model.provider}/${ctx.model.id}`);
|
|
@@ -37,7 +37,8 @@ import {
|
|
|
37
37
|
type ManagedProviderId,
|
|
38
38
|
type SubscriptionCredential,
|
|
39
39
|
} from '../../../core/subscription-state.js';
|
|
40
|
-
import { readMergedLaunchConfig } from '../../../core/config.js';
|
|
40
|
+
import { readMergedLaunchConfig, type MergedLaunchConfig } from '../../../core/config.js';
|
|
41
|
+
import type { ProviderOptionsConfig } from '../../../types.js';
|
|
41
42
|
import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from '../../../core/model-routes.js';
|
|
42
43
|
import { envModelExact, envNodeId } from '../../../shared/env.js';
|
|
43
44
|
import { ManagedProviderCoolingError } from '../../../core/runtime/managed-provider-cooling.js';
|
|
@@ -83,6 +84,10 @@ type ProviderRotationState = {
|
|
|
83
84
|
extensionAPI?: ExtensionAPI;
|
|
84
85
|
delegatedProviderStreams: Map<string, ProviderStream>;
|
|
85
86
|
options?: Readonly<ProviderRotationOptions>;
|
|
87
|
+
/** Per-provider behavior options from merged config, refreshed at session
|
|
88
|
+
* start and before every agent turn so a settings toggle reaches a broker
|
|
89
|
+
* that is already live. */
|
|
90
|
+
providerOptions?: Record<string, ProviderOptionsConfig>;
|
|
86
91
|
/** Consecutive route-queue passes that exhausted every route without a single
|
|
87
92
|
* HTTP response — the poisoned-process signature counted across turns. */
|
|
88
93
|
transportOnlyExhaustedPasses: number;
|
|
@@ -563,6 +568,18 @@ async function streamProviderAttempt(
|
|
|
563
568
|
fetch: withAnthropicFallbackBeta(options?.fetch ?? globalThis.fetch),
|
|
564
569
|
}
|
|
565
570
|
: {}),
|
|
571
|
+
// Codex fast mode: the ChatGPT backend serves the turn at its priority
|
|
572
|
+
// tier. The wire value is `priority` (`fast` is rejected 400), and the
|
|
573
|
+
// response always echoes `service_tier: "default"` regardless — only
|
|
574
|
+
// generation timing shows whether it took effect.
|
|
575
|
+
...(providerId === OPENAI_CODEX_PROVIDER_ID && state.providerOptions?.[OPENAI_CODEX_PROVIDER_ID]?.fastMode === true
|
|
576
|
+
? {
|
|
577
|
+
onPayload: async (payload: unknown, payloadModel: Model<any>) => {
|
|
578
|
+
const callerPayload = await options?.onPayload?.(payload, payloadModel);
|
|
579
|
+
return { ...((callerPayload === undefined ? payload : callerPayload) as Record<string, unknown>), service_tier: "priority" };
|
|
580
|
+
},
|
|
581
|
+
}
|
|
582
|
+
: {}),
|
|
566
583
|
onResponse: async (response: { status: number; headers: Record<string, string> }, responseModel: Model<any>) => {
|
|
567
584
|
observedStatus = response.status;
|
|
568
585
|
if (response.status === 429 || response.status === 503) {
|
|
@@ -957,8 +974,13 @@ function parseProvider(value: string | undefined): ManagedProviderId | undefined
|
|
|
957
974
|
return isManagedProvider(value) ? value : undefined;
|
|
958
975
|
}
|
|
959
976
|
|
|
960
|
-
|
|
961
|
-
|
|
977
|
+
/** Merged config for the NODE's scope (its own cwd/profile), not this
|
|
978
|
+
* process's ambient one. */
|
|
979
|
+
function readTargetLaunchConfig(state: ProviderRotationState, ctx: ExtensionContext): MergedLaunchConfig {
|
|
980
|
+
return readMergedLaunchConfig(ctx.cwd, configuredValue(state, 'profileId', 'CRTR_PROFILE_ID') || null);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
function installDeclaredRouteProviders(state: ProviderRotationState, pi: ExtensionAPI, ctx: ExtensionContext, config: MergedLaunchConfig): void {
|
|
962
984
|
const providerIds = new Set(Object.values({ ...(config.modelRoutes ?? {}), ...(config.legacyModelRoutes ?? {}) }).map((route) => route.providerId));
|
|
963
985
|
for (const providerId of providerIds) {
|
|
964
986
|
if (isManagedProvider(providerId) || state.delegatedProviderStreams.has(providerId)) continue;
|
|
@@ -1129,12 +1151,17 @@ export function createProviderRotationExtension(options?: ProviderRotationOption
|
|
|
1129
1151
|
|
|
1130
1152
|
pi.on("session_start", async (_event, ctx) => {
|
|
1131
1153
|
state.runtimeContext = ctx;
|
|
1132
|
-
|
|
1154
|
+
const config = readTargetLaunchConfig(state, ctx);
|
|
1155
|
+
state.providerOptions = config.providerOptions;
|
|
1156
|
+
installDeclaredRouteProviders(state, pi, ctx, config);
|
|
1133
1157
|
updateRotationStatus(state, ctx);
|
|
1134
1158
|
});
|
|
1135
1159
|
|
|
1136
1160
|
pi.on("before_agent_start", async (_event, ctx) => {
|
|
1137
1161
|
state.runtimeContext = ctx;
|
|
1162
|
+
// Re-read per turn: this is what makes a provider-options toggle apply to
|
|
1163
|
+
// a broker that is already running, on its next turn.
|
|
1164
|
+
state.providerOptions = readTargetLaunchConfig(state, ctx).providerOptions;
|
|
1138
1165
|
const restored = await restoreHigherRankIfAvailable(state, pi, ctx);
|
|
1139
1166
|
if (restored && ctx.model && isManagedProvider(ctx.model.provider)) {
|
|
1140
1167
|
logRotation(`restored higher-ranked route ${ctx.model.provider}/${ctx.model.id}`);
|
|
@@ -54,6 +54,11 @@ export declare class GraphOverlay implements Component {
|
|
|
54
54
|
refresh(): void;
|
|
55
55
|
invalidate(): void;
|
|
56
56
|
private buildSnapshot;
|
|
57
|
+
/** Fold state is presentation-only. Reproject the visible DFS from the fully
|
|
58
|
+
* fetched topology so h/l never cross the daemon boundary. The explicit stack
|
|
59
|
+
* also keeps a deep graph from consuming the JavaScript call stack. */
|
|
60
|
+
private projectRows;
|
|
61
|
+
private repaintFolds;
|
|
57
62
|
private renderSnapshotRow;
|
|
58
63
|
render(width: number): string[];
|
|
59
64
|
/** A top/bottom border row: `<lc>─ <label> ────<rc>`, frame in the theme border
|