@sema-agent/server 1.313.0 → 1.314.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 (38) hide show
  1. package/dist/auth-bridge.d.ts +3 -2
  2. package/dist/bench/s1/live-deps.js +2 -2
  3. package/dist/budget.d.ts +4 -76
  4. package/dist/budget.js +4 -83
  5. package/dist/capabilities/sandbox-file-send.d.ts +2 -1
  6. package/dist/config-types.d.ts +1 -1
  7. package/dist/elicitation.d.ts +5 -3
  8. package/dist/elicitation.js +3 -2
  9. package/dist/fleet-lease.d.ts +1 -1
  10. package/dist/fleet-lease.js +1 -1
  11. package/dist/hooks/hook-llm.d.ts +5 -4
  12. package/dist/hooks/hook-runner.d.ts +1 -1
  13. package/dist/hooks/hook-runner.js +1 -1
  14. package/dist/http/server.js +67 -85
  15. package/dist/key-resolver.d.ts +1 -1
  16. package/dist/key-resolver.js +1 -1
  17. package/dist/leader/grader-env-factory.d.ts +1 -1
  18. package/dist/leader/grader-env-factory.js +2 -2
  19. package/dist/leader/wire.d.ts +1 -1
  20. package/dist/leader/wire.js +1 -1
  21. package/dist/main.js +26 -26
  22. package/dist/memory-scope.d.ts +18 -0
  23. package/dist/memory-scope.js +38 -0
  24. package/dist/observability/cost-taxonomy.d.ts +34 -0
  25. package/dist/observability/cost-taxonomy.js +26 -0
  26. package/dist/observability/prompt-manifest.d.ts +75 -0
  27. package/dist/observability/prompt-manifest.js +82 -0
  28. package/dist/plugins/web-search.d.ts +4 -3
  29. package/dist/question.d.ts +2 -1
  30. package/dist/question.js +3 -2
  31. package/dist/run-local.js +2 -2
  32. package/dist/runtime-caps-resolver.d.ts +7 -7
  33. package/dist/runtime-caps-resolver.js +3 -3
  34. package/dist/security.d.ts +2 -16
  35. package/dist/security.js +3 -37
  36. package/dist/tool-approval.d.ts +2 -1
  37. package/dist/tool-approval.js +3 -2
  38. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -63,10 +63,10 @@ import { exportMemoryScope } from "./memory-export.js";
63
63
  import { performMemorySync } from "./memory-sync.js";
64
64
  import { createMemorySyncRunner, createMemorySyncTransport } from "./memory-sync-client.js";
65
65
  import { createLeaderEndpoint } from "./leader/endpoint.js";
66
- import { buildLeaderRunner } from "./leader/wire.js";
66
+ import { createLeaderRunner } from "./leader/wire.js";
67
67
  import { WorkflowNotifyGate, JournalingWorkflowRunStore, FileWorkflowNotifyJournalStore, } from "./orchestration/workflow-notify-journal.js";
68
68
  import { FileWorkflowCompletionInbox, InMemoryWorkflowCompletionInbox, resolveCompletionRoute, resolveServedSession, } from "./orchestration/workflow-completion-inbox.js";
69
- import { buildPricing, buildTracer, buildSideQueryAccountant, cappedCeiling, ModelUsageTracker, PromptManifestTracker } from "./budget.js";
69
+ import { buildPricing, createTracer, createSideQueryAccountant, cappedCeiling, ModelUsageTracker, PromptManifestTracker } from "./budget.js";
70
70
  import { CostQuota } from "./observability/cost-quota.js";
71
71
  import { startOtlpExporter } from "./observability/otel-exporter.js";
72
72
  import { HEARTBEAT_MS, backgroundAgentOutput, taskHandleOutput, taskHandleStop } from "./runs.js";
@@ -84,14 +84,14 @@ import { LocalTaskAttachmentStore } from "./plugins/local-task-attachment-store.
84
84
  import { MinioBlobBackend, SQL_BLOB_DEFAULT_MAX_BYTES } from "./plugins/blob-backend.js";
85
85
  import { TiDBBackgroundAgentStore, PgBackgroundAgentStore, ensureTiDBBackgroundAgentSchema, ensurePgBackgroundAgentSchema } from "./plugins/background-agent-store-sql.js";
86
86
  import { TiDBMailboxStore, PgMailboxStore, ensureTiDBMailboxSchema, ensurePgMailboxSchema } from "./plugins/mailbox-store-sql.js";
87
- import { createPrincipalCapsClient, gateExecutionLane, scopedTokenNeedsWorker, applyObserverEnvOptIn } from "./runtime-caps-resolver.js";
87
+ import { createPrincipalEntitlementsClient, gateExecutionLane, scopedTokenNeedsWorker, applyObserverEnvOptIn } from "./runtime-caps-resolver.js";
88
88
  import { applyRuntimeGovernance, stripDelegationTools } from "./runtime-governance.js";
89
89
  import { parseTaskSettings, applyTaskSettings, coercePermissionMode, withPermissionMode, effectiveThinking, acceptAppendSystemPrompt, hasConstitutionAnchors, providerDropsAppend, MAX_SETTINGS_OUTPUT_STYLE_CHARS } from "./task-settings.js";
90
- import { buildTaskHooks, composeHooks } from "./hooks/hook-runner.js";
90
+ import { createTaskHooks, composeHooks } from "./hooks/hook-runner.js";
91
91
  import { createHookLlm } from "./hooks/hook-llm.js";
92
92
  import { selfOrchestrationFromBody, enableForkFromBody, workflowModelAllowlistFor, normalizeRetainSubagentSessions } from "./task-workflow.js";
93
93
  import { FleetUsageAccumulator, startFleetClientFromEnv } from "./fleet-client.js";
94
- import { buildFleetLeaseFromEnv } from "./fleet-lease.js";
94
+ import { createFleetLeaseFromEnv } from "./fleet-lease.js";
95
95
  import { reclaimOrphansAtBoot } from "./boot-reclaim.js";
96
96
  import { evictLspOnDestroy } from "./lsp-evict.js";
97
97
  import { makeLoadProjectMemory, makeProbeInstructionSources } from "./project-memory.js";
@@ -104,7 +104,7 @@ import { createWorkerHardenedVmRunner } from "./orchestration/hardened-vm-worker
104
104
  import { WorkflowAgentRegistry } from "./orchestration/workflow-agent-steer.js";
105
105
  import { SubagentSteerRegistry } from "./orchestration/subagent-steer.js";
106
106
  import { FleetEventBus, fleetBackgroundChildPublisher } from "./fleet/fleet-bus.js";
107
- import { buildKeyResolver } from "./key-resolver.js";
107
+ import { createKeyResolver } from "./key-resolver.js";
108
108
  function serviceVersion() {
109
109
  try {
110
110
  const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
@@ -668,9 +668,9 @@ async function main() {
668
668
  const modelUsageTracker = new ModelUsageTracker();
669
669
  const promptManifestTracker = new PromptManifestTracker();
670
670
  const fleetUsage = config.configCenter && process.env.FLEET_ADVERTISE_ADDRESS ? new FleetUsageAccumulator() : undefined;
671
- const fleetLease = buildFleetLeaseFromEnv(config, { logger, metrics });
672
- const tracer = buildTracer(metrics, costQuota, modelUsageTracker, fleetUsage, fleetLease, (m) => config.modelQuotaWeights[m] ?? 1, promptManifestTracker);
673
- const sideQueryAccounting = buildSideQueryAccountant(metrics, costQuota, fleetUsage, fleetLease, (m) => config.modelQuotaWeights[m] ?? 1);
671
+ const fleetLease = createFleetLeaseFromEnv(config, { logger, metrics });
672
+ const tracer = createTracer(metrics, costQuota, modelUsageTracker, fleetUsage, fleetLease, (m) => config.modelQuotaWeights[m] ?? 1, promptManifestTracker);
673
+ const sideQueryAccounting = createSideQueryAccountant(metrics, costQuota, fleetUsage, fleetLease, (m) => config.modelQuotaWeights[m] ?? 1);
674
674
  const toolResultStore = backend?.toolResult ? backend.toolResult() : undefined;
675
675
  const sessionPolicyStore = backend ? backend.sessionPolicy() : undefined;
676
676
  const fileSnapshotStore = backend ? backend.fileSnapshot() : undefined;
@@ -975,7 +975,7 @@ async function main() {
975
975
  });
976
976
  }
977
977
  const principalCaps = config.configCenter && !config.configCenter.dryRun
978
- ? createPrincipalCapsClient({
978
+ ? createPrincipalEntitlementsClient({
979
979
  baseUrl: config.configCenter.baseUrl,
980
980
  token: config.configCenter.token,
981
981
  ...(config.configCenter.worker ? { worker: config.configCenter.worker } : {}),
@@ -1190,19 +1190,19 @@ async function main() {
1190
1190
  tracer,
1191
1191
  promptSource,
1192
1192
  sessionStore: subRunnerSessions,
1193
- ...(executionEnvFactory ? { executionEnvFactory } : {}),
1194
- ...(lspManager ? { lspManager } : {}),
1195
- ...(backgroundAgentStore ? { backgroundAgentStore } : {}),
1196
- ...(mailboxStore ? { mailboxStore } : {}),
1197
- ...(rosterStore ? { rosterStore } : {}),
1198
- ...(runnerDeps.onBackgroundChildEvent ? { onBackgroundChildEvent: runnerDeps.onBackgroundChildEvent } : {}),
1199
- ...(runnerDeps.loadProjectMemory ? { loadProjectMemory: runnerDeps.loadProjectMemory } : {}),
1200
- ...(runnerDeps.probeInstructionSources ? { probeInstructionSources: runnerDeps.probeInstructionSources } : {}),
1193
+ executionEnvFactory: executionEnvFactory ? executionEnvFactory : undefined,
1194
+ lspManager: lspManager ? lspManager : undefined,
1195
+ backgroundAgentStore: backgroundAgentStore ? backgroundAgentStore : undefined,
1196
+ mailboxStore: mailboxStore ? mailboxStore : undefined,
1197
+ rosterStore: rosterStore ? rosterStore : undefined,
1198
+ onBackgroundChildEvent: runnerDeps.onBackgroundChildEvent ? runnerDeps.onBackgroundChildEvent : undefined,
1199
+ loadProjectMemory: runnerDeps.loadProjectMemory ? runnerDeps.loadProjectMemory : undefined,
1200
+ probeInstructionSources: runnerDeps.probeInstructionSources ? runnerDeps.probeInstructionSources : undefined,
1201
1201
  hooks: deploymentHooks,
1202
- ...(runnerDeps.onError ? { onError: runnerDeps.onError } : {}),
1202
+ onError: runnerDeps.onError ? runnerDeps.onError : undefined,
1203
1203
  toolResultStore,
1204
- ...(sessionPolicyStore ? { sessionPolicyStore } : {}),
1205
- ...(checkpointStore ? { checkpointStore } : {}),
1204
+ sessionPolicyStore: sessionPolicyStore ? sessionPolicyStore : undefined,
1205
+ checkpointStore: checkpointStore ? checkpointStore : undefined,
1206
1206
  });
1207
1207
  const authorize = createAuthorizer(config, sessionStore);
1208
1208
  const runStore = backend ? backend.run() : undefined;
@@ -1575,7 +1575,7 @@ async function main() {
1575
1575
  if (!planeDeferred)
1576
1576
  markRosterLanded(r.effective);
1577
1577
  mutateInPlace(pricing, buildPricing(config.models));
1578
- keyResolver = buildKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1578
+ keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1579
1579
  const lkgPersisted = await persistLkgDurable(r.effective, r.etag);
1580
1580
  const reasons = restartReasons(effective, r.effective);
1581
1581
  const skillsChangeDetected = reasons.includes("skills");
@@ -1675,7 +1675,7 @@ async function main() {
1675
1675
  if (!planeDeferredLate)
1676
1676
  markRosterLanded(r.effective);
1677
1677
  mutateInPlace(pricing, buildPricing(config.models));
1678
- keyResolver = buildKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1678
+ keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1679
1679
  effective = r.effective;
1680
1680
  latestEffective = r.effective;
1681
1681
  ccEtag = r.etag;
@@ -1705,7 +1705,7 @@ async function main() {
1705
1705
  if (bootConfigPending)
1706
1706
  void bootConfigPending.then((r) => (lkgBooted ? refreshTick(r) : deferredBootApply(r)), () => { });
1707
1707
  }
1708
- let keyResolver = buildKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1708
+ let keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
1709
1709
  if (process.env.ANTHROPIC_AUTH_TOKEN && !process.env.ANTHROPIC_API_KEY && (Object.keys(config.modelApiKeys).length > 0 || Object.keys(config.modelApiKeyEnv).length > 0)) {
1710
1710
  logger.warn("per_model_key_bearer_gateway_combo", {
1711
1711
  perModelKeys: Object.keys(config.modelApiKeys).length + Object.keys(config.modelApiKeyEnv).length,
@@ -1789,7 +1789,7 @@ async function main() {
1789
1789
  (leaderProvider === "e2b" ||
1790
1790
  (leaderProvider === "k8s" && "s3" in leaderMinio && executionEnvFactory) ||
1791
1791
  (leaderProvider === "host" && executionEnvFactory))
1792
- ? createLeaderEndpoint(buildLeaderRunner({
1792
+ ? createLeaderEndpoint(createLeaderRunner({
1793
1793
  brain, models: config.models, roles: config.roles, pricing, logger,
1794
1794
  fanoutEnabled: config.leaderFanoutEnabled,
1795
1795
  ...((process.env.MODEL_ROUTER_ID || process.env.MODEL_CHEAP_ID)
@@ -1997,7 +1997,7 @@ async function main() {
1997
1997
  return undefined;
1998
1998
  }
1999
1999
  const effMode = coercePermissionMode(body.permissionMode) ?? parsedSettings.settings?.permissions?.defaultMode;
2000
- return buildTaskHooks(hc, {
2000
+ return createTaskHooks(hc, {
2001
2001
  logger,
2002
2002
  sessionId: auth?.sessionId ?? "",
2003
2003
  cwd: (auth?.sessionId ? perSessionCwd.get(auth.sessionId) : undefined) ?? process.cwd(),
@@ -0,0 +1,18 @@
1
+ import { FileMemoryEngineBackend } from "@sema-agent/core";
2
+ import type { ServiceConfig } from "./config-types.js";
3
+ export declare function memoryScopeFor(config: ServiceConfig, principal?: string, projectId?: string): string | undefined;
4
+ export declare function memoryEngineRemoteLanePosture(config: ServiceConfig): {
5
+ lane: string;
6
+ posture: "dark" | "forced";
7
+ } | undefined;
8
+ export declare function memoryEngineBackendFor(config: ServiceConfig, fallbackRoot?: string): {
9
+ backend: FileMemoryEngineBackend;
10
+ root: string;
11
+ } | undefined;
12
+ export declare function memorySpecForRequest(scope: string | undefined, memoryWrite: boolean | undefined, defaultScopes?: string[]): {
13
+ scope: string;
14
+ scopes?: string[];
15
+ writeScope?: string | null;
16
+ scopeContract?: "v2";
17
+ } | undefined;
18
+ //# sourceMappingURL=memory-scope.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { join } from "node:path";
2
+ import { FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope } from "@sema-agent/core";
3
+ export function memoryScopeFor(config, principal, projectId) {
4
+ if (config.requirePrincipal === true) {
5
+ if (config.memoryEngineBackend === "pg" || config.memoryEngineBackend === "tidb") {
6
+ if (!principal)
7
+ return undefined;
8
+ return projectId ? formatProjScope(principal, projectId) : formatUserScope(principal);
9
+ }
10
+ return undefined;
11
+ }
12
+ return config.memoryScope;
13
+ }
14
+ export function memoryEngineRemoteLanePosture(config) {
15
+ const lane = config.remoteExec?.provider;
16
+ if (lane === undefined || lane === "host")
17
+ return undefined;
18
+ return { lane, posture: config.memoryEngineRemoteLaneAllowed === true ? "forced" : "dark" };
19
+ }
20
+ export function memoryEngineBackendFor(config, fallbackRoot) {
21
+ if (config.requirePrincipal === true || !config.memoryEngineEnabled)
22
+ return undefined;
23
+ if (memoryEngineRemoteLanePosture(config)?.posture === "dark")
24
+ return undefined;
25
+ const root = resolveMemoryEngineRoot(config.memoryEngineDir ?? fallbackRoot);
26
+ const dir = join(root, "memory");
27
+ return { backend: new FileMemoryEngineBackend(dir, { controlDir: deriveControlPlaneDir(root, dir) }), root };
28
+ }
29
+ export function memorySpecForRequest(scope, memoryWrite, defaultScopes) {
30
+ if (!scope)
31
+ return undefined;
32
+ const isV2 = (k) => k.startsWith("user:") || k.startsWith("org:") || k.startsWith("proj:") || k.startsWith("userproj:");
33
+ const extras = (defaultScopes ?? []).filter((s, i, arr) => typeof s === "string" && s.length > 0 && s !== scope && arr.indexOf(s) === i);
34
+ const layered = extras.length > 0 ? { scopes: [scope, ...extras], writeScope: scope } : {};
35
+ const v2 = isV2(scope) || extras.some(isV2) ? { scopeContract: "v2" } : {};
36
+ return memoryWrite === false ? { scope, ...layered, writeScope: null, ...v2 } : { scope, ...layered, ...v2 };
37
+ }
38
+ //# sourceMappingURL=memory-scope.js.map
@@ -0,0 +1,34 @@
1
+ export interface InfraCostRates {
2
+ toolCallMicroUsd: number;
3
+ sandboxSecMicroUsd: number;
4
+ egressGbMicroUsd: number;
5
+ }
6
+ export interface InfraUsage {
7
+ toolCalls: number;
8
+ sandboxWalltimeMs: number;
9
+ egressBytes: number;
10
+ }
11
+ export interface InfraCostBreakdown {
12
+ toolCallMicroUsd: number;
13
+ sandboxWalltimeMicroUsd: number;
14
+ egressMicroUsd: number;
15
+ totalMicroUsd: number;
16
+ }
17
+ export interface LlmCostBreakdown {
18
+ llmRootMicroUsd: number;
19
+ nestedSubagentMicroUsd: number;
20
+ memoryConsolidationMicroUsd: number;
21
+ compactionMicroUsd: number;
22
+ }
23
+ export interface SupervisorCostBreakdown {
24
+ llm: LlmCostBreakdown | null;
25
+ infra: InfraCostBreakdown;
26
+ totalMicroUsd: number;
27
+ }
28
+ export declare function infraCost(usage: InfraUsage, rates: InfraCostRates): InfraCostBreakdown;
29
+ export declare function composeSupervisorCost(llm: LlmCostBreakdown | null, llmTotalMicroUsd: number, infra: InfraCostBreakdown): SupervisorCostBreakdown;
30
+ export declare function hasInfraPricing(r: InfraCostRates): boolean;
31
+ export declare function infraUsageFromEvents(events: ReadonlyArray<{
32
+ type?: string;
33
+ }>, runDurationMs: number): InfraUsage;
34
+ //# sourceMappingURL=cost-taxonomy.d.ts.map
@@ -0,0 +1,26 @@
1
+ const nonNeg = (n) => (Number.isFinite(n) && n > 0 ? n : 0);
2
+ export function infraCost(usage, rates) {
3
+ const toolCallMicroUsd = nonNeg(usage.toolCalls) * nonNeg(rates.toolCallMicroUsd);
4
+ const sandboxWalltimeMicroUsd = (nonNeg(usage.sandboxWalltimeMs) / 1000) * nonNeg(rates.sandboxSecMicroUsd);
5
+ const egressMicroUsd = (nonNeg(usage.egressBytes) / 1_000_000_000) * nonNeg(rates.egressGbMicroUsd);
6
+ return {
7
+ toolCallMicroUsd,
8
+ sandboxWalltimeMicroUsd,
9
+ egressMicroUsd,
10
+ totalMicroUsd: toolCallMicroUsd + sandboxWalltimeMicroUsd + egressMicroUsd,
11
+ };
12
+ }
13
+ export function composeSupervisorCost(llm, llmTotalMicroUsd, infra) {
14
+ return { llm, infra, totalMicroUsd: nonNeg(llmTotalMicroUsd) + infra.totalMicroUsd };
15
+ }
16
+ export function hasInfraPricing(r) {
17
+ return r.toolCallMicroUsd > 0 || r.sandboxSecMicroUsd > 0 || r.egressGbMicroUsd > 0;
18
+ }
19
+ export function infraUsageFromEvents(events, runDurationMs) {
20
+ return {
21
+ toolCalls: events.reduce((n, e) => (e.type === "tool_start" ? n + 1 : n), 0),
22
+ sandboxWalltimeMs: nonNeg(runDurationMs),
23
+ egressBytes: 0,
24
+ };
25
+ }
26
+ //# sourceMappingURL=cost-taxonomy.js.map
@@ -0,0 +1,75 @@
1
+ export interface PromptManifestRecord {
2
+ constitution: string;
3
+ blocks: Array<{
4
+ id: string;
5
+ chars: number;
6
+ hash: string;
7
+ }>;
8
+ sections?: Array<{
9
+ id: string;
10
+ slot: string;
11
+ carrier: string;
12
+ cadence: string;
13
+ cacheClass: string;
14
+ chars: number;
15
+ hash: string;
16
+ contentHash?: string;
17
+ }>;
18
+ tools?: Array<{
19
+ wireName: string;
20
+ aliases: string[];
21
+ contractId: string;
22
+ implementationRevision: string;
23
+ cardId: string;
24
+ shapeDigest: string;
25
+ wireSchemaDigest: string;
26
+ }>;
27
+ totalChars: number;
28
+ }
29
+ export declare function promptManifestRecordOf(e: {
30
+ constitution: string;
31
+ blocks: Array<{
32
+ id: string;
33
+ chars: number;
34
+ hash: string;
35
+ }>;
36
+ sections?: Array<{
37
+ id: string;
38
+ slot: string;
39
+ carrier: string;
40
+ cadence: string;
41
+ cacheClass: string;
42
+ chars: number;
43
+ hash: string;
44
+ contentHash?: string;
45
+ }>;
46
+ tools?: Array<{
47
+ wireName: string;
48
+ aliases: string[];
49
+ contractId: string;
50
+ implementationRevision: string;
51
+ cardId: string;
52
+ shapeDigest: string;
53
+ wireSchemaDigest: string;
54
+ }>;
55
+ totalChars: number;
56
+ }): PromptManifestRecord;
57
+ export declare function configAssembledRecordOf(e: {
58
+ catalogVersion?: unknown;
59
+ fields?: unknown;
60
+ overrideReasons?: unknown;
61
+ ts?: unknown;
62
+ }): Record<string, unknown> | undefined;
63
+ export declare class PromptManifestTracker {
64
+ private readonly byTask;
65
+ private readonly configByTask;
66
+ private readonly active;
67
+ private leaseCounter;
68
+ register(taskId: string): number;
69
+ record(taskId: string, m: PromptManifestRecord): void;
70
+ recordConfig(taskId: string, rec: Record<string, unknown>): void;
71
+ drainConfig(taskId: string): Array<Record<string, unknown>> | undefined;
72
+ drain(taskId: string): PromptManifestRecord[] | undefined;
73
+ clear(taskId: string, lease: number): void;
74
+ }
75
+ //# sourceMappingURL=prompt-manifest.d.ts.map
@@ -0,0 +1,82 @@
1
+ export function promptManifestRecordOf(e) {
2
+ return {
3
+ constitution: String(e.constitution),
4
+ blocks: (Array.isArray(e.blocks) ? e.blocks : []).map((b) => ({ id: String(b.id), chars: b.chars, hash: String(b.hash) })),
5
+ ...(Array.isArray(e.sections)
6
+ ? { sections: e.sections.map((s) => ({ id: String(s.id), slot: String(s.slot), carrier: String(s.carrier), cadence: String(s.cadence), cacheClass: String(s.cacheClass), chars: s.chars, hash: String(s.hash), ...(typeof s.contentHash === "string" ? { contentHash: s.contentHash } : {}) })) }
7
+ : {}),
8
+ ...(Array.isArray(e.tools)
9
+ ? { tools: e.tools.map((t) => ({ wireName: String(t.wireName), aliases: (Array.isArray(t.aliases) ? t.aliases : []).map(String), contractId: String(t.contractId), implementationRevision: String(t.implementationRevision), cardId: String(t.cardId), shapeDigest: String(t.shapeDigest), wireSchemaDigest: String(t.wireSchemaDigest) })) }
10
+ : {}),
11
+ totalChars: e.totalChars,
12
+ };
13
+ }
14
+ export function configAssembledRecordOf(e) {
15
+ const rec = {
16
+ catalogVersion: e.catalogVersion,
17
+ fields: e.fields,
18
+ ...(e.overrideReasons !== undefined ? { overrideReasons: e.overrideReasons } : {}),
19
+ ts: e.ts,
20
+ };
21
+ try {
22
+ if (JSON.stringify(rec).length > 32_768)
23
+ return undefined;
24
+ }
25
+ catch {
26
+ return undefined;
27
+ }
28
+ return rec;
29
+ }
30
+ export class PromptManifestTracker {
31
+ byTask = new Map();
32
+ configByTask = new Map();
33
+ active = new Map();
34
+ leaseCounter = 0;
35
+ register(taskId) {
36
+ if (!taskId)
37
+ return 0;
38
+ const lease = ++this.leaseCounter;
39
+ this.active.set(taskId, lease);
40
+ return lease;
41
+ }
42
+ record(taskId, m) {
43
+ if (!taskId || !this.active.has(taskId))
44
+ return;
45
+ const q = this.byTask.get(taskId);
46
+ if (q)
47
+ q.push(m);
48
+ else
49
+ this.byTask.set(taskId, [m]);
50
+ }
51
+ recordConfig(taskId, rec) {
52
+ if (!taskId || !this.active.has(taskId))
53
+ return;
54
+ const q = this.configByTask.get(taskId);
55
+ if (q)
56
+ q.push(rec);
57
+ else
58
+ this.configByTask.set(taskId, [rec]);
59
+ }
60
+ drainConfig(taskId) {
61
+ const q = this.configByTask.get(taskId);
62
+ if (!q || q.length === 0)
63
+ return undefined;
64
+ this.configByTask.delete(taskId);
65
+ return q;
66
+ }
67
+ drain(taskId) {
68
+ const q = this.byTask.get(taskId);
69
+ if (!q || q.length === 0)
70
+ return undefined;
71
+ this.byTask.delete(taskId);
72
+ return q;
73
+ }
74
+ clear(taskId, lease) {
75
+ if (this.active.get(taskId) !== lease)
76
+ return;
77
+ this.byTask.delete(taskId);
78
+ this.active.delete(taskId);
79
+ this.configByTask.delete(taskId);
80
+ }
81
+ }
82
+ //# sourceMappingURL=prompt-manifest.js.map
@@ -17,11 +17,12 @@ export interface WebSearchOpts {
17
17
  blockedDomains?: string[];
18
18
  }
19
19
  export type WebSearchFn = (query: string, signal?: AbortSignal, opts?: WebSearchOpts) => Promise<WebSearchResult[]>;
20
- export declare function setWebSearchBadPayloadObserver(fn: ((provider: string) => void) | undefined): void;
21
- export declare function createWebSearchBackend(cfg: WebSearchBackendConfig): {
20
+ export interface WebSearchBackend {
22
21
  search: WebSearchFn;
23
22
  maxResults: number;
24
- };
23
+ }
24
+ export declare function setWebSearchBadPayloadObserver(fn: ((provider: string) => void) | undefined): void;
25
+ export declare function createWebSearchBackend(cfg: WebSearchBackendConfig): WebSearchBackend;
25
26
  export declare function webSearchConfigFromEnv(env?: NodeJS.ProcessEnv): WebSearchBackendConfig | undefined;
26
27
  export declare function webSearchConfigFromSettings(raw: unknown): WebSearchBackendConfig | undefined;
27
28
  //# sourceMappingURL=web-search.d.ts.map
@@ -17,13 +17,14 @@ export interface QuestionThrottle {
17
17
  ttlMs: number;
18
18
  }
19
19
  export declare const DEFAULT_QUESTION_THROTTLE: QuestionThrottle;
20
- export declare function parseQuestionAnswer(body: unknown): {
20
+ export declare function parseQuestionResponse(body: unknown): {
21
21
  ok: true;
22
22
  value: QuestionAnswer;
23
23
  } | {
24
24
  ok: false;
25
25
  error: string;
26
26
  };
27
+ export declare const parseQuestionAnswer: typeof parseQuestionResponse;
27
28
  export declare class QuestionCoordinator {
28
29
  private readonly als;
29
30
  private readonly pending;
package/dist/question.js CHANGED
@@ -8,7 +8,7 @@ export const DEFAULT_QUESTION_THROTTLE = {
8
8
  ttlMs: 5 * 60_000,
9
9
  };
10
10
  const NO_HUMAN = { answers: [] };
11
- export function parseQuestionAnswer(body) {
11
+ export function parseQuestionResponse(body) {
12
12
  if (body === null || typeof body !== "object" || Array.isArray(body))
13
13
  return { ok: false, error: "body must be an object" };
14
14
  const answers = body.answers;
@@ -30,6 +30,7 @@ export function parseQuestionAnswer(body) {
30
30
  }
31
31
  return { ok: true, value: { answers: out } };
32
32
  }
33
+ export const parseQuestionAnswer = parseQuestionResponse;
33
34
  function boundQuestions(questions) {
34
35
  const redacted = redactDeep(questions);
35
36
  try {
@@ -115,7 +116,7 @@ export class QuestionCoordinator {
115
116
  return answer;
116
117
  };
117
118
  respond(id, principal, body) {
118
- const parsed = parseQuestionAnswer(body);
119
+ const parsed = parseQuestionResponse(body);
119
120
  if (!parsed.ok)
120
121
  return { status: 400, body: { error: parsed.error } };
121
122
  const entry = this.pending.get(id);
package/dist/run-local.js CHANGED
@@ -21,7 +21,7 @@ import { buildScenarios, selectScenario, centerScenarios } from "./capabilities/
21
21
  import { HttpError, memoryEngineBackendFor, memorySpecForRequest } from "./security.js";
22
22
  import { createMemorySyncRunner, createMemorySyncTransport } from "./memory-sync-client.js";
23
23
  import { buildPricing } from "./budget.js";
24
- import { buildKeyResolver } from "./key-resolver.js";
24
+ import { createKeyResolver } from "./key-resolver.js";
25
25
  import { createLogger } from "./observability/logger.js";
26
26
  import { createMetrics } from "./observability/metrics.js";
27
27
  export function parseArgs(argv) {
@@ -183,7 +183,7 @@ export async function runLocal(argv, deps = {}) {
183
183
  return 2;
184
184
  }
185
185
  const sessionStore = fileBackend.sessionStore;
186
- const keyResolver = buildKeyResolver(config.modelApiKeyEnv);
186
+ const keyResolver = createKeyResolver(config.modelApiKeyEnv);
187
187
  const hostRx = config.remoteExec?.provider === "host" ? config.remoteExec : undefined;
188
188
  const workspaceDir = args.workspace ?? hostRx?.workspaceBase ?? process.cwd();
189
189
  const executionEnvFactory = hostRx
@@ -2,7 +2,7 @@ import type { RuntimeCaps } from "@sema-agent/core";
2
2
  import type { EntitlementRuntimeCaps } from "@sema-agent/registry-core";
3
3
  import { fetchPrincipalCaps, type ExecutionRuling } from "./sema-registry.js";
4
4
  import type { ScenarioRuling } from "./capabilities/scenarios.js";
5
- export interface RuntimeCapsResolverOpts {
5
+ export interface EntitlementsResolverOpts {
6
6
  baseUrl: string;
7
7
  token: string;
8
8
  worker?: string;
@@ -15,18 +15,18 @@ export interface RuntimeCapsResolverOpts {
15
15
  }
16
16
  export declare function toCoreRuntimeCaps(ent: EntitlementRuntimeCaps | null | undefined): RuntimeCaps | undefined;
17
17
  export declare function scopedTokenNeedsWorker(token: string, worker: string | undefined): boolean;
18
- export interface PrincipalCapsClient {
18
+ export interface PrincipalEntitlementsClient {
19
19
  resolveRuntimeCaps: (principal: string | undefined) => Promise<RuntimeCaps | undefined>;
20
20
  scenarioRuling: (principal: string | undefined) => Promise<ScenarioRuling | undefined>;
21
21
  executionRuling: (principal: string | undefined) => Promise<ExecutionRuling | undefined>;
22
22
  }
23
23
  export declare function gateExecutionLane(ruling: ExecutionRuling | undefined, ownLane: string): void;
24
- export declare function createPrincipalCapsClient(opts: RuntimeCapsResolverOpts): PrincipalCapsClient;
25
- export declare function createRuntimeCapsResolver(opts: RuntimeCapsResolverOpts): (principal: string | undefined) => Promise<RuntimeCaps | undefined>;
26
- export type RuntimeCapsResolverFn = (principal: string | undefined) => RuntimeCaps | undefined | Promise<RuntimeCaps | undefined>;
27
- export declare function applyObserverEnvOptIn(centerResolver: RuntimeCapsResolverFn | undefined, opts: {
24
+ export declare function createPrincipalEntitlementsClient(opts: EntitlementsResolverOpts): PrincipalEntitlementsClient;
25
+ export declare function createEntitlementsResolver(opts: EntitlementsResolverOpts): (principal: string | undefined) => Promise<RuntimeCaps | undefined>;
26
+ export type EntitlementsResolverFn = (principal: string | undefined) => RuntimeCaps | undefined | Promise<RuntimeCaps | undefined>;
27
+ export declare function applyObserverEnvOptIn(centerResolver: EntitlementsResolverFn | undefined, opts: {
28
28
  experimentalObserverAgents: boolean;
29
29
  requirePrincipal: boolean;
30
30
  warn?: (msg: string, fields?: Record<string, unknown>) => void;
31
- }): RuntimeCapsResolverFn | undefined;
31
+ }): EntitlementsResolverFn | undefined;
32
32
  //# sourceMappingURL=runtime-caps-resolver.d.ts.map
@@ -36,7 +36,7 @@ export function gateExecutionLane(ruling, ownLane) {
36
36
  });
37
37
  }
38
38
  }
39
- export function createPrincipalCapsClient(opts) {
39
+ export function createPrincipalEntitlementsClient(opts) {
40
40
  const ttlMs = opts.ttlMs ?? 60_000;
41
41
  const denyTtlMs = opts.denyTtlMs ?? Math.min(ttlMs, 10_000);
42
42
  const fetchImpl = opts.fetchImpl ?? fetch;
@@ -115,8 +115,8 @@ export function createPrincipalCapsClient(opts) {
115
115
  executionRuling: async (principal) => (principal ? (await load(principal)).execution : undefined),
116
116
  };
117
117
  }
118
- export function createRuntimeCapsResolver(opts) {
119
- return createPrincipalCapsClient(opts).resolveRuntimeCaps;
118
+ export function createEntitlementsResolver(opts) {
119
+ return createPrincipalEntitlementsClient(opts).resolveRuntimeCaps;
120
120
  }
121
121
  export function applyObserverEnvOptIn(centerResolver, opts) {
122
122
  if (!opts.experimentalObserverAgents)
@@ -1,5 +1,5 @@
1
1
  import type { IncomingMessage } from "node:http";
2
- import { FileMemoryEngineBackend, type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
2
+ import { type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
3
3
  import type { ServiceConfig } from "./config-types.js";
4
4
  import type { TaskRequestBody } from "./http/wire-types.js";
5
5
  import type { StagingHandle } from "./session-sync-kernel.js";
@@ -80,21 +80,7 @@ export declare function ssoVerifiedPrincipal(req: IncomingMessage): string | und
80
80
  export declare function setSsoScope(req: IncomingMessage, scope: string): void;
81
81
  export declare function ssoVerifiedScope(req: IncomingMessage): string | undefined;
82
82
  export declare function verifiedPrincipal(req: IncomingMessage, config: ServiceConfig): string | undefined;
83
- export declare function memoryScopeFor(config: ServiceConfig, principal?: string, projectId?: string): string | undefined;
84
- export declare function memoryEngineRemoteLanePosture(config: ServiceConfig): {
85
- lane: string;
86
- posture: "dark" | "forced";
87
- } | undefined;
88
- export declare function memoryEngineBackendFor(config: ServiceConfig, fallbackRoot?: string): {
89
- backend: FileMemoryEngineBackend;
90
- root: string;
91
- } | undefined;
92
- export declare function memorySpecForRequest(scope: string | undefined, memoryWrite: boolean | undefined, defaultScopes?: string[]): {
93
- scope: string;
94
- scopes?: string[];
95
- writeScope?: string | null;
96
- scopeContract?: "v2";
97
- } | undefined;
83
+ export { memoryScopeFor, memoryEngineRemoteLanePosture, memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
98
84
  export declare function approvalHmacMessage(env: {
99
85
  sessionId: string;
100
86
  boundCallId?: string | null;
package/dist/security.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { createHash, createHmac, createPublicKey, timingSafeEqual, verify as cryptoVerify } from "node:crypto";
2
- import { join } from "node:path";
3
- import { uuidv7, FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope } from "@sema-agent/core";
2
+ import { uuidv7 } from "@sema-agent/core";
4
3
  import { PROJECT_ID_REGEX } from "@sema-agent/registry-core";
5
4
  export { parseApprovalHmacKeys, parsePrincipalJwks } from "./auth-keys.js";
5
+ import { memoryScopeFor } from "./memory-scope.js";
6
6
  const UUIDV7_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
7
7
  export function isUuidV7(s) {
8
8
  return UUIDV7_RE.test(s);
@@ -128,41 +128,7 @@ export function verifiedPrincipal(req, config) {
128
128
  assertPrincipalShape(sub);
129
129
  return sub;
130
130
  }
131
- export function memoryScopeFor(config, principal, projectId) {
132
- if (config.requirePrincipal === true) {
133
- if (config.memoryEngineBackend === "pg" || config.memoryEngineBackend === "tidb") {
134
- if (!principal)
135
- return undefined;
136
- return projectId ? formatProjScope(principal, projectId) : formatUserScope(principal);
137
- }
138
- return undefined;
139
- }
140
- return config.memoryScope;
141
- }
142
- export function memoryEngineRemoteLanePosture(config) {
143
- const lane = config.remoteExec?.provider;
144
- if (lane === undefined || lane === "host")
145
- return undefined;
146
- return { lane, posture: config.memoryEngineRemoteLaneAllowed === true ? "forced" : "dark" };
147
- }
148
- export function memoryEngineBackendFor(config, fallbackRoot) {
149
- if (config.requirePrincipal === true || !config.memoryEngineEnabled)
150
- return undefined;
151
- if (memoryEngineRemoteLanePosture(config)?.posture === "dark")
152
- return undefined;
153
- const root = resolveMemoryEngineRoot(config.memoryEngineDir ?? fallbackRoot);
154
- const dir = join(root, "memory");
155
- return { backend: new FileMemoryEngineBackend(dir, { controlDir: deriveControlPlaneDir(root, dir) }), root };
156
- }
157
- export function memorySpecForRequest(scope, memoryWrite, defaultScopes) {
158
- if (!scope)
159
- return undefined;
160
- const isV2 = (k) => k.startsWith("user:") || k.startsWith("org:") || k.startsWith("proj:") || k.startsWith("userproj:");
161
- const extras = (defaultScopes ?? []).filter((s, i, arr) => typeof s === "string" && s.length > 0 && s !== scope && arr.indexOf(s) === i);
162
- const layered = extras.length > 0 ? { scopes: [scope, ...extras], writeScope: scope } : {};
163
- const v2 = isV2(scope) || extras.some(isV2) ? { scopeContract: "v2" } : {};
164
- return memoryWrite === false ? { scope, ...layered, writeScope: null, ...v2 } : { scope, ...layered, ...v2 };
165
- }
131
+ export { memoryScopeFor, memoryEngineRemoteLanePosture, memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
166
132
  export function approvalHmacMessage(env) {
167
133
  return JSON.stringify([env.sessionId, env.boundCallId ?? null, env.boundInputHash ?? null, env.decision, env.reason ?? null]);
168
134
  }
@@ -20,7 +20,7 @@ export interface ToolApprovalRunContext {
20
20
  abortSignal?: AbortSignal;
21
21
  }
22
22
  export type ToolApprovalDecision = "allow" | "allow_session" | "deny";
23
- export declare function parseToolApprovalDecision(body: unknown): {
23
+ export declare function parseToolApprovalResponse(body: unknown): {
24
24
  ok: true;
25
25
  value: ToolApprovalDecision;
26
26
  updatedInput?: unknown;
@@ -28,6 +28,7 @@ export declare function parseToolApprovalDecision(body: unknown): {
28
28
  ok: false;
29
29
  error: string;
30
30
  };
31
+ export declare const parseToolApprovalDecision: typeof parseToolApprovalResponse;
31
32
  export declare class ToolApprovalCoordinator {
32
33
  private readonly als;
33
34
  private readonly pending;