@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.
Files changed (113) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +82 -1
  3. package/dist/agent-repo.d.ts +93 -0
  4. package/dist/agent-repo.js +109 -0
  5. package/dist/agent-state-kind.d.ts +12 -0
  6. package/dist/agent-state-kind.js +189 -0
  7. package/dist/asset-service.d.ts +104 -0
  8. package/dist/asset-service.js +267 -0
  9. package/dist/committed-source-tree.d.ts +10 -0
  10. package/dist/committed-source-tree.js +35 -0
  11. package/dist/credential-push.d.ts +33 -0
  12. package/dist/credential-push.js +109 -0
  13. package/dist/event-collector-registry.d.ts +20 -0
  14. package/dist/event-collector-registry.js +115 -0
  15. package/dist/event-collector.d.ts +39 -0
  16. package/dist/event-collector.js +365 -0
  17. package/dist/hub-session-lookups.d.ts +135 -0
  18. package/dist/hub-session-lookups.js +663 -0
  19. package/dist/hub-session-orchestrator.d.ts +25 -0
  20. package/dist/hub-session-orchestrator.js +87 -0
  21. package/dist/index.d.ts +27 -0
  22. package/dist/index.js +24 -0
  23. package/dist/package-registry-kind.d.ts +70 -0
  24. package/dist/package-registry-kind.js +260 -0
  25. package/dist/repo-store/index.d.ts +4 -0
  26. package/dist/repo-store/index.js +3 -0
  27. package/dist/repo-store/store.d.ts +41 -0
  28. package/dist/repo-store/store.js +1829 -0
  29. package/dist/repo-store/subscribe-kind.d.ts +56 -0
  30. package/dist/repo-store/subscribe-kind.js +144 -0
  31. package/dist/repo-store/types.d.ts +571 -0
  32. package/dist/repo-store/types.js +42 -0
  33. package/dist/session-service.d.ts +416 -0
  34. package/dist/session-service.js +1191 -0
  35. package/dist/sidecar-allocation/contracts.d.ts +78 -0
  36. package/dist/sidecar-allocation/contracts.js +21 -0
  37. package/dist/sidecar-allocation/index.d.ts +4 -0
  38. package/dist/sidecar-allocation/index.js +3 -0
  39. package/dist/sidecar-allocation/placement-policy.d.ts +11 -0
  40. package/dist/sidecar-allocation/placement-policy.js +21 -0
  41. package/dist/sidecar-allocation/plugin-registry.d.ts +11 -0
  42. package/dist/sidecar-allocation/plugin-registry.js +37 -0
  43. package/dist/sidecar-allocation/reconciler.d.ts +42 -0
  44. package/dist/sidecar-allocation/reconciler.js +431 -0
  45. package/dist/skill-kind.d.ts +41 -0
  46. package/dist/skill-kind.js +292 -0
  47. package/dist/substrate.d.ts +8 -0
  48. package/dist/substrate.js +21 -0
  49. package/dist/workflow-allocation-service.d.ts +58 -0
  50. package/dist/workflow-allocation-service.js +239 -0
  51. package/dist/workflow-closure-resolution.d.ts +106 -0
  52. package/dist/workflow-closure-resolution.js +123 -0
  53. package/dist/workflow-definition-ensure.d.ts +24 -0
  54. package/dist/workflow-definition-ensure.js +75 -0
  55. package/dist/workflow-dispatch-service.d.ts +40 -0
  56. package/dist/workflow-dispatch-service.js +146 -0
  57. package/dist/workflow-dispatch-settlement.d.ts +29 -0
  58. package/dist/workflow-dispatch-settlement.js +140 -0
  59. package/dist/workflow-kind.d.ts +37 -0
  60. package/dist/workflow-kind.js +310 -0
  61. package/dist/workflow-probe-gate.d.ts +214 -0
  62. package/dist/workflow-probe-gate.js +207 -0
  63. package/dist/workflow-run-event-log.d.ts +21 -0
  64. package/dist/workflow-run-event-log.js +51 -0
  65. package/dist/workflow-run-kind.d.ts +440 -0
  66. package/dist/workflow-run-kind.js +2916 -0
  67. package/dist/workflow-run-reader.d.ts +47 -0
  68. package/dist/workflow-run-reader.js +153 -0
  69. package/dist/workflow-run-restore.d.ts +15 -0
  70. package/dist/workflow-run-restore.js +26 -0
  71. package/dist/workflow-source-closure.d.ts +35 -0
  72. package/dist/workflow-source-closure.js +342 -0
  73. package/dist/ws/index.d.ts +3 -0
  74. package/dist/ws/index.js +3 -0
  75. package/dist/ws/sidecar-events.d.ts +222 -0
  76. package/dist/ws/sidecar-events.js +72 -0
  77. package/dist/ws/sidecar-handler.d.ts +305 -0
  78. package/dist/ws/sidecar-handler.js +2537 -0
  79. package/dist/ws/sidecar-token-authenticator.d.ts +17 -0
  80. package/dist/ws/sidecar-token-authenticator.js +81 -0
  81. package/package.json +35 -12
  82. package/src/agent-repo.test.ts +0 -310
  83. package/src/agent-repo.ts +0 -165
  84. package/src/agent-state-kind.test.ts +0 -247
  85. package/src/agent-state-kind.ts +0 -204
  86. package/src/asset-service.test.ts +0 -540
  87. package/src/asset-service.ts +0 -378
  88. package/src/available-skills-stanza.test.ts +0 -87
  89. package/src/available-skills-stanza.ts +0 -47
  90. package/src/credential-push.ts +0 -65
  91. package/src/event-collector-registry.test.ts +0 -73
  92. package/src/event-collector-registry.ts +0 -171
  93. package/src/event-collector.test.ts +0 -1387
  94. package/src/event-collector.ts +0 -424
  95. package/src/hub-session-lookups.ts +0 -206
  96. package/src/hub-session-orchestrator.test.ts +0 -510
  97. package/src/hub-session-orchestrator.ts +0 -213
  98. package/src/index.ts +0 -78
  99. package/src/repo-store/index.ts +0 -15
  100. package/src/repo-store/store.test.ts +0 -1169
  101. package/src/repo-store/store.ts +0 -428
  102. package/src/repo-store/types.ts +0 -253
  103. package/src/session-service.test.ts +0 -895
  104. package/src/session-service.ts +0 -464
  105. package/src/skill-kind.test.ts +0 -599
  106. package/src/skill-kind.ts +0 -350
  107. package/src/ws/index.ts +0 -18
  108. package/src/ws/sidecar-events.test.ts +0 -96
  109. package/src/ws/sidecar-events.ts +0 -231
  110. package/src/ws/sidecar-handler.test.ts +0 -2217
  111. package/src/ws/sidecar-handler.ts +0 -1574
  112. package/tsconfig.json +0 -4
  113. package/tsconfig.tsbuildinfo +0 -1
@@ -1,213 +0,0 @@
1
- // Hub-side orchestrator for the sidecar event emitter.
2
- //
3
- // Subscribes to the sidecar router's events and runs the host-side
4
- // reactions: dispatching inference events to the event collector,
5
- // refreshing grants and credentials on reconnect, ingesting state
6
- // packs, re-deploying stale agents, persisting mail, and forwarding
7
- // mail.delivered notifications back to subscribers.
8
- //
9
- // The orchestrator depends on a narrow `HubSessionRouterFacade` rather
10
- // than the full SidecarRouter, so tests can drive subscriber behavior
11
- // with a small stub and an isolated emitter.
12
-
13
- import { eq } from "drizzle-orm";
14
- import { type } from "arktype";
15
- import type { DB } from "@intx/db";
16
- import { agentInstance } from "@intx/db/schema";
17
- import { resolveInstanceSources } from "@intx/db";
18
- import { parseMailToEmail } from "@intx/mime";
19
- import { parseInferenceEvent } from "@intx/types/runtime";
20
- import type { GrantRule, GrantStore } from "@intx/types/authz";
21
- import type { InferenceSource } from "@intx/types/runtime";
22
- import { getLogger } from "@intx/log";
23
-
24
- import type { AgentRepoStore } from "./agent-repo";
25
- import type { EventCollectorRegistry } from "./event-collector-registry";
26
- import type { SidecarEventEmitter } from "./ws/sidecar-events";
27
- import { parseAgentId, requireInstance } from "./hub-session-lookups";
28
-
29
- const log = getLogger(["hub", "orchestrator"]);
30
-
31
- /** Subset of `SidecarRouter` the orchestrator drives outbound. The
32
- * narrow surface keeps tests honest and decouples the orchestrator
33
- * from the rest of the router API. */
34
- export type HubSessionRouterFacade = {
35
- sendGrantsUpdate(agentAddress: string, grants: GrantRule[]): Promise<void>;
36
- sendSourcesUpdate(
37
- agentAddress: string,
38
- sources: InferenceSource[],
39
- defaultSource: string,
40
- ): Promise<void>;
41
- sendPack(
42
- agentAddress: string,
43
- pack: Uint8Array,
44
- ref: string,
45
- commitSha: string,
46
- ): Promise<void>;
47
- dispatchAgentEvent(agentAddress: string, event: unknown): void;
48
- };
49
-
50
- export type HubSessionOrchestratorDeps = {
51
- events: SidecarEventEmitter;
52
- router: HubSessionRouterFacade;
53
- db: DB["db"];
54
- eventCollectors: EventCollectorRegistry;
55
- grantStore: GrantStore;
56
- agentRepoStore: AgentRepoStore;
57
- };
58
-
59
- export type HubSessionOrchestrator = {
60
- /** Unsubscribe all listeners. Tests use this between cases; the hub
61
- * application doesn't need to dispose because the orchestrator's
62
- * lifetime matches the process. */
63
- dispose(): void;
64
- };
65
-
66
- export function createHubSessionOrchestrator(
67
- deps: HubSessionOrchestratorDeps,
68
- ): HubSessionOrchestrator {
69
- const { events, router, db, eventCollectors, grantStore, agentRepoStore } =
70
- deps;
71
-
72
- const unsubscribers: (() => void)[] = [];
73
-
74
- unsubscribers.push(
75
- events.on("agent.event", ({ agentAddress, event }) => {
76
- const validated = parseInferenceEvent(event);
77
- if (validated instanceof type.errors) {
78
- log.warn("Received invalid agent event for {agentAddress}: {summary}", {
79
- agentAddress,
80
- summary: validated.summary,
81
- });
82
- return;
83
- }
84
- eventCollectors.dispatch(agentAddress, validated);
85
- }),
86
- );
87
-
88
- unsubscribers.push(
89
- events.on("sidecar.disconnect", ({ agentAddresses }) => {
90
- for (const addr of agentAddresses) {
91
- eventCollectors.abandon(addr);
92
- }
93
- }),
94
- );
95
-
96
- unsubscribers.push(
97
- events.on("mail.outbound.undelivered", ({ recipients }) => {
98
- // The hub has no external mail transport today. Anything that
99
- // could not be delivered locally or queued for a disconnected
100
- // agent is dropped; log so operators can see it.
101
- log.warn("Dropping mail with no local recipient: {recipients}", {
102
- recipients: recipients.join(", "),
103
- });
104
- }),
105
- );
106
-
107
- unsubscribers.push(
108
- events.on("agent.deploy.ack", async ({ agentAddress, publicKey }) => {
109
- const instance = await requireInstance(db, agentAddress);
110
- await db
111
- .update(agentInstance)
112
- .set({ publicKey })
113
- .where(eq(agentInstance.id, instance.id));
114
- }),
115
- );
116
-
117
- unsubscribers.push(
118
- events.on("agent.reconnected", async ({ agentAddress }) => {
119
- const instance = await requireInstance(db, agentAddress);
120
-
121
- if (!instance.sessionId) {
122
- throw new Error(
123
- `Agent "${agentAddress}" reconnected but has no active session`,
124
- );
125
- }
126
- const sessionId = instance.sessionId;
127
-
128
- // Refresh grants before creating any local state. If this
129
- // fails, the address is rejected and nothing needs cleanup.
130
- const grants = await grantStore.collectGrants(
131
- instance.principalId,
132
- instance.tenantId,
133
- );
134
- await router.sendGrantsUpdate(agentAddress, grants);
135
-
136
- // Re-resolve and push credentials so the agent picks up any
137
- // rotations that happened while the sidecar was disconnected.
138
- // Fail-open: a stale credential causes runtime 401s, not a
139
- // security escalation, so we log rather than reject the
140
- // reconnect.
141
- try {
142
- const sources = await resolveInstanceSources(
143
- db,
144
- instance.tenantId,
145
- instance,
146
- );
147
- if (sources.length > 0) {
148
- const [first] = sources;
149
- if (first !== undefined) {
150
- await router.sendSourcesUpdate(agentAddress, sources, first.id);
151
- }
152
- }
153
- } catch (err: unknown) {
154
- const msg = err instanceof Error ? err.message : String(err);
155
- log.warn(
156
- "Failed to push credentials on reconnect for {agentAddress}: {msg}",
157
- { agentAddress, msg },
158
- );
159
- }
160
-
161
- const now = new Date();
162
- if (instance.status !== "running") {
163
- await db
164
- .update(agentInstance)
165
- .set({ status: "running", updatedAt: now })
166
- .where(eq(agentInstance.id, instance.id));
167
- }
168
- if (!eventCollectors.has(agentAddress)) {
169
- eventCollectors.create(
170
- agentAddress,
171
- instance.tenantId,
172
- sessionId,
173
- instance.id,
174
- );
175
- log.info(
176
- "Restored event collector for reconnected agent {agentAddress}",
177
- { agentAddress },
178
- );
179
- }
180
- }),
181
- );
182
-
183
- unsubscribers.push(
184
- events.on("deploy.ref.stale", async ({ agentAddress }) => {
185
- const agentId = parseAgentId(agentAddress);
186
- const { pack, commitSha, ref } =
187
- await agentRepoStore.createDeployPack(agentId);
188
- await router.sendPack(agentAddress, pack, ref, commitSha);
189
- log.info("Re-deployed stale agent {agentAddress}", { agentAddress });
190
- }),
191
- );
192
-
193
- unsubscribers.push(
194
- events.on("mail.persisted", (row) => {
195
- const parsed = parseMailToEmail(row.raw, row.id);
196
- router.dispatchAgentEvent(row.address, {
197
- type: "mail.delivered",
198
- data: {
199
- ...parsed,
200
- id: row.id,
201
- direction: row.direction,
202
- receivedAt: row.createdAt.toISOString(),
203
- },
204
- });
205
- }),
206
- );
207
-
208
- return {
209
- dispose() {
210
- for (const off of unsubscribers) off();
211
- },
212
- };
213
- }
package/src/index.ts DELETED
@@ -1,78 +0,0 @@
1
- export {
2
- createAgentRepoStore,
3
- type AgentRepoStore,
4
- type DeployContent,
5
- } from "./agent-repo";
6
- export {
7
- createSessionService,
8
- SessionLaunchError,
9
- type SessionService,
10
- } from "./session-service";
11
- export {
12
- createEventCollectorRegistry,
13
- type EventCollectorRegistry,
14
- } from "./event-collector-registry";
15
- export {
16
- createSidecarRouter,
17
- type SidecarRouter,
18
- type SidecarRouterConfig,
19
- type WsHandle,
20
- createSidecarEmitter,
21
- type SidecarEventEmitter,
22
- type SidecarEventMap,
23
- type SidecarEventType,
24
- type SidecarEventListener,
25
- type SidecarLookups,
26
- type SidecarMailPersistedPayload,
27
- type SidecarMailPersistedRow,
28
- } from "./ws";
29
- export {
30
- createHubSessionLookups,
31
- type HubSessionLookupsDeps,
32
- } from "./hub-session-lookups";
33
- export {
34
- createHubSessionOrchestrator,
35
- type HubSessionOrchestrator,
36
- type HubSessionOrchestratorDeps,
37
- type HubSessionRouterFacade,
38
- } from "./hub-session-orchestrator";
39
- export { pushSourceUpdates } from "./credential-push";
40
- export {
41
- skillKindHandler,
42
- skillAuthorize,
43
- skillFrontmatterSchema,
44
- getSkillIndex,
45
- type SkillIndexEntry,
46
- type SkillFrontmatter,
47
- type SkillPrincipal,
48
- type SkillHubPrincipal,
49
- type SkillSidecarPrincipal,
50
- } from "./skill-kind";
51
- export {
52
- createAssetService,
53
- AssetServiceError,
54
- type AssetService,
55
- type Asset,
56
- type AgentAsset,
57
- type AgentAssetWithAsset,
58
- type AccessMode,
59
- type CreateAssetParams,
60
- type PopulateAssetParams,
61
- type AttachAssetParams,
62
- type AssetServiceErrorReason,
63
- } from "./asset-service";
64
- export {
65
- buildAvailableSkillsStanza,
66
- type AvailableSkillEntry,
67
- } from "./available-skills-stanza";
68
- export type {
69
- CreateRepoStoreConfig,
70
- InitRepoOpts,
71
- KindHandler,
72
- Principal,
73
- RefEntry,
74
- RepoAction,
75
- RepoId,
76
- RepoStore,
77
- } from "./repo-store";
78
- export { createRepoStore, UserPrincipal } from "./repo-store";
@@ -1,15 +0,0 @@
1
- export type {
2
- AuthorizeFn,
3
- InitRepoOpts,
4
- KindHandler,
5
- Principal,
6
- RefEntry,
7
- RepoAction,
8
- RepoId,
9
- RepoKind,
10
- RepoStore,
11
- TreeContent,
12
- ValidatePushResult,
13
- } from "./types";
14
- export { UserPrincipal } from "./types";
15
- export { createRepoStore, type CreateRepoStoreConfig } from "./store";