@intx/hub-sessions 0.1.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/LICENSE +176 -0
- package/README.md +82 -1
- package/dist/agent-repo.d.ts +93 -0
- package/dist/agent-repo.js +109 -0
- package/dist/agent-state-kind.d.ts +12 -0
- package/dist/agent-state-kind.js +189 -0
- package/dist/asset-service.d.ts +104 -0
- package/dist/asset-service.js +267 -0
- package/dist/committed-source-tree.d.ts +10 -0
- package/dist/committed-source-tree.js +35 -0
- package/dist/credential-push.d.ts +33 -0
- package/dist/credential-push.js +109 -0
- package/dist/event-collector-registry.d.ts +20 -0
- package/dist/event-collector-registry.js +115 -0
- package/dist/event-collector.d.ts +39 -0
- package/dist/event-collector.js +365 -0
- package/dist/hub-session-lookups.d.ts +135 -0
- package/dist/hub-session-lookups.js +663 -0
- package/dist/hub-session-orchestrator.d.ts +25 -0
- package/dist/hub-session-orchestrator.js +87 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +24 -0
- package/dist/package-registry-kind.d.ts +70 -0
- package/dist/package-registry-kind.js +260 -0
- package/dist/repo-store/index.d.ts +4 -0
- package/dist/repo-store/index.js +3 -0
- package/dist/repo-store/store.d.ts +41 -0
- package/dist/repo-store/store.js +1829 -0
- package/dist/repo-store/subscribe-kind.d.ts +56 -0
- package/dist/repo-store/subscribe-kind.js +144 -0
- package/dist/repo-store/types.d.ts +571 -0
- package/dist/repo-store/types.js +42 -0
- package/dist/session-service.d.ts +416 -0
- package/dist/session-service.js +1191 -0
- 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.d.ts +41 -0
- package/dist/skill-kind.js +292 -0
- package/dist/substrate.d.ts +8 -0
- package/dist/substrate.js +21 -0
- 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 +37 -0
- package/dist/workflow-kind.js +310 -0
- package/dist/workflow-probe-gate.d.ts +214 -0
- package/dist/workflow-probe-gate.js +207 -0
- package/dist/workflow-run-event-log.d.ts +21 -0
- package/dist/workflow-run-event-log.js +51 -0
- package/dist/workflow-run-kind.d.ts +440 -0
- package/dist/workflow-run-kind.js +2916 -0
- package/dist/workflow-run-reader.d.ts +47 -0
- package/dist/workflow-run-reader.js +153 -0
- 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 -0
- package/dist/ws/index.js +3 -0
- package/dist/ws/sidecar-events.d.ts +222 -0
- package/dist/ws/sidecar-events.js +72 -0
- package/dist/ws/sidecar-handler.d.ts +305 -0
- package/dist/ws/sidecar-handler.js +2537 -0
- package/dist/ws/sidecar-token-authenticator.d.ts +17 -0
- package/dist/ws/sidecar-token-authenticator.js +81 -0
- package/package.json +35 -12
- package/src/agent-repo.test.ts +0 -310
- package/src/agent-repo.ts +0 -165
- package/src/agent-state-kind.test.ts +0 -247
- package/src/agent-state-kind.ts +0 -204
- package/src/asset-service.test.ts +0 -540
- package/src/asset-service.ts +0 -378
- package/src/available-skills-stanza.test.ts +0 -87
- package/src/available-skills-stanza.ts +0 -47
- package/src/credential-push.ts +0 -65
- package/src/event-collector-registry.test.ts +0 -73
- package/src/event-collector-registry.ts +0 -171
- package/src/event-collector.test.ts +0 -1387
- package/src/event-collector.ts +0 -424
- package/src/hub-session-lookups.ts +0 -206
- package/src/hub-session-orchestrator.test.ts +0 -510
- package/src/hub-session-orchestrator.ts +0 -213
- package/src/index.ts +0 -78
- package/src/repo-store/index.ts +0 -15
- package/src/repo-store/store.test.ts +0 -1169
- package/src/repo-store/store.ts +0 -428
- package/src/repo-store/types.ts +0 -253
- package/src/session-service.test.ts +0 -895
- package/src/session-service.ts +0 -464
- package/src/skill-kind.test.ts +0 -599
- package/src/skill-kind.ts +0 -350
- package/src/ws/index.ts +0 -18
- package/src/ws/sidecar-events.test.ts +0 -96
- package/src/ws/sidecar-events.ts +0 -231
- package/src/ws/sidecar-handler.test.ts +0 -2217
- package/src/ws/sidecar-handler.ts +0 -1574
- package/tsconfig.json +0 -4
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Type } from "arktype";
|
|
2
|
+
import type { Principal, RepoId, RepoStore } from "./types.js";
|
|
3
|
+
export type SubscribeKindOpts = {
|
|
4
|
+
signal: AbortSignal;
|
|
5
|
+
from: "head" | {
|
|
6
|
+
seq: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Workflow-event kinds to surface. Matches against the inner
|
|
10
|
+
* payload's `type` field after the validator narrows the blob. The
|
|
11
|
+
* helper yields only events whose `type` appears in this list.
|
|
12
|
+
*/
|
|
13
|
+
kinds: readonly string[];
|
|
14
|
+
bufferLimit?: number;
|
|
15
|
+
};
|
|
16
|
+
export type SubscribeKindEntry<T> = {
|
|
17
|
+
/**
|
|
18
|
+
* Workflow-event seq parsed from the committed filename
|
|
19
|
+
* (`runs/<runId>/events/<seq>.json`). Distinct from the substrate's
|
|
20
|
+
* commit-level seq exposed by `RepoStore.subscribe`.
|
|
21
|
+
*/
|
|
22
|
+
seq: number;
|
|
23
|
+
/**
|
|
24
|
+
* Owning runId, parsed from the committed blob's path. The substrate
|
|
25
|
+
* stores each run's event log under `runs/<runId>/events/`; the helper
|
|
26
|
+
* surfaces the path segment so consumers can attribute each yielded
|
|
27
|
+
* event to its run without re-walking the tree. Required by the
|
|
28
|
+
* workflow-host scheduler's live-ingest path, which routes incoming
|
|
29
|
+
* `TimerSet` events to per-run queue entries.
|
|
30
|
+
*/
|
|
31
|
+
runId: string;
|
|
32
|
+
event: T;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Typed entrypoint over `RepoStore.subscribe` for the workflow-run
|
|
36
|
+
* event log. The substrate emits one ref-update envelope per commit;
|
|
37
|
+
* each commit may add one or more `runs/<runId>/events/<seq>.json`
|
|
38
|
+
* blobs. This helper loads those blobs from the new commit's tree,
|
|
39
|
+
* narrows each through the supplied arktype validator, applies the
|
|
40
|
+
* kinds filter against the inner `type` discriminator, and yields one
|
|
41
|
+
* `{ seq, event }` entry per matching blob.
|
|
42
|
+
*
|
|
43
|
+
* The path-layout vocabulary (the `runs/`/`events/` prefixes and the
|
|
44
|
+
* `<seq>.json` filename shape) lives in the workflow-run kind handler,
|
|
45
|
+
* which is the authority for what may land under this prefix; this
|
|
46
|
+
* helper imports it rather than re-encoding it. The substrate
|
|
47
|
+
* `subscribe` it wraps is a generic ref-tail primitive and knows
|
|
48
|
+
* nothing about workflow-runs.
|
|
49
|
+
*
|
|
50
|
+
* Diff scope: the helper enumerates event blobs present in the new
|
|
51
|
+
* commit but absent from the old commit. A commit that does not add
|
|
52
|
+
* any event blobs (e.g. a kind-handler-internal rewrite) produces no
|
|
53
|
+
* entries even if the kinds filter would otherwise match earlier
|
|
54
|
+
* events.
|
|
55
|
+
*/
|
|
56
|
+
export declare function subscribeKind<V extends Type>(store: RepoStore, principal: Principal, repoId: RepoId, ref: string, validator: V, opts: SubscribeKindOpts): AsyncGenerator<SubscribeKindEntry<V["infer"]>, void, void>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
import { requireEventSeq, WORKFLOW_RUN_EVENTS_DIR, WORKFLOW_RUN_RUNS_PREFIX, } from "../workflow-run-kind.js";
|
|
3
|
+
/**
|
|
4
|
+
* Substrate envelope shape. Imported textually rather than from
|
|
5
|
+
* `types.ts` so this helper has a local, validator-checked view of
|
|
6
|
+
* what `RepoStore.subscribe` yields and does not depend on the
|
|
7
|
+
* substrate's TypeScript type for runtime safety.
|
|
8
|
+
*/
|
|
9
|
+
const SubstrateEvent = type({
|
|
10
|
+
type: "'ref.updated'",
|
|
11
|
+
ref: "string",
|
|
12
|
+
"oldSha?": "string | null",
|
|
13
|
+
newSha: "string",
|
|
14
|
+
});
|
|
15
|
+
const KindEnvelope = type({
|
|
16
|
+
type: "string",
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Typed entrypoint over `RepoStore.subscribe` for the workflow-run
|
|
20
|
+
* event log. The substrate emits one ref-update envelope per commit;
|
|
21
|
+
* each commit may add one or more `runs/<runId>/events/<seq>.json`
|
|
22
|
+
* blobs. This helper loads those blobs from the new commit's tree,
|
|
23
|
+
* narrows each through the supplied arktype validator, applies the
|
|
24
|
+
* kinds filter against the inner `type` discriminator, and yields one
|
|
25
|
+
* `{ seq, event }` entry per matching blob.
|
|
26
|
+
*
|
|
27
|
+
* The path-layout vocabulary (the `runs/`/`events/` prefixes and the
|
|
28
|
+
* `<seq>.json` filename shape) lives in the workflow-run kind handler,
|
|
29
|
+
* which is the authority for what may land under this prefix; this
|
|
30
|
+
* helper imports it rather than re-encoding it. The substrate
|
|
31
|
+
* `subscribe` it wraps is a generic ref-tail primitive and knows
|
|
32
|
+
* nothing about workflow-runs.
|
|
33
|
+
*
|
|
34
|
+
* Diff scope: the helper enumerates event blobs present in the new
|
|
35
|
+
* commit but absent from the old commit. A commit that does not add
|
|
36
|
+
* any event blobs (e.g. a kind-handler-internal rewrite) produces no
|
|
37
|
+
* entries even if the kinds filter would otherwise match earlier
|
|
38
|
+
* events.
|
|
39
|
+
*/
|
|
40
|
+
export async function* subscribeKind(store, principal, repoId, ref, validator, opts) {
|
|
41
|
+
const kindsAllowed = new Set(opts.kinds);
|
|
42
|
+
const subscribeOpts = {
|
|
43
|
+
signal: opts.signal,
|
|
44
|
+
from: opts.from,
|
|
45
|
+
};
|
|
46
|
+
if (opts.bufferLimit !== undefined) {
|
|
47
|
+
subscribeOpts.bufferLimit = opts.bufferLimit;
|
|
48
|
+
}
|
|
49
|
+
const iter = store.subscribe(principal, repoId, ref, subscribeOpts);
|
|
50
|
+
for await (const { event } of iter) {
|
|
51
|
+
const envelope = SubstrateEvent(event);
|
|
52
|
+
if (envelope instanceof type.errors) {
|
|
53
|
+
throw new Error(`subscribe_kind_envelope_invalid: ${envelope.summary}`);
|
|
54
|
+
}
|
|
55
|
+
const newReads = await store.openCommittedReadsAtCommit(principal, repoId, envelope.newSha);
|
|
56
|
+
// A commit a concurrent GC pruned between the ref-update event and
|
|
57
|
+
// this read yields nothing; the substrate surfaces that as `null`.
|
|
58
|
+
if (newReads === null)
|
|
59
|
+
continue;
|
|
60
|
+
const oldReads = envelope.oldSha === undefined || envelope.oldSha === null
|
|
61
|
+
? null
|
|
62
|
+
: await store.openCommittedReadsAtCommit(principal, repoId, envelope.oldSha);
|
|
63
|
+
const candidates = await collectAddedEventBlobs(newReads, oldReads);
|
|
64
|
+
for (const candidate of candidates) {
|
|
65
|
+
const raw = await newReads.readBlobByOid(candidate.oid);
|
|
66
|
+
let parsedJson;
|
|
67
|
+
try {
|
|
68
|
+
parsedJson = JSON.parse(new TextDecoder().decode(raw));
|
|
69
|
+
}
|
|
70
|
+
catch (cause) {
|
|
71
|
+
throw new Error(`subscribe_kind_invalid_json: ${candidate.blobPath}`, {
|
|
72
|
+
cause,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const kind = KindEnvelope(parsedJson);
|
|
76
|
+
if (kind instanceof type.errors) {
|
|
77
|
+
throw new Error(`subscribe_kind_missing_type: ${candidate.blobPath}: ${kind.summary}`);
|
|
78
|
+
}
|
|
79
|
+
if (!kindsAllowed.has(kind.type))
|
|
80
|
+
continue;
|
|
81
|
+
const narrowed = validator(parsedJson);
|
|
82
|
+
if (narrowed instanceof type.errors) {
|
|
83
|
+
throw new Error(`subscribe_kind_validation_failed: ${candidate.blobPath}: ${narrowed.summary}`);
|
|
84
|
+
}
|
|
85
|
+
yield { seq: candidate.seq, runId: candidate.runId, event: narrowed };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Diff the `runs/<runId>/events/` subtree between the new and old commit
|
|
91
|
+
* reads and return the event candidates present in the new commit but
|
|
92
|
+
* not the old. `oldReads` is `null` for the ref's first commit (no prior
|
|
93
|
+
* tip) or when the prior commit is no longer in the object store, in
|
|
94
|
+
* which case every event in the new commit is treated as added.
|
|
95
|
+
* Filenames that fail the `<seq>.json` shape are surfaced as errors
|
|
96
|
+
* rather than silently skipped — the workflow-run kind handler's
|
|
97
|
+
* validatePush is the authority for what may land under this prefix, so
|
|
98
|
+
* an unexpected shape here is a substrate-side invariant violation.
|
|
99
|
+
*/
|
|
100
|
+
async function collectAddedEventBlobs(newReads, oldReads) {
|
|
101
|
+
const newSet = await enumerateEventBlobs(newReads);
|
|
102
|
+
if (oldReads === null) {
|
|
103
|
+
return [...newSet.values()].sort(byRunThenSeq);
|
|
104
|
+
}
|
|
105
|
+
const oldSet = await enumerateEventBlobs(oldReads);
|
|
106
|
+
const out = [];
|
|
107
|
+
for (const [key, candidate] of newSet) {
|
|
108
|
+
if (oldSet.has(key))
|
|
109
|
+
continue;
|
|
110
|
+
out.push(candidate);
|
|
111
|
+
}
|
|
112
|
+
out.sort(byRunThenSeq);
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
function byRunThenSeq(a, b) {
|
|
116
|
+
if (a.runId < b.runId)
|
|
117
|
+
return -1;
|
|
118
|
+
if (a.runId > b.runId)
|
|
119
|
+
return 1;
|
|
120
|
+
return a.seq - b.seq;
|
|
121
|
+
}
|
|
122
|
+
async function enumerateEventBlobs(reads) {
|
|
123
|
+
const out = new Map();
|
|
124
|
+
const runs = await reads.listDir(WORKFLOW_RUN_RUNS_PREFIX);
|
|
125
|
+
for (const runEntry of runs) {
|
|
126
|
+
if (runEntry.type !== "tree")
|
|
127
|
+
continue;
|
|
128
|
+
const runId = runEntry.name;
|
|
129
|
+
const events = await reads.listDir(`${WORKFLOW_RUN_RUNS_PREFIX}/${runId}/${WORKFLOW_RUN_EVENTS_DIR}`);
|
|
130
|
+
for (const blob of events) {
|
|
131
|
+
if (blob.type !== "blob")
|
|
132
|
+
continue;
|
|
133
|
+
const blobPath = `${WORKFLOW_RUN_RUNS_PREFIX}/${runId}/${WORKFLOW_RUN_EVENTS_DIR}/${blob.name}`;
|
|
134
|
+
const seq = requireEventSeq(blob.name, blobPath);
|
|
135
|
+
out.set(`${runId}/${blob.name}`, {
|
|
136
|
+
seq,
|
|
137
|
+
runId,
|
|
138
|
+
blobPath,
|
|
139
|
+
oid: blob.oid,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return out;
|
|
144
|
+
}
|