@intx/hub-sessions 0.2.2 → 0.3.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.
- package/README.md +3 -5
- package/dist/agent-repo.d.ts +9 -5
- package/dist/agent-repo.js +2 -2
- package/dist/agent-state-kind.js +4 -0
- package/dist/asset-service.d.ts +1 -20
- package/dist/asset-service.js +9 -91
- package/dist/committed-source-tree.d.ts +10 -0
- package/dist/committed-source-tree.js +35 -0
- package/dist/credential-push.d.ts +7 -6
- package/dist/credential-push.js +42 -18
- package/dist/event-collector-registry.d.ts +1 -1
- package/dist/event-collector-registry.js +4 -4
- package/dist/event-collector.d.ts +1 -1
- package/dist/event-collector.js +10 -2
- package/dist/hub-session-lookups.d.ts +125 -7
- package/dist/hub-session-lookups.js +539 -80
- package/dist/hub-session-orchestrator.js +14 -49
- package/dist/index.d.ts +17 -8
- package/dist/index.js +14 -6
- package/dist/repo-store/index.d.ts +1 -1
- package/dist/repo-store/store.d.ts +1 -1
- package/dist/repo-store/store.js +138 -1
- package/dist/repo-store/subscribe-kind.d.ts +6 -3
- package/dist/repo-store/subscribe-kind.js +42 -77
- package/dist/repo-store/types.d.ts +94 -6
- package/dist/session-service.d.ts +277 -96
- package/dist/session-service.js +741 -547
- package/dist/sidecar-allocation/contracts.d.ts +78 -0
- package/dist/sidecar-allocation/contracts.js +21 -0
- package/dist/sidecar-allocation/index.d.ts +4 -0
- package/dist/sidecar-allocation/index.js +3 -0
- package/dist/sidecar-allocation/placement-policy.d.ts +11 -0
- package/dist/sidecar-allocation/placement-policy.js +21 -0
- package/dist/sidecar-allocation/plugin-registry.d.ts +11 -0
- package/dist/sidecar-allocation/plugin-registry.js +37 -0
- package/dist/sidecar-allocation/reconciler.d.ts +42 -0
- package/dist/sidecar-allocation/reconciler.js +431 -0
- package/dist/skill-kind.js +4 -0
- package/dist/substrate.d.ts +3 -3
- package/dist/substrate.js +1 -1
- package/dist/workflow-allocation-service.d.ts +58 -0
- package/dist/workflow-allocation-service.js +239 -0
- package/dist/workflow-closure-resolution.d.ts +106 -0
- package/dist/workflow-closure-resolution.js +123 -0
- package/dist/workflow-definition-ensure.d.ts +24 -0
- package/dist/workflow-definition-ensure.js +75 -0
- package/dist/workflow-dispatch-service.d.ts +40 -0
- package/dist/workflow-dispatch-service.js +146 -0
- package/dist/workflow-dispatch-settlement.d.ts +29 -0
- package/dist/workflow-dispatch-settlement.js +140 -0
- package/dist/workflow-kind.d.ts +17 -1
- package/dist/workflow-kind.js +127 -80
- package/dist/workflow-probe-gate.d.ts +214 -0
- package/dist/workflow-probe-gate.js +207 -0
- package/dist/workflow-run-kind.d.ts +128 -14
- package/dist/workflow-run-kind.js +353 -83
- package/dist/workflow-run-reader.d.ts +1 -1
- package/dist/workflow-run-reader.js +3 -7
- package/dist/workflow-run-restore.d.ts +15 -0
- package/dist/workflow-run-restore.js +26 -0
- package/dist/workflow-source-closure.d.ts +35 -0
- package/dist/workflow-source-closure.js +342 -0
- package/dist/ws/index.d.ts +3 -3
- package/dist/ws/index.js +1 -1
- package/dist/ws/sidecar-events.d.ts +100 -12
- package/dist/ws/sidecar-events.js +2 -0
- package/dist/ws/sidecar-handler.d.ts +128 -7
- package/dist/ws/sidecar-handler.js +1069 -135
- package/dist/ws/sidecar-token-authenticator.d.ts +3 -1
- package/dist/ws/sidecar-token-authenticator.js +64 -7
- package/package.json +14 -13
- package/dist/available-skills-stanza.d.ts +0 -21
- package/dist/available-skills-stanza.js +0 -32
|
@@ -80,14 +80,18 @@ export type AuthorizeFn = (principal: Principal, repoId: RepoId, ref: string, ac
|
|
|
80
80
|
* commit under validation -- present in the prospective tree and absent from
|
|
81
81
|
* the prior tree. The kind handler authoritatively detects this during its
|
|
82
82
|
* validation walk and surfaces it so callers do not re-derive terminal-ness
|
|
83
|
-
* by sniffing committed path shapes. `
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
83
|
+
* by sniffing committed path shapes. `status` is the terminal run state the
|
|
84
|
+
* terminal event maps to, matching the `workflow_run.status` vocabulary, so a
|
|
85
|
+
* caller flips the run's row without re-parsing the event type.
|
|
86
|
+
* `terminalEventJson` carries the raw bytes of the terminal event blob so a
|
|
87
|
+
* caller that needs the full event (the supervisor's terminal-write broadcast)
|
|
88
|
+
* can reconstruct it without a second read. A commit that carries an
|
|
89
|
+
* already-terminal run forward unchanged (e.g. a later compaction commit) is
|
|
90
|
+
* NOT newly terminal and does not appear here.
|
|
88
91
|
*/
|
|
89
92
|
export type NewlyTerminalRun = {
|
|
90
93
|
runId: string;
|
|
94
|
+
status: "completed" | "failed" | "cancelled";
|
|
91
95
|
terminalEventJson: string;
|
|
92
96
|
};
|
|
93
97
|
export type ValidatePushResult = {
|
|
@@ -315,6 +319,48 @@ export interface KindHandler {
|
|
|
315
319
|
newSha: string;
|
|
316
320
|
}) => Promise<void> | void;
|
|
317
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* A single child entry returned by `CommittedReads.listDir`. `name` is
|
|
324
|
+
* the entry's own path segment (no parent prefix); `oid` is its git
|
|
325
|
+
* object id; `type` is the git tree-entry kind. `oid` lets a consumer
|
|
326
|
+
* read a blob's bytes via `readBlobByOid` without re-resolving the path,
|
|
327
|
+
* and lets it prove a subtree byte-unchanged by OID equality.
|
|
328
|
+
*/
|
|
329
|
+
export type CommittedTreeEntry = {
|
|
330
|
+
readonly name: string;
|
|
331
|
+
readonly oid: string;
|
|
332
|
+
readonly type: "blob" | "tree" | "commit";
|
|
333
|
+
};
|
|
334
|
+
/**
|
|
335
|
+
* Cache-backed reads pinned to the commit a ref resolved to at the
|
|
336
|
+
* moment `openCommittedReads` was called. Every read resolves against
|
|
337
|
+
* the git object store, never the materialized working tree, so a
|
|
338
|
+
* consumer observes committed state even when the on-disk checkout lags
|
|
339
|
+
* the committed tree. The pin is fixed at open time: a concurrent commit
|
|
340
|
+
* that advances the ref afterwards does not shift the reads, so an
|
|
341
|
+
* enumerate-then-read sequence sees a single coherent snapshot.
|
|
342
|
+
*
|
|
343
|
+
* `listDir` returns the direct children of a repo-root-relative POSIX
|
|
344
|
+
* directory path (no leading or trailing slash; the empty string lists
|
|
345
|
+
* the root). A path that is absent, or resolves to a non-tree, lists as
|
|
346
|
+
* the empty array — mirroring the prior-tree closures the substrate
|
|
347
|
+
* hands a kind handler. `readBlobByOid` reads a blob's bytes by its
|
|
348
|
+
* object id; a read fault surfaces as a thrown error rather than an
|
|
349
|
+
* empty result so a consumer cannot silently degrade a missing object
|
|
350
|
+
* into an absent event.
|
|
351
|
+
*/
|
|
352
|
+
export type CommittedReads = {
|
|
353
|
+
listDir(relPath: string): Promise<CommittedTreeEntry[]>;
|
|
354
|
+
readBlobByOid(oid: string): Promise<Uint8Array>;
|
|
355
|
+
/**
|
|
356
|
+
* The git tree object id of the subtree at `relPath` (the empty string
|
|
357
|
+
* or "." is the commit's root tree), or `null` when `relPath` is absent
|
|
358
|
+
* or resolves to a non-tree. This is the content identity a source
|
|
359
|
+
* closure freezes for a package materialized from the tree: the sidecar
|
|
360
|
+
* re-checks the checked-out subtree against it.
|
|
361
|
+
*/
|
|
362
|
+
treeOid(relPath: string): Promise<string | null>;
|
|
363
|
+
};
|
|
318
364
|
export interface RepoStore {
|
|
319
365
|
/**
|
|
320
366
|
* Bookkeeping primitive. Idempotent. Creates the repo directory
|
|
@@ -368,8 +414,16 @@ export interface RepoStore {
|
|
|
368
414
|
* via `resolveRef` first; the substrate exposes no force-write
|
|
369
415
|
* mode because silently overwriting a losing concurrent update is
|
|
370
416
|
* never the right behavior.
|
|
417
|
+
*
|
|
418
|
+
* Returns the runs the received pack drove to a terminal event,
|
|
419
|
+
* aggregated across every commit it carried. The kind handler
|
|
420
|
+
* detects terminal-ness authoritatively during validation; the
|
|
421
|
+
* substrate forwards it so a caller can react (flip the run's DB
|
|
422
|
+
* row, deactivate its principal) without re-deriving terminal-ness
|
|
423
|
+
* from the committed path shape. Empty for kinds and packs that
|
|
424
|
+
* produce none.
|
|
371
425
|
*/
|
|
372
|
-
receivePack(principal: Principal, repoId: RepoId, ref: string, pack: Uint8Array, commitSha: string, expectedOldSha: string | null): Promise<
|
|
426
|
+
receivePack(principal: Principal, repoId: RepoId, ref: string, pack: Uint8Array, commitSha: string, expectedOldSha: string | null): Promise<NewlyTerminalRun[]>;
|
|
373
427
|
createPack(principal: Principal, repoId: RepoId, ref: string): Promise<{
|
|
374
428
|
pack: Uint8Array;
|
|
375
429
|
commitSha: string;
|
|
@@ -425,6 +479,40 @@ export interface RepoStore {
|
|
|
425
479
|
* they reach into for ref-listing and pack negotiation.
|
|
426
480
|
*/
|
|
427
481
|
getRepoDir(repoId: RepoId): string;
|
|
482
|
+
/**
|
|
483
|
+
* Open cache-backed reads of the committed tree at `ref`'s tip. The
|
|
484
|
+
* ref is resolved once, at call time, and every read the returned
|
|
485
|
+
* handle serves is pinned to that commit and resolves through the git
|
|
486
|
+
* object store — not the materialized working tree `getRepoDir` points
|
|
487
|
+
* at. A consumer that must observe committed state (e.g. start-time
|
|
488
|
+
* recovery reconstructing a ledger from the persisted log) reads
|
|
489
|
+
* through this rather than the working tree, which a non-atomic
|
|
490
|
+
* post-commit materialization can leave lagging on a contended
|
|
491
|
+
* filesystem.
|
|
492
|
+
*
|
|
493
|
+
* Gated under the same `resolveRef` action as `resolveRef` / `listRefs`
|
|
494
|
+
* / `subscribe`. Returns `null` when the repo does not yet exist
|
|
495
|
+
* (mirrors `listRefs`'s empty-list contract for uninitialised repos)
|
|
496
|
+
* or when `ref` does not resolve to a commit.
|
|
497
|
+
*/
|
|
498
|
+
openCommittedReads(principal: Principal, repoId: RepoId, ref: string): Promise<CommittedReads | null>;
|
|
499
|
+
/**
|
|
500
|
+
* Open cache-backed reads of the committed tree at an explicit commit,
|
|
501
|
+
* the by-SHA counterpart of `openCommittedReads`. A consumer that
|
|
502
|
+
* already holds a commit id — e.g. the `newSha`/`oldSha` of a
|
|
503
|
+
* ref-update event it is diffing — reads that exact commit through
|
|
504
|
+
* this, even after the ref has advanced past it. Every read the handle
|
|
505
|
+
* serves resolves through the git object store, pinned to `commitSha`.
|
|
506
|
+
*
|
|
507
|
+
* Gated under the same `resolveRef` action as `openCommittedReads`.
|
|
508
|
+
* `commitSha` is validated at the boundary: a malformed SHA throws
|
|
509
|
+
* `commit_sha_invalid`. Returns `null` when the repo does not yet exist
|
|
510
|
+
* or when `commitSha` names no commit in the object store (a commit a
|
|
511
|
+
* concurrent GC pruned between the caller learning of it and reading
|
|
512
|
+
* it), so a caller diffing a possibly-vanished commit gets an empty
|
|
513
|
+
* view rather than a mid-walk throw.
|
|
514
|
+
*/
|
|
515
|
+
openCommittedReadsAtCommit(principal: Principal, repoId: RepoId, commitSha: string): Promise<CommittedReads | null>;
|
|
428
516
|
/**
|
|
429
517
|
* Tail a ref's commit log. Returns an async iterator that emits
|
|
430
518
|
* `{ seq, event }` entries: one per commit on the ref. `seq` is
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { type DB } from "@intx/db";
|
|
2
|
+
import type { CredentialDelivery } from "@intx/types/sidecar";
|
|
3
|
+
import type { CredentialCipher } from "@intx/types";
|
|
2
4
|
import type { CryptoProvider, HarnessConfig, InferenceSource, MessageAttachment } from "@intx/types/runtime";
|
|
3
5
|
import { type RegistryConfig, type ScopeRoute } from "@intx/tool-packaging";
|
|
4
6
|
import { type ToolPackagePin } from "@intx/types/tool-packages";
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
+
import type { SourceRefPin, WorkflowProjectionWithSources, WorkflowSourceAssetMount } from "@intx/types/sidecar";
|
|
8
|
+
import type { WorkflowDefinitionAssetSource, WorkflowDefinitionRegistrySource, WorkflowDefinitionSource } from "@intx/types/workflow-sources";
|
|
9
|
+
import { type DeployContent as OrchestratorDeployContent } from "@intx/workflow-deploy";
|
|
7
10
|
import type { AgentRepoStore, DeployContent } from "./agent-repo.js";
|
|
8
11
|
import { type AssetService } from "./asset-service.js";
|
|
9
|
-
import type { SidecarRouter } from "./ws/sidecar-handler.js";
|
|
12
|
+
import type { AllocatedSidecarTarget, SidecarAllocationRouter, SidecarRouter } from "./ws/sidecar-handler.js";
|
|
13
|
+
import { type ResolveAssetAttachmentFn } from "./workflow-closure-resolution.js";
|
|
14
|
+
import { type InstallAndApproveResult } from "./workflow-probe-gate.js";
|
|
10
15
|
export declare class SessionLaunchError extends Error {
|
|
11
16
|
/** Which phase failed: "write", "provision", "pack", or "start". */
|
|
12
17
|
readonly phase: string;
|
|
@@ -27,58 +32,33 @@ export type SessionService = {
|
|
|
27
32
|
stageWorkflowStep(params: {
|
|
28
33
|
agentAddress: string;
|
|
29
34
|
agentId: string;
|
|
30
|
-
|
|
35
|
+
runId: string;
|
|
31
36
|
config: HarnessConfig;
|
|
32
37
|
deployContent: DeployContent;
|
|
33
38
|
toolPackagePins?: readonly ToolPackagePin[];
|
|
39
|
+
allocationTarget?: AllocatedSidecarTarget;
|
|
34
40
|
}): Promise<void>;
|
|
35
41
|
/**
|
|
36
|
-
* Deploy a
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* row. Returns the head's agent-key ack (the key the head signs its
|
|
42
|
-
* reconnect challenges with).
|
|
43
|
-
*/
|
|
44
|
-
deployInstanceAtHead(params: {
|
|
45
|
-
agentAddress: string;
|
|
46
|
-
agentId: string;
|
|
47
|
-
instanceId: string;
|
|
48
|
-
config: HarnessConfig;
|
|
49
|
-
deployContent: DeployContent;
|
|
50
|
-
toolPackagePins?: readonly ToolPackagePin[];
|
|
51
|
-
}): Promise<{
|
|
52
|
-
publicKey: string;
|
|
53
|
-
}>;
|
|
54
|
-
/**
|
|
55
|
-
* Deploy a one-step workflow once at the head through the deploy core,
|
|
56
|
-
* without the DB-backed `workflow_deployment` projection row. Stages the
|
|
57
|
-
* head's deploy tree (deploy-tree write, pack, asset fan-out), fires the
|
|
58
|
-
* deployment `agent.deploy` frame carrying the workflow definition +
|
|
59
|
-
* source pin (the sidecar initializes the head repo and spawns the
|
|
60
|
-
* workflow-process child), then delivers the pack to the head. Returns
|
|
61
|
-
* the sidecar supervisor's principal public key. See `DeploySingleStepFn`.
|
|
62
|
-
*/
|
|
63
|
-
deploySingleStepAtHead: DeploySingleStepFn;
|
|
64
|
-
/**
|
|
65
|
-
* Deploy a multi-step `WorkflowDefinition` through the workflow-deploy
|
|
66
|
-
* orchestrator's multi-step branch. This is the general workflow
|
|
67
|
-
* deploy entry point: it is not coupled to a single agent's
|
|
68
|
-
* credential/session model the way `launchSession` is. The
|
|
69
|
-
* orchestrator derives every per-step address
|
|
70
|
-
* from `deploymentId` + `deploymentDomain`, provisions each step's
|
|
71
|
-
* agent-state repo via the shared per-agent deploy phases, writes the
|
|
72
|
-
* workflow repo, and fires the deployment-level `agent.deploy` frame.
|
|
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`.
|
|
73
47
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
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.
|
|
77
56
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
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.
|
|
80
60
|
*/
|
|
81
|
-
|
|
61
|
+
deployWorkflowFromSource(params: DeployWorkflowFromSourceParams): Promise<DeployWorkflowDefinitionResult>;
|
|
82
62
|
/**
|
|
83
63
|
* Compose a signed RFC 2822 message from the user and deliver it to the
|
|
84
64
|
* agent via the mail transport. Throws if the agent is unreachable.
|
|
@@ -90,49 +70,114 @@ export type SessionService = {
|
|
|
90
70
|
*/
|
|
91
71
|
endSession(agentAddress: string, reason: string): Promise<void>;
|
|
92
72
|
};
|
|
93
|
-
export type
|
|
94
|
-
/**
|
|
73
|
+
export type DeployWorkflowDefinitionResult = {
|
|
74
|
+
/** Echoes the deployment id recorded on the projection row. */
|
|
75
|
+
anchorRunId: string;
|
|
76
|
+
/** Deployment-level mail address the supervisor registers on the bus. */
|
|
77
|
+
deploymentAddress: string;
|
|
78
|
+
/** Supervisor principal public key from the sidecar's deploy ack. */
|
|
79
|
+
publicKey: string;
|
|
80
|
+
};
|
|
81
|
+
export type DeployWorkflowFromSourceParams = {
|
|
82
|
+
/** Owning tenant; recorded on the deployment's anchor run. */
|
|
95
83
|
tenantId: string;
|
|
96
84
|
/**
|
|
97
|
-
* Stable deployment identifier
|
|
98
|
-
*
|
|
99
|
-
* it is the `workflow_deployment` row's primary key. The caller owns
|
|
100
|
-
* its generation.
|
|
85
|
+
* Stable deployment identifier and anchor-run id. The deployment-level
|
|
86
|
+
* address derives from it; the caller owns its generation.
|
|
101
87
|
*/
|
|
102
|
-
|
|
88
|
+
anchorRunId: string;
|
|
89
|
+
/** Mail domain the deployment's derived addresses live under. */
|
|
90
|
+
deploymentDomain: string;
|
|
103
91
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* deployment-level supervisor address.
|
|
92
|
+
* The deployment-level mail address, derived by the caller from `anchorRunId`
|
|
93
|
+
* + `deploymentDomain`. Re-derived and asserted coherent inside
|
|
94
|
+
* `deployCodeSourcedWorkflow`.
|
|
108
95
|
*/
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
|
|
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;
|
|
112
107
|
/**
|
|
113
|
-
* The `workflow`-kind asset the definition
|
|
114
|
-
*
|
|
115
|
-
* source
|
|
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.
|
|
116
111
|
*/
|
|
117
112
|
definitionAssetId: string;
|
|
118
113
|
/**
|
|
119
|
-
* Harness
|
|
120
|
-
*
|
|
121
|
-
*
|
|
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.
|
|
122
117
|
*/
|
|
123
118
|
config: HarnessConfig;
|
|
124
|
-
/** Deploy-tree content shared across every step's launch. */
|
|
125
|
-
deployContent: DeployContent;
|
|
126
|
-
/** Tool-package pins to ship with every step's deploy. */
|
|
127
|
-
toolPackagePins?: readonly ToolPackagePin[];
|
|
128
119
|
};
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
120
|
+
/**
|
|
121
|
+
* 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.
|
|
125
|
+
*/
|
|
126
|
+
export type InstallAndApproveWorkflowSourceParams = {
|
|
127
|
+
/** Where the definition's bytes come from at probe time. */
|
|
128
|
+
source: WorkflowDefinitionSource;
|
|
129
|
+
/** The `interchange.workflow` entry-module path the sidecar evaluates. */
|
|
130
|
+
entry: string;
|
|
131
|
+
/**
|
|
132
|
+
* A `name@range` spec for the definition package. REQUIRED for the `registry`
|
|
133
|
+
* and asset-`tarball` variants; omitted for the asset-`source` variant.
|
|
134
|
+
*/
|
|
135
|
+
pin?: string;
|
|
136
|
+
/** The `workflow`-kind asset the frozen definition projects a definition over. */
|
|
137
|
+
definitionAssetId: string;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Inputs to deploy a previously-frozen code-sourced approval bundle to a
|
|
141
|
+
* dedicated allocation. Mirrors `DeployPreparedWorkflowDefinitionParams` for the
|
|
142
|
+
* source-ref lineage: the anchor `workflow_run` row already exists from prepare
|
|
143
|
+
* time, so the deploy UPDATES it under the allocation-ownership lock rather than
|
|
144
|
+
* inserting a fresh one.
|
|
145
|
+
*/
|
|
146
|
+
export type DeployPreparedCodeSourcedWorkflowParams = {
|
|
147
|
+
/** Owning tenant; the definition's own tenant for credential resolution. */
|
|
148
|
+
tenantId: string;
|
|
149
|
+
/** The pre-inserted anchor run id, fixed at prepare time. */
|
|
150
|
+
anchorRunId: string;
|
|
151
|
+
/** Mail domain the deployment's derived addresses live under. */
|
|
152
|
+
deploymentDomain: string;
|
|
153
|
+
/** The deployment-level mail address; re-derived and asserted coherent. */
|
|
154
|
+
agentAddress: string;
|
|
155
|
+
/** Where the definition's bytes come from, rehydrated from the frozen bundle. */
|
|
156
|
+
source: WorkflowDefinitionSource;
|
|
157
|
+
/** The frozen approval bundle rehydrated from the launch spec. */
|
|
158
|
+
approved: InstallAndApproveResult;
|
|
159
|
+
/** Harness config carrying the re-resolved per-step inference chain. */
|
|
160
|
+
config: HarnessConfig;
|
|
161
|
+
/** The exact allocation generation to deploy onto. */
|
|
162
|
+
allocationTarget: AllocatedSidecarTarget;
|
|
163
|
+
/** Cipher for the definition's tenant-owned credential bindings, if any. */
|
|
164
|
+
credentialCipher?: CredentialCipher;
|
|
165
|
+
};
|
|
166
|
+
export type PreparedWorkflowDeployer = {
|
|
167
|
+
/**
|
|
168
|
+
* Install + probe + gate + freeze a code-sourced definition on shared
|
|
169
|
+
* capacity, returning the frozen bundle WITHOUT deploying it. The exclusive
|
|
170
|
+
* prepare path persists the bundle and deploys it later via
|
|
171
|
+
* `deployPreparedCodeSourcedWorkflow`.
|
|
172
|
+
*/
|
|
173
|
+
installAndApproveWorkflowSource(params: InstallAndApproveWorkflowSourceParams): Promise<InstallAndApproveResult>;
|
|
174
|
+
/**
|
|
175
|
+
* Deploy a previously-frozen code-sourced approval bundle to a dedicated
|
|
176
|
+
* allocation, updating the pre-existing anchor run under the
|
|
177
|
+
* allocation-ownership lock. No re-probe: the frozen projection/hash/closure
|
|
178
|
+
* ride verbatim.
|
|
179
|
+
*/
|
|
180
|
+
deployPreparedCodeSourcedWorkflow(params: DeployPreparedCodeSourcedWorkflowParams): Promise<DeployWorkflowDefinitionResult>;
|
|
136
181
|
};
|
|
137
182
|
export type UserMessageParams = {
|
|
138
183
|
agentAddress: string;
|
|
@@ -149,6 +194,8 @@ export type UserMessageParams = {
|
|
|
149
194
|
};
|
|
150
195
|
export type SessionServiceDeps = {
|
|
151
196
|
sidecarRouter: SidecarRouter;
|
|
197
|
+
/** Present when this Hub can route deploy phases to exclusive allocations. */
|
|
198
|
+
sidecarAllocationRouter?: SidecarAllocationRouter;
|
|
152
199
|
agentRepoStore: AgentRepoStore;
|
|
153
200
|
/**
|
|
154
201
|
* Optional asset attachment integration. When set, the deploy flow
|
|
@@ -209,27 +256,161 @@ export type SessionServiceDeps = {
|
|
|
209
256
|
* production multi-step callback does, rather than casting `unknown`.
|
|
210
257
|
*/
|
|
211
258
|
export declare function bridgeOrchestratorDeployContent(content: OrchestratorDeployContent): DeployContent;
|
|
212
|
-
/**
|
|
213
|
-
|
|
214
|
-
* dependency against `SidecarRouter.sendAgentDeploy`. The router
|
|
215
|
-
* accepts an optional `workflow` projection on the deploy frame; the
|
|
216
|
-
* sidecar's deploy router uses field presence to route the frame to
|
|
217
|
-
* the workflow deploy path. The supervisor public key returned by the
|
|
218
|
-
* sidecar's `agent.deploy.ack` is threaded back as the
|
|
219
|
-
* `MultiStepDeployResult.publicKey`.
|
|
220
|
-
*
|
|
221
|
-
* Exported so the co-located caller-site test can assert that the
|
|
222
|
-
* closure constructed in `launchSession` reaches the wire surface via
|
|
223
|
-
* `sendAgentDeploy` with a `workflow` field structurally matching the
|
|
224
|
-
* `AgentDeployFrame.workflow` schema.
|
|
225
|
-
*/
|
|
226
|
-
export declare function sendMultiStepDeployFrame(args: {
|
|
259
|
+
/** Fields the deploy frame carries onto `sendAgentDeploy`. */
|
|
260
|
+
type DeployFrameCommonArgs = {
|
|
227
261
|
sidecarRouter: SidecarRouter;
|
|
262
|
+
sidecarAllocationRouter?: SidecarAllocationRouter;
|
|
263
|
+
allocationTarget?: AllocatedSidecarTarget;
|
|
228
264
|
agentAddress: string;
|
|
229
265
|
config: HarnessConfig;
|
|
230
|
-
definition: WorkflowDefinition;
|
|
231
266
|
sources: Record<string, InferenceSource[]>;
|
|
232
|
-
}
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* For a code-sourced (npm) deploy the hub never holds the live
|
|
270
|
+
* `WorkflowDefinition` -- it lives only in the airlocked child. The gate/freeze
|
|
271
|
+
* layer hashed the inert projection; the deploy frame carries that hash and the
|
|
272
|
+
* source-ref pin, and the sidecar re-materializes and evaluates the pinned code
|
|
273
|
+
* from the pin, so no inline definition rides the frame. The content hash is
|
|
274
|
+
* owned by the gate, so this frame never recomputes it -- recomputing over a
|
|
275
|
+
* live wire lineage would diverge from the inert projection the child
|
|
276
|
+
* re-verifies against.
|
|
277
|
+
*/
|
|
278
|
+
export type SourceRefDeployFrameArgs = DeployFrameCommonArgs & {
|
|
279
|
+
lineage: "source-ref";
|
|
280
|
+
/**
|
|
281
|
+
* The gate-frozen wire hash of the approved projection -- stamped onto the
|
|
282
|
+
* frame VERBATIM. This arm does not recompute it: the freeze layer owns the
|
|
283
|
+
* content hash, and the child re-verifies its closure evaluation against this
|
|
284
|
+
* exact value.
|
|
285
|
+
*/
|
|
286
|
+
approvedWireHash: string;
|
|
287
|
+
/**
|
|
288
|
+
* The source-ref pin: where the definition's bytes come from plus the frozen
|
|
289
|
+
* dependency closure the hub resolved for it. The two co-travel, so they are
|
|
290
|
+
* one required object on this arm (see `SourceRefPin`) -- the sidecar
|
|
291
|
+
* re-materializes the exact tree from the pin at apply time.
|
|
292
|
+
*/
|
|
293
|
+
sourceRef: SourceRefPin;
|
|
294
|
+
/**
|
|
295
|
+
* Resolved credential material for the definition's credential bindings,
|
|
296
|
+
* delivered to the child on the frame. The hub resolves + decrypts here; the
|
|
297
|
+
* source-ref child decrypts nothing. The grant that AUTHORIZES a credential's
|
|
298
|
+
* use is minted per-run by run-grant materialization, not carried on this
|
|
299
|
+
* frame.
|
|
300
|
+
*/
|
|
301
|
+
credentials?: CredentialDelivery;
|
|
302
|
+
/**
|
|
303
|
+
* The projection's inline onTrigger section bodies, each already in inert wire
|
|
304
|
+
* form with its per-step inference sources pinned and its own wire hash --
|
|
305
|
+
* 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.
|
|
308
|
+
*/
|
|
309
|
+
referencedDefinitions?: readonly WorkflowProjectionWithSources[];
|
|
310
|
+
/**
|
|
311
|
+
* Source assets the pin's `kind:"asset"` closure entries read from, delivered
|
|
312
|
+
* inline on the frame so the sidecar checks them out into its durable
|
|
313
|
+
* per-deployment source store. Absent for a registry-sourced pin (its tarballs
|
|
314
|
+
* are fetched over HTTP).
|
|
315
|
+
*/
|
|
316
|
+
assets?: readonly WorkflowSourceAssetMount[];
|
|
317
|
+
};
|
|
318
|
+
export type SendMultiStepDeployFrameArgs = SourceRefDeployFrameArgs;
|
|
319
|
+
/**
|
|
320
|
+
* Emit the source-ref deploy frame onto `SidecarRouter.sendAgentDeploy`. The
|
|
321
|
+
* router accepts an optional `workflow` projection on the deploy frame; the
|
|
322
|
+
* sidecar's deploy router uses field presence to route the frame to the
|
|
323
|
+
* workflow deploy path, and returns the supervisor public key on the
|
|
324
|
+
* `agent.deploy.ack`.
|
|
325
|
+
*
|
|
326
|
+
* The gate/freeze layer already hashed the inert projection, so the frozen hash
|
|
327
|
+
* and the inert projection ride the frame verbatim -- this never recomputes the
|
|
328
|
+
* content hash. Recomputing over a live wire lineage would diverge from the
|
|
329
|
+
* inert projection the child re-verifies against.
|
|
330
|
+
*
|
|
331
|
+
* Exported so the co-located caller-site test can assert that the constructed
|
|
332
|
+
* closure reaches the wire surface via `sendAgentDeploy` with a `workflow`
|
|
333
|
+
* field structurally matching the `AgentDeployFrame.workflow` schema.
|
|
334
|
+
*/
|
|
335
|
+
export declare function sendMultiStepDeployFrame(args: SendMultiStepDeployFrameArgs): Promise<{
|
|
336
|
+
publicKey: string;
|
|
337
|
+
}>;
|
|
338
|
+
/**
|
|
339
|
+
* Arguments for `deployCodeSourcedWorkflow`. The `approved` bundle is the
|
|
340
|
+
* `installAndApproveWorkflowDefinition` output verbatim -- the frozen hash,
|
|
341
|
+
* inert projection, and closure travel together inside it so no caller can pair
|
|
342
|
+
* a hash with a mismatched projection or closure. The remaining fields are the
|
|
343
|
+
* operator/asset config the approve step never sees: the per-step inference
|
|
344
|
+
* `sources`, the deploy `config`, the target `agentAddress`, and the `source`
|
|
345
|
+
* ref that names where the definition's bytes are published.
|
|
346
|
+
*/
|
|
347
|
+
type DeployCodeSourcedCommonArgs = DeployFrameCommonArgs & {
|
|
348
|
+
approved: InstallAndApproveResult;
|
|
349
|
+
/**
|
|
350
|
+
* The hub DB handle, the definition's OWN tenant, the deployment's anchor run
|
|
351
|
+
* id, and the mail domain its run address lives under. REQUIRED: this function
|
|
352
|
+
* writes the deployment's anchor `workflow_run` row, and run-grant
|
|
353
|
+
* materialization keys off it. `tenantId` is the definition's own tenant
|
|
354
|
+
* (tenant-owned credential resolution walks up from it); do not pass a
|
|
355
|
+
* request/config tenant that may differ. `anchorRunId` is caller-supplied: the
|
|
356
|
+
* deployment mail address is frozen into the approved package bytes at
|
|
357
|
+
* authoring time, so the run id it derives from is fixed before this runs and
|
|
358
|
+
* cannot be minted here. `deploymentDomain` pairs with `anchorRunId` to
|
|
359
|
+
* re-derive the run address and assert it matches `agentAddress`, failing
|
|
360
|
+
* closed on an incoherent pair.
|
|
361
|
+
*/
|
|
362
|
+
db: DB["db"];
|
|
363
|
+
tenantId: string;
|
|
364
|
+
anchorRunId: string;
|
|
365
|
+
deploymentDomain: string;
|
|
366
|
+
/**
|
|
367
|
+
* Credential cipher, REQUIRED only when the definition carries credential
|
|
368
|
+
* bindings (resolution fails closed without it); omit for a binding-free
|
|
369
|
+
* deployment.
|
|
370
|
+
*/
|
|
371
|
+
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
|
+
};
|
|
381
|
+
/** Deploy a definition published to an npm registry: the sidecar fetches its
|
|
382
|
+
* tarballs over HTTP, so no source asset is delivered. */
|
|
383
|
+
export type DeployCodeSourcedRegistryArgs = DeployCodeSourcedCommonArgs & {
|
|
384
|
+
source: WorkflowDefinitionRegistrySource;
|
|
385
|
+
};
|
|
386
|
+
/** Deploy a definition sourced from a hub `package-registry` asset: the caller
|
|
387
|
+
* mints `resolveAttachment` so this glue delivers the asset packs the sidecar
|
|
388
|
+
* checks out, without importing the asset service. */
|
|
389
|
+
export type DeployCodeSourcedAssetArgs = DeployCodeSourcedCommonArgs & {
|
|
390
|
+
source: WorkflowDefinitionAssetSource;
|
|
391
|
+
resolveAttachment: ResolveAssetAttachmentFn;
|
|
392
|
+
};
|
|
393
|
+
export type DeployCodeSourcedWorkflowArgs = DeployCodeSourcedRegistryArgs | DeployCodeSourcedAssetArgs;
|
|
394
|
+
/**
|
|
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.
|
|
407
|
+
*
|
|
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.
|
|
411
|
+
*/
|
|
412
|
+
export declare function deployCodeSourcedWorkflow(args: DeployCodeSourcedWorkflowArgs): Promise<{
|
|
233
413
|
publicKey: string;
|
|
234
414
|
}>;
|
|
235
|
-
export declare function createSessionService(deps: SessionServiceDeps): SessionService;
|
|
415
|
+
export declare function createSessionService(deps: SessionServiceDeps): SessionService & PreparedWorkflowDeployer;
|
|
416
|
+
export {};
|