@sema-agent/server 1.314.0 → 1.316.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/dist/approval-hmac.d.ts +17 -0
- package/dist/approval-hmac.js +27 -0
- package/dist/config-center/apply-effective.d.ts +22 -0
- package/dist/config-center/apply-effective.js +283 -0
- package/dist/config-center/http-client.d.ts +23 -0
- package/dist/config-center/http-client.js +109 -0
- package/dist/config-center/restart-signal.d.ts +12 -0
- package/dist/config-center/restart-signal.js +70 -0
- package/dist/config-center/skills-mcp.d.ts +13 -0
- package/dist/config-center/skills-mcp.js +113 -0
- package/dist/config-center/types.d.ts +143 -0
- package/dist/config-center/types.js +2 -0
- package/dist/fleet/fleet-bus.js +92 -83
- package/dist/hooks/hook-runner.js +18 -9
- package/dist/http/idempotency.d.ts +1 -0
- package/dist/http/idempotency.js +3 -0
- package/dist/http/principal-gate.d.ts +12 -0
- package/dist/http/principal-gate.js +52 -0
- package/dist/http/route-ctx.d.ts +67 -0
- package/dist/http/route-ctx.js +2 -0
- package/dist/http/routes/attachments.d.ts +4 -0
- package/dist/http/routes/attachments.js +106 -0
- package/dist/http/routes/capabilities.d.ts +4 -0
- package/dist/http/routes/capabilities.js +111 -0
- package/dist/http/routes/images.d.ts +20 -0
- package/dist/http/routes/images.js +572 -0
- package/dist/http/routes/memory-policy.d.ts +4 -0
- package/dist/http/routes/memory-policy.js +105 -0
- package/dist/http/routes/observability.d.ts +4 -0
- package/dist/http/routes/observability.js +63 -0
- package/dist/http/routes/session-sync.d.ts +36 -0
- package/dist/http/routes/session-sync.js +513 -0
- package/dist/http/routes/sessions-list.d.ts +4 -0
- package/dist/http/routes/sessions-list.js +117 -0
- package/dist/http/routes/sessions.d.ts +17 -0
- package/dist/http/routes/sessions.js +746 -0
- package/dist/http/send.d.ts +6 -0
- package/dist/http/send.js +19 -0
- package/dist/http/server.d.ts +101 -76
- package/dist/http/server.js +129 -2410
- package/dist/http/sse-log.d.ts +25 -0
- package/dist/http/sse-log.js +59 -0
- package/dist/http/workspace-content.d.ts +3 -0
- package/dist/http/workspace-content.js +20 -0
- package/dist/index.d.ts +1 -1
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.js +169 -165
- package/dist/main.js +462 -451
- package/dist/plugins/approval-store-sql.d.ts +52 -0
- package/dist/plugins/approval-store-sql.js +119 -0
- package/dist/plugins/breaker-state-sql.d.ts +29 -0
- package/dist/plugins/breaker-state-sql.js +104 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +67 -0
- package/dist/plugins/checkpoint-store-sql.js +224 -0
- package/dist/plugins/file-snapshot-store-sql.d.ts +38 -0
- package/dist/plugins/file-snapshot-store-sql.js +210 -0
- package/dist/plugins/image-bake-store-sql.d.ts +53 -0
- package/dist/plugins/image-bake-store-sql.js +463 -0
- package/dist/plugins/image-index-sql.d.ts +33 -0
- package/dist/plugins/image-index-sql.js +328 -0
- package/dist/plugins/k8s-bg-scripts.d.ts +19 -0
- package/dist/plugins/k8s-bg-scripts.js +129 -0
- package/dist/plugins/k8s-exec-protocol.d.ts +20 -0
- package/dist/plugins/k8s-exec-protocol.js +87 -0
- package/dist/plugins/outcome-ledger-sql.d.ts +70 -0
- package/dist/plugins/outcome-ledger-sql.js +158 -0
- package/dist/plugins/pg-approval-store.d.ts +1 -27
- package/dist/plugins/pg-approval-store.js +1 -83
- package/dist/plugins/pg-breaker-state.d.ts +1 -19
- package/dist/plugins/pg-breaker-state.js +1 -88
- package/dist/plugins/pg-checkpoint-store.d.ts +1 -33
- package/dist/plugins/pg-checkpoint-store.js +1 -189
- package/dist/plugins/pg-cost-quota.js +3 -143
- package/dist/plugins/pg-file-snapshot-store.d.ts +1 -27
- package/dist/plugins/pg-file-snapshot-store.js +1 -190
- package/dist/plugins/pg-image-bake.d.ts +1 -40
- package/dist/plugins/pg-image-bake.js +1 -420
- package/dist/plugins/pg-image-index.d.ts +1 -21
- package/dist/plugins/pg-image-index.js +1 -217
- package/dist/plugins/pg-outcome-ledger.d.ts +2 -22
- package/dist/plugins/pg-outcome-ledger.js +1 -104
- package/dist/plugins/pg-rate-limiter.d.ts +2 -32
- package/dist/plugins/pg-rate-limiter.js +4 -147
- package/dist/plugins/pg-resume-anchor-store.d.ts +1 -13
- package/dist/plugins/pg-resume-anchor-store.js +1 -22
- package/dist/plugins/pg-run-store.d.ts +1 -75
- package/dist/plugins/pg-run-store.js +1 -287
- package/dist/plugins/pg-session-policy-store.d.ts +1 -11
- package/dist/plugins/pg-session-policy-store.js +1 -90
- package/dist/plugins/pg-tool-result-store.d.ts +1 -15
- package/dist/plugins/pg-tool-result-store.js +1 -52
- package/dist/plugins/pg-workflow-journal-store.d.ts +1 -20
- package/dist/plugins/pg-workflow-journal-store.js +1 -34
- package/dist/plugins/pg-workflow-run-store.d.ts +1 -55
- package/dist/plugins/pg-workflow-run-store.js +1 -220
- package/dist/plugins/remote-env-k8s.d.ts +5 -38
- package/dist/plugins/remote-env-k8s.js +7 -213
- package/dist/plugins/resume-anchor-store-sql.d.ts +23 -0
- package/dist/plugins/resume-anchor-store-sql.js +38 -0
- package/dist/plugins/run-store-sql.d.ts +89 -0
- package/dist/plugins/run-store-sql.js +397 -0
- package/dist/plugins/session-policy-store-sql.d.ts +22 -0
- package/dist/plugins/session-policy-store-sql.js +109 -0
- package/dist/plugins/sql-driver.d.ts +25 -0
- package/dist/plugins/sql-driver.js +59 -0
- package/dist/plugins/tidb-approval-store.d.ts +1 -39
- package/dist/plugins/tidb-approval-store.js +1 -71
- package/dist/plugins/tidb-breaker-state.d.ts +1 -17
- package/dist/plugins/tidb-breaker-state.js +1 -74
- package/dist/plugins/tidb-checkpoint-store.d.ts +1 -49
- package/dist/plugins/tidb-checkpoint-store.js +1 -191
- package/dist/plugins/tidb-file-snapshot-store.d.ts +1 -27
- package/dist/plugins/tidb-file-snapshot-store.js +1 -192
- package/dist/plugins/tidb-image-bake.d.ts +1 -38
- package/dist/plugins/tidb-image-bake.js +1 -348
- package/dist/plugins/tidb-image-index.d.ts +1 -19
- package/dist/plugins/tidb-image-index.js +1 -149
- package/dist/plugins/tidb-outcome-ledger.d.ts +1 -57
- package/dist/plugins/tidb-outcome-ledger.js +1 -97
- package/dist/plugins/tidb-resume-anchor-store.d.ts +1 -13
- package/dist/plugins/tidb-resume-anchor-store.js +1 -22
- package/dist/plugins/tidb-run-store.d.ts +1 -75
- package/dist/plugins/tidb-run-store.js +1 -306
- package/dist/plugins/tidb-session-policy-store.d.ts +1 -11
- package/dist/plugins/tidb-session-policy-store.js +1 -86
- package/dist/plugins/tidb-tool-result-store.d.ts +1 -13
- package/dist/plugins/tidb-tool-result-store.js +1 -38
- package/dist/plugins/tidb-workflow-journal-store.d.ts +1 -20
- package/dist/plugins/tidb-workflow-journal-store.js +1 -34
- package/dist/plugins/tidb-workflow-run-store.d.ts +1 -61
- package/dist/plugins/tidb-workflow-run-store.js +1 -231
- package/dist/plugins/tool-result-store-sql.d.ts +25 -0
- package/dist/plugins/tool-result-store-sql.js +69 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +30 -0
- package/dist/plugins/workflow-journal-store-sql.js +53 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +85 -0
- package/dist/plugins/workflow-run-store-sql.js +299 -0
- package/dist/plugins/write-behind-counter.d.ts +14 -3
- package/dist/plugins/write-behind-counter.js +39 -12
- package/dist/principal-jwt.d.ts +44 -0
- package/dist/principal-jwt.js +95 -0
- package/dist/security.d.ts +2 -58
- package/dist/security.js +3 -118
- package/dist/sema-registry.d.ts +5 -200
- package/dist/sema-registry.js +4 -567
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { skillContentHash } from "@sema-agent/registry-core";
|
|
2
|
+
import { fetchSkillContent } from "./http-client.js";
|
|
3
|
+
export async function applyCenterSkills(baseline, manifest, baseUrl, token, logger, fetchImpl = fetch, diskCacheDir) {
|
|
4
|
+
const { promises: fsp } = await import("node:fs");
|
|
5
|
+
const { join: joinPath } = await import("node:path");
|
|
6
|
+
const diskRead = async (hash) => {
|
|
7
|
+
if (!diskCacheDir)
|
|
8
|
+
return undefined;
|
|
9
|
+
const hex = hash.replace(/^sha256:/, "");
|
|
10
|
+
if (!/^[0-9a-f]{64}$/.test(hex))
|
|
11
|
+
return undefined;
|
|
12
|
+
try {
|
|
13
|
+
const text = await fsp.readFile(joinPath(diskCacheDir, hex), "utf8");
|
|
14
|
+
if (skillContentHash(text) === hash)
|
|
15
|
+
return text;
|
|
16
|
+
logger?.warn("sema_registry_skill_cache_corrupt", { hash, note: "on-disk body fails its own hash — ignored, refetching from center" });
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
};
|
|
22
|
+
const pendingWrites = [];
|
|
23
|
+
const diskWrite = (hash, content) => {
|
|
24
|
+
if (!diskCacheDir)
|
|
25
|
+
return;
|
|
26
|
+
const hex = hash.replace(/^sha256:/, "");
|
|
27
|
+
pendingWrites.push((async () => {
|
|
28
|
+
await fsp.mkdir(diskCacheDir, { recursive: true });
|
|
29
|
+
const tmp = joinPath(diskCacheDir, `${hex}.${Math.random().toString(36).slice(2, 8)}.tmp`);
|
|
30
|
+
await fsp.writeFile(tmp, content, { mode: 0o600 });
|
|
31
|
+
await fsp.rename(tmp, joinPath(diskCacheDir, hex));
|
|
32
|
+
})().catch((err) => logger?.warn("sema_registry_skill_cache_write_failed", { hash, err: String(err) })));
|
|
33
|
+
};
|
|
34
|
+
const byName = new Map(baseline.map((s) => [s.spec.name, s]));
|
|
35
|
+
const contentCache = new Map();
|
|
36
|
+
const seenNames = new Set();
|
|
37
|
+
for (const m of manifest.skills ?? []) {
|
|
38
|
+
if (m.enabled === false)
|
|
39
|
+
continue;
|
|
40
|
+
if (seenNames.has(m.name))
|
|
41
|
+
logger?.warn("sema_registry_skill_duplicate_name", { name: m.name, note: "duplicate name in center manifest — last entry wins" });
|
|
42
|
+
seenNames.add(m.name);
|
|
43
|
+
try {
|
|
44
|
+
let content = contentCache.get(m.contentHash);
|
|
45
|
+
if (content === undefined)
|
|
46
|
+
content = await diskRead(m.contentHash);
|
|
47
|
+
if (content === undefined) {
|
|
48
|
+
content = await fetchSkillContent(baseUrl, token, m.contentHash, fetchImpl);
|
|
49
|
+
diskWrite(m.contentHash, content);
|
|
50
|
+
}
|
|
51
|
+
contentCache.set(m.contentHash, content);
|
|
52
|
+
const overrodeBuiltin = byName.has(m.name);
|
|
53
|
+
byName.set(m.name, { spec: { name: m.name, description: m.description, content }, scenarios: m.scenarios ?? [] });
|
|
54
|
+
logger?.info("sema_registry_skill", { name: m.name, hash: m.contentHash, scenarios: m.scenarios, overrodeBuiltin });
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
logger?.warn("sema_registry_skill_failed", { name: m.name, hash: m.contentHash, err: String(err), note: "keeping baseline if any; skipping center version" });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
await Promise.all(pendingWrites);
|
|
61
|
+
return [...byName.values()];
|
|
62
|
+
}
|
|
63
|
+
function resolveRefs(refs, server, kind, logger) {
|
|
64
|
+
if (!refs)
|
|
65
|
+
return {};
|
|
66
|
+
const out = {};
|
|
67
|
+
for (const [key, envName] of Object.entries(refs)) {
|
|
68
|
+
const v = process.env[envName];
|
|
69
|
+
if (v === undefined) {
|
|
70
|
+
logger?.warn("sema_registry_mcp_env_missing", { server, kind, key, envName, note: "skipping this MCP server — referenced env var is unset in this service" });
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
out[key] = v;
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
export function resolveMcpServers(mcp, logger) {
|
|
78
|
+
const out = [];
|
|
79
|
+
for (const s of mcp.servers ?? []) {
|
|
80
|
+
if (s.enabled === false)
|
|
81
|
+
continue;
|
|
82
|
+
const allow = s.allowTools && s.allowTools.length > 0 ? { allowTools: s.allowTools } : {};
|
|
83
|
+
const elicit = s.elicitation === true ? { elicitation: true } : {};
|
|
84
|
+
if (s.transport.kind === "stdio") {
|
|
85
|
+
const env = resolveRefs(s.transport.envRefs, s.name, "env", logger);
|
|
86
|
+
if (env === null)
|
|
87
|
+
continue;
|
|
88
|
+
out.push({
|
|
89
|
+
scenarios: s.scenarios ?? [],
|
|
90
|
+
spec: { name: s.name, transport: { kind: "stdio", command: s.transport.command, args: s.transport.args, ...(Object.keys(env).length ? { env } : {}) }, ...allow, ...elicit },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
const headers = resolveRefs(s.transport.headerRefs, s.name, "header", logger);
|
|
95
|
+
if (headers === null)
|
|
96
|
+
continue;
|
|
97
|
+
out.push({
|
|
98
|
+
scenarios: s.scenarios ?? [],
|
|
99
|
+
spec: { name: s.name, transport: { kind: "http", url: s.transport.url, ...(Object.keys(headers).length ? { headers } : {}), ...(s.transport.principalHeader ? { principalHeader: s.transport.principalHeader } : {}) }, ...allow, ...elicit },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (out.length > 0)
|
|
104
|
+
logger?.info("sema_registry_mcp", { servers: out.map((s) => s.spec.name) });
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
export function mcpForScenario(servers, scenario) {
|
|
108
|
+
if (!servers || servers.length === 0)
|
|
109
|
+
return undefined;
|
|
110
|
+
const hit = servers.filter((s) => s.scenarios.length === 0 || s.scenarios.includes(scenario)).map((s) => s.spec);
|
|
111
|
+
return hit.length > 0 ? hit : undefined;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=skills-mcp.js.map
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { CollabTemplateWire } from "../capabilities/collab-wire.js";
|
|
2
|
+
import type { Autonomy, CommandRule } from "../runtime-governance.js";
|
|
3
|
+
export interface CenterModel {
|
|
4
|
+
name: string;
|
|
5
|
+
id: string;
|
|
6
|
+
provider: string;
|
|
7
|
+
api: "openai-completions" | "anthropic-messages";
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
apiKeyEnv?: string;
|
|
10
|
+
sealedApiKey?: {
|
|
11
|
+
ciphertext: string;
|
|
12
|
+
publicKeyId: string;
|
|
13
|
+
alg: string;
|
|
14
|
+
setAt?: string;
|
|
15
|
+
};
|
|
16
|
+
tier?: string;
|
|
17
|
+
reasoning?: boolean;
|
|
18
|
+
vision?: boolean;
|
|
19
|
+
contextWindow?: number;
|
|
20
|
+
maxTokens?: number;
|
|
21
|
+
autoCompactTokens?: number;
|
|
22
|
+
charsPerToken?: number;
|
|
23
|
+
cost?: {
|
|
24
|
+
input: number;
|
|
25
|
+
output: number;
|
|
26
|
+
cacheRead?: number;
|
|
27
|
+
cacheWrite?: number;
|
|
28
|
+
};
|
|
29
|
+
quotaWeight?: number;
|
|
30
|
+
defaultThinking?: string;
|
|
31
|
+
reasoningEffortLevels?: string[];
|
|
32
|
+
extraBody?: Record<string, unknown>;
|
|
33
|
+
promptGuidance?: string[];
|
|
34
|
+
enabled?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export type CenterRoleTarget = {
|
|
37
|
+
model: string;
|
|
38
|
+
} | {
|
|
39
|
+
select: unknown;
|
|
40
|
+
};
|
|
41
|
+
export interface CenterTeam {
|
|
42
|
+
name: string;
|
|
43
|
+
members: {
|
|
44
|
+
role: string;
|
|
45
|
+
modelRole?: string;
|
|
46
|
+
model?: string;
|
|
47
|
+
systemPrompt?: string;
|
|
48
|
+
}[];
|
|
49
|
+
rounds: number;
|
|
50
|
+
synthesizer?: {
|
|
51
|
+
role: string;
|
|
52
|
+
modelRole?: string;
|
|
53
|
+
systemPrompt?: string;
|
|
54
|
+
};
|
|
55
|
+
scenario?: string;
|
|
56
|
+
maxTranscriptTokens?: number;
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface CenterSkillManifest {
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
scenarios: string[];
|
|
63
|
+
contentHash: string;
|
|
64
|
+
enabled?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface CenterMcpServer {
|
|
67
|
+
name: string;
|
|
68
|
+
scenarios: string[];
|
|
69
|
+
enabled?: boolean;
|
|
70
|
+
allowTools?: string[];
|
|
71
|
+
elicitation?: boolean;
|
|
72
|
+
transport: {
|
|
73
|
+
kind: "stdio";
|
|
74
|
+
command: string;
|
|
75
|
+
args?: string[];
|
|
76
|
+
envRefs?: Record<string, string>;
|
|
77
|
+
} | {
|
|
78
|
+
kind: "http";
|
|
79
|
+
url: string;
|
|
80
|
+
headerRefs?: Record<string, string>;
|
|
81
|
+
principalHeader?: string;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export interface EffectiveConfig {
|
|
85
|
+
version: number;
|
|
86
|
+
updatedAt: string;
|
|
87
|
+
models: {
|
|
88
|
+
models: CenterModel[];
|
|
89
|
+
roles: Record<string, CenterRoleTarget>;
|
|
90
|
+
atModelAllowlist?: string[];
|
|
91
|
+
};
|
|
92
|
+
teams?: {
|
|
93
|
+
teams: CenterTeam[];
|
|
94
|
+
};
|
|
95
|
+
collab?: {
|
|
96
|
+
templates: CollabTemplateWire[];
|
|
97
|
+
};
|
|
98
|
+
skills?: {
|
|
99
|
+
skills: CenterSkillManifest[];
|
|
100
|
+
};
|
|
101
|
+
mcp?: {
|
|
102
|
+
servers: CenterMcpServer[];
|
|
103
|
+
};
|
|
104
|
+
scenarios?: {
|
|
105
|
+
scenarios: Array<{
|
|
106
|
+
name: string;
|
|
107
|
+
toolset: string;
|
|
108
|
+
enabled?: boolean;
|
|
109
|
+
}>;
|
|
110
|
+
};
|
|
111
|
+
runtime?: {
|
|
112
|
+
rateLimitPerMin?: number;
|
|
113
|
+
approvalRequire?: string[];
|
|
114
|
+
maxTaskCostUsd?: number;
|
|
115
|
+
maxTaskTokens?: number;
|
|
116
|
+
maxPrincipalCostUsd?: number;
|
|
117
|
+
costQuotaWindowSec?: number;
|
|
118
|
+
autonomy?: Autonomy;
|
|
119
|
+
commandPolicy?: CommandRule[];
|
|
120
|
+
};
|
|
121
|
+
projects?: {
|
|
122
|
+
projects?: Record<string, unknown>;
|
|
123
|
+
} | Record<string, unknown>;
|
|
124
|
+
governance?: {
|
|
125
|
+
autonomy?: Autonomy;
|
|
126
|
+
commandPolicy?: CommandRule[];
|
|
127
|
+
approvalRequire?: string[];
|
|
128
|
+
};
|
|
129
|
+
plugins?: {
|
|
130
|
+
plugins?: unknown[];
|
|
131
|
+
};
|
|
132
|
+
prompts?: unknown;
|
|
133
|
+
}
|
|
134
|
+
export interface ExecutionRuling {
|
|
135
|
+
required: boolean;
|
|
136
|
+
allowedLanes: string[];
|
|
137
|
+
sessionMirror?: SessionMirrorRuling;
|
|
138
|
+
}
|
|
139
|
+
export interface SessionMirrorRuling {
|
|
140
|
+
engineUrl: string;
|
|
141
|
+
required: boolean;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/fleet/fleet-bus.js
CHANGED
|
@@ -262,94 +262,78 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
262
262
|
return u.tokens;
|
|
263
263
|
return undefined;
|
|
264
264
|
};
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (e.parentSessionId)
|
|
288
|
-
return { hostSessionId: e.parentSessionId };
|
|
289
|
-
const host = e.parentTaskId ? bus.snapshot().tasks.find((r) => r.id === e.parentTaskId && r.scope === (e.scope ?? "default")) : undefined;
|
|
290
|
-
return host?.sessionId ? { hostSessionId: host.sessionId } : {};
|
|
291
|
-
})()
|
|
292
|
-
: {}),
|
|
293
|
-
...(!(e.sessionScoped && e.owner) && !e.workflowRunId && (e.rootSessionId ?? e.parentSessionId)
|
|
294
|
-
? (() => {
|
|
295
|
-
if (e.rootSessionId)
|
|
296
|
-
return { hostSessionId: e.rootSessionId };
|
|
297
|
-
const childScope = e.scope ?? "default";
|
|
298
|
-
for (const pm of meta.values()) {
|
|
299
|
-
if (pm.aliasUuid === e.parentSessionId && (pm.tenantScope ?? "default") === childScope) {
|
|
300
|
-
return pm.hostSessionId ? { hostSessionId: pm.hostSessionId } : {};
|
|
301
|
-
}
|
|
302
|
-
}
|
|
265
|
+
const handleSpawn = (e) => {
|
|
266
|
+
const tomb = meta.get(e.taskId);
|
|
267
|
+
const inheritParent = !e.parentTaskId && !e.parentSessionId && tomb?.done === true;
|
|
268
|
+
const m = {
|
|
269
|
+
...(e.parentTaskId ? { parentTaskId: e.parentTaskId } : {}),
|
|
270
|
+
...(!e.parentTaskId && e.parentSessionId ? { parentSessionLink: e.parentSessionId } : {}),
|
|
271
|
+
...(inheritParent && tomb?.parentTaskId !== undefined ? { parentTaskId: tomb.parentTaskId } : {}),
|
|
272
|
+
...(inheritParent && tomb?.parentSessionLink !== undefined ? { parentSessionLink: tomb.parentSessionLink } : {}),
|
|
273
|
+
...(inheritParent && tomb?.resolvedParentId !== undefined ? { resolvedParentId: tomb.resolvedParentId } : {}),
|
|
274
|
+
...(e.sessionScoped && e.owner ? { hostSessionId: e.rootSessionId ?? e.owner } : {}),
|
|
275
|
+
tenantScope: e.scope ?? "default",
|
|
276
|
+
sessionScoped: e.sessionScoped,
|
|
277
|
+
spawnedAt: e.startedAt ?? Date.now(),
|
|
278
|
+
...(e.rootSessionId ? { rootSessionId: e.rootSessionId } : {}),
|
|
279
|
+
...(e.parentToolCallId ? { parentToolCallId: e.parentToolCallId } : {}),
|
|
280
|
+
...(e.sessionId ? { aliasUuid: e.sessionId } : {}),
|
|
281
|
+
...(e.workflowRunId ? { workflowRunId: e.workflowRunId } : {}),
|
|
282
|
+
...(e.workflowRunId && !(e.sessionScoped && e.owner)
|
|
283
|
+
? (() => {
|
|
284
|
+
if (e.rootSessionId)
|
|
285
|
+
return { hostSessionId: e.rootSessionId };
|
|
286
|
+
if (e.parentSessionId)
|
|
303
287
|
return { hostSessionId: e.parentSessionId };
|
|
304
|
-
|
|
305
|
-
: {}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
else {
|
|
318
|
-
remember(e.taskId, m);
|
|
319
|
-
}
|
|
320
|
-
if (m.done) {
|
|
321
|
-
dlog("bg_child_event", { kind: `${e.kind}-after-terminal-ignored`, taskId: e.taskId });
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
if (m.parentToolCallId === undefined && e.parentToolCallId)
|
|
325
|
-
m.parentToolCallId = e.parentToolCallId;
|
|
326
|
-
if (e.kind === "tick") {
|
|
327
|
-
if (!m.suppressedTwin && e.progressTaskId && (!e.progressParentTaskId || e.progressParentTaskId === (m.parentTaskId ?? m.parentSessionLink))) {
|
|
328
|
-
const tail = ` ${e.progressTaskId}`;
|
|
329
|
-
for (const row of bus.snapshot().tasks) {
|
|
330
|
-
if (row.id.endsWith(tail))
|
|
331
|
-
bus.removeTask(row.id);
|
|
332
|
-
}
|
|
333
|
-
m.suppressedTwin = true;
|
|
334
|
-
}
|
|
335
|
-
if (m.aliasUuid === undefined && e.progressTaskId && (!e.progressParentTaskId || e.progressParentTaskId === (m.parentTaskId ?? m.parentSessionLink))) {
|
|
336
|
-
m.aliasUuid = e.progressTaskId;
|
|
337
|
-
for (const [cid, cm] of meta) {
|
|
338
|
-
if ((cm.parentTaskId ?? cm.parentSessionLink) === m.aliasUuid && cm.resolvedParentId === undefined && !cm.done) {
|
|
339
|
-
bus.publishTask({ id: cid, ...rowTags(cm) });
|
|
288
|
+
const host = e.parentTaskId ? bus.snapshot().tasks.find((r) => r.id === e.parentTaskId && r.scope === (e.scope ?? "default")) : undefined;
|
|
289
|
+
return host?.sessionId ? { hostSessionId: host.sessionId } : {};
|
|
290
|
+
})()
|
|
291
|
+
: {}),
|
|
292
|
+
...(!(e.sessionScoped && e.owner) && !e.workflowRunId && (e.rootSessionId ?? e.parentSessionId)
|
|
293
|
+
? (() => {
|
|
294
|
+
if (e.rootSessionId)
|
|
295
|
+
return { hostSessionId: e.rootSessionId };
|
|
296
|
+
const childScope = e.scope ?? "default";
|
|
297
|
+
for (const pm of meta.values()) {
|
|
298
|
+
if (pm.aliasUuid === e.parentSessionId && (pm.tenantScope ?? "default") === childScope) {
|
|
299
|
+
return pm.hostSessionId ? { hostSessionId: pm.hostSessionId } : {};
|
|
300
|
+
}
|
|
340
301
|
}
|
|
302
|
+
return { hostSessionId: e.parentSessionId };
|
|
303
|
+
})()
|
|
304
|
+
: {}),
|
|
305
|
+
};
|
|
306
|
+
remember(e.taskId, m);
|
|
307
|
+
bus.publishTask({ id: e.taskId, name: redactSecrets(e.description ?? e.name ?? e.taskId), ...(e.agentType ? { agentType: redactSecrets(e.agentType) } : {}), ...rowTags(m), status: "running", tokens: 0, ...(e.transcriptId ? { transcriptId: e.transcriptId } : {}) });
|
|
308
|
+
dlog("bg_child_event", { kind: "spawn", taskId: e.taskId, sessionScoped: e.sessionScoped, scope: m.tenantScope, hostSessionId: m.hostSessionId ?? null, parentTaskId: m.parentTaskId ?? null });
|
|
309
|
+
};
|
|
310
|
+
const handleTick = (e, m) => {
|
|
311
|
+
if (!m.suppressedTwin && e.progressTaskId && (!e.progressParentTaskId || e.progressParentTaskId === (m.parentTaskId ?? m.parentSessionLink))) {
|
|
312
|
+
const tail = ` ${e.progressTaskId}`;
|
|
313
|
+
for (const row of bus.snapshot().tasks) {
|
|
314
|
+
if (row.id.endsWith(tail))
|
|
315
|
+
bus.removeTask(row.id);
|
|
316
|
+
}
|
|
317
|
+
m.suppressedTwin = true;
|
|
318
|
+
}
|
|
319
|
+
if (m.aliasUuid === undefined && e.progressTaskId && (!e.progressParentTaskId || e.progressParentTaskId === (m.parentTaskId ?? m.parentSessionLink))) {
|
|
320
|
+
m.aliasUuid = e.progressTaskId;
|
|
321
|
+
for (const [cid, cm] of meta) {
|
|
322
|
+
if ((cm.parentTaskId ?? cm.parentSessionLink) === m.aliasUuid && cm.resolvedParentId === undefined && !cm.done) {
|
|
323
|
+
bus.publishTask({ id: cid, ...rowTags(cm) });
|
|
341
324
|
}
|
|
342
325
|
}
|
|
343
|
-
const tokens = sumUsage(e.usage);
|
|
344
|
-
const name = e.name ? redactSecrets(e.name) : undefined;
|
|
345
|
-
const agentType = e.agentType ? redactSecrets(e.agentType) : name;
|
|
346
|
-
const currentAction = e.currentAction ? redactSecrets(e.currentAction) : undefined;
|
|
347
|
-
const currentTool = e.currentTool
|
|
348
|
-
? { toolName: e.currentTool.toolName, ...(e.currentTool.target !== undefined ? { target: redactSecrets(e.currentTool.target).slice(0, 300) } : {}) }
|
|
349
|
-
: undefined;
|
|
350
|
-
bus.publishTask({ id: e.taskId, ...rowTags(m), status: "running", ...(tokens !== undefined ? { tokens } : {}), ...(name ? { name } : {}), ...(agentType ? { agentType } : {}), ...(currentAction ? { currentAction } : {}), ...(currentTool ? { currentTool } : {}), ...(e.usage?.toolUses !== undefined ? { toolUses: e.usage.toolUses } : {}), ...(e.transcriptId ? { transcriptId: e.transcriptId } : {}) });
|
|
351
|
-
return;
|
|
352
326
|
}
|
|
327
|
+
const tokens = sumUsage(e.usage);
|
|
328
|
+
const name = e.name ? redactSecrets(e.name) : undefined;
|
|
329
|
+
const agentType = e.agentType ? redactSecrets(e.agentType) : name;
|
|
330
|
+
const currentAction = e.currentAction ? redactSecrets(e.currentAction) : undefined;
|
|
331
|
+
const currentTool = e.currentTool
|
|
332
|
+
? { toolName: e.currentTool.toolName, ...(e.currentTool.target !== undefined ? { target: redactSecrets(e.currentTool.target).slice(0, 300) } : {}) }
|
|
333
|
+
: undefined;
|
|
334
|
+
bus.publishTask({ id: e.taskId, ...rowTags(m), status: "running", ...(tokens !== undefined ? { tokens } : {}), ...(name ? { name } : {}), ...(agentType ? { agentType } : {}), ...(currentAction ? { currentAction } : {}), ...(currentTool ? { currentTool } : {}), ...(e.usage?.toolUses !== undefined ? { toolUses: e.usage.toolUses } : {}), ...(e.transcriptId ? { transcriptId: e.transcriptId } : {}) });
|
|
335
|
+
};
|
|
336
|
+
const handleTerminal = (e, m) => {
|
|
353
337
|
const status = e.status === "completed" ? "completed" : e.status === "killed" ? "killed" : "failed";
|
|
354
338
|
bus.publishTask({
|
|
355
339
|
id: e.taskId, ...rowTags(m), status,
|
|
@@ -420,6 +404,31 @@ export function fleetBackgroundChildPublisher(bus, log) {
|
|
|
420
404
|
m.done = true;
|
|
421
405
|
m.suppressedTwin = true;
|
|
422
406
|
};
|
|
407
|
+
return (e) => {
|
|
408
|
+
if (e.kind === "spawn") {
|
|
409
|
+
handleSpawn(e);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
const m = meta.get(e.taskId) ?? { sessionScoped: e.sessionScoped, tenantScope: "default", spawnedAt: Date.now() };
|
|
413
|
+
if (!meta.has(e.taskId)) {
|
|
414
|
+
remember(e.taskId, m);
|
|
415
|
+
dlog("bg_child_event", { kind: `${e.kind}-lazy-mint`, taskId: e.taskId, sessionScoped: e.sessionScoped });
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
remember(e.taskId, m);
|
|
419
|
+
}
|
|
420
|
+
if (m.done) {
|
|
421
|
+
dlog("bg_child_event", { kind: `${e.kind}-after-terminal-ignored`, taskId: e.taskId });
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
if (m.parentToolCallId === undefined && e.parentToolCallId)
|
|
425
|
+
m.parentToolCallId = e.parentToolCallId;
|
|
426
|
+
if (e.kind === "tick") {
|
|
427
|
+
handleTick(e, m);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
handleTerminal(e, m);
|
|
431
|
+
};
|
|
423
432
|
}
|
|
424
433
|
export function fleetRunLabels(objective) {
|
|
425
434
|
const oneLine = redactSecrets((objective ?? "").replace(/\s+/g, " ")).trim();
|
|
@@ -523,7 +523,7 @@ export function createTaskHooks(config, ctx) {
|
|
|
523
523
|
const onceFired = new Set();
|
|
524
524
|
const hooks = {};
|
|
525
525
|
if (pre) {
|
|
526
|
-
|
|
526
|
+
const preToolUseHook = async (toolName, input, tctx) => {
|
|
527
527
|
let currentInput = input;
|
|
528
528
|
let rewritten = false;
|
|
529
529
|
let asked;
|
|
@@ -608,9 +608,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
608
608
|
}
|
|
609
609
|
return undefined;
|
|
610
610
|
};
|
|
611
|
+
hooks.preToolUse = preToolUseHook;
|
|
611
612
|
}
|
|
612
613
|
if (post) {
|
|
613
|
-
|
|
614
|
+
const postToolUseHook = async (toolName, input, output, tctx) => {
|
|
614
615
|
const contexts = [];
|
|
615
616
|
const responseText = output.content
|
|
616
617
|
.map((c) => (c && typeof c === "object" && typeof c.text === "string" ? c.text : ""))
|
|
@@ -657,9 +658,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
657
658
|
}
|
|
658
659
|
return contexts.length > 0 ? { additionalContext: contexts.join("\n") } : undefined;
|
|
659
660
|
};
|
|
661
|
+
hooks.postToolUse = postToolUseHook;
|
|
660
662
|
}
|
|
661
663
|
if (postFailure) {
|
|
662
|
-
|
|
664
|
+
const postToolUseFailureHook = async (toolName, input, f, tctx) => {
|
|
663
665
|
const contexts = [];
|
|
664
666
|
const payload = {
|
|
665
667
|
...basePayload(ctx),
|
|
@@ -700,9 +702,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
700
702
|
}
|
|
701
703
|
return contexts.length > 0 ? { additionalContext: contexts.join("\n") } : undefined;
|
|
702
704
|
};
|
|
705
|
+
hooks.postToolUseFailure = postToolUseFailureHook;
|
|
703
706
|
}
|
|
704
707
|
if (postBatch) {
|
|
705
|
-
|
|
708
|
+
const postToolBatchHook = async (calls) => {
|
|
706
709
|
const contexts = [];
|
|
707
710
|
const payload = {
|
|
708
711
|
...basePayload(ctx),
|
|
@@ -740,9 +743,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
740
743
|
}
|
|
741
744
|
return contexts.length > 0 ? { additionalContext: contexts.join("\n") } : undefined;
|
|
742
745
|
};
|
|
746
|
+
hooks.postToolBatch = postToolBatchHook;
|
|
743
747
|
}
|
|
744
748
|
if (promptSubmit) {
|
|
745
|
-
|
|
749
|
+
const userPromptSubmitHook = async (prompt) => {
|
|
746
750
|
const contexts = [];
|
|
747
751
|
const payload = { ...basePayload(ctx), hook_event_name: "UserPromptSubmit", prompt: clip(prompt, MAX_TOOL_INPUT_CHARS) };
|
|
748
752
|
const singles = await runMatchingEntries("UserPromptSubmit", ignoreMatchers(promptSubmit), "", payload, ctx, onceFired, Date.now() + MAX_HOOK_EVENT_TOTAL_SECONDS * 1000);
|
|
@@ -777,9 +781,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
777
781
|
}
|
|
778
782
|
return contexts.length > 0 ? { additionalContext: contexts.join("\n") } : undefined;
|
|
779
783
|
};
|
|
784
|
+
hooks.userPromptSubmit = userPromptSubmitHook;
|
|
780
785
|
}
|
|
781
786
|
if (stopEntries) {
|
|
782
|
-
|
|
787
|
+
const stopHook = async (sctx) => {
|
|
783
788
|
const payload = { ...basePayload(ctx), hook_event_name: "Stop", stop_hook_active: sctx.stopHookActive };
|
|
784
789
|
let llmExtra;
|
|
785
790
|
const wantsPrompt = stopEntries.some((g) => g.hooks.some((h) => h.type === "prompt"));
|
|
@@ -867,9 +872,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
867
872
|
...(contexts.length ? { additionalContext: contexts.join("\n") } : {}),
|
|
868
873
|
};
|
|
869
874
|
};
|
|
875
|
+
hooks.stop = stopHook;
|
|
870
876
|
}
|
|
871
877
|
if (stopFailureEntries) {
|
|
872
|
-
|
|
878
|
+
const stopFailureHook = async (fctx) => {
|
|
873
879
|
const turnError = toAssistantTurnError(fctx.errorKind);
|
|
874
880
|
const payload = {
|
|
875
881
|
...basePayload(ctx),
|
|
@@ -879,9 +885,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
879
885
|
};
|
|
880
886
|
await runObserveOnlyEvent("StopFailure", stopFailureEntries, turnError, payload, ctx, onceFired);
|
|
881
887
|
};
|
|
888
|
+
hooks.stopFailure = stopFailureHook;
|
|
882
889
|
}
|
|
883
890
|
if (preCompactEntries) {
|
|
884
|
-
|
|
891
|
+
const preCompactHook = async (pctx) => {
|
|
885
892
|
const payload = {
|
|
886
893
|
...basePayload(ctx),
|
|
887
894
|
hook_event_name: "PreCompact",
|
|
@@ -911,9 +918,10 @@ export function createTaskHooks(config, ctx) {
|
|
|
911
918
|
}
|
|
912
919
|
return undefined;
|
|
913
920
|
};
|
|
921
|
+
hooks.preCompact = preCompactHook;
|
|
914
922
|
}
|
|
915
923
|
if (postCompactEntries) {
|
|
916
|
-
|
|
924
|
+
const postCompactHook = async (cctx) => {
|
|
917
925
|
const payload = {
|
|
918
926
|
...basePayload(ctx),
|
|
919
927
|
hook_event_name: "PostCompact",
|
|
@@ -922,6 +930,7 @@ export function createTaskHooks(config, ctx) {
|
|
|
922
930
|
};
|
|
923
931
|
await runObserveOnlyEvent("PostCompact", postCompactEntries, cctx.trigger, payload, ctx, onceFired);
|
|
924
932
|
};
|
|
933
|
+
hooks.postCompact = postCompactHook;
|
|
925
934
|
}
|
|
926
935
|
return hooks;
|
|
927
936
|
}
|
|
@@ -9,4 +9,5 @@ export declare class IdempotencyCache<T> {
|
|
|
9
9
|
private live;
|
|
10
10
|
private maybeSweep;
|
|
11
11
|
}
|
|
12
|
+
export declare function scopedIdempotencyKey(raw: string | undefined, source: string | null, principal: string | undefined): string | undefined;
|
|
12
13
|
//# sourceMappingURL=idempotency.d.ts.map
|
package/dist/http/idempotency.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IncomingMessage } from "node:http";
|
|
2
|
+
import type { ServiceConfig } from "../config-types.js";
|
|
3
|
+
export declare function headerStr(v: string | string[] | undefined): string | undefined;
|
|
4
|
+
export declare function safeEqual(a: string, b: string): boolean;
|
|
5
|
+
export declare function authorized(req: IncomingMessage, token: string): boolean;
|
|
6
|
+
export declare function systemFor(req: IncomingMessage, config: ServiceConfig): string | null | undefined;
|
|
7
|
+
export declare function bearerPresentedButUnverified(req: IncomingMessage, config: ServiceConfig): boolean;
|
|
8
|
+
export declare function gatedPrincipal(req: IncomingMessage, config: ServiceConfig): string | undefined;
|
|
9
|
+
export declare function explicitOperatorOk(principal: string | undefined, operatorPrincipals: readonly string[]): boolean;
|
|
10
|
+
export declare function isOperator(principal: string | undefined, operatorPrincipals: readonly string[]): boolean;
|
|
11
|
+
export declare function explicitOperator(principal: string | undefined, operatorPrincipals: readonly string[]): boolean;
|
|
12
|
+
//# sourceMappingURL=principal-gate.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { verifiedPrincipal, ssoVerifiedPrincipal } from "../security.js";
|
|
3
|
+
export function headerStr(v) {
|
|
4
|
+
return Array.isArray(v) ? v[0] : v;
|
|
5
|
+
}
|
|
6
|
+
export function safeEqual(a, b) {
|
|
7
|
+
const ab = Buffer.from(a, "utf8");
|
|
8
|
+
const bb = Buffer.from(b, "utf8");
|
|
9
|
+
return ab.length === bb.length && timingSafeEqual(ab, bb);
|
|
10
|
+
}
|
|
11
|
+
export function authorized(req, token) {
|
|
12
|
+
const h = req.headers.authorization ?? "";
|
|
13
|
+
return safeEqual(h, `Bearer ${token}`) || safeEqual(h, `token ${token}`);
|
|
14
|
+
}
|
|
15
|
+
export function systemFor(req, config) {
|
|
16
|
+
for (const [tok, system] of Object.entries(config.authTokens ?? {})) {
|
|
17
|
+
if (authorized(req, tok))
|
|
18
|
+
return system;
|
|
19
|
+
}
|
|
20
|
+
if (config.authToken && authorized(req, config.authToken))
|
|
21
|
+
return null;
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
export function bearerPresentedButUnverified(req, config) {
|
|
25
|
+
const h = req.headers.authorization;
|
|
26
|
+
if (typeof h !== "string" || !/^(Bearer|token) /i.test(h))
|
|
27
|
+
return false;
|
|
28
|
+
if (ssoVerifiedPrincipal(req))
|
|
29
|
+
return false;
|
|
30
|
+
if (systemFor(req, config) !== undefined)
|
|
31
|
+
return false;
|
|
32
|
+
if (config.traceToken && authorized(req, config.traceToken))
|
|
33
|
+
return false;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
export function gatedPrincipal(req, config) {
|
|
37
|
+
if (bearerPresentedButUnverified(req, config))
|
|
38
|
+
return undefined;
|
|
39
|
+
return verifiedPrincipal(req, config);
|
|
40
|
+
}
|
|
41
|
+
export function explicitOperatorOk(principal, operatorPrincipals) {
|
|
42
|
+
return operatorPrincipals.length > 0 && principal !== undefined && operatorPrincipals.includes(principal);
|
|
43
|
+
}
|
|
44
|
+
export function isOperator(principal, operatorPrincipals) {
|
|
45
|
+
if (operatorPrincipals.length === 0)
|
|
46
|
+
return true;
|
|
47
|
+
return principal !== undefined && operatorPrincipals.includes(principal);
|
|
48
|
+
}
|
|
49
|
+
export function explicitOperator(principal, operatorPrincipals) {
|
|
50
|
+
return operatorPrincipals.length > 0 && principal !== undefined && operatorPrincipals.includes(principal);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=principal-gate.js.map
|