@intx/hub-sessions 0.3.0 → 0.4.0

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.
Files changed (67) hide show
  1. package/dist/agent-repo.d.ts +14 -2
  2. package/dist/agent-repo.js +17 -4
  3. package/dist/agent-state-kind.js +14 -63
  4. package/dist/asset-service.js +14 -10
  5. package/dist/credential-push.d.ts +48 -4
  6. package/dist/credential-push.js +138 -6
  7. package/dist/event-collector-registry.d.ts +2 -1
  8. package/dist/event-collector-registry.js +38 -9
  9. package/dist/event-collector.d.ts +11 -1
  10. package/dist/event-collector.js +36 -3
  11. package/dist/hub-session-lookups.d.ts +1 -1
  12. package/dist/hub-session-lookups.js +68 -72
  13. package/dist/hub-session-orchestrator.d.ts +2 -3
  14. package/dist/hub-session-orchestrator.js +13 -12
  15. package/dist/index.d.ts +7 -6
  16. package/dist/index.js +7 -6
  17. package/dist/reconciliation-scheduler.d.ts +14 -0
  18. package/dist/reconciliation-scheduler.js +55 -0
  19. package/dist/repo-store/index.d.ts +1 -0
  20. package/dist/repo-store/index.js +1 -0
  21. package/dist/repo-store/user-principal-gate.d.ts +26 -0
  22. package/dist/repo-store/user-principal-gate.js +78 -0
  23. package/dist/session-service.d.ts +66 -121
  24. package/dist/session-service.js +444 -411
  25. package/dist/sidecar-allocation/capability-policy.d.ts +27 -0
  26. package/dist/sidecar-allocation/capability-policy.js +124 -0
  27. package/dist/sidecar-allocation/contracts.d.ts +29 -6
  28. package/dist/sidecar-allocation/contracts.js +7 -2
  29. package/dist/sidecar-allocation/index.d.ts +4 -3
  30. package/dist/sidecar-allocation/index.js +3 -2
  31. package/dist/sidecar-allocation/operation.d.ts +10 -0
  32. package/dist/sidecar-allocation/operation.js +54 -0
  33. package/dist/sidecar-allocation/plugin-registry.d.ts +16 -3
  34. package/dist/sidecar-allocation/plugin-registry.js +36 -12
  35. package/dist/sidecar-allocation/reconciler.d.ts +16 -4
  36. package/dist/sidecar-allocation/reconciler.js +486 -92
  37. package/dist/skill-kind.js +8 -62
  38. package/dist/substrate.d.ts +1 -1
  39. package/dist/substrate.js +1 -1
  40. package/dist/workflow-allocation-service.d.ts +21 -15
  41. package/dist/workflow-allocation-service.js +440 -125
  42. package/dist/workflow-dispatch-service.d.ts +4 -2
  43. package/dist/workflow-dispatch-service.js +89 -26
  44. package/dist/workflow-kind.d.ts +12 -0
  45. package/dist/workflow-kind.js +17 -60
  46. package/dist/workflow-probe-gate.d.ts +99 -27
  47. package/dist/workflow-probe-gate.js +196 -21
  48. package/dist/workflow-run-kind.d.ts +112 -19
  49. package/dist/workflow-run-kind.js +626 -210
  50. package/dist/workflow-run-restore.d.ts +1 -0
  51. package/dist/workflow-run-restore.js +5 -1
  52. package/dist/workflow-source-pins.d.ts +8 -0
  53. package/dist/workflow-source-pins.js +14 -0
  54. package/dist/ws/index.d.ts +1 -1
  55. package/dist/ws/index.js +1 -1
  56. package/dist/ws/pending-tracker.d.ts +93 -0
  57. package/dist/ws/pending-tracker.js +132 -0
  58. package/dist/ws/sidecar-events.d.ts +43 -29
  59. package/dist/ws/sidecar-events.js +0 -2
  60. package/dist/ws/sidecar-handler.d.ts +122 -85
  61. package/dist/ws/sidecar-handler.js +925 -878
  62. package/dist/ws/sidecar-handler.test-helpers.d.ts +38 -0
  63. package/dist/ws/sidecar-handler.test-helpers.js +95 -0
  64. package/dist/ws/sidecar-token-authenticator.js +37 -23
  65. package/package.json +13 -13
  66. package/dist/sidecar-allocation/placement-policy.d.ts +0 -11
  67. package/dist/sidecar-allocation/placement-policy.js +0 -21
@@ -1,7 +1,7 @@
1
- import { type DB } from "@intx/db";
1
+ import { type DB, type SidecarAllocation } from "@intx/db";
2
2
  import type { CredentialDelivery } from "@intx/types/sidecar";
3
3
  import type { CredentialCipher } from "@intx/types";
4
- import type { CryptoProvider, HarnessConfig, InferenceSource, MessageAttachment } from "@intx/types/runtime";
4
+ import type { HarnessConfig, InferenceSource } from "@intx/types/runtime";
5
5
  import { type RegistryConfig, type ScopeRoute } from "@intx/tool-packaging";
6
6
  import { type ToolPackagePin } from "@intx/types/tool-packages";
7
7
  import type { SourceRefPin, WorkflowProjectionWithSources, WorkflowSourceAssetMount } from "@intx/types/sidecar";
@@ -9,9 +9,10 @@ import type { WorkflowDefinitionAssetSource, WorkflowDefinitionRegistrySource, W
9
9
  import { type DeployContent as OrchestratorDeployContent } from "@intx/workflow-deploy";
10
10
  import type { AgentRepoStore, DeployContent } from "./agent-repo.js";
11
11
  import { type AssetService } from "./asset-service.js";
12
- import type { AllocatedSidecarTarget, SidecarAllocationRouter, SidecarRouter } from "./ws/sidecar-handler.js";
12
+ import type { AllocatedSidecarTarget, SidecarAllocationRouter, SidecarRouter, WorkflowProbeResult } from "./ws/sidecar-handler.js";
13
13
  import { type ResolveAssetAttachmentFn } from "./workflow-closure-resolution.js";
14
14
  import { type InstallAndApproveResult } from "./workflow-probe-gate.js";
15
+ import type { SidecarReconciliationContext } from "./sidecar-allocation/operation.js";
15
16
  export declare class SessionLaunchError extends Error {
16
17
  /** Which phase failed: "write", "provision", "pack", or "start". */
17
18
  readonly phase: string;
@@ -36,35 +37,8 @@ export type SessionService = {
36
37
  config: HarnessConfig;
37
38
  deployContent: DeployContent;
38
39
  toolPackagePins?: readonly ToolPackagePin[];
39
- allocationTarget?: AllocatedSidecarTarget;
40
+ allocationTarget: AllocatedSidecarTarget;
40
41
  }): Promise<void>;
41
- /**
42
- * Deploy a CODE-SOURCED workflow definition end to end: install + probe +
43
- * gate + freeze (`approve-probed`), then deploy the frozen definition by
44
- * source-ref. This is the general workflow deploy entry point the
45
- * `POST /deployments` route drives; it never hydrates a live definition from a
46
- * static `workflow.json`.
47
- *
48
- * The service owns the source-read wiring (`repoStore` committed reads and
49
- * asset pack fan-out) and the registry configuration, so the caller passes
50
- * only the deploy intent: where the definition's bytes come from
51
- * (`source`/`entry`/`pin`), the `workflow`-kind asset the definition projects
52
- * over (`definitionAssetId`), and the shared harness config. The method
53
- * dispatches on `source.kind`/`source.package.format` to build the install
54
- * args, pins every top-level step's inference source under the frozen
55
- * approval, and persists the deployment's anchor run.
56
- *
57
- * Persists the deployment's anchor `workflow_run` (id = `anchorRunId`) via
58
- * `deployCodeSourcedWorkflow`, so the deployment is listable per tenant.
59
- * Returns the supervisor's principal public key from the sidecar deploy ack.
60
- */
61
- deployWorkflowFromSource(params: DeployWorkflowFromSourceParams): Promise<DeployWorkflowDefinitionResult>;
62
- /**
63
- * Compose a signed RFC 2822 message from the user and deliver it to the
64
- * agent via the mail transport. Throws if the agent is unreachable.
65
- * Returns the raw MIME bytes of the assembled message.
66
- */
67
- sendUserMessage(params: UserMessageParams): Promise<Uint8Array>;
68
42
  /**
69
43
  * Undeploy an agent and wait for the sidecar to acknowledge.
70
44
  */
@@ -78,50 +52,11 @@ export type DeployWorkflowDefinitionResult = {
78
52
  /** Supervisor principal public key from the sidecar's deploy ack. */
79
53
  publicKey: string;
80
54
  };
81
- export type DeployWorkflowFromSourceParams = {
82
- /** Owning tenant; recorded on the deployment's anchor run. */
83
- tenantId: string;
84
- /**
85
- * Stable deployment identifier and anchor-run id. The deployment-level
86
- * address derives from it; the caller owns its generation.
87
- */
88
- anchorRunId: string;
89
- /** Mail domain the deployment's derived addresses live under. */
90
- deploymentDomain: string;
91
- /**
92
- * The deployment-level mail address, derived by the caller from `anchorRunId`
93
- * + `deploymentDomain`. Re-derived and asserted coherent inside
94
- * `deployCodeSourcedWorkflow`.
95
- */
96
- agentAddress: string;
97
- /** Where the definition's bytes come from at apply time. */
98
- source: WorkflowDefinitionSource;
99
- /** The `interchange.workflow` entry-module path the sidecar evaluates. */
100
- entry: string;
101
- /**
102
- * A `name@range` spec for the definition package. REQUIRED for the `registry`
103
- * and asset-`tarball` variants (the pin selects the member); omitted for the
104
- * asset-`source` variant, whose member is selected by `package.packageName`.
105
- */
106
- pin?: string;
107
- /**
108
- * The `workflow`-kind asset the frozen definition projects a
109
- * `workflow_definition` over. Distinct from a `source.kind === "asset"`
110
- * source's `assetId`, which names where the bytes live.
111
- */
112
- definitionAssetId: string;
113
- /**
114
- * Harness config shared across the deployment. Its `sources`/`defaultSource`
115
- * are the operator-supplied inference chain; the method pins each top-level
116
- * step to one approved source from it.
117
- */
118
- config: HarnessConfig;
119
- };
120
55
  /**
121
56
  * Install/probe/gate/freeze inputs for a code-sourced workflow, DECOUPLED from
122
- * deploy. The exclusive prepare path calls this on shared capacity at request
123
- * time to freeze the approval, persists the frozen bundle, and deploys it to a
124
- * dedicated allocation later with no re-probe.
57
+ * deploy. The provisioned prepare path calls this on probe-scoped capacity,
58
+ * persists the frozen bundle, and deploys it to the workflow allocation later
59
+ * with no re-probe.
125
60
  */
126
61
  export type InstallAndApproveWorkflowSourceParams = {
127
62
  /** Where the definition's bytes come from at probe time. */
@@ -135,6 +70,10 @@ export type InstallAndApproveWorkflowSourceParams = {
135
70
  pin?: string;
136
71
  /** The `workflow`-kind asset the frozen definition projects a definition over. */
137
72
  definitionAssetId: string;
73
+ /** The exact provisioned generation that executes the probe. */
74
+ allocationTarget: AllocatedSidecarTarget;
75
+ /** Optional durable handoff invoked with the raw probe answer. */
76
+ onProbeResult?: (result: WorkflowProbeResult) => Promise<void>;
138
77
  };
139
78
  /**
140
79
  * Inputs to deploy a previously-frozen code-sourced approval bundle to a
@@ -160,13 +99,15 @@ export type DeployPreparedCodeSourcedWorkflowParams = {
160
99
  config: HarnessConfig;
161
100
  /** The exact allocation generation to deploy onto. */
162
101
  allocationTarget: AllocatedSidecarTarget;
102
+ /** Current owner and cancellation of this initialization attempt. */
103
+ reconciliation: SidecarReconciliationContext;
163
104
  /** Cipher for the definition's tenant-owned credential bindings, if any. */
164
105
  credentialCipher?: CredentialCipher;
165
106
  };
166
107
  export type PreparedWorkflowDeployer = {
167
108
  /**
168
- * Install + probe + gate + freeze a code-sourced definition on shared
169
- * capacity, returning the frozen bundle WITHOUT deploying it. The exclusive
109
+ * Install + probe + gate + freeze a code-sourced definition, returning the
110
+ * frozen bundle WITHOUT deploying it. The provisioned
170
111
  * prepare path persists the bundle and deploys it later via
171
112
  * `deployPreparedCodeSourcedWorkflow`.
172
113
  */
@@ -179,22 +120,9 @@ export type PreparedWorkflowDeployer = {
179
120
  */
180
121
  deployPreparedCodeSourcedWorkflow(params: DeployPreparedCodeSourcedWorkflowParams): Promise<DeployWorkflowDefinitionResult>;
181
122
  };
182
- export type UserMessageParams = {
183
- agentAddress: string;
184
- from: string;
185
- messageId: string;
186
- date: Date;
187
- content: string;
188
- attachments?: MessageAttachment[];
189
- inReplyTo?: string;
190
- references?: string[];
191
- sessionId: string;
192
- tenantId: string;
193
- cryptoProvider: CryptoProvider;
194
- };
195
123
  export type SessionServiceDeps = {
196
124
  sidecarRouter: SidecarRouter;
197
- /** Present when this Hub can route deploy phases to exclusive allocations. */
125
+ /** Present when this Hub can route deploy phases to provisioned allocations. */
198
126
  sidecarAllocationRouter?: SidecarAllocationRouter;
199
127
  agentRepoStore: AgentRepoStore;
200
128
  /**
@@ -258,9 +186,8 @@ export type SessionServiceDeps = {
258
186
  export declare function bridgeOrchestratorDeployContent(content: OrchestratorDeployContent): DeployContent;
259
187
  /** Fields the deploy frame carries onto `sendAgentDeploy`. */
260
188
  type DeployFrameCommonArgs = {
261
- sidecarRouter: SidecarRouter;
262
- sidecarAllocationRouter?: SidecarAllocationRouter;
263
- allocationTarget?: AllocatedSidecarTarget;
189
+ sidecarAllocationRouter: SidecarAllocationRouter;
190
+ allocationTarget: AllocatedSidecarTarget;
264
191
  agentAddress: string;
265
192
  config: HarnessConfig;
266
193
  sources: Record<string, InferenceSource[]>;
@@ -303,8 +230,8 @@ export type SourceRefDeployFrameArgs = DeployFrameCommonArgs & {
303
230
  * The projection's inline onTrigger section bodies, each already in inert wire
304
231
  * form with its per-step inference sources pinned and its own wire hash --
305
232
  * built by `deployCodeSourcedWorkflow` from the frozen projection. The sidecar
306
- * stages each body's `sources.json` (and re-verify hash). Absent when the
307
- * projection has no inline onTrigger body.
233
+ * seals each body's sources into the run record and re-verifies against its
234
+ * wire hash. Absent when the projection has no inline onTrigger body.
308
235
  */
309
236
  referencedDefinitions?: readonly WorkflowProjectionWithSources[];
310
237
  /**
@@ -332,7 +259,7 @@ export type SendMultiStepDeployFrameArgs = SourceRefDeployFrameArgs;
332
259
  * closure reaches the wire surface via `sendAgentDeploy` with a `workflow`
333
260
  * field structurally matching the `AgentDeployFrame.workflow` schema.
334
261
  */
335
- export declare function sendMultiStepDeployFrame(args: SendMultiStepDeployFrameArgs): Promise<{
262
+ export declare function sendMultiStepDeployFrame(args: SendMultiStepDeployFrameArgs, signal?: AbortSignal, beforeSend?: () => Promise<void>): Promise<{
336
263
  publicKey: string;
337
264
  }>;
338
265
  /**
@@ -364,19 +291,12 @@ type DeployCodeSourcedCommonArgs = DeployFrameCommonArgs & {
364
291
  anchorRunId: string;
365
292
  deploymentDomain: string;
366
293
  /**
367
- * Credential cipher, REQUIRED only when the definition carries credential
368
- * bindings (resolution fails closed without it); omit for a binding-free
369
- * deployment.
294
+ * Credential cipher, REQUIRED whenever the definition carries credential
295
+ * bindings OR any pinned inference source (top-level or inline body) references
296
+ * a credential; resolution fails closed without it. Omit only for a deploy with
297
+ * neither.
370
298
  */
371
299
  credentialCipher?: CredentialCipher;
372
- /**
373
- * Present only for a prepared exclusive deploy: route the source-ref frame to
374
- * this dedicated allocation instead of the shared router. `sidecarAllocationRouter`
375
- * carries the allocation transport and is REQUIRED whenever `allocationTarget`
376
- * is set. A shared deploy omits both.
377
- */
378
- allocationTarget?: AllocatedSidecarTarget;
379
- sidecarAllocationRouter?: SidecarAllocationRouter;
380
300
  };
381
301
  /** Deploy a definition published to an npm registry: the sidecar fetches its
382
302
  * tarballs over HTTP, so no source asset is delivered. */
@@ -392,25 +312,50 @@ export type DeployCodeSourcedAssetArgs = DeployCodeSourcedCommonArgs & {
392
312
  };
393
313
  export type DeployCodeSourcedWorkflowArgs = DeployCodeSourcedRegistryArgs | DeployCodeSourcedAssetArgs;
394
314
  /**
395
- * The single public composition entrypoint for a SHARED code-sourced (npm)
396
- * deploy: emit the source-ref frame, then INSERT the deployment's anchor
397
- * `workflow_run` row -- the deployment's first-class record that owns its
398
- * routing address and public key. Run-grant materialization keys off this row
399
- * (address + live status), so WITHOUT it no per-run grants (tool, capability, OR
400
- * credential) ever materialize for a source-ref deployment. Born "deployed"
401
- * (live but pre-trigger): the first trigger's materialization flips it to
402
- * "running" via `anchorWithPrincipal`'s guarded update, which a row born
403
- * "running" would skip. Its `anchorRunId` equals its own id, so the anchor
404
- * references itself. The deployer read grant is deferred to the production
405
- * route, which carries the authenticated deployer principal; this stays a
406
- * single insert with no grant row to pair atomically.
315
+ * A direct allocation-bound composition entrypoint for tests and low-level
316
+ * callers: prepare, INSERT the deployment's anchor `workflow_run` row, THEN emit
317
+ * the source-ref frame. The anchor row is the deployment's first-class record
318
+ * that owns its routing address and public key. Run-grant materialization keys
319
+ * off this row (address + live status), so WITHOUT it no per-run grants (tool,
320
+ * capability, OR credential) ever materialize for a source-ref deployment. Born
321
+ * "deployed" (live but pre-trigger) with a null public key: the first trigger's
322
+ * materialization flips it to "running" via `anchorWithPrincipal`'s guarded
323
+ * update, which a row born "running" would skip. Its `anchorRunId` equals its
324
+ * own id, so the anchor references itself. The deployer read grant is deferred
325
+ * to the production route, which carries the authenticated deployer principal.
326
+ *
327
+ * ORDERING IS LOAD-BEARING. The anchor row must be committed and visible to the
328
+ * pack-receipt connection BEFORE the frame reaches the wire: the frame spawns
329
+ * the child, whose first events pack races the ack back, and
330
+ * `receiveWorkflowRunPack` fails closed on a missing live anchor. Emitting first
331
+ * (the previous order) rejected that first pack and never bootstrapped the log.
332
+ * This works because `args.db` is the autocommit handle (`DB["db"]`, which the
333
+ * type forbids from being a transaction) and the INSERT is NOT wrapped in a
334
+ * transaction with the emit -- so the row is durably visible the instant the
335
+ * INSERT statement returns. Do NOT relax `db` to a transaction executor or wrap
336
+ * anchor+emit in one transaction to make them atomic: that reopens the race.
407
337
  *
408
- * The prepared exclusive path does NOT use this wrapper: its anchor row already
409
- * exists from prepare time, so it wraps `emitSourceRefDeployFrame` with an
410
- * UPDATE-under-allocation-lock instead of this INSERT.
338
+ * On emit failure the anchor row is rolled back or fenced by the `frameSent`
339
+ * evidence from the transport. `leakedAgent: false` (safe to fully roll back) is
340
+ * the STRONG claim and is made only on positive proof the frame never reached
341
+ * the wire (`isDeployFrameFailure && frameSent === false`); every other failure
342
+ * -- a sent-but-unacked frame OR any untagged error -- is treated as
343
+ * possibly-live: the anchor is fenced `deployed` -> `failed` and the error is
344
+ * `leakedAgent: true`.
345
+ *
346
+ * The prepared provisioned path does NOT use this composition: its anchor row
347
+ * already exists from prepare time, so it drives `emitSourceRefDeployFrame` and
348
+ * an UPDATE-under-allocation-lock instead.
411
349
  */
412
350
  export declare function deployCodeSourcedWorkflow(args: DeployCodeSourcedWorkflowArgs): Promise<{
413
351
  publicKey: string;
414
352
  }>;
353
+ /** Resolve deferred sender mail after claiming the previous initializer's lease. */
354
+ export declare function recoverSenderDeploy(args: {
355
+ db: DB["db"];
356
+ sidecarRouter: Pick<SidecarRouter, "noteSenderDeploySettled">;
357
+ allocation: SidecarAllocation;
358
+ reconciliation: SidecarReconciliationContext;
359
+ }): Promise<void>;
415
360
  export declare function createSessionService(deps: SessionServiceDeps): SessionService & PreparedWorkflowDeployer;
416
361
  export {};