@intx/hub-sessions 0.1.2 → 0.2.2
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 +84 -1
- package/dist/agent-repo.d.ts +89 -0
- package/dist/agent-repo.js +109 -0
- package/dist/agent-state-kind.d.ts +12 -0
- package/dist/agent-state-kind.js +185 -0
- package/dist/asset-service.d.ts +123 -0
- package/dist/asset-service.js +349 -0
- package/dist/available-skills-stanza.d.ts +21 -0
- package/dist/available-skills-stanza.js +32 -0
- package/dist/credential-push.d.ts +32 -0
- package/dist/credential-push.js +85 -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 +357 -0
- package/dist/hub-session-lookups.d.ts +17 -0
- package/dist/hub-session-lookups.js +204 -0
- package/dist/hub-session-orchestrator.d.ts +25 -0
- package/dist/hub-session-orchestrator.js +122 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +16 -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 +1692 -0
- package/dist/repo-store/subscribe-kind.d.ts +53 -0
- package/dist/repo-store/subscribe-kind.js +179 -0
- package/dist/repo-store/types.d.ts +483 -0
- package/dist/repo-store/types.js +42 -0
- package/dist/session-service.d.ts +235 -0
- package/dist/session-service.js +997 -0
- package/dist/skill-kind.d.ts +41 -0
- package/dist/skill-kind.js +288 -0
- package/dist/substrate.d.ts +8 -0
- package/dist/substrate.js +21 -0
- package/dist/workflow-kind.d.ts +21 -0
- package/dist/workflow-kind.js +263 -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 +326 -0
- package/dist/workflow-run-kind.js +2646 -0
- package/dist/workflow-run-reader.d.ts +47 -0
- package/dist/workflow-run-reader.js +157 -0
- package/dist/ws/index.d.ts +3 -0
- package/dist/ws/index.js +3 -0
- package/dist/ws/sidecar-events.d.ts +134 -0
- package/dist/ws/sidecar-events.js +70 -0
- package/dist/ws/sidecar-handler.d.ts +184 -0
- package/dist/ws/sidecar-handler.js +1603 -0
- package/dist/ws/sidecar-token-authenticator.d.ts +15 -0
- package/dist/ws/sidecar-token-authenticator.js +24 -0
- package/package.json +34 -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
|
@@ -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";
|
package/src/repo-store/index.ts
DELETED
|
@@ -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";
|