@dougbots/avenor-core 0.15.0 → 0.16.1

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/index.d.ts CHANGED
@@ -144,11 +144,122 @@ interface WorkflowControllerCreateParams {
144
144
  controller_id: string;
145
145
  max_inflight: number;
146
146
  }
147
+ interface MessageSendParams {
148
+ to_run_id: string;
149
+ message_id: string;
150
+ generation: string;
151
+ body: string;
152
+ no_reply?: boolean;
153
+ }
154
+ interface MessageSendResult {
155
+ outcome: string;
156
+ message_id?: string;
157
+ generation?: string;
158
+ }
159
+ interface MessageWaitParams {
160
+ message_id: string;
161
+ generation: string;
162
+ timeout_ms?: number;
163
+ }
164
+ interface MessageInbound {
165
+ message_id: string;
166
+ from_run_id: string;
167
+ sender?: string;
168
+ kind?: string;
169
+ payload?: unknown;
170
+ }
171
+ interface MessageWaitResult {
172
+ outcome: string;
173
+ message_id?: string;
174
+ reply?: MessageInbound;
175
+ }
176
+ interface MessageWithdrawParams {
177
+ message_id: string;
178
+ generation: string;
179
+ }
180
+ interface MessageFence {
181
+ sender: string;
182
+ message_id: string;
183
+ generation: string;
184
+ deadline: number;
185
+ terminal: boolean;
186
+ }
187
+ interface MessageWithdrawResult {
188
+ outcome: string;
189
+ fence?: MessageFence;
190
+ }
191
+ interface MessageReceiveParams {
192
+ generation: string;
193
+ timeout_ms?: number;
194
+ limit?: number;
195
+ }
196
+ interface MessageReceiveResult {
197
+ messages: MessageInbound[];
198
+ generation?: string;
199
+ }
200
+ interface MessagePeersParams {
201
+ generation: string;
202
+ }
203
+ interface MessagePeer {
204
+ run_id: string;
205
+ session?: unknown;
206
+ }
207
+ interface MessagePeersResult {
208
+ peers: MessagePeer[];
209
+ generation?: string;
210
+ }
211
+ interface MessagePreflightResult {
212
+ protocol: number;
213
+ generation: string;
214
+ }
215
+ interface ResumeParams {
216
+ run_id: string;
217
+ target: string;
218
+ message: string;
219
+ label?: string;
220
+ idempotency_key?: string;
221
+ sentinel_file?: string;
222
+ on_event?: string;
223
+ }
224
+ interface ResumeResult {
225
+ run_id: string;
226
+ label: string;
227
+ runtime_id: string;
228
+ session_id: string;
229
+ sentinel_file: string;
230
+ on_event: string;
231
+ }
232
+ interface SessionRenameResult {
233
+ run_id: string;
234
+ label: string;
235
+ previous_label: string;
236
+ }
237
+ interface SessionLastResult {
238
+ run_id: string;
239
+ label?: string;
240
+ has_record: boolean;
241
+ final_output: string;
242
+ stop_reason?: string;
243
+ final_output_truncated?: boolean;
244
+ at?: number;
245
+ }
147
246
  declare class RpcError extends Error {
148
247
  readonly code: number;
149
248
  readonly data?: unknown;
150
249
  constructor(code: number, message: string, data?: unknown);
151
250
  }
251
+ /**
252
+ * A transport failure that marks the control client closed: a send refused
253
+ * because the socket is already closed, a pending call rejected because the
254
+ * read side closed, or a socket write failure. A peer's structured rejection
255
+ * (RpcError) or a call timeout do not close the client and are not classified
256
+ * here.
257
+ */
258
+ declare class ClosedSocketError extends Error {
259
+ constructor(message: string);
260
+ }
261
+ /** True when the error is a transport failure that closed the client. */
262
+ declare function isClosedSocketError(error: unknown): boolean;
152
263
  type OwnerAuthFailureKind = 'unauthenticated' | 'unsupported' | 'timeout';
153
264
  /** A classified owner-authentication rejection, not generic transport failure. */
154
265
  declare class OwnerAuthError extends Error {
@@ -225,17 +336,23 @@ declare class Client {
225
336
  workflowControllerCreate(params: WorkflowControllerCreateParams): Promise<Record<string, unknown>>;
226
337
  workflowControllerEnable(controllerId: string): Promise<Record<string, unknown>>;
227
338
  workflowControllerDisable(controllerId: string, reason: string): Promise<Record<string, unknown>>;
228
- brokerSend(fromRunId: string, toRunId: string, message: string, role?: string): Promise<void>;
229
- brokerAsk(toRunId: string, message: string, role?: string, timeoutMs?: number): Promise<Record<string, unknown>>;
230
- brokerPeers(): Promise<Array<Record<string, unknown>>>;
231
- brokerCancel(messageId: string): Promise<void>;
232
- brokerReceive(): Promise<Array<{
233
- from_run_id: string;
339
+ messageSend(params: MessageSendParams): Promise<MessageSendResult>;
340
+ messageWait(params: MessageWaitParams): Promise<MessageWaitResult>;
341
+ messageReply(params: {
342
+ to_run_id: string;
234
343
  message_id: string;
235
- message: string;
236
- role?: string;
237
- }>>;
238
- brokerReply(toRunId: string, replyTo: string, message: string): Promise<void>;
344
+ correlation_id?: string;
345
+ body: string;
346
+ }): Promise<MessageSendResult>;
347
+ messageWithdraw(params: MessageWithdrawParams): Promise<MessageWithdrawResult>;
348
+ messageReceive(params: MessageReceiveParams): Promise<MessageReceiveResult>;
349
+ messagePeers(params: MessagePeersParams): Promise<MessagePeersResult>;
350
+ messagePreflight(): Promise<MessagePreflightResult>;
351
+ resume(params: ResumeParams): Promise<ResumeResult>;
352
+ sessionRename(sessionId: string, name: string): Promise<SessionRenameResult>;
353
+ sessionLast(runtimeId: string): Promise<SessionLastResult>;
354
+ sessionLastSet(runtimeId: string, finalOutput: string, stopReason: string, truncated: boolean): Promise<void>;
355
+ workflowCancel(workflowId: string, actor: string, reason: string): Promise<Record<string, unknown>>;
239
356
  isClosed(): boolean;
240
357
  close(): void;
241
358
  }
@@ -488,6 +605,20 @@ declare class Supervisor {
488
605
  * Public run IDs are canonical; labels are lookup-only aliases.
489
606
  */
490
607
  getRunByReference(reference: string): RunInfo | undefined;
608
+ /**
609
+ * Look up a run by its public run ID only, never by a label alias. The
610
+ * messaging router resolves public IDs and labels on separate planes, so a
611
+ * label that happens to equal another run's old ID must not match here.
612
+ */
613
+ getRunById(runId: string): RunInfo | undefined;
614
+ /**
615
+ * Register a run this supervisor resumed, so its ID and label stay resolvable.
616
+ * Last write wins: an existing entry with the same run ID, or a label held by
617
+ * another run, is replaced. Duplicate rejection is the resume provider's job.
618
+ */
619
+ registerResumed(run: RunInfo): void;
620
+ /** The one place a run's ID and label are registered, for spawn and for resume. */
621
+ private register;
491
622
  /** Match a stored run by its broker runtime ID. */
492
623
  getRunByRuntimeId(runtimeId: string): RunInfo | undefined;
493
624
  /**
@@ -689,20 +820,6 @@ declare function answerPermissionTool(args: {
689
820
  ok: boolean;
690
821
  }>;
691
822
  //#endregion
692
- //#region src/tools/follow-up.d.ts
693
- interface FollowUpToolArgs {
694
- runId: string;
695
- message: string;
696
- label?: string;
697
- supervisorId?: string;
698
- }
699
- interface FollowUpToolResult {
700
- run_id: string;
701
- label: string;
702
- runtime_id?: string;
703
- }
704
- declare const followUpTool: (args: FollowUpToolArgs) => Promise<FollowUpToolResult>;
705
- //#endregion
706
823
  //#region src/tools/shutdown.d.ts
707
824
  declare function shutdownTool(args: {
708
825
  supervisorId?: string;
@@ -712,57 +829,369 @@ declare function shutdownTool(args: {
712
829
  cleaned_up: string[];
713
830
  }>;
714
831
  //#endregion
715
- //#region src/tools/ask.d.ts
716
- interface AskToolArgs {
717
- toRunId: string;
718
- message: string;
719
- supervisorId?: string;
720
- timeoutMs?: number;
721
- }
722
- interface AskResult {
723
- reply: string;
724
- from_run_id: string;
725
- }
832
+ //#region src/messaging-text.d.ts
833
+ /** Every outcome the contract declares: the nine messaging rows and the two tool rows. */
834
+ declare const MESSAGE_OUTCOMES: [string, ...string[]];
835
+ type MessageOutcome = (typeof MESSAGE_OUTCOMES)[number];
836
+ /** The ask acceptance window the message ids encode, in milliseconds. */
837
+ declare const MAX_WAIT_MS = 600000;
838
+ /** The bound `session_last_set` carries from the producer, in code points. */
839
+ declare const MAX_FINAL_OUTPUT_RUNES = 4096;
840
+ /** Render the (action, outcome) template; an unlisted pair renders as "". */
841
+ declare function renderOutcome(action: string, outcome: string, facts?: Record<string, string>): string;
842
+ /** Render a repair sentence; the templates are the conformance fixture's `repairs`. */
843
+ declare function repair(code: string, facts?: Record<string, string>): string;
844
+ /** Render one of the peers `last` templates. */
845
+ declare function renderLast(key: string, facts?: Record<string, string>): string;
846
+ /**
847
+ * Render a value for a template fact as one JSON string literal. Control,
848
+ * format, line- and paragraph-separator characters are escaped, so a label a
849
+ * producer controls cannot carry a bidi override or a zero-width character into
850
+ * tool text. The rule is byte-identical to internal/messaging.Quote.
851
+ */
852
+ declare function quote(value: string): string;
853
+ /** Escape the same characters as quote without adding the surrounding quotes. */
854
+ declare function sanitize(value: string): string;
855
+ /** Render every value with quote and join them with ", ". */
856
+ declare function quoteList(values: string[]): string;
857
+ /**
858
+ * Mint a versioned message id whose acceptance deadline is encoded inside it.
859
+ * The zero-deadline form spans the shared wait window, exactly like
860
+ * messaging.NewMsgID(now, time.Time{}).
861
+ */
862
+ declare function newMsgID(now?: number): string;
863
+ /**
864
+ * Map pi's raw stop reasons onto avenor's canonical words, so a Pi host's
865
+ * published reason and a Pi child's session.end reason agree. The table is
866
+ * exactly internal/runtime/pi/events.go:normalizePiStopReason's; a spelling it
867
+ * does not know passes through and stays unknown here too.
868
+ */
869
+ declare function normalizeTurnStopReason(stopReason: string): string;
870
+ /**
871
+ * Read the last assistant message's text and raw stop reason from an agent_end
872
+ * payload's `messages`, the TS twin of internal/runtime/pi's extractPiText plus
873
+ * the per-message `stopReason` read that translateAgentEnd does. Go also falls
874
+ * back to payload-level stopReason/errorMessage and normalises the stop reason;
875
+ * this helper sees only the messages array and does neither.
876
+ */
877
+ declare function extractTurnText(messages: unknown[]): {
878
+ text: string;
879
+ stopReason: string;
880
+ };
881
+ /** Bound a published turn at the same rune count the Go recorder uses. */
882
+ declare function boundFinalOutput(text: string): string;
883
+ /** Extract the reply body from a wait result payload, as askclient.RenderReply does. */
726
884
  declare function extractReplyMessage(result: Record<string, unknown>): string;
727
885
  /**
728
- * Build the failure message every ask path reports: the broker message id plus
729
- * whether the ask edge is still pending (withdrawable via avenor_cancel) or
730
- * already gone.
886
+ * Render the shared ask failure sentence for an ask that failed. The outcome
887
+ * and the sentence both come from the contract, so TS and Go text agree.
731
888
  */
732
- declare function formatAskFailure(messageId: string, pending: boolean, detail: string): string;
889
+ declare function renderAskFailure(messageId: string, target: string, outcome?: MessageOutcome): string;
733
890
  /**
734
891
  * Reduce a caller-supplied ask timeout to what the broker accepts: a positive
735
892
  * finite number of milliseconds, or undefined to keep the broker's own wait.
736
893
  */
737
894
  declare function normalizeAskTimeoutMs(timeoutMs: number | undefined): number | undefined;
738
- declare const askTool: (args: AskToolArgs) => Promise<AskResult>;
739
895
  //#endregion
740
- //#region src/tools/peers.d.ts
741
- interface PeersToolArgs {
742
- supervisorId?: string;
743
- }
744
- interface PeerEntry {
896
+ //#region src/message.d.ts
897
+ type MessageCallerKind = 'owner' | 'broker';
898
+ type MessageSurface = 'pi-host' | 'pi-child' | 'opencode' | 'mcp-ts' | 'mcp' | 'channeltools' | 'sidecar';
899
+ /** One peers `list` entry: the tool's projection of the broker's SessionInfo. */
900
+ interface PeerRecord {
745
901
  run_id: string;
746
902
  label?: string;
903
+ kind?: string;
747
904
  status?: string;
748
905
  backend?: string;
749
906
  model?: string;
750
907
  dir?: string;
751
908
  }
752
- interface PeersResult {
753
- peers: PeerEntry[];
909
+ /**
910
+ * One routed call's outcome and the facts a surface reports. `text` is the
911
+ * (action, outcome) render template and is set on every result, so no surface
912
+ * composes a sentence and every failure says whether an ask can still be
913
+ * withdrawn.
914
+ */
915
+ interface ProviderResult {
916
+ action?: string;
917
+ outcome: MessageOutcome;
918
+ messageId?: string;
919
+ reply?: string;
920
+ text?: string;
921
+ runId?: string;
922
+ runtimeId?: string;
923
+ sessionId?: string;
924
+ label?: string;
925
+ previousLabel?: string;
926
+ sentinelFile?: string;
927
+ onEvent?: string;
928
+ finalOutput?: string;
929
+ stopReason?: string;
930
+ truncated?: boolean;
931
+ hasRecord?: boolean;
932
+ /** A peers `list` transport's error text; set only on an incomplete listing. */
933
+ detail?: string;
934
+ }
935
+ interface Resolution {
936
+ runId: string;
937
+ publicRunId?: string;
938
+ match: 'unique' | 'ambiguous' | 'none';
939
+ label?: string;
940
+ candidates?: string[];
941
+ }
942
+ interface RunFacts {
943
+ live: boolean;
944
+ resumable: boolean;
945
+ status: string;
946
+ }
947
+ interface PeersProviderResult {
948
+ peers: PeerRecord[];
949
+ /** Set when the transport returned peers together with an error. */
950
+ detail?: string;
951
+ }
952
+ /**
953
+ * What one bound surface supplies to the router: who it speaks as, how it
954
+ * resolves and reads state, and the action methods only it can perform.
955
+ */
956
+ interface MessageProvider {
957
+ caller(): {
958
+ kind: MessageCallerKind;
959
+ runId: string;
960
+ };
961
+ surface(): MessageSurface;
962
+ role(): string;
963
+ resolve(ref: string): Promise<Resolution>;
964
+ state(runId: string): Promise<RunFacts>;
965
+ tell(targetRunId: string, message: string): Promise<ProviderResult>;
966
+ ask(targetRunId: string, message: string, timeoutMs?: number, signal?: AbortSignal): Promise<ProviderResult>;
967
+ reply(inboundAskId: string, message: string, askerRunId: string): Promise<ProviderResult>;
968
+ withdraw(messageId: string): Promise<ProviderResult>;
969
+ controlReply?(target: string, payload: unknown): Promise<ProviderResult>;
970
+ /** `target` is the RESOLVED runtime id; the provider mints runId and paths. */
971
+ resume(req: {
972
+ target: string;
973
+ message: string;
974
+ label?: string;
975
+ idempotencyKey?: string;
976
+ }): Promise<ProviderResult>;
977
+ rename(req: {
978
+ sessionId?: string;
979
+ name: string;
980
+ }): Promise<ProviderResult>;
981
+ last(runId: string): Promise<ProviderResult>;
982
+ peers(): Promise<PeersProviderResult>;
983
+ /** Host surfaces that own a turn loop publish their own finished turn. */
984
+ recordLastTurn?(text: string, stopReason: string, truncated: boolean): Promise<void>;
985
+ claimAsk?(messageId: string): string | undefined;
986
+ restoreAsk?(messageId: string, askerRunId: string): void;
987
+ /** Drop a claim once the asker has the answer; the claim map may belong to the surface. */
988
+ releaseAsk?(messageId: string): void;
989
+ onResumed?(result: ProviderResult): void | Promise<void>;
990
+ registerResumed?(result: ProviderResult): void | Promise<void>;
991
+ }
992
+ /** A typed tool denial: one fixed code and the rendered sentence. */
993
+ declare class ToolError extends Error {
994
+ readonly code: string;
995
+ readonly facts: Record<string, string>;
996
+ constructor(code: string, message: string, facts?: Record<string, string>);
997
+ }
998
+ interface MessageInput {
999
+ action: 'tell' | 'ask' | 'reply' | 'resume' | 'withdraw' | 'control_reply';
1000
+ target?: string;
1001
+ message?: string;
1002
+ reply_to?: string;
1003
+ message_id?: string;
1004
+ timeout_ms?: number;
1005
+ label?: string;
1006
+ idempotency_key?: string;
1007
+ payload?: Record<string, unknown>;
1008
+ }
1009
+ interface PeersInput {
1010
+ action?: 'list' | 'rename' | 'last';
1011
+ name?: string;
1012
+ session_id?: string;
1013
+ target?: string;
1014
+ }
1015
+ interface PeersRouterResult {
1016
+ action: 'list' | 'rename' | 'last';
1017
+ outcome?: MessageOutcome;
1018
+ text: string;
1019
+ peers: PeerRecord[];
1020
+ renamed?: {
1021
+ run_id: string;
1022
+ label: string;
1023
+ previous_label: string;
1024
+ };
1025
+ last?: {
1026
+ run_id: string;
1027
+ runtime_id: string;
1028
+ label: string;
1029
+ final_output: string;
1030
+ stop_reason: string;
1031
+ final_output_truncated: boolean;
1032
+ };
754
1033
  }
755
- declare const peersTool: (args: PeersToolArgs) => Promise<PeersResult>;
1034
+ /**
1035
+ * Phase 1 for avenor_message: the action enum, the action's permitted and
1036
+ * required field sets, and each field's declared wire type and limits. The
1037
+ * table is the one the Go router validates against.
1038
+ */
1039
+ declare function assertMessageInput(input: unknown): asserts input is MessageInput;
1040
+ /**
1041
+ * Phase 1 for avenor_peers. An omitted action means `list`; a present but
1042
+ * non-string or unknown action is one invalid action, like the Go router.
1043
+ */
1044
+ declare function assertPeersInput(input: unknown): asserts input is PeersInput;
1045
+ /** Route one avenor_message call through one provider. */
1046
+ declare function executeMessage(provider: MessageProvider, input: unknown, options?: {
1047
+ signal?: AbortSignal;
1048
+ }): Promise<ProviderResult>;
1049
+ /** Route one avenor_peers call through one provider. */
1050
+ declare function executePeers(provider: MessageProvider, input: unknown): Promise<PeersRouterResult>;
1051
+ /**
1052
+ * Render the peers list block the surfaces show: the one list text for the
1053
+ * shared records, so every surface that routes through the router renders a
1054
+ * peer identically.
1055
+ */
1056
+ declare function renderPeerList(records: PeerRecord[]): string;
1057
+ /**
1058
+ * The one result object every surface returns for a routed message call.
1059
+ * Snake_case and the contract field set, exactly like the Go router's
1060
+ * `Result.Output()`: a fact that is absent is a key that is absent, `text` is
1061
+ * always present, and the resume paths travel with the result that minted them.
1062
+ */
1063
+ declare function resultOutput(result: ProviderResult): Record<string, unknown>;
1064
+ /**
1065
+ * The one structured result every surface returns for a peers call, matching
1066
+ * `router.PeersDetails` field for field: `list` carries the peer records,
1067
+ * `rename` the new and previous label, `last` the recorded turn. An optional
1068
+ * peer field that is absent is a key that is absent.
1069
+ */
1070
+ declare function peersDetails(result: PeersRouterResult): Record<string, unknown>;
756
1071
  //#endregion
757
- //#region src/tools/cancel.d.ts
758
- interface CancelToolArgs {
759
- messageId: string;
760
- supervisorId?: string;
1072
+ //#region src/tools/message.d.ts
1073
+ /**
1074
+ * The one avenor_message handler: every surface routes through it, so the six
1075
+ * actions and their failure text exist once. A router tool error is thrown as a
1076
+ * typed Error, which each surface reports as its own error result.
1077
+ */
1078
+ declare function messageTool(args: unknown, provider: MessageProvider, options?: {
1079
+ signal?: AbortSignal;
1080
+ }): Promise<ProviderResult>;
1081
+ /** Bind the handler to one provider. */
1082
+ declare function createMessageTool(provider: MessageProvider): (args: unknown, options?: {
1083
+ signal?: AbortSignal;
1084
+ }) => Promise<ProviderResult>;
1085
+ //#endregion
1086
+ //#region src/tools/message-provider.d.ts
1087
+ /** The control-client surface a host provider needs, narrowed for testability. */
1088
+ interface MessageClient {
1089
+ messageSend(params: {
1090
+ to_run_id: string;
1091
+ message_id: string;
1092
+ generation: string;
1093
+ body: string;
1094
+ no_reply?: boolean;
1095
+ }): Promise<MessageSendResult>;
1096
+ messageWait(params: {
1097
+ message_id: string;
1098
+ generation: string;
1099
+ timeout_ms?: number;
1100
+ }): Promise<MessageWaitResult>;
1101
+ messageReply(params: {
1102
+ to_run_id: string;
1103
+ message_id: string;
1104
+ correlation_id?: string;
1105
+ body: string;
1106
+ }): Promise<MessageSendResult>;
1107
+ messageWithdraw(params: {
1108
+ message_id: string;
1109
+ generation: string;
1110
+ }): Promise<MessageWithdrawResult>;
1111
+ messagePeers(params: {
1112
+ generation: string;
1113
+ }): Promise<MessagePeersResult>;
1114
+ resume(params: {
1115
+ run_id: string;
1116
+ target: string;
1117
+ message: string;
1118
+ label?: string;
1119
+ idempotency_key?: string;
1120
+ sentinel_file?: string;
1121
+ on_event?: string;
1122
+ }): Promise<ResumeResult>;
1123
+ sessionRename(sessionId: string, name: string): Promise<SessionRenameResult>;
1124
+ sessionLast(runtimeId: string): Promise<SessionLastResult>;
1125
+ sessionLastSet(runtimeId: string, finalOutput: string, stopReason: string, truncated: boolean): Promise<void>;
1126
+ status(runtimeId?: string): Promise<Record<string, unknown>>;
761
1127
  }
762
- interface CancelResult {
763
- cancelled: boolean;
1128
+ /** One route's answer from a child surface's inherited broker. */
1129
+ interface ChildBroker {
1130
+ tell(targetRunId: string, message: string, messageId: string): Promise<ProviderResult>;
1131
+ ask(targetRunId: string, message: string, messageId: string, timeoutMs?: number, signal?: AbortSignal): Promise<ProviderResult>;
1132
+ reply(askerRunId: string, inboundAskId: string, message: string): Promise<ProviderResult>;
1133
+ withdraw(messageId: string): Promise<ProviderResult>;
1134
+ peers(): Promise<PeersProviderResult>;
1135
+ rename(req: {
1136
+ sessionId?: string;
1137
+ name: string;
1138
+ }): Promise<ProviderResult>;
1139
+ last(runId: string): Promise<ProviderResult>;
1140
+ }
1141
+ interface PendingAsk {
1142
+ from_run_id: string;
1143
+ message_id: string;
764
1144
  }
765
- declare const cancelTool: (args: CancelToolArgs) => Promise<CancelResult>;
1145
+ declare const SUPERVISOR_RUN_ID = "supervisor";
1146
+ /** The broker rejected a receive because the caller's generation is stale. */
1147
+ declare function isGenerationMismatchError(error: unknown): boolean;
1148
+ interface HostProviderOptions {
1149
+ surface: MessageSurface;
1150
+ supervisorId: string;
1151
+ generation: string;
1152
+ client: MessageClient;
1153
+ /** The pending inbound asks the surface's poll fills; absent = no inbound. */
1154
+ pendingAsks?: Map<string, PendingAsk>;
1155
+ /** The poll generation a restore is scoped to, so a restart cannot resurrect an ask. */
1156
+ pollGeneration?: () => number;
1157
+ /** Runs after a successful resume registration; the surface's own tracking. */
1158
+ onResumed?: (result: ProviderResult) => void | Promise<void>;
1159
+ }
1160
+ type AskClaims = Map<string, {
1161
+ asker: string;
1162
+ generation: number;
1163
+ }>;
1164
+ /** Install the claim/restore pair both factories share, so a restart cannot resurrect a stale ask. */
1165
+ declare function installAskClaims(provider: MessageProvider, claims: AskClaims, pendingAsks: Map<string, PendingAsk>, pollGeneration: (() => number) | undefined): void;
1166
+ /**
1167
+ * Build the bound host provider: one supervisor, one generation, one control
1168
+ * client. It never reads an ambient singleton or retargets, and it never
1169
+ * preflights per call.
1170
+ */
1171
+ declare function createHostMessageProvider(options: HostProviderOptions): MessageProvider;
1172
+ interface ChildProviderOptions {
1173
+ surface: MessageSurface;
1174
+ runId: string;
1175
+ broker: ChildBroker;
1176
+ /** The pending inbound asks the child's poll fills. */
1177
+ pendingAsks?: Map<string, PendingAsk>;
1178
+ /** The poll generation a restore is scoped to, so a restart cannot resurrect an ask. */
1179
+ pollGeneration?: () => number;
1180
+ }
1181
+ /**
1182
+ * Build a child provider over the surface's inherited broker. A child never
1183
+ * learns a public run id, and it cannot read a sentinel, so it is never
1184
+ * resumable from here: the supervisor owns a resume.
1185
+ */
1186
+ declare function createChildMessageProvider(options: ChildProviderOptions): MessageProvider;
1187
+ //#endregion
1188
+ //#region src/tools/peers.d.ts
1189
+ interface PeersToolArgs extends PeersInput {}
1190
+ type PeersResult = PeersRouterResult;
1191
+ /** The one avenor_peers handler; it resolves and reads through the bound provider. */
1192
+ declare function peersTool(args: PeersToolArgs, provider: MessageProvider): Promise<PeersResult>;
1193
+ /** Bind the peers handler to one provider. */
1194
+ declare function createPeersTool(provider: MessageProvider): (args: PeersToolArgs) => Promise<PeersResult>;
766
1195
  //#endregion
767
1196
  //#region src/tools/kill.d.ts
768
1197
  interface KillToolArgs {
@@ -779,6 +1208,10 @@ declare const killTool: (args: KillToolArgs) => Promise<KillResult>;
779
1208
  //#region src/tools/broker-receive.d.ts
780
1209
  interface BrokerReceiveArgs {
781
1210
  supervisorId?: string;
1211
+ /** The generation this poll is bound to; absent asks the tool to preflight once. */
1212
+ generation?: string;
1213
+ /** Bound on the receive wait; the caller owns it, so the tool adds no default. */
1214
+ timeout_ms?: number;
782
1215
  }
783
1216
  interface InboundAsk {
784
1217
  from_run_id: string;
@@ -788,21 +1221,11 @@ interface InboundAsk {
788
1221
  }
789
1222
  interface BrokerReceiveResult {
790
1223
  asks: InboundAsk[];
1224
+ /** The generation the receive ran under, so the caller can bind its next poll. */
1225
+ generation?: string;
791
1226
  }
792
1227
  declare const brokerReceiveTool: (args: BrokerReceiveArgs) => Promise<BrokerReceiveResult>;
793
1228
  //#endregion
794
- //#region src/tools/broker-reply.d.ts
795
- interface BrokerReplyArgs {
796
- toRunId: string;
797
- replyTo: string;
798
- message: string;
799
- supervisorId?: string;
800
- }
801
- interface BrokerReplyResult {
802
- ok: true;
803
- }
804
- declare const brokerReplyTool: (args: BrokerReplyArgs) => Promise<BrokerReplyResult>;
805
- //#endregion
806
1229
  //#region src/tools/workflow-client.d.ts
807
1230
  type GetSupervisorClient = typeof getSupervisorClient;
808
1231
  //#endregion
@@ -880,4 +1303,19 @@ type WorkflowReadyResult = Record<string, unknown>;
880
1303
  declare function createWorkflowReadyTool(getSupervisorClient: GetSupervisorClient): (args: WorkflowReadyToolArgs) => Promise<WorkflowReadyResult>;
881
1304
  declare const workflowReadyTool: (args: WorkflowReadyToolArgs) => Promise<WorkflowReadyResult>;
882
1305
  //#endregion
883
- export { type AskResult, type AskToolArgs, type BrokerReceiveArgs, type BrokerReceiveResult, type BrokerReplyArgs, type BrokerReplyResult, type CancelResult, type CancelToolArgs, type Client, DEFAULT_RUN_REDUCER_LIMITS, type Event, type ExecutionIdentity, type FollowUpToolArgs, type FollowUpToolResult, ForeignPeerError, type HistoryOptions, type HistoryResult, type InboundAsk, type InspectResult, type KillResult, type KillToolArgs, type NormalizedRunEvent, type ObserveRunOptions, type OwnerAttachOptions, OwnerAuthError, OwnerRecordMissingError, type PeerEntry, type PeersResult, type ResultResult, type ResultToolArgs, RpcError, type RunChunkRole, type RunIdentity, type RunInfo, type RunObserver, type RunObserverClient, type RunPermissionOption, type RunPermissionSummary, RunReducer, type RunReducerLimits, type RunSnapshot, type RunSnapshotSeed, type RunToolState, type RunToolSummary, type RunTranscriptEntry, type SpawnMetadata, type SpawnParams, type SpawnResult, type SpawnSelectionInput, type SpawnToolArgs, type SpawnToolResult, StaleOwnerRecordError, type StatusListResult, type StatusResult, type StatusToolArgs, type StatusView, type SubscribeOptions, Supervisor, type SupervisorOptions, THINKING_LEVELS, type ThinkingLevel, type ThinkingOutcome, type WorkflowCompleteParams, type WorkflowCompleteResult, type WorkflowCompleteToolArgs, type WorkflowControllerCreateParams, type WorkflowControllerStatusResult, type WorkflowControllerStatusToolArgs, type WorkflowEventsResult, type WorkflowEventsToolArgs, type WorkflowGateOperation, type WorkflowGateParams, type WorkflowGateResult, type WorkflowGateToolArgs, type WorkflowHeartbeatParams, type WorkflowInspectResult, type WorkflowInspectToolArgs, type WorkflowReadyResult, type WorkflowReadyToolArgs, type WorkflowStatusResult, type WorkflowStatusToolArgs, type WorkflowWaitResult, type WorkflowWaitToolArgs, answerPermissionTool, askTool, attachOwner, brokerReceiveTool, brokerReplyTool, cancelTool, createRunSnapshot, createWorkflowCompleteTool, createWorkflowControllerStatusTool, createWorkflowEventsTool, createWorkflowGateTool, createWorkflowInspectTool, createWorkflowReadyTool, createWorkflowStatusTool, createWorkflowWaitTool, dial, evaluateThinkingPolicy, eventsTool, extractEventText, extractReplyMessage, findAvenorBinary, followUpTool, formatAskFailure, getInstallDir, getVersion, inspectTool, installerBinaryPath, isThinkingLevel, killTool, normalizeAskTimeoutMs, normalizeRunEvent, observeRun, peersTool, reduceRunSnapshot, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool, validateSpawnSelection, validateThinking, validateThinkingForBackend, validateThinkingForBackendResume, workflowCompleteTool, workflowControllerStatusTool, workflowEventsTool, workflowGateTool, workflowInspectTool, workflowReadyTool, workflowStatusTool, workflowWaitTool };
1306
+ //#region src/tools/workflow-cancel.d.ts
1307
+ interface WorkflowCancelArgs {
1308
+ workflow_id: string;
1309
+ actor: string;
1310
+ reason: string;
1311
+ supervisorId?: string;
1312
+ }
1313
+ type WorkflowCancelResult = Record<string, unknown>;
1314
+ /**
1315
+ * Cancel a workflow. The manager validates the actor before the reason, so the
1316
+ * handler checks them in the same order and forwards all three unchanged.
1317
+ */
1318
+ declare function createWorkflowCancelTool(getSupervisorClient: GetSupervisorClient): (args: WorkflowCancelArgs) => Promise<WorkflowCancelResult>;
1319
+ declare const workflowCancelTool: (args: WorkflowCancelArgs) => Promise<WorkflowCancelResult>;
1320
+ //#endregion
1321
+ export { type AskClaims, type BrokerReceiveArgs, type BrokerReceiveResult, type ChildBroker, type Client, ClosedSocketError, DEFAULT_RUN_REDUCER_LIMITS, type Event, type ExecutionIdentity, ForeignPeerError, type HistoryOptions, type HistoryResult, type InboundAsk, type InspectResult, type KillResult, type KillToolArgs, MAX_FINAL_OUTPUT_RUNES, MAX_WAIT_MS, MESSAGE_OUTCOMES, type MessageCallerKind, type MessageClient, type MessageInput, type MessageOutcome, type MessageProvider, type MessageSurface, type NormalizedRunEvent, type ObserveRunOptions, type OwnerAttachOptions, OwnerAuthError, OwnerRecordMissingError, type PeerRecord, type PeersInput, type PeersProviderResult, type PeersResult, type PeersRouterResult, type PeersToolArgs, type PendingAsk, type ProviderResult, type Resolution, type ResultResult, type ResultToolArgs, RpcError, type RunChunkRole, type RunFacts, type RunIdentity, type RunInfo, type RunObserver, type RunObserverClient, type RunPermissionOption, type RunPermissionSummary, RunReducer, type RunReducerLimits, type RunSnapshot, type RunSnapshotSeed, type RunToolState, type RunToolSummary, type RunTranscriptEntry, SUPERVISOR_RUN_ID, type SpawnMetadata, type SpawnParams, type SpawnResult, type SpawnSelectionInput, type SpawnToolArgs, type SpawnToolResult, StaleOwnerRecordError, type StatusListResult, type StatusResult, type StatusToolArgs, type StatusView, type SubscribeOptions, Supervisor, type SupervisorClientOptions, type SupervisorOptions, THINKING_LEVELS, type ThinkingLevel, type ThinkingOutcome, ToolError, type WorkflowCancelArgs, type WorkflowCancelResult, type WorkflowCompleteParams, type WorkflowCompleteResult, type WorkflowCompleteToolArgs, type WorkflowControllerCreateParams, type WorkflowControllerStatusResult, type WorkflowControllerStatusToolArgs, type WorkflowEventsResult, type WorkflowEventsToolArgs, type WorkflowGateOperation, type WorkflowGateParams, type WorkflowGateResult, type WorkflowGateToolArgs, type WorkflowHeartbeatParams, type WorkflowInspectResult, type WorkflowInspectToolArgs, type WorkflowReadyResult, type WorkflowReadyToolArgs, type WorkflowStatusResult, type WorkflowStatusToolArgs, type WorkflowWaitResult, type WorkflowWaitToolArgs, answerPermissionTool, assertMessageInput, assertPeersInput, attachOwner, boundFinalOutput, brokerReceiveTool, createChildMessageProvider, createHostMessageProvider, createMessageTool, createPeersTool, createRunSnapshot, createWorkflowCancelTool, createWorkflowCompleteTool, createWorkflowControllerStatusTool, createWorkflowEventsTool, createWorkflowGateTool, createWorkflowInspectTool, createWorkflowReadyTool, createWorkflowStatusTool, createWorkflowWaitTool, dial, evaluateThinkingPolicy, eventsTool, executeMessage, executePeers, extractEventText, extractReplyMessage, extractTurnText, findAvenorBinary, getInstallDir, getSupervisorClient, getVersion, inspectTool, installAskClaims, installerBinaryPath, isClosedSocketError, isGenerationMismatchError, isThinkingLevel, killTool, messageTool, newMsgID, normalizeAskTimeoutMs, normalizeRunEvent, normalizeTurnStopReason, observeRun, peersDetails, peersTool, quote, quoteList, reduceRunSnapshot, renderAskFailure, renderLast, renderOutcome, renderPeerList, repair, resultOutput, resultTool, sanitize, shutdownTool, socketsRoot, spawnTool, statusTool, validateSpawnSelection, validateThinking, validateThinkingForBackend, validateThinkingForBackendResume, workflowCancelTool, workflowCompleteTool, workflowControllerStatusTool, workflowEventsTool, workflowGateTool, workflowInspectTool, workflowReadyTool, workflowStatusTool, workflowWaitTool };