@corbat-tech/coco 2.40.0 → 2.41.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.
@@ -1704,6 +1704,53 @@ var init_auth = __esm({
1704
1704
 
1705
1705
  // src/runtime/agent-runtime.ts
1706
1706
  init_env();
1707
+
1708
+ // src/providers/pricing.ts
1709
+ init_catalog();
1710
+ var MODEL_PRICING = getCatalogModelPricingMap();
1711
+ var DEFAULT_PRICING = {
1712
+ anthropic: { inputPerMillion: 3, outputPerMillion: 15, contextWindow: 2e5 },
1713
+ openai: { inputPerMillion: 2.5, outputPerMillion: 10, contextWindow: 128e3 },
1714
+ codex: { inputPerMillion: 0, outputPerMillion: 0, contextWindow: 128e3 },
1715
+ // ChatGPT Plus/Pro subscription
1716
+ gemini: { inputPerMillion: 0.1, outputPerMillion: 0.4, contextWindow: 1e6 },
1717
+ vertex: { inputPerMillion: 0.1, outputPerMillion: 0.4, contextWindow: 1048576 },
1718
+ kimi: { inputPerMillion: 1.2, outputPerMillion: 1.2, contextWindow: 8192 },
1719
+ "kimi-code": { inputPerMillion: 0, outputPerMillion: 0, contextWindow: 131072 },
1720
+ // Included in subscription
1721
+ copilot: { inputPerMillion: 0, outputPerMillion: 0, contextWindow: 2e5 },
1722
+ // Included in subscription
1723
+ lmstudio: { inputPerMillion: 0, outputPerMillion: 0, contextWindow: 32768 },
1724
+ // Free - local models
1725
+ ollama: { inputPerMillion: 0, outputPerMillion: 0, contextWindow: 128e3 },
1726
+ // Free - local models
1727
+ groq: { inputPerMillion: 0.05, outputPerMillion: 0.08, contextWindow: 128e3 },
1728
+ // Free tier available
1729
+ openrouter: { inputPerMillion: 2, outputPerMillion: 8, contextWindow: 2e5 },
1730
+ // Varies by model
1731
+ mistral: { inputPerMillion: 0.25, outputPerMillion: 0.75, contextWindow: 32768 },
1732
+ deepseek: { inputPerMillion: 0.14, outputPerMillion: 0.28, contextWindow: 128e3 },
1733
+ // Very cheap
1734
+ together: { inputPerMillion: 0.2, outputPerMillion: 0.2, contextWindow: 32768 },
1735
+ huggingface: { inputPerMillion: 0, outputPerMillion: 0, contextWindow: 32768 },
1736
+ // Free tier
1737
+ qwen: { inputPerMillion: 0.3, outputPerMillion: 1.2, contextWindow: 131072 }
1738
+ // qwen-coder-plus pricing
1739
+ };
1740
+ function estimateCost(model2, inputTokens, outputTokens, provider) {
1741
+ const pricing = MODEL_PRICING[model2] ?? (provider ? DEFAULT_PRICING[provider] : DEFAULT_PRICING.anthropic);
1742
+ const inputCost = inputTokens / 1e6 * pricing.inputPerMillion;
1743
+ const outputCost = outputTokens / 1e6 * pricing.outputPerMillion;
1744
+ return {
1745
+ inputCost,
1746
+ outputCost,
1747
+ totalCost: inputCost + outputCost,
1748
+ inputTokens,
1749
+ outputTokens,
1750
+ model: model2,
1751
+ currency: "USD"
1752
+ };
1753
+ }
1707
1754
  var DEFAULT_CONFIG = {
1708
1755
  name: "coco",
1709
1756
  level: "info",
@@ -2172,6 +2219,22 @@ function isAgentMode(value) {
2172
2219
  }
2173
2220
 
2174
2221
  // src/runtime/context.ts
2222
+ var RuntimePolicyViolation = class extends Error {
2223
+ code;
2224
+ subject;
2225
+ tenantId;
2226
+ policyPath;
2227
+ severity;
2228
+ constructor(input) {
2229
+ super(input.message);
2230
+ this.name = "RuntimePolicyViolation";
2231
+ this.code = input.code;
2232
+ this.subject = input.subject;
2233
+ this.tenantId = input.tenantId;
2234
+ this.policyPath = input.policyPath;
2235
+ this.severity = input.severity ?? "blocked";
2236
+ }
2237
+ };
2175
2238
  function createRuntimeRequestContext(input = {}) {
2176
2239
  return {
2177
2240
  surface: input.surface ?? "api",
@@ -2214,6 +2277,27 @@ function runtimeContextToMetadata(context) {
2214
2277
  dataClassification: context.policy?.dataBoundary?.classification
2215
2278
  };
2216
2279
  }
2280
+ function createRuntimeTenantBoundary(context, hostMode = "local") {
2281
+ return {
2282
+ hostMode,
2283
+ surface: context?.surface ?? "api",
2284
+ tenantId: context?.tenant?.id,
2285
+ required: hostMode === "hosted" && context?.surface !== "cli"
2286
+ };
2287
+ }
2288
+ function assertRuntimeTenantBoundary(context, hostMode = "local", subject = "runtime operation") {
2289
+ const boundary = createRuntimeTenantBoundary(context, hostMode);
2290
+ if (boundary.required && !boundary.tenantId) {
2291
+ throw new RuntimePolicyViolation({
2292
+ code: "tenant_required",
2293
+ subject,
2294
+ tenantId: boundary.tenantId,
2295
+ policyPath: "runtimeContext.tenant.id",
2296
+ message: `Runtime tenant is required for hosted ${boundary.surface} operations.`
2297
+ });
2298
+ }
2299
+ return boundary;
2300
+ }
2217
2301
  function evaluateRuntimeToolPolicy(policy, input) {
2218
2302
  if (policy?.allowedTools && !policy.allowedTools.includes(input.toolName)) {
2219
2303
  return {
@@ -2257,23 +2341,65 @@ function evaluateRuntimeRiskPolicy(policy, input) {
2257
2341
  }
2258
2342
  return { allowed: true, risk: input.risk };
2259
2343
  }
2344
+ function assertRuntimeTurnWithinPolicy(policy, input) {
2345
+ const maxTurns = policy?.costBudget?.maxTurns;
2346
+ if (maxTurns !== void 0 && input.currentTurns >= maxTurns) {
2347
+ throw new RuntimePolicyViolation({
2348
+ code: "max_turns_exceeded",
2349
+ subject: input.subject,
2350
+ tenantId: input.tenantId,
2351
+ policyPath: "runtimePolicy.costBudget.maxTurns",
2352
+ message: `Runtime policy turn budget exceeded: ${input.currentTurns}/${maxTurns}`
2353
+ });
2354
+ }
2355
+ }
2260
2356
  function assertRuntimeUsageWithinPolicy(policy, usage) {
2261
2357
  const budget = policy?.costBudget;
2358
+ const subject = usage.subject ?? "runtime usage";
2262
2359
  if (!budget) return;
2263
2360
  if (budget.maxInputTokens !== void 0 && (usage.inputTokens ?? 0) > budget.maxInputTokens) {
2264
- throw new Error(
2265
- `Runtime policy input token budget exceeded: ${usage.inputTokens ?? 0}/${budget.maxInputTokens}`
2266
- );
2361
+ throw new RuntimePolicyViolation({
2362
+ code: "input_tokens_exceeded",
2363
+ subject,
2364
+ tenantId: usage.tenantId,
2365
+ policyPath: "runtimePolicy.costBudget.maxInputTokens",
2366
+ message: `Runtime policy input token budget exceeded: ${usage.inputTokens ?? 0}/${budget.maxInputTokens}`
2367
+ });
2267
2368
  }
2268
2369
  if (budget.maxOutputTokens !== void 0 && (usage.outputTokens ?? 0) > budget.maxOutputTokens) {
2269
- throw new Error(
2270
- `Runtime policy output token budget exceeded: ${usage.outputTokens ?? 0}/${budget.maxOutputTokens}`
2271
- );
2370
+ throw new RuntimePolicyViolation({
2371
+ code: "output_tokens_exceeded",
2372
+ subject,
2373
+ tenantId: usage.tenantId,
2374
+ policyPath: "runtimePolicy.costBudget.maxOutputTokens",
2375
+ message: `Runtime policy output token budget exceeded: ${usage.outputTokens ?? 0}/${budget.maxOutputTokens}`
2376
+ });
2377
+ }
2378
+ if (budget.maxEstimatedCostUsd !== void 0 && (usage.estimatedCostUsd ?? 0) > budget.maxEstimatedCostUsd) {
2379
+ throw new RuntimePolicyViolation({
2380
+ code: "estimated_cost_exceeded",
2381
+ subject,
2382
+ tenantId: usage.tenantId,
2383
+ policyPath: "runtimePolicy.costBudget.maxEstimatedCostUsd",
2384
+ message: `Runtime policy estimated cost budget exceeded: ${usage.estimatedCostUsd ?? 0}/${budget.maxEstimatedCostUsd}`
2385
+ });
2272
2386
  }
2273
2387
  }
2388
+ function createRetentionCutoffs(policy, now = /* @__PURE__ */ new Date()) {
2389
+ const retention = policy?.retention;
2390
+ return {
2391
+ conversationBefore: cutoffIso(now, retention?.conversationDays),
2392
+ eventBefore: cutoffIso(now, retention?.eventDays),
2393
+ artifactBefore: cutoffIso(now, retention?.artifactDays)
2394
+ };
2395
+ }
2274
2396
  function cloneRuntimePolicy(policy) {
2275
2397
  return mergeRuntimePolicy(void 0, policy) ?? {};
2276
2398
  }
2399
+ function cutoffIso(now, days) {
2400
+ if (days === void 0) return void 0;
2401
+ return new Date(now.getTime() - days * 24 * 60 * 60 * 1e3).toISOString();
2402
+ }
2277
2403
  function riskRank(risk) {
2278
2404
  switch (risk) {
2279
2405
  case "read-only":
@@ -6602,10 +6728,6 @@ var VertexProvider = class {
6602
6728
  }
6603
6729
  };
6604
6730
 
6605
- // src/providers/pricing.ts
6606
- init_catalog();
6607
- getCatalogModelPricingMap();
6608
-
6609
6731
  // src/providers/circuit-breaker.ts
6610
6732
  init_errors();
6611
6733
  var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
@@ -7262,6 +7384,7 @@ var LEGACY_ROLE_MAPPINGS = [
7262
7384
  { legacy: "coder", role: "coder", reason: "legacy executor role" },
7263
7385
  { legacy: "test", role: "tester", reason: "test authoring/execution" },
7264
7386
  { legacy: "tester", role: "tester", reason: "legacy executor role" },
7387
+ { legacy: "verifier", role: "tester", reason: "verification maps to tester capability" },
7265
7388
  { legacy: "tdd", role: "tester", reason: "test-first implementation" },
7266
7389
  { legacy: "e2e", role: "tester", reason: "end-to-end testing" },
7267
7390
  { legacy: "review", role: "reviewer", reason: "code review" },
@@ -7997,7 +8120,7 @@ var NULL_EVENT_LOG = {
7997
8120
  function graphNodeToTask(node, workflowInput) {
7998
8121
  return {
7999
8122
  id: node.id,
8000
- role: node.agentRole ?? "coder",
8123
+ role: node.agentRole ?? mapLegacyAgentRole(node.id, "coder"),
8001
8124
  objective: node.description,
8002
8125
  context: {
8003
8126
  workflowInput,
@@ -8183,6 +8306,239 @@ function cloneArtifact(artifact) {
8183
8306
  };
8184
8307
  }
8185
8308
 
8309
+ // src/runtime/agent-runner.ts
8310
+ var AgentRunner = class {
8311
+ constructor(options = {}) {
8312
+ this.options = options;
8313
+ }
8314
+ options;
8315
+ async run(input) {
8316
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
8317
+ const trace = input.trace ?? createAgentTraceContext({ taskId: input.task.id });
8318
+ this.options.eventLog?.record("agent.started", {
8319
+ taskId: input.task.id,
8320
+ role: input.task.role,
8321
+ trace
8322
+ });
8323
+ try {
8324
+ const raw = await (this.options.executor ?? defaultExecutor)({
8325
+ task: input.task,
8326
+ capability: input.capability,
8327
+ trace,
8328
+ assertToolAllowed: (toolName) => {
8329
+ const decision = evaluateAgentToolPolicy({
8330
+ capability: input.capability,
8331
+ toolName,
8332
+ manifest: input.toolRiskManifest
8333
+ });
8334
+ this.options.eventLog?.record("agent.tool.called", {
8335
+ taskId: input.task.id,
8336
+ role: input.task.role,
8337
+ toolName,
8338
+ decision,
8339
+ trace
8340
+ });
8341
+ if (!decision.allowed) {
8342
+ throw new Error(decision.reason ?? `Tool '${toolName}' is not allowed.`);
8343
+ }
8344
+ }
8345
+ });
8346
+ const result = normalizeAgentRunResult({
8347
+ id: `${input.task.id}-run-${Date.now().toString(36)}`,
8348
+ taskId: input.task.id,
8349
+ role: input.task.role,
8350
+ success: raw.success ?? true,
8351
+ output: raw.output,
8352
+ turns: raw.turns,
8353
+ toolsUsed: raw.toolsUsed,
8354
+ usage: {
8355
+ inputTokens: raw.inputTokens ?? 0,
8356
+ outputTokens: raw.outputTokens ?? 0,
8357
+ estimated: raw.inputTokens === void 0 || raw.outputTokens === void 0
8358
+ },
8359
+ startedAt,
8360
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
8361
+ durationMs: Date.now() - Date.parse(startedAt),
8362
+ error: raw.error,
8363
+ metadata: { ...raw.metadata, trace }
8364
+ });
8365
+ this.options.eventLog?.record(result.success ? "agent.completed" : "agent.failed", {
8366
+ taskId: input.task.id,
8367
+ role: input.task.role,
8368
+ agentRunId: result.id,
8369
+ trace,
8370
+ error: result.error
8371
+ });
8372
+ return result;
8373
+ } catch (error) {
8374
+ const message = error instanceof Error ? error.message : String(error);
8375
+ const result = normalizeAgentRunResult({
8376
+ id: `${input.task.id}-run-${Date.now().toString(36)}`,
8377
+ taskId: input.task.id,
8378
+ role: input.task.role,
8379
+ success: false,
8380
+ output: message,
8381
+ startedAt,
8382
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
8383
+ durationMs: Date.now() - Date.parse(startedAt),
8384
+ error: message,
8385
+ metadata: { trace }
8386
+ });
8387
+ this.options.eventLog?.record("agent.failed", {
8388
+ taskId: input.task.id,
8389
+ role: input.task.role,
8390
+ agentRunId: result.id,
8391
+ trace,
8392
+ error: message
8393
+ });
8394
+ return result;
8395
+ }
8396
+ }
8397
+ };
8398
+ function createAgentRunner(options) {
8399
+ return new AgentRunner(options);
8400
+ }
8401
+ async function defaultExecutor(context) {
8402
+ return {
8403
+ output: `Agent ${context.capability.role} accepted task '${context.task.objective}'.`
8404
+ };
8405
+ }
8406
+
8407
+ // src/runtime/runtime-agent-node-executor.ts
8408
+ var AgentDefinitionRegistry = class {
8409
+ definitionsByRole = /* @__PURE__ */ new Map();
8410
+ definitionsById = /* @__PURE__ */ new Map();
8411
+ constructor(definitions = []) {
8412
+ for (const definition of definitions) {
8413
+ this.register(definition);
8414
+ }
8415
+ }
8416
+ register(definition) {
8417
+ this.definitionsById.set(definition.id, cloneDefinition(definition));
8418
+ this.definitionsByRole.set(definition.role, cloneDefinition(definition));
8419
+ }
8420
+ get(id) {
8421
+ const definition = this.definitionsById.get(id);
8422
+ return definition ? cloneDefinition(definition) : void 0;
8423
+ }
8424
+ getByRole(role) {
8425
+ const definition = this.definitionsByRole.get(role);
8426
+ return definition ? cloneDefinition(definition) : void 0;
8427
+ }
8428
+ list() {
8429
+ return [...this.definitionsById.values()].map(cloneDefinition);
8430
+ }
8431
+ };
8432
+ var RuntimeAgentNodeExecutor = class {
8433
+ constructor(options) {
8434
+ this.options = options;
8435
+ this.runner = options.runner ?? new AgentRunner(options.runnerOptions);
8436
+ }
8437
+ options;
8438
+ runner;
8439
+ execute = async (execution) => {
8440
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
8441
+ const definition = this.options.registry.getByRole(execution.task.role);
8442
+ if (!definition) {
8443
+ return normalizeAgentRunResult({
8444
+ id: `${execution.workflowRunId}-${execution.node.id}-missing-definition`,
8445
+ taskId: execution.task.id,
8446
+ role: execution.task.role,
8447
+ success: false,
8448
+ output: "",
8449
+ startedAt,
8450
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
8451
+ error: `No agent definition registered for role '${execution.task.role}'.`,
8452
+ metadata: {
8453
+ workflowRunId: execution.workflowRunId,
8454
+ nodeId: execution.node.id,
8455
+ trace: execution.trace
8456
+ }
8457
+ });
8458
+ }
8459
+ const blockedTool = this.findBlockedTool(definition, execution);
8460
+ if (blockedTool) {
8461
+ return normalizeAgentRunResult({
8462
+ id: `${execution.workflowRunId}-${execution.node.id}-policy-blocked`,
8463
+ taskId: execution.task.id,
8464
+ role: execution.task.role,
8465
+ success: false,
8466
+ output: "",
8467
+ startedAt,
8468
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
8469
+ error: blockedTool,
8470
+ metadata: {
8471
+ workflowRunId: execution.workflowRunId,
8472
+ nodeId: execution.node.id,
8473
+ agentDefinitionId: definition.id,
8474
+ trace: execution.trace
8475
+ }
8476
+ });
8477
+ }
8478
+ const input = {
8479
+ task: {
8480
+ ...execution.task,
8481
+ context: {
8482
+ ...execution.task.context,
8483
+ instructions: definition.instructions,
8484
+ sharedState: execution.sharedState.readForRole(definition.role)
8485
+ }
8486
+ },
8487
+ capability: definition.capability,
8488
+ trace: execution.trace,
8489
+ toolRiskManifest: this.options.toolRiskManifest
8490
+ };
8491
+ const result = await this.runner.run(input);
8492
+ return normalizeAgentRunResult({
8493
+ ...result,
8494
+ metadata: {
8495
+ ...result.metadata,
8496
+ workflowRunId: execution.workflowRunId,
8497
+ nodeId: execution.node.id,
8498
+ agentDefinitionId: definition.id
8499
+ }
8500
+ });
8501
+ };
8502
+ findBlockedTool(definition, execution) {
8503
+ for (const toolName of execution.node.requiredTools ?? []) {
8504
+ const agentDecision = evaluateAgentToolPolicy({
8505
+ capability: definition.capability,
8506
+ toolName,
8507
+ manifest: this.options.toolRiskManifest
8508
+ });
8509
+ execution.eventLog.record("agent.tool.called", {
8510
+ workflowRunId: execution.workflowRunId,
8511
+ nodeId: execution.node.id,
8512
+ taskId: execution.task.id,
8513
+ role: execution.task.role,
8514
+ toolName,
8515
+ decision: agentDecision,
8516
+ trace: execution.trace
8517
+ });
8518
+ if (!agentDecision.allowed) {
8519
+ return agentDecision.reason ?? `Tool '${toolName}' is not allowed for agent.`;
8520
+ }
8521
+ const runtimeDecision = evaluateRuntimeToolPolicy(this.options.runtimePolicy, {
8522
+ toolName,
8523
+ risk: agentDecision.risk
8524
+ });
8525
+ if (!runtimeDecision.allowed) {
8526
+ return runtimeDecision.reason ?? `Tool '${toolName}' is blocked by runtime policy.`;
8527
+ }
8528
+ }
8529
+ return void 0;
8530
+ }
8531
+ };
8532
+ function createAgentDefinitionRegistry(definitions = []) {
8533
+ return new AgentDefinitionRegistry(definitions);
8534
+ }
8535
+ function createRuntimeAgentNodeExecutor(options) {
8536
+ return new RuntimeAgentNodeExecutor(options).execute;
8537
+ }
8538
+ function cloneDefinition(definition) {
8539
+ return structuredClone(definition);
8540
+ }
8541
+
8186
8542
  // src/runtime/workflow-registry.ts
8187
8543
  function cloneWorkflow(workflow) {
8188
8544
  return {
@@ -8516,14 +8872,22 @@ var WorkflowEngine = class {
8516
8872
  this.catalog = catalog;
8517
8873
  this.eventLog = eventLog;
8518
8874
  this.sharedState = options.sharedState ?? new InMemorySharedWorkspaceStore();
8519
- this.nodeExecutor = options.nodeExecutor;
8520
8875
  this.runtimePolicy = options.runtimePolicy;
8876
+ this.runtimeContext = options.runtimeContext;
8877
+ this.runtimeHostMode = options.runtimeHostMode ?? "local";
8878
+ this.nodeExecutor = options.nodeExecutor ?? (options.agentDefinitionRegistry ? createRuntimeAgentNodeExecutor({
8879
+ ...options.agentNodeExecutorOptions,
8880
+ registry: options.agentDefinitionRegistry,
8881
+ runtimePolicy: options.runtimePolicy
8882
+ }) : void 0);
8521
8883
  }
8522
8884
  catalog;
8523
8885
  eventLog;
8524
8886
  handlers = /* @__PURE__ */ new Map();
8525
8887
  sharedState;
8526
8888
  runtimePolicy;
8889
+ runtimeContext;
8890
+ runtimeHostMode;
8527
8891
  nodeExecutor;
8528
8892
  registerHandler(workflowId, handler) {
8529
8893
  if (!this.catalog.get(workflowId)) {
@@ -8538,6 +8902,7 @@ var WorkflowEngine = class {
8538
8902
  return this.catalog.createPlan(workflowId, input, this.eventLog);
8539
8903
  }
8540
8904
  async run(request) {
8905
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, "workflow.run");
8541
8906
  const workflow = this.catalog.get(request.workflowId);
8542
8907
  if (!workflow) {
8543
8908
  throw new Error(`Unknown workflow: ${request.workflowId}`);
@@ -8657,7 +9022,14 @@ var AgentRuntime = class {
8657
9022
  this.model = options.model ?? options.providerConfig?.model ?? getDefaultModel(options.providerType);
8658
9023
  this.runtimeContext = options.runtimeContext ? createRuntimeRequestContext(options.runtimeContext) : void 0;
8659
9024
  this.runtimePolicy = mergeRuntimePolicy(this.runtimeContext?.policy, options.runtimePolicy);
8660
- this.workflowEngine = options.workflowEngine ?? createWorkflowEngine(void 0, this.eventLog, { runtimePolicy: this.runtimePolicy });
9025
+ this.runtimeHostMode = options.runtimeHostMode ?? "local";
9026
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, "runtime.initialize");
9027
+ this.workflowEngine = options.workflowEngine ?? createWorkflowEngine(void 0, this.eventLog, {
9028
+ runtimePolicy: this.runtimePolicy,
9029
+ runtimeContext: this.runtimeContext,
9030
+ runtimeHostMode: this.runtimeHostMode,
9031
+ agentDefinitionRegistry: options.agentDefinitionRegistry
9032
+ });
8661
9033
  }
8662
9034
  options;
8663
9035
  providerRegistry;
@@ -8673,6 +9045,9 @@ var AgentRuntime = class {
8673
9045
  provider;
8674
9046
  runtimeContext;
8675
9047
  runtimePolicy;
9048
+ runtimeHostMode;
9049
+ requestTimestampsBySubject = /* @__PURE__ */ new Map();
9050
+ activeRuns = 0;
8676
9051
  async initialize() {
8677
9052
  const providerInjected = Boolean(this.options.provider);
8678
9053
  const provider = this.options.provider ?? await this.providerRegistry.createProvider(this.providerType, {
@@ -8721,10 +9096,12 @@ var AgentRuntime = class {
8721
9096
  },
8722
9097
  modes: listAgentModes(),
8723
9098
  context: this.runtimeContext,
8724
- policy: this.runtimePolicy
9099
+ policy: this.runtimePolicy,
9100
+ hostMode: this.runtimeHostMode
8725
9101
  };
8726
9102
  }
8727
9103
  createSession(options = {}) {
9104
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, "session.create");
8728
9105
  const session = this.runtimeSessionStore.create({
8729
9106
  ...options,
8730
9107
  metadata: {
@@ -8748,6 +9125,27 @@ var AgentRuntime = class {
8748
9125
  listSessions() {
8749
9126
  return this.runtimeSessionStore.list();
8750
9127
  }
9128
+ cleanupRetention(options = {}) {
9129
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, "retention.cleanup");
9130
+ const dryRun = options.dryRun ?? true;
9131
+ const cutoffs = createRetentionCutoffs(this.runtimePolicy, options.now);
9132
+ const expiredSessionIds = cutoffs.conversationBefore ? this.runtimeSessionStore.list().filter((session) => session.updatedAt < cutoffs.conversationBefore).map((session) => session.id) : [];
9133
+ const deletedSessionIds = dryRun ? [] : expiredSessionIds.filter((id) => this.runtimeSessionStore.delete(id));
9134
+ this.eventLog.record("retention.cleanup", {
9135
+ dryRun,
9136
+ cutoffs,
9137
+ expiredSessionIds,
9138
+ deletedSessionIds,
9139
+ tenantId: this.runtimeContext?.tenant?.id,
9140
+ runtimeApi: true
9141
+ });
9142
+ return {
9143
+ dryRun,
9144
+ cutoffs,
9145
+ expiredSessionIds,
9146
+ deletedSessionIds
9147
+ };
9148
+ }
8751
9149
  async runTurn(input) {
8752
9150
  const provider = this.provider;
8753
9151
  if (!provider) {
@@ -8758,6 +9156,12 @@ var AgentRuntime = class {
8758
9156
  throw new Error(`Runtime session not found: ${input.sessionId}`);
8759
9157
  }
8760
9158
  const effectiveSession = input.mode && input.mode !== session.mode ? { ...session, mode: input.mode } : session;
9159
+ assertRuntimeTurnWithinPolicy(this.runtimePolicy, {
9160
+ subject: "turn.run",
9161
+ currentTurns: countUserTurns(effectiveSession),
9162
+ tenantId: this.runtimeContext?.tenant?.id
9163
+ });
9164
+ const releaseRuntimeRequest = this.beginRuntimeRequest("turn.run");
8761
9165
  this.eventLog.record("turn.started", {
8762
9166
  sessionId: effectiveSession.id,
8763
9167
  provider: this.providerType,
@@ -8774,7 +9178,13 @@ var AgentRuntime = class {
8774
9178
  permissionPolicy: this.permissionPolicy,
8775
9179
  eventLog: this.eventLog
8776
9180
  });
8777
- assertRuntimeUsageWithinPolicy(this.runtimePolicy, result.usage);
9181
+ const estimatedCostUsd = this.estimateTurnCost(result);
9182
+ assertRuntimeUsageWithinPolicy(this.runtimePolicy, {
9183
+ ...result.usage,
9184
+ estimatedCostUsd,
9185
+ tenantId: this.runtimeContext?.tenant?.id,
9186
+ subject: "turn.run"
9187
+ });
8778
9188
  const updatedSession = this.runtimeSessionStore.update({
8779
9189
  ...effectiveSession,
8780
9190
  messages: [
@@ -8791,6 +9201,7 @@ var AgentRuntime = class {
8791
9201
  sessionId: updatedSession.id,
8792
9202
  inputTokens: result.usage.inputTokens,
8793
9203
  outputTokens: result.usage.outputTokens,
9204
+ estimatedCostUsd,
8794
9205
  model: result.model,
8795
9206
  runtimeApi: true
8796
9207
  });
@@ -8802,6 +9213,8 @@ var AgentRuntime = class {
8802
9213
  runtimeApi: true
8803
9214
  });
8804
9215
  throw error;
9216
+ } finally {
9217
+ releaseRuntimeRequest();
8805
9218
  }
8806
9219
  }
8807
9220
  async *streamTurn(input) {
@@ -8814,6 +9227,12 @@ var AgentRuntime = class {
8814
9227
  throw new Error(`Runtime session not found: ${input.sessionId}`);
8815
9228
  }
8816
9229
  const effectiveSession = input.mode && input.mode !== session.mode ? { ...session, mode: input.mode } : session;
9230
+ assertRuntimeTurnWithinPolicy(this.runtimePolicy, {
9231
+ subject: "turn.stream",
9232
+ currentTurns: countUserTurns(effectiveSession),
9233
+ tenantId: this.runtimeContext?.tenant?.id
9234
+ });
9235
+ const releaseRuntimeRequest = this.beginRuntimeRequest("turn.stream");
8817
9236
  const messages = [
8818
9237
  ...effectiveSession.messages,
8819
9238
  {
@@ -8863,7 +9282,13 @@ var AgentRuntime = class {
8863
9282
  model: input.options?.model ?? this.getModel(),
8864
9283
  mode: effectiveSession.mode
8865
9284
  };
8866
- assertRuntimeUsageWithinPolicy(this.runtimePolicy, result.usage);
9285
+ const estimatedCostUsd = this.estimateTurnCost(result);
9286
+ assertRuntimeUsageWithinPolicy(this.runtimePolicy, {
9287
+ ...result.usage,
9288
+ estimatedCostUsd,
9289
+ tenantId: this.runtimeContext?.tenant?.id,
9290
+ subject: "turn.stream"
9291
+ });
8867
9292
  const updatedSession = this.runtimeSessionStore.update({
8868
9293
  ...effectiveSession,
8869
9294
  messages: [
@@ -8882,6 +9307,7 @@ var AgentRuntime = class {
8882
9307
  sessionId: updatedSession.id,
8883
9308
  inputTokens: result.usage.inputTokens,
8884
9309
  outputTokens: result.usage.outputTokens,
9310
+ estimatedCostUsd,
8885
9311
  model: result.model,
8886
9312
  streaming: true,
8887
9313
  runtimeApi: true
@@ -8911,9 +9337,11 @@ var AgentRuntime = class {
8911
9337
  runtimeApi: true
8912
9338
  });
8913
9339
  }
9340
+ releaseRuntimeRequest();
8914
9341
  }
8915
9342
  }
8916
9343
  async executeTool(input) {
9344
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, "tool.execute");
8917
9345
  const startedAt = performance.now();
8918
9346
  const session = input.sessionId ? this.getSession(input.sessionId) : void 0;
8919
9347
  if (input.sessionId && !session) {
@@ -9024,6 +9452,7 @@ var AgentRuntime = class {
9024
9452
  };
9025
9453
  }
9026
9454
  assertToolAllowed(mode, toolName, input) {
9455
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, "tool.assertAllowed");
9027
9456
  const tool = this.toolRegistry.get(toolName);
9028
9457
  if (!tool) {
9029
9458
  this.eventLog.record("tool.blocked", {
@@ -9053,109 +9482,69 @@ var AgentRuntime = class {
9053
9482
  });
9054
9483
  return allowed;
9055
9484
  }
9056
- };
9057
- async function createAgentRuntime(options) {
9058
- const runtime = new AgentRuntime(options);
9059
- await runtime.initialize();
9060
- return runtime;
9061
- }
9062
-
9063
- // src/runtime/agent-runner.ts
9064
- var AgentRunner = class {
9065
- constructor(options = {}) {
9066
- this.options = options;
9485
+ beginRuntimeRequest(subject) {
9486
+ assertRuntimeTenantBoundary(this.runtimeContext, this.runtimeHostMode, subject);
9487
+ this.assertWithinRateLimit(subject);
9488
+ this.assertWithinConcurrencyLimit(subject);
9489
+ this.activeRuns += 1;
9490
+ let released = false;
9491
+ return () => {
9492
+ if (released) return;
9493
+ released = true;
9494
+ this.activeRuns = Math.max(0, this.activeRuns - 1);
9495
+ };
9067
9496
  }
9068
- options;
9069
- async run(input) {
9070
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
9071
- const trace = input.trace ?? createAgentTraceContext({ taskId: input.task.id });
9072
- this.options.eventLog?.record("agent.started", {
9073
- taskId: input.task.id,
9074
- role: input.task.role,
9075
- trace
9076
- });
9077
- try {
9078
- const raw = await (this.options.executor ?? defaultExecutor)({
9079
- task: input.task,
9080
- capability: input.capability,
9081
- trace,
9082
- assertToolAllowed: (toolName) => {
9083
- const decision = evaluateAgentToolPolicy({
9084
- capability: input.capability,
9085
- toolName,
9086
- manifest: input.toolRiskManifest
9087
- });
9088
- this.options.eventLog?.record("agent.tool.called", {
9089
- taskId: input.task.id,
9090
- role: input.task.role,
9091
- toolName,
9092
- decision,
9093
- trace
9094
- });
9095
- if (!decision.allowed) {
9096
- throw new Error(decision.reason ?? `Tool '${toolName}' is not allowed.`);
9097
- }
9098
- }
9099
- });
9100
- const result = normalizeAgentRunResult({
9101
- id: `${input.task.id}-run-${Date.now().toString(36)}`,
9102
- taskId: input.task.id,
9103
- role: input.task.role,
9104
- success: raw.success ?? true,
9105
- output: raw.output,
9106
- turns: raw.turns,
9107
- toolsUsed: raw.toolsUsed,
9108
- usage: {
9109
- inputTokens: raw.inputTokens ?? 0,
9110
- outputTokens: raw.outputTokens ?? 0,
9111
- estimated: raw.inputTokens === void 0 || raw.outputTokens === void 0
9112
- },
9113
- startedAt,
9114
- completedAt: (/* @__PURE__ */ new Date()).toISOString(),
9115
- durationMs: Date.now() - Date.parse(startedAt),
9116
- error: raw.error,
9117
- metadata: { ...raw.metadata, trace }
9118
- });
9119
- this.options.eventLog?.record(result.success ? "agent.completed" : "agent.failed", {
9120
- taskId: input.task.id,
9121
- role: input.task.role,
9122
- agentRunId: result.id,
9123
- trace,
9124
- error: result.error
9125
- });
9126
- return result;
9127
- } catch (error) {
9128
- const message = error instanceof Error ? error.message : String(error);
9129
- const result = normalizeAgentRunResult({
9130
- id: `${input.task.id}-run-${Date.now().toString(36)}`,
9131
- taskId: input.task.id,
9132
- role: input.task.role,
9133
- success: false,
9134
- output: message,
9135
- startedAt,
9136
- completedAt: (/* @__PURE__ */ new Date()).toISOString(),
9137
- durationMs: Date.now() - Date.parse(startedAt),
9138
- error: message,
9139
- metadata: { trace }
9497
+ assertWithinRateLimit(subject) {
9498
+ const maxRequestsPerMinute = this.runtimePolicy?.rateLimit?.maxRequestsPerMinute;
9499
+ if (maxRequestsPerMinute === void 0) return;
9500
+ const now = Date.now();
9501
+ const windowStart = now - 6e4;
9502
+ const key = `${this.runtimeContext?.tenant?.id ?? "global"}:${subject}`;
9503
+ const recent = (this.requestTimestampsBySubject.get(key) ?? []).filter(
9504
+ (timestamp) => timestamp > windowStart
9505
+ );
9506
+ if (recent.length >= maxRequestsPerMinute) {
9507
+ this.requestTimestampsBySubject.set(key, recent);
9508
+ throw new RuntimePolicyViolation({
9509
+ code: "rate_limit_exceeded",
9510
+ subject,
9511
+ tenantId: this.runtimeContext?.tenant?.id,
9512
+ policyPath: "runtimePolicy.rateLimit.maxRequestsPerMinute",
9513
+ message: `Runtime policy rate limit exceeded: ${recent.length}/${maxRequestsPerMinute} requests per minute.`
9140
9514
  });
9141
- this.options.eventLog?.record("agent.failed", {
9142
- taskId: input.task.id,
9143
- role: input.task.role,
9144
- agentRunId: result.id,
9145
- trace,
9146
- error: message
9515
+ }
9516
+ recent.push(now);
9517
+ this.requestTimestampsBySubject.set(key, recent);
9518
+ }
9519
+ assertWithinConcurrencyLimit(subject) {
9520
+ const maxConcurrentRuns = this.runtimePolicy?.rateLimit?.maxConcurrentRuns;
9521
+ if (maxConcurrentRuns === void 0) return;
9522
+ if (this.activeRuns >= maxConcurrentRuns) {
9523
+ throw new RuntimePolicyViolation({
9524
+ code: "concurrency_limit_exceeded",
9525
+ subject,
9526
+ tenantId: this.runtimeContext?.tenant?.id,
9527
+ policyPath: "runtimePolicy.rateLimit.maxConcurrentRuns",
9528
+ message: `Runtime policy concurrency limit exceeded: ${this.activeRuns}/${maxConcurrentRuns} active runs.`
9147
9529
  });
9148
- return result;
9149
9530
  }
9150
9531
  }
9532
+ estimateTurnCost(result) {
9533
+ return estimateCost(
9534
+ result.model,
9535
+ result.usage.inputTokens,
9536
+ result.usage.outputTokens,
9537
+ this.providerType
9538
+ ).totalCost;
9539
+ }
9151
9540
  };
9152
- function createAgentRunner(options) {
9153
- return new AgentRunner(options);
9541
+ function countUserTurns(session) {
9542
+ return session.messages.filter((message) => message.role === "user").length;
9154
9543
  }
9155
- async function defaultExecutor(context) {
9156
- return {
9157
- output: `Agent ${context.capability.role} accepted task '${context.task.objective}'.`
9158
- };
9544
+ async function createAgentRuntime(options) {
9545
+ const runtime = new AgentRuntime(options);
9546
+ await runtime.initialize();
9547
+ return runtime;
9159
9548
  }
9160
9549
 
9161
9550
  // src/runtime/tool-calling-turn-runner.ts
@@ -9398,10 +9787,24 @@ function rowToEvent(row) {
9398
9787
  function persistBestEffort(promise) {
9399
9788
  void promise.catch(() => void 0);
9400
9789
  }
9790
+ function assertPostgresSyncStoreNotHosted(options) {
9791
+ if (options.hostMode === "hosted") {
9792
+ throw new Error(
9793
+ "Postgres sync runtime stores are local/cache-compatible only. Use async hosted Postgres stores in hosted mode."
9794
+ );
9795
+ }
9796
+ }
9797
+ function requireTenantId(options) {
9798
+ if (!options.tenantId) {
9799
+ throw new Error("Postgres hosted runtime stores require tenantId.");
9800
+ }
9801
+ return options.tenantId;
9802
+ }
9401
9803
  var PostgresRuntimeSessionStore = class {
9402
9804
  constructor(client, options = {}) {
9403
9805
  this.client = client;
9404
9806
  this.options = options;
9807
+ assertPostgresSyncStoreNotHosted(options);
9405
9808
  }
9406
9809
  client;
9407
9810
  options;
@@ -9482,6 +9885,104 @@ var PostgresRuntimeSessionStore = class {
9482
9885
  return deleted;
9483
9886
  }
9484
9887
  };
9888
+ var AsyncPostgresRuntimeSessionStore = class {
9889
+ constructor(client, options) {
9890
+ this.client = client;
9891
+ this.tenantId = requireTenantId(options);
9892
+ }
9893
+ client;
9894
+ tenantId;
9895
+ async create(options = {}) {
9896
+ const now = (/* @__PURE__ */ new Date()).toISOString();
9897
+ const session = {
9898
+ id: options.id ?? createSessionId2(),
9899
+ createdAt: now,
9900
+ updatedAt: now,
9901
+ mode: options.mode ?? "ask",
9902
+ messages: options.messages ? options.messages.map((message) => ({ ...message })) : [],
9903
+ instructions: options.instructions,
9904
+ metadata: { ...options.metadata, tenantId: this.tenantId }
9905
+ };
9906
+ const result = await this.client.query(
9907
+ `insert into coco_runtime_sessions
9908
+ (id, tenant_id, created_at, updated_at, mode, messages, instructions, metadata)
9909
+ values ($1, $2, $3, $4, $5, $6::jsonb, $7, $8::jsonb)
9910
+ on conflict (id) do update set
9911
+ updated_at = excluded.updated_at,
9912
+ mode = excluded.mode,
9913
+ messages = excluded.messages,
9914
+ instructions = excluded.instructions,
9915
+ metadata = excluded.metadata
9916
+ where coco_runtime_sessions.tenant_id = excluded.tenant_id`,
9917
+ [
9918
+ session.id,
9919
+ this.tenantId,
9920
+ session.createdAt,
9921
+ session.updatedAt,
9922
+ session.mode,
9923
+ JSON.stringify(session.messages),
9924
+ session.instructions ?? null,
9925
+ JSON.stringify(session.metadata)
9926
+ ]
9927
+ );
9928
+ if (result.rowCount === 0) {
9929
+ throw new Error(`Runtime session id is already owned by another tenant: ${session.id}`);
9930
+ }
9931
+ return structuredClone(session);
9932
+ }
9933
+ async get(id) {
9934
+ const result = await this.client.query(
9935
+ `select * from coco_runtime_sessions
9936
+ where id = $1 and tenant_id = $2
9937
+ limit 1`,
9938
+ [id, this.tenantId]
9939
+ );
9940
+ const row = result.rows[0];
9941
+ return row ? rowToSession(row) : void 0;
9942
+ }
9943
+ async update(session) {
9944
+ const updated = {
9945
+ ...session,
9946
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9947
+ messages: session.messages.map((message) => ({ ...message })),
9948
+ metadata: { ...session.metadata, tenantId: this.tenantId }
9949
+ };
9950
+ const result = await this.client.query(
9951
+ `update coco_runtime_sessions
9952
+ set updated_at = $3, mode = $4, messages = $5::jsonb, instructions = $6, metadata = $7::jsonb
9953
+ where id = $1 and tenant_id = $2`,
9954
+ [
9955
+ updated.id,
9956
+ this.tenantId,
9957
+ updated.updatedAt,
9958
+ updated.mode,
9959
+ JSON.stringify(updated.messages),
9960
+ updated.instructions ?? null,
9961
+ JSON.stringify(updated.metadata)
9962
+ ]
9963
+ );
9964
+ if (result.rowCount === 0) {
9965
+ throw new Error(`Runtime session not found for tenant ${this.tenantId}: ${updated.id}`);
9966
+ }
9967
+ return structuredClone(updated);
9968
+ }
9969
+ async list() {
9970
+ const result = await this.client.query(
9971
+ `select * from coco_runtime_sessions
9972
+ where tenant_id = $1
9973
+ order by updated_at desc`,
9974
+ [this.tenantId]
9975
+ );
9976
+ return result.rows.map(rowToSession);
9977
+ }
9978
+ async delete(id) {
9979
+ const result = await this.client.query(
9980
+ "delete from coco_runtime_sessions where id = $1 and tenant_id = $2",
9981
+ [id, this.tenantId]
9982
+ );
9983
+ return (result.rowCount ?? 0) > 0;
9984
+ }
9985
+ };
9485
9986
  function createPostgresRuntimeSessionQueries(client, options = {}) {
9486
9987
  return {
9487
9988
  async get(id) {
@@ -9509,6 +10010,7 @@ var PostgresEventLog = class {
9509
10010
  constructor(client, options = {}) {
9510
10011
  this.client = client;
9511
10012
  this.options = options;
10013
+ assertPostgresSyncStoreNotHosted(options);
9512
10014
  }
9513
10015
  client;
9514
10016
  options;
@@ -9546,12 +10048,106 @@ var PostgresEventLog = class {
9546
10048
  this.events = [];
9547
10049
  }
9548
10050
  };
10051
+ var AsyncPostgresEventLog = class {
10052
+ constructor(client, options) {
10053
+ this.client = client;
10054
+ this.tenantId = requireTenantId(options);
10055
+ }
10056
+ client;
10057
+ tenantId;
10058
+ async record(type, data = {}) {
10059
+ const event = {
10060
+ id: randomUUID(),
10061
+ type,
10062
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
10063
+ data: { ...data, tenantId: this.tenantId }
10064
+ };
10065
+ await this.client.query(
10066
+ `insert into coco_runtime_events (id, tenant_id, type, timestamp, data)
10067
+ values ($1, $2, $3, $4, $5::jsonb)`,
10068
+ [event.id, this.tenantId, event.type, event.timestamp, JSON.stringify(event.data)]
10069
+ );
10070
+ return event;
10071
+ }
10072
+ async list() {
10073
+ return listPostgresRuntimeEvents(this.client, { tenantId: this.tenantId });
10074
+ }
10075
+ async count() {
10076
+ const result = await this.client.query(
10077
+ "select count(*)::int as count from coco_runtime_events where tenant_id = $1",
10078
+ [this.tenantId]
10079
+ );
10080
+ return Number(result.rows[0]?.count ?? 0);
10081
+ }
10082
+ async clear() {
10083
+ await this.client.query("delete from coco_runtime_events where tenant_id = $1", [
10084
+ this.tenantId
10085
+ ]);
10086
+ }
10087
+ };
10088
+ var PostgresRuntimeAuditStore = class {
10089
+ constructor(client, options) {
10090
+ this.client = client;
10091
+ this.tenantId = requireTenantId(options);
10092
+ }
10093
+ client;
10094
+ tenantId;
10095
+ async record(input) {
10096
+ const record = {
10097
+ id: randomUUID(),
10098
+ tenantId: this.tenantId,
10099
+ type: input.type,
10100
+ subject: input.subject,
10101
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
10102
+ data: { ...input.data }
10103
+ };
10104
+ await this.client.query(
10105
+ `insert into coco_runtime_audit_events
10106
+ (id, tenant_id, type, subject, timestamp, data)
10107
+ values ($1, $2, $3, $4, $5, $6::jsonb)`,
10108
+ [
10109
+ record.id,
10110
+ record.tenantId,
10111
+ record.type,
10112
+ record.subject ?? null,
10113
+ record.timestamp,
10114
+ JSON.stringify(record.data)
10115
+ ]
10116
+ );
10117
+ return record;
10118
+ }
10119
+ async list() {
10120
+ const result = await this.client.query(
10121
+ `select * from coco_runtime_audit_events
10122
+ where tenant_id = $1
10123
+ order by timestamp asc`,
10124
+ [this.tenantId]
10125
+ );
10126
+ return result.rows.map((row) => ({
10127
+ id: row.id,
10128
+ tenantId: row.tenant_id,
10129
+ type: row.type,
10130
+ subject: row.subject ?? void 0,
10131
+ timestamp: dateToIso(row.timestamp),
10132
+ data: parseJson(row.data, {})
10133
+ }));
10134
+ }
10135
+ };
9549
10136
  function createPostgresRuntimeSessionStore(client, options) {
9550
10137
  return new PostgresRuntimeSessionStore(client, options);
9551
10138
  }
9552
10139
  function createPostgresEventLog(client, options) {
9553
10140
  return new PostgresEventLog(client, options);
9554
10141
  }
10142
+ function createAsyncPostgresRuntimeSessionStore(client, options) {
10143
+ return new AsyncPostgresRuntimeSessionStore(client, options);
10144
+ }
10145
+ function createAsyncPostgresEventLog(client, options) {
10146
+ return new AsyncPostgresEventLog(client, options);
10147
+ }
10148
+ function createPostgresRuntimeAuditStore(client, options) {
10149
+ return new PostgresRuntimeAuditStore(client, options);
10150
+ }
9555
10151
  async function listPostgresRuntimeEvents(client, options = {}) {
9556
10152
  const result = await client.query(
9557
10153
  `select * from coco_runtime_events
@@ -9563,6 +10159,76 @@ async function listPostgresRuntimeEvents(client, options = {}) {
9563
10159
  return result.rows.map(rowToEvent);
9564
10160
  }
9565
10161
 
10162
+ // src/runtime/tenant-scope.ts
10163
+ var TenantScopedRuntimeSessionStore = class {
10164
+ constructor(inner, options) {
10165
+ this.inner = inner;
10166
+ this.options = options;
10167
+ }
10168
+ inner;
10169
+ options;
10170
+ create(options = {}) {
10171
+ return this.inner.create({
10172
+ ...options,
10173
+ metadata: this.withTenant(options.metadata)
10174
+ });
10175
+ }
10176
+ get(id) {
10177
+ const session = this.inner.get(id);
10178
+ return session && this.belongsToTenant(session) ? session : void 0;
10179
+ }
10180
+ update(session) {
10181
+ if (!this.belongsToTenant(session)) {
10182
+ throw new Error(
10183
+ `Runtime session ${session.id} does not belong to tenant ${this.options.tenantId}.`
10184
+ );
10185
+ }
10186
+ return this.inner.update({
10187
+ ...session,
10188
+ metadata: this.withTenant(session.metadata)
10189
+ });
10190
+ }
10191
+ list() {
10192
+ return this.inner.list().filter((session) => this.belongsToTenant(session));
10193
+ }
10194
+ delete(id) {
10195
+ if (!this.get(id)) return false;
10196
+ return this.inner.delete(id);
10197
+ }
10198
+ withTenant(metadata) {
10199
+ return { ...metadata, tenantId: this.options.tenantId };
10200
+ }
10201
+ belongsToTenant(session) {
10202
+ return session.metadata["tenantId"] === this.options.tenantId;
10203
+ }
10204
+ };
10205
+ var TenantScopedEventLog = class {
10206
+ constructor(inner, options) {
10207
+ this.inner = inner;
10208
+ this.options = options;
10209
+ }
10210
+ inner;
10211
+ options;
10212
+ record(type, data = {}) {
10213
+ return this.inner.record(type, { ...data, tenantId: this.options.tenantId });
10214
+ }
10215
+ list() {
10216
+ return this.inner.list().filter((event) => event.data["tenantId"] === this.options.tenantId);
10217
+ }
10218
+ count() {
10219
+ return this.list().length;
10220
+ }
10221
+ clear() {
10222
+ throw new Error("Tenant-scoped event logs do not support partial clear.");
10223
+ }
10224
+ };
10225
+ function createTenantScopedRuntimeSessionStore(inner, tenantId) {
10226
+ return new TenantScopedRuntimeSessionStore(inner, { tenantId });
10227
+ }
10228
+ function createTenantScopedEventLog(inner, tenantId) {
10229
+ return new TenantScopedEventLog(inner, { tenantId });
10230
+ }
10231
+
9566
10232
  // src/runtime/extension-manifests.ts
9567
10233
  function createMcpToolPolicy(server, tool, risk, allowedModes = ["ask", "plan", "build", "debug", "review", "architect"]) {
9568
10234
  return {
@@ -9655,7 +10321,7 @@ function runGuardrails(stage, content, config = {}) {
9655
10321
  findings.push({
9656
10322
  id,
9657
10323
  stage,
9658
- severity: "warning",
10324
+ severity: actionToSeverity(config.promptInjectionAction ?? "warn"),
9659
10325
  message: `Potential prompt-injection pattern detected: ${id}`
9660
10326
  });
9661
10327
  }
@@ -9678,6 +10344,26 @@ function runGuardrails(stage, content, config = {}) {
9678
10344
  findings
9679
10345
  };
9680
10346
  }
10347
+ async function runGuardrailPipeline(steps, config = {}) {
10348
+ const outputs = [];
10349
+ const findings = [];
10350
+ for (const step of steps) {
10351
+ const effectiveConfig = { ...config, ...step.config };
10352
+ const result = runGuardrails(step.stage, step.content, effectiveConfig);
10353
+ const policyFindings = await effectiveConfig.policyProvider?.evaluate({
10354
+ stage: step.stage,
10355
+ content: result.content,
10356
+ findings: result.findings
10357
+ }) ?? [];
10358
+ outputs.push({ stage: step.stage, content: result.content });
10359
+ findings.push(...result.findings, ...policyFindings);
10360
+ }
10361
+ return {
10362
+ allowed: !findings.some((finding) => finding.severity === "blocked"),
10363
+ outputs,
10364
+ findings
10365
+ };
10366
+ }
9681
10367
  function validateStructuredOutput(output, schema) {
9682
10368
  if (!schema) return [];
9683
10369
  const result = schema.safeParse(output);
@@ -9691,6 +10377,16 @@ function validateStructuredOutput(output, schema) {
9691
10377
  }
9692
10378
  ];
9693
10379
  }
10380
+ function actionToSeverity(action) {
10381
+ switch (action) {
10382
+ case "allow":
10383
+ return "info";
10384
+ case "warn":
10385
+ return "warning";
10386
+ case "block":
10387
+ return "blocked";
10388
+ }
10389
+ }
9694
10390
 
9695
10391
  // src/runtime/blueprints.ts
9696
10392
  function mapActionModeToRuntimeMode(mode) {
@@ -9788,7 +10484,7 @@ var InMemoryKnowledgeRetriever = class {
9788
10484
  const limit = options.limit ?? 5;
9789
10485
  const minScore = options.minScore ?? 0;
9790
10486
  const tenantId = tenantIdFromRetrievalOptions(options);
9791
- return this.documents.filter((document) => sourceMatchesTenant(document.metadata, tenantId, options.dataBoundary)).map((document) => ({
10487
+ return this.documents.filter((document) => sourceAccessible(document, { ...options, tenantId })).map((document) => ({
9792
10488
  ...document,
9793
10489
  score: scoreDocument(document, terms)
9794
10490
  })).filter((source) => source.score >= minScore && source.score > 0).sort((a, b) => b.score - a.score).slice(0, limit);
@@ -9813,7 +10509,24 @@ var SimpleTextChunker = class {
9813
10509
  title: document.title,
9814
10510
  content,
9815
10511
  url: document.url,
9816
- metadata: { ...document.metadata, chunkIndex: index }
10512
+ tenantId: document.tenantId,
10513
+ sourceId: document.sourceId,
10514
+ acl: document.acl,
10515
+ classification: document.classification,
10516
+ version: document.version,
10517
+ updatedAt: document.updatedAt,
10518
+ deletedAt: document.deletedAt,
10519
+ metadata: {
10520
+ ...document.metadata,
10521
+ tenantId: document.tenantId ?? document.metadata?.["tenantId"],
10522
+ sourceId: document.sourceId ?? document.metadata?.["sourceId"],
10523
+ acl: document.acl ?? document.metadata?.["acl"],
10524
+ classification: document.classification ?? document.metadata?.["classification"],
10525
+ version: document.version ?? document.metadata?.["version"],
10526
+ updatedAt: document.updatedAt ?? document.metadata?.["updatedAt"],
10527
+ deletedAt: document.deletedAt ?? document.metadata?.["deletedAt"],
10528
+ chunkIndex: index
10529
+ }
9817
10530
  });
9818
10531
  index++;
9819
10532
  offset += maxChars - overlapChars;
@@ -9832,16 +10545,104 @@ var InMemoryVectorStore = class {
9832
10545
  const limit = options.limit ?? 5;
9833
10546
  const minScore = options.minScore ?? 0;
9834
10547
  const tenantId = tenantIdFromRetrievalOptions(options);
9835
- return this.chunks.filter((chunk2) => sourceMatchesTenant(chunk2.metadata, tenantId, options.dataBoundary)).map((chunk2) => ({
10548
+ return this.chunks.filter((chunk2) => sourceAccessible(chunk2, { ...options, tenantId })).map((chunk2) => ({
9836
10549
  id: chunk2.id,
9837
10550
  title: chunk2.title,
9838
10551
  content: chunk2.content,
9839
10552
  url: chunk2.url,
9840
10553
  score: cosineSimilarity(embedding, chunk2.embedding),
9841
- metadata: { ...chunk2.metadata, documentId: chunk2.documentId }
10554
+ metadata: {
10555
+ ...chunk2.metadata,
10556
+ tenantId: chunk2.tenantId ?? chunk2.metadata?.["tenantId"],
10557
+ sourceId: chunk2.sourceId ?? chunk2.metadata?.["sourceId"],
10558
+ acl: chunk2.acl ?? chunk2.metadata?.["acl"],
10559
+ classification: chunk2.classification ?? chunk2.metadata?.["classification"],
10560
+ version: chunk2.version ?? chunk2.metadata?.["version"],
10561
+ updatedAt: chunk2.updatedAt ?? chunk2.metadata?.["updatedAt"],
10562
+ deletedAt: chunk2.deletedAt ?? chunk2.metadata?.["deletedAt"],
10563
+ documentId: chunk2.documentId
10564
+ }
9842
10565
  })).filter((source) => source.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
9843
10566
  }
9844
10567
  };
10568
+ function createDocumentAccessPolicy(input) {
10569
+ return {
10570
+ canAccess({ document, options }) {
10571
+ const tenantId = options.tenantId ?? input.tenantId;
10572
+ const userId = options.userId ?? input.userId;
10573
+ const roles = options.roles ?? input.roles ?? [];
10574
+ const groups = options.groups ?? input.groups ?? [];
10575
+ const metadata = document.metadata ?? {};
10576
+ if (document.deletedAt ?? metadata["deletedAt"]) return false;
10577
+ const documentTenantId = document.tenantId ?? stringMetadata(metadata, "tenantId");
10578
+ const visibility = stringMetadata(metadata, "visibility");
10579
+ if (tenantId && documentTenantId !== tenantId && visibility !== "global") return false;
10580
+ const acl = document.acl ?? metadata["acl"];
10581
+ if (!acl) return input.requireAcl !== true;
10582
+ if (acl.public === true) return true;
10583
+ if (userId && acl.userIds?.includes(userId)) return true;
10584
+ if (acl.roles?.some((role) => roles.includes(role))) return true;
10585
+ if (acl.groups?.some((group) => groups.includes(group))) return true;
10586
+ return false;
10587
+ }
10588
+ };
10589
+ }
10590
+ function createRagIngestionJob(id, pipeline) {
10591
+ const job = {
10592
+ id,
10593
+ status: "pending",
10594
+ async run() {
10595
+ job.status = "running";
10596
+ job.startedAt = (/* @__PURE__ */ new Date()).toISOString();
10597
+ try {
10598
+ job.result = await pipeline.ingest();
10599
+ job.status = "completed";
10600
+ } catch (error) {
10601
+ job.status = "failed";
10602
+ job.error = error instanceof Error ? error.message : String(error);
10603
+ } finally {
10604
+ job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
10605
+ }
10606
+ return { ...job };
10607
+ }
10608
+ };
10609
+ return job;
10610
+ }
10611
+ function verifyCitations(citations, sources) {
10612
+ const byId = new Map(sources.map((source) => [source.id, source]));
10613
+ const unsupportedCitations = [];
10614
+ const missingSourceIds = [];
10615
+ for (const citation of citations) {
10616
+ const source = byId.get(citation.sourceId);
10617
+ if (!source) {
10618
+ missingSourceIds.push(citation.sourceId);
10619
+ unsupportedCitations.push(citation);
10620
+ }
10621
+ }
10622
+ return {
10623
+ valid: unsupportedCitations.length === 0,
10624
+ unsupportedCitations,
10625
+ missingSourceIds
10626
+ };
10627
+ }
10628
+ function evaluateGroundedness(answer, sources) {
10629
+ const answerTerms = new Set(tokenize(answer));
10630
+ const sourceTerms = new Set(sources.flatMap((source) => tokenize(source.content)));
10631
+ const overlap = [...answerTerms].filter((term) => sourceTerms.has(term)).length;
10632
+ const score = answerTerms.size === 0 ? 0 : overlap / answerTerms.size;
10633
+ const injection = /ignore|override|bypass|reveal|exfiltrate/i.test(
10634
+ sources.map((source) => source.content).join("\n")
10635
+ );
10636
+ const reasons = [];
10637
+ if (score < 0.2) reasons.push("Answer has low lexical support in retrieved sources.");
10638
+ if (injection) reasons.push("Retrieved sources contain prompt-injection indicators.");
10639
+ return {
10640
+ grounded: score >= 0.2 && !injection,
10641
+ score,
10642
+ blocked: injection,
10643
+ reasons
10644
+ };
10645
+ }
9845
10646
  function createInMemoryKnowledgeRetriever(documents) {
9846
10647
  return new InMemoryKnowledgeRetriever(documents);
9847
10648
  }
@@ -9908,10 +10709,15 @@ function mergeRetrievalOptionsWithRuntimeContext(options, runtimeContext) {
9908
10709
  function tenantIdFromRetrievalOptions(options) {
9909
10710
  return options.tenantId ?? options.runtimeContext?.tenant?.id;
9910
10711
  }
9911
- function sourceMatchesTenant(metadata, tenantId, dataBoundary) {
9912
- if (!tenantId || dataBoundary?.allowCrossTenantMemory === true) return true;
9913
- const sourceTenantId = metadata?.["tenantId"];
9914
- return sourceTenantId === tenantId || metadata?.["visibility"] === "global";
10712
+ function sourceAccessible(document, options) {
10713
+ if (options.documentAccessPolicy) {
10714
+ return options.documentAccessPolicy.canAccess({ document, options });
10715
+ }
10716
+ const metadata = document.metadata ?? {};
10717
+ if (document.deletedAt ?? metadata["deletedAt"]) return false;
10718
+ if (!options.tenantId || options.dataBoundary?.allowCrossTenantMemory === true) return true;
10719
+ const sourceTenantId = document.tenantId ?? metadata["tenantId"];
10720
+ return sourceTenantId === options.tenantId || metadata["visibility"] === "global";
9915
10721
  }
9916
10722
  async function retrieveFromVectorPipeline(query, options, retrievalOptions) {
9917
10723
  if (!options.embeddingProvider || !options.vectorStore) return [];
@@ -9919,6 +10725,10 @@ async function retrieveFromVectorPipeline(query, options, retrievalOptions) {
9919
10725
  if (!embedding) return [];
9920
10726
  return options.vectorStore.search(embedding, retrievalOptions);
9921
10727
  }
10728
+ function stringMetadata(metadata, key) {
10729
+ const value = metadata[key];
10730
+ return typeof value === "string" ? value : void 0;
10731
+ }
9922
10732
  function cosineSimilarity(a, b) {
9923
10733
  if (a.length === 0 || b.length === 0 || a.length !== b.length) return 0;
9924
10734
  let dot = 0;
@@ -10043,7 +10853,188 @@ var RuntimeToolExecutor = class {
10043
10853
  function createRuntimeToolExecutor(options) {
10044
10854
  return new RuntimeToolExecutor(options);
10045
10855
  }
10856
+ var InMemoryTraceExporter = class {
10857
+ spans = [];
10858
+ async export(span) {
10859
+ this.spans.push(structuredClone(span));
10860
+ }
10861
+ list() {
10862
+ return this.spans.map((span) => structuredClone(span));
10863
+ }
10864
+ clear() {
10865
+ this.spans = [];
10866
+ }
10867
+ };
10868
+ var FileTraceExporter = class {
10869
+ constructor(filePath) {
10870
+ this.filePath = filePath;
10871
+ mkdirSync(dirname(filePath), { recursive: true });
10872
+ }
10873
+ filePath;
10874
+ async export(span) {
10875
+ appendFileSync(this.filePath, JSON.stringify(span) + "\n", "utf-8");
10876
+ }
10877
+ list() {
10878
+ try {
10879
+ return readFileSync(this.filePath, "utf-8").split("\n").filter(Boolean).map((line) => JSON.parse(line));
10880
+ } catch {
10881
+ return [];
10882
+ }
10883
+ }
10884
+ clear() {
10885
+ writeFileSync(this.filePath, "", "utf-8");
10886
+ }
10887
+ };
10888
+ var OpenTelemetryTraceExporter = class {
10889
+ spans = [];
10890
+ async export(span) {
10891
+ this.spans.push(structuredClone(span));
10892
+ }
10893
+ toOtlpJson() {
10894
+ return {
10895
+ resourceSpans: [
10896
+ {
10897
+ scopeSpans: [
10898
+ {
10899
+ spans: this.spans.map((span) => ({
10900
+ traceId: span.traceId,
10901
+ spanId: span.spanId,
10902
+ parentSpanId: span.parentSpanId,
10903
+ name: span.name,
10904
+ kind: span.kind,
10905
+ startTimeUnixNano: Date.parse(span.timestamp) * 1e6,
10906
+ endTimeUnixNano: Date.parse(span.timestamp) * 1e6,
10907
+ attributes: Object.entries(span.attributes).map(([key, value]) => ({
10908
+ key,
10909
+ value: { stringValue: JSON.stringify(value) }
10910
+ }))
10911
+ }))
10912
+ }
10913
+ ]
10914
+ }
10915
+ ]
10916
+ };
10917
+ }
10918
+ };
10919
+ async function exportRuntimeEventsAsSpans(events, exporter) {
10920
+ const spans = events.map(eventToSpan);
10921
+ for (const span of spans) {
10922
+ await exporter.export(span);
10923
+ }
10924
+ await exporter.flush?.();
10925
+ return spans;
10926
+ }
10927
+ function eventToSpan(event) {
10928
+ const trace = isRecord(event.data["trace"]) ? event.data["trace"] : {};
10929
+ const traceId = stringValue(trace["traceId"]) ?? stringValue(event.data["traceId"]) ?? event.id;
10930
+ const spanId = stringValue(trace["spanId"]) ?? stringValue(event.data["spanId"]) ?? event.id;
10931
+ return {
10932
+ id: event.id,
10933
+ traceId,
10934
+ spanId,
10935
+ parentSpanId: stringValue(trace["parentSpanId"]) ?? stringValue(event.data["parentSpanId"]),
10936
+ kind: inferSpanKind(event),
10937
+ name: event.type,
10938
+ timestamp: event.timestamp,
10939
+ attributes: redactTraceAttributes(event.data)
10940
+ };
10941
+ }
10942
+ function collectRuntimeMetrics(events) {
10943
+ const snapshot = {
10944
+ events: events.length,
10945
+ byKind: {
10946
+ workflow: 0,
10947
+ agent: 0,
10948
+ llm: 0,
10949
+ tool: 0,
10950
+ rag: 0,
10951
+ gate: 0,
10952
+ handoff: 0,
10953
+ state: 0,
10954
+ runtime: 0
10955
+ },
10956
+ tokens: { input: 0, output: 0 },
10957
+ estimatedCostUsd: 0,
10958
+ retries: 0,
10959
+ policyBlocks: 0,
10960
+ errorsByClass: {},
10961
+ toolsUsed: {},
10962
+ gatesFailed: 0,
10963
+ tenantUsage: {}
10964
+ };
10965
+ for (const event of events) {
10966
+ const kind = inferSpanKind(event);
10967
+ snapshot.byKind[kind] += 1;
10968
+ const inputTokens = numberValue(event.data["inputTokens"]);
10969
+ const outputTokens = numberValue(event.data["outputTokens"]);
10970
+ const estimatedCostUsd = numberValue(event.data["estimatedCostUsd"]);
10971
+ snapshot.tokens.input += inputTokens;
10972
+ snapshot.tokens.output += outputTokens;
10973
+ snapshot.estimatedCostUsd += estimatedCostUsd;
10974
+ if (event.data["attempt"] && numberValue(event.data["attempt"]) > 1) snapshot.retries += 1;
10975
+ if (event.type === "tool.blocked" || event.data["runtimePolicyBlocked"] === true) {
10976
+ snapshot.policyBlocks += 1;
10977
+ }
10978
+ if (event.type.endsWith(".failed") || event.type === "error") {
10979
+ const key = stringValue(event.data["error"]) ?? event.type;
10980
+ snapshot.errorsByClass[key] = (snapshot.errorsByClass[key] ?? 0) + 1;
10981
+ }
10982
+ const tool = stringValue(event.data["tool"]) ?? stringValue(event.data["toolName"]);
10983
+ if (tool) snapshot.toolsUsed[tool] = (snapshot.toolsUsed[tool] ?? 0) + 1;
10984
+ if (event.type === "workflow.gate.failed") snapshot.gatesFailed += 1;
10985
+ const tenantId = stringValue(event.data["tenantId"]);
10986
+ if (tenantId) {
10987
+ snapshot.tenantUsage[tenantId] ??= {
10988
+ events: 0,
10989
+ inputTokens: 0,
10990
+ outputTokens: 0,
10991
+ estimatedCostUsd: 0
10992
+ };
10993
+ snapshot.tenantUsage[tenantId].events += 1;
10994
+ snapshot.tenantUsage[tenantId].inputTokens += inputTokens;
10995
+ snapshot.tenantUsage[tenantId].outputTokens += outputTokens;
10996
+ snapshot.tenantUsage[tenantId].estimatedCostUsd += estimatedCostUsd;
10997
+ }
10998
+ }
10999
+ return snapshot;
11000
+ }
11001
+ function redactTraceAttributes(input) {
11002
+ return redactUnknown(input);
11003
+ }
11004
+ function inferSpanKind(event) {
11005
+ if (event.type.startsWith("workflow.gate")) return "gate";
11006
+ if (event.type.startsWith("workflow.")) return "workflow";
11007
+ if (event.type.startsWith("agent.handoff")) return "handoff";
11008
+ if (event.type.startsWith("agent.")) return "agent";
11009
+ if (event.type.startsWith("tool.") || event.type === "agent.tool.called") return "tool";
11010
+ if (event.type.startsWith("shared_state.") || event.type.startsWith("checkpoint.")) {
11011
+ return "state";
11012
+ }
11013
+ if (event.type.startsWith("turn.")) return "llm";
11014
+ return "runtime";
11015
+ }
11016
+ function redactUnknown(value) {
11017
+ if (typeof value === "string") {
11018
+ return redactSecrets(value, { enabled: true }).content;
11019
+ }
11020
+ if (Array.isArray(value)) return value.map(redactUnknown);
11021
+ if (isRecord(value)) {
11022
+ return Object.fromEntries(
11023
+ Object.entries(value).map(([key, nested]) => [key, redactUnknown(nested)])
11024
+ );
11025
+ }
11026
+ return value;
11027
+ }
11028
+ function isRecord(value) {
11029
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11030
+ }
11031
+ function stringValue(value) {
11032
+ return typeof value === "string" ? value : void 0;
11033
+ }
11034
+ function numberValue(value) {
11035
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
11036
+ }
10046
11037
 
10047
- export { AGENT_MODES, AgentGraphEngine, AgentRunner, AgentRuntime, DEFAULT_WORKFLOWS, DefaultPermissionPolicy, DefaultRuntimeTurnRunner, FileEventLog, FileRuntimeSessionStore, FileSharedWorkspaceStore, InMemoryEventLog, InMemoryKnowledgeRetriever, InMemoryRuntimeSessionStore, InMemorySharedWorkspaceStore, InMemoryVectorStore, PostgresEventLog, PostgresRuntimeSessionStore, ProviderRegistry, RuntimeToolExecutor, SharedWorkspaceState, SimpleTextChunker, ToolCallingRuntimeTurnRunner, WorkflowCatalog, WorkflowEngine, WorkflowRegistry, createAgentArtifact, createAgentFromBlueprint, createAgentGraphEngine, createAgentRunner, createAgentRuntime, createAgentTraceContext, createBaseBlueprint, createDefaultRuntimeTurnRunner, createEventLog, createFileEventLog, createFileRuntimeSessionStore, createInMemoryKnowledgeRetriever, createInMemoryVectorStore, createMcpToolPolicy, createPermissionPolicy, createPostgresEventLog, createPostgresRuntimeSessionQueries, createPostgresRuntimeSessionStore, createProviderRegistry, createRagPipeline, createRuntimeHttpServer, createRuntimeRequestContext, createRuntimeSessionStore, createRuntimeToolExecutor, createSafeToolRegistry, createSimpleTextChunker, createSummaryArtifact, createToolCallingRuntimeTurnRunner, createWorkflowCatalog, createWorkflowEngine, createWorkflowRegistry, defaultPublicGuardrails, dryRunAgentGraphNodeExecutor, evaluateAgentToolPolicy, formatRetrievedSourcesForPrompt, getAgentMode, isAgentMode, listAgentModes, listLegacyAgentRoleMappings, listPostgresRuntimeEvents, mapActionModeToRuntimeMode, mapLegacyAgentRole, mergeRuntimePolicy, normalizeAgentRunResult, redactSecrets, runGuardrails, runtimeContextToMetadata, validateAgentCapabilities, validateAgentGraph, validateStructuredOutput, workflowToAgentGraph };
11038
+ export { AGENT_MODES, AgentDefinitionRegistry, AgentGraphEngine, AgentRunner, AgentRuntime, AsyncPostgresEventLog, AsyncPostgresRuntimeSessionStore, DEFAULT_WORKFLOWS, DefaultPermissionPolicy, DefaultRuntimeTurnRunner, FileEventLog, FileRuntimeSessionStore, FileSharedWorkspaceStore, FileTraceExporter, InMemoryEventLog, InMemoryKnowledgeRetriever, InMemoryRuntimeSessionStore, InMemorySharedWorkspaceStore, InMemoryTraceExporter, InMemoryVectorStore, OpenTelemetryTraceExporter, PostgresEventLog, PostgresRuntimeAuditStore, PostgresRuntimeSessionStore, ProviderRegistry, RuntimeAgentNodeExecutor, RuntimePolicyViolation, RuntimeToolExecutor, SharedWorkspaceState, SimpleTextChunker, TenantScopedEventLog, TenantScopedRuntimeSessionStore, ToolCallingRuntimeTurnRunner, WorkflowCatalog, WorkflowEngine, WorkflowRegistry, assertRuntimeTenantBoundary, assertRuntimeTurnWithinPolicy, collectRuntimeMetrics, createAgentArtifact, createAgentDefinitionRegistry, createAgentFromBlueprint, createAgentGraphEngine, createAgentRunner, createAgentRuntime, createAgentTraceContext, createAsyncPostgresEventLog, createAsyncPostgresRuntimeSessionStore, createBaseBlueprint, createDefaultRuntimeTurnRunner, createDocumentAccessPolicy, createEventLog, createFileEventLog, createFileRuntimeSessionStore, createInMemoryKnowledgeRetriever, createInMemoryVectorStore, createMcpToolPolicy, createPermissionPolicy, createPostgresEventLog, createPostgresRuntimeAuditStore, createPostgresRuntimeSessionQueries, createPostgresRuntimeSessionStore, createProviderRegistry, createRagIngestionJob, createRagPipeline, createRetentionCutoffs, createRuntimeAgentNodeExecutor, createRuntimeHttpServer, createRuntimeRequestContext, createRuntimeSessionStore, createRuntimeTenantBoundary, createRuntimeToolExecutor, createSafeToolRegistry, createSimpleTextChunker, createSummaryArtifact, createTenantScopedEventLog, createTenantScopedRuntimeSessionStore, createToolCallingRuntimeTurnRunner, createWorkflowCatalog, createWorkflowEngine, createWorkflowRegistry, defaultPublicGuardrails, dryRunAgentGraphNodeExecutor, evaluateAgentToolPolicy, evaluateGroundedness, eventToSpan, exportRuntimeEventsAsSpans, formatRetrievedSourcesForPrompt, getAgentMode, isAgentMode, listAgentModes, listLegacyAgentRoleMappings, listPostgresRuntimeEvents, mapActionModeToRuntimeMode, mapLegacyAgentRole, mergeRuntimePolicy, normalizeAgentRunResult, redactSecrets, redactTraceAttributes, runGuardrailPipeline, runGuardrails, runtimeContextToMetadata, validateAgentCapabilities, validateAgentGraph, validateStructuredOutput, verifyCitations, workflowToAgentGraph };
10048
11039
  //# sourceMappingURL=index.js.map
10049
11040
  //# sourceMappingURL=index.js.map