@arnilo/prism 0.0.15 → 0.0.16

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 (90) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/agent-definitions.js +2 -3
  3. package/dist/agent-loops.js +12 -7
  4. package/dist/agent-run-lifecycle.d.ts +1 -2
  5. package/dist/agent-run-lifecycle.js +1 -1
  6. package/dist/agent-run-state.js +16 -3
  7. package/dist/agents.d.ts +1 -1
  8. package/dist/agents.js +121 -51
  9. package/dist/cache-helpers.js +18 -9
  10. package/dist/checkpoints.js +5 -9
  11. package/dist/cli-init.js +3 -7
  12. package/dist/cli-runner.d.ts +1 -1
  13. package/dist/cli-runner.js +74 -13
  14. package/dist/compaction.js +5 -4
  15. package/dist/config.js +7 -4
  16. package/dist/content.js +26 -24
  17. package/dist/context-budget.js +12 -8
  18. package/dist/contracts.d.ts +3 -3
  19. package/dist/contracts.js +4 -1
  20. package/dist/contribution-parsing.js +6 -2
  21. package/dist/conversations.js +2 -1
  22. package/dist/credentials.d.ts +1 -1
  23. package/dist/credentials.js +3 -1
  24. package/dist/event-multiplexer.js +1 -3
  25. package/dist/feedback.js +11 -9
  26. package/dist/guardrails.d.ts +1 -1
  27. package/dist/guardrails.js +17 -14
  28. package/dist/identity.js +10 -2
  29. package/dist/index.d.ts +82 -83
  30. package/dist/index.js +42 -42
  31. package/dist/input.d.ts +2 -2
  32. package/dist/input.js +40 -24
  33. package/dist/instruction-injection.d.ts +1 -1
  34. package/dist/node/agent-definitions.js +16 -8
  35. package/dist/node/contribution-discovery.d.ts +1 -2
  36. package/dist/node/contribution-discovery.js +3 -3
  37. package/dist/node/session-store-jsonl.js +10 -7
  38. package/dist/node/settings.d.ts +1 -1
  39. package/dist/node/settings.js +1 -1
  40. package/dist/node/system-project-prompts.js +2 -4
  41. package/dist/node/trust.js +1 -1
  42. package/dist/persistence-lifecycle.js +1 -3
  43. package/dist/provider-events.js +3 -1
  44. package/dist/provider-request-policy.js +3 -4
  45. package/dist/providers/media.d.ts +1 -1
  46. package/dist/providers/openai-compatible.js +3 -4
  47. package/dist/providers/openai-primitives.js +7 -7
  48. package/dist/redaction.d.ts +1 -0
  49. package/dist/redaction.js +5 -2
  50. package/dist/resources.d.ts +2 -2
  51. package/dist/resources.js +2 -2
  52. package/dist/rpc.js +42 -9
  53. package/dist/run-ledger.js +13 -4
  54. package/dist/run-limits.js +49 -10
  55. package/dist/secure-agent.js +1 -1
  56. package/dist/security.js +7 -2
  57. package/dist/session-stores.d.ts +1 -1
  58. package/dist/session-stores.js +13 -13
  59. package/dist/structured-output.js +2 -2
  60. package/dist/system-prompts.js +7 -2
  61. package/dist/testing/compaction-conformance.js +5 -1
  62. package/dist/testing/extension-conformance.js +15 -3
  63. package/dist/testing/feedback.d.ts +1 -3
  64. package/dist/testing/feedback.js +1 -1
  65. package/dist/testing/persistence-schema.js +206 -37
  66. package/dist/testing/provider-conformance.js +3 -3
  67. package/dist/testing/run-ledger-conformance.js +1 -1
  68. package/dist/testing/session-store-conformance.js +1 -1
  69. package/dist/testing/tool-conformance.js +30 -5
  70. package/dist/thinking.js +4 -1
  71. package/dist/tools.d.ts +2 -2
  72. package/dist/tools.js +24 -5
  73. package/docs/0.1.0-readiness.md +139 -0
  74. package/docs/index.md +3 -1
  75. package/docs/migration.md +29 -0
  76. package/docs/performance.md +33 -0
  77. package/docs/public-contracts.md +1 -1
  78. package/docs/release-and-install.md +106 -17
  79. package/package.json +14 -6
  80. package/docs/review-coverage-2026-07-14.md +0 -260
  81. package/docs/review-coverage-2026-07-15.md +0 -193
  82. package/docs/review-coverage-2026-07-17-provider-validation.md +0 -192
  83. package/docs/review-coverage-2026-07-19-phase-3.md +0 -174
  84. package/docs/review-coverage-2026-07-20-phase-4.md +0 -175
  85. package/docs/review-coverage-2026-07-21-phase-5.md +0 -172
  86. package/docs/review-coverage-2026-07-22-phase-6.md +0 -209
  87. package/docs/review-coverage-2026-07-22-phase-7.md +0 -173
  88. package/docs/review-coverage-2026-07-23-phase-8.md +0 -245
  89. package/docs/review-coverage-2026-07-25-phase-9.md +0 -256
  90. package/docs/review-coverage-2026-07-26-phase-10.md +0 -132
@@ -1,16 +1,16 @@
1
- import process from "node:process";
2
- import { createAgent, createMockProvider, providerDone, providerTextDelta, resolveInstructionInjectors, createContributionRegistry } from "./index.js";
3
1
  import { readFile } from "node:fs/promises";
4
2
  import { basename, dirname } from "node:path";
3
+ import process from "node:process";
4
+ import { initUsage, runInitCommand } from "./cli-init.js";
5
5
  import { createContributionRegistries, registerDiscoveredContributions } from "./contributions.js";
6
- import { createSkillRegistry } from "./skills.js";
7
- import { discoverContributions } from "./node/contribution-discovery.js";
6
+ import { createAgent, createContributionRegistry, createMockProvider, providerDone, providerTextDelta, resolveInstructionInjectors, } from "./index.js";
8
7
  import { discoverAgentBundles } from "./node/agent-definitions.js";
8
+ import { discoverContributions } from "./node/contribution-discovery.js";
9
9
  import { registerDiscoveredInstructionInjectors } from "./node/instruction-injectors.js";
10
10
  import { loadSystemPromptFiles } from "./node/system-project-prompts.js";
11
11
  import { createPathTrustPolicy } from "./node/trust.js";
12
12
  import { runRpcServer } from "./rpc.js";
13
- import { initUsage, runInitCommand } from "./cli-init.js";
13
+ import { createSkillRegistry } from "./skills.js";
14
14
  export const usage = `Usage: prism [--mode print|json|rpc] [-p prompt] [options]
15
15
  prism init <dir> [--provider <name>] [--with-workflows] [--with-evals] [--force]
16
16
 
@@ -37,7 +37,27 @@ Options:
37
37
  --system-md-file <path> Read SYSTEM.md from <path> instead (source: user)
38
38
  -h, --help Show this help
39
39
  `;
40
- const valueFlags = new Set(["--prompt", "--mode", "--provider", "--model", "--session", "--config", "--resource", "--extension", "--tool", "--system", "--context", "--compact", "--max-tool-rounds", "--discover-kinds", "--instruction", "--injector-file", "--agents-md-file", "--system-md-file", "--agents-config"]);
40
+ const valueFlags = new Set([
41
+ "--prompt",
42
+ "--mode",
43
+ "--provider",
44
+ "--model",
45
+ "--session",
46
+ "--config",
47
+ "--resource",
48
+ "--extension",
49
+ "--tool",
50
+ "--system",
51
+ "--context",
52
+ "--compact",
53
+ "--max-tool-rounds",
54
+ "--discover-kinds",
55
+ "--instruction",
56
+ "--injector-file",
57
+ "--agents-md-file",
58
+ "--system-md-file",
59
+ "--agents-config",
60
+ ]);
41
61
  const boolFlags = new Set(["--discover", "--no-discovery", "--no-agents-md", "--no-system-md"]);
42
62
  const ALL_KINDS = ["skill", "tool", "context", "instructions"];
43
63
  export function parseCliArgs(argv) {
@@ -157,10 +177,43 @@ export function parseCliArgs(argv) {
157
177
  break;
158
178
  }
159
179
  }
160
- return { mode, prompt, provider, model, session, config, resources, extensions, tools, system, context, compact, maxToolRounds, help, discover, discoverKinds, noDiscovery, agentsConfig, discoveredSkills: [], discoveredInjectors: [], discoveredAgents: [], instructions, injectorFiles, resolvedInstructionInjectors: [], noAgentsMd, noSystemMd, agentsMdFile, systemMdFile, systemPromptLayers: [] };
180
+ return {
181
+ mode,
182
+ prompt,
183
+ provider,
184
+ model,
185
+ session,
186
+ config,
187
+ resources,
188
+ extensions,
189
+ tools,
190
+ system,
191
+ context,
192
+ compact,
193
+ maxToolRounds,
194
+ help,
195
+ discover,
196
+ discoverKinds,
197
+ noDiscovery,
198
+ agentsConfig,
199
+ discoveredSkills: [],
200
+ discoveredInjectors: [],
201
+ discoveredAgents: [],
202
+ instructions,
203
+ injectorFiles,
204
+ resolvedInstructionInjectors: [],
205
+ noAgentsMd,
206
+ noSystemMd,
207
+ agentsMdFile,
208
+ systemMdFile,
209
+ systemPromptLayers: [],
210
+ };
161
211
  }
162
212
  function parseKinds(csv, flag) {
163
- const kinds = csv.split(",").map((k) => k.trim()).filter(Boolean);
213
+ const kinds = csv
214
+ .split(",")
215
+ .map((k) => k.trim())
216
+ .filter(Boolean);
164
217
  if (kinds.length === 0)
165
218
  throw new CliUsageError(`Invalid value for ${flag}: ${csv}`);
166
219
  const invalid = kinds.filter((k) => !ALL_KINDS.includes(k));
@@ -193,7 +246,12 @@ export async function runCli(argv, runtime) {
193
246
  }
194
247
  try {
195
248
  if (options.mode === "rpc") {
196
- await runRpcServer({ stdin: runtime.stdin, stdout: runtime.stdout, createSession: (id) => (runtime.createSession ?? defaultCreateSession)({ ...options, session: id ?? options.session }), commands: runtime.commands });
249
+ await runRpcServer({
250
+ stdin: runtime.stdin,
251
+ stdout: runtime.stdout,
252
+ createSession: (id) => (runtime.createSession ?? defaultCreateSession)({ ...options, session: id ?? options.session }),
253
+ commands: runtime.commands,
254
+ });
197
255
  return 0;
198
256
  }
199
257
  if (!options.prompt)
@@ -248,7 +306,12 @@ export async function runCli(argv, runtime) {
248
306
  // the containment check (the user named it, so it's trusted by that act).
249
307
  const layers = await loadSystemPromptFiles({
250
308
  ...(options.noAgentsMd ? {} : { workspaceRoot, trust, ...(options.agentsMdFile ? { agentsMdPath: options.agentsMdFile } : {}) }),
251
- ...(options.noSystemMd ? {} : { ...(runtime.globalRoot !== undefined ? { globalRoot: runtime.globalRoot } : {}), ...(options.systemMdFile ? { systemMdPath: options.systemMdFile } : {}) }),
309
+ ...(options.noSystemMd
310
+ ? {}
311
+ : {
312
+ ...(runtime.globalRoot !== undefined ? { globalRoot: runtime.globalRoot } : {}),
313
+ ...(options.systemMdFile ? { systemMdPath: options.systemMdFile } : {}),
314
+ }),
252
315
  });
253
316
  options = { ...options, systemPromptLayers: layers };
254
317
  }
@@ -306,9 +369,7 @@ function runOptions(options) {
306
369
  ...(options.discover && !options.noDiscovery && options.discoveredSkills.length > 0
307
370
  ? { activeSkills: options.discoveredSkills.map((s) => s.name) }
308
371
  : {}),
309
- ...(options.resolvedInstructionInjectors.length > 0
310
- ? { instructionInjectors: options.resolvedInstructionInjectors }
311
- : {}),
372
+ ...(options.resolvedInstructionInjectors.length > 0 ? { instructionInjectors: options.resolvedInstructionInjectors } : {}),
312
373
  };
313
374
  }
314
375
  // ponytail: resolve --instruction names against discovered injectors (fail-closed) and load
@@ -27,10 +27,11 @@ export function isCompactionEntryData(value) {
27
27
  if (!value || typeof value !== "object" || Array.isArray(value))
28
28
  return false;
29
29
  const data = value;
30
- return (data.throughEntryId === undefined || typeof data.throughEntryId === "string")
31
- && (data.keepEntryIds === undefined || (Array.isArray(data.keepEntryIds) && data.keepEntryIds.every((item) => typeof item === "string")))
32
- && (data.strategy === undefined || typeof data.strategy === "string")
33
- && (data.trigger === undefined || typeof data.trigger === "string");
30
+ return ((data.throughEntryId === undefined || typeof data.throughEntryId === "string") &&
31
+ (data.keepEntryIds === undefined ||
32
+ (Array.isArray(data.keepEntryIds) && data.keepEntryIds.every((item) => typeof item === "string"))) &&
33
+ (data.strategy === undefined || typeof data.strategy === "string") &&
34
+ (data.trigger === undefined || typeof data.trigger === "string"));
34
35
  }
35
36
  function summarize(entries) {
36
37
  const lines = entries.flatMap((entry) => entryText(entry));
package/dist/config.js CHANGED
@@ -31,9 +31,10 @@ function mergeObjects(base, override, path = "config") {
31
31
  const childPath = `${path}.${key}`;
32
32
  assertSafeJsonKey(key, childPath);
33
33
  const current = result[key];
34
- result[key] = isPlainObject(current) && isPlainObject(value)
35
- ? mergeObjects(current, value, childPath)
36
- : cloneJsonValue(value, childPath);
34
+ result[key] =
35
+ isPlainObject(current) && isPlainObject(value)
36
+ ? mergeObjects(current, value, childPath)
37
+ : cloneJsonValue(value, childPath);
37
38
  }
38
39
  return result;
39
40
  }
@@ -77,7 +78,9 @@ function isSafeJsonValue(value) {
77
78
  }
78
79
  function assertSafeJsonValue(value, path) {
79
80
  if (Array.isArray(value)) {
80
- value.forEach((entry, index) => assertSafeJsonValue(entry, `${path}[${index}]`));
81
+ value.forEach((entry, index) => {
82
+ assertSafeJsonValue(entry, `${path}[${index}]`);
83
+ });
81
84
  return;
82
85
  }
83
86
  if (!isPlainObject(value))
package/dist/content.js CHANGED
@@ -112,12 +112,12 @@ export function assertSsrfAllowedUrl(url, policy = {}) {
112
112
  }
113
113
  if (policy.denyPrivateHosts === false)
114
114
  return;
115
- if (hostname === "localhost"
116
- || hostname.endsWith(".localhost")
117
- || hostname.endsWith(".local")
118
- || hostname === "metadata"
119
- || hostname === "metadata.google.internal"
120
- || hostname === "instance-data") {
115
+ if (hostname === "localhost" ||
116
+ hostname.endsWith(".localhost") ||
117
+ hostname.endsWith(".local") ||
118
+ hostname === "metadata" ||
119
+ hostname === "metadata.google.internal" ||
120
+ hostname === "instance-data") {
121
121
  throw new MediaContentError("ssrf_denied", `Media URL host ${hostname} is not allowed`);
122
122
  }
123
123
  if (isBlockedIp(hostname)) {
@@ -306,9 +306,7 @@ async function fetchBoundedMediaUrl(url, options) {
306
306
  assertSsrfAllowedUrl(url, options.ssrf);
307
307
  const timeoutController = new AbortController();
308
308
  const timeout = setTimeout(() => timeoutController.abort(), options.timeoutMs);
309
- const signal = options.signal
310
- ? AbortSignal.any([options.signal, timeoutController.signal])
311
- : timeoutController.signal;
309
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutController.signal]) : timeoutController.signal;
312
310
  try {
313
311
  if (options.fetch)
314
312
  return await readFetchResponse(await options.fetch(url, { signal, redirect: "error" }), options.maxBytes);
@@ -372,7 +370,13 @@ async function raceAbort(promise, signal) {
372
370
  reject(signal.reason);
373
371
  };
374
372
  signal.addEventListener("abort", onAbort, { once: true });
375
- promise.then((value) => { cleanup(); resolve(value); }, (error) => { cleanup(); reject(error); });
373
+ promise.then((value) => {
374
+ cleanup();
375
+ resolve(value);
376
+ }, (error) => {
377
+ cleanup();
378
+ reject(error);
379
+ });
376
380
  });
377
381
  }
378
382
  async function readFetchResponse(response, maxBytes) {
@@ -479,22 +483,22 @@ function isBlockedIp(hostname) {
479
483
  }
480
484
  function isBlockedIpv4(address) {
481
485
  const [a, b] = address.split(".").map(Number);
482
- return a === 0
483
- || a === 10
484
- || a === 127
485
- || (a === 100 && b >= 64 && b <= 127)
486
- || (a === 169 && b === 254)
487
- || (a === 172 && b >= 16 && b <= 31)
488
- || (a === 192 && (b === 0 || b === 168))
489
- || (a === 198 && (b === 18 || b === 19 || b === 51))
490
- || (a === 203 && b === 0)
491
- || a >= 224;
486
+ return (a === 0 ||
487
+ a === 10 ||
488
+ a === 127 ||
489
+ (a === 100 && b >= 64 && b <= 127) ||
490
+ (a === 169 && b === 254) ||
491
+ (a === 172 && b >= 16 && b <= 31) ||
492
+ (a === 192 && (b === 0 || b === 168)) ||
493
+ (a === 198 && (b === 18 || b === 19 || b === 51)) ||
494
+ (a === 203 && b === 0) ||
495
+ a >= 224);
492
496
  }
493
497
  function isBlockedIpv6(address) {
494
498
  const words = parseIpv6Words(address);
495
499
  if (!words)
496
500
  return true;
497
- if (words.every((word) => word === 0) || words.slice(0, 7).every((word) => word === 0) && words[7] === 1)
501
+ if (words.every((word) => word === 0) || (words.slice(0, 7).every((word) => word === 0) && words[7] === 1))
498
502
  return true;
499
503
  if ((words[0] & 0xfe00) === 0xfc00)
500
504
  return true;
@@ -517,9 +521,7 @@ function parseIpv6Words(address) {
517
521
  if (missing < 0 || (parts.length === 1 && missing !== 0))
518
522
  return undefined;
519
523
  const words = [...left, ...Array.from({ length: missing }, () => "0"), ...right].map((part) => Number.parseInt(part, 16));
520
- return words.length === 8 && words.every((word) => Number.isInteger(word) && word >= 0 && word <= 0xffff)
521
- ? words
522
- : undefined;
524
+ return words.length === 8 && words.every((word) => Number.isInteger(word) && word >= 0 && word <= 0xffff) ? words : undefined;
523
525
  }
524
526
  function startsWith(bytes, prefix) {
525
527
  if (bytes.length < prefix.length)
@@ -197,13 +197,14 @@ function isContextBudgetReport(value) {
197
197
  if (!value || typeof value !== "object" || Array.isArray(value))
198
198
  return false;
199
199
  const report = value;
200
- return Array.isArray(report.omitted)
201
- && typeof report.keptTokens === "number"
202
- && typeof report.keptBytes === "number"
203
- && typeof report.truncated === "boolean";
200
+ return (Array.isArray(report.omitted) &&
201
+ typeof report.keptTokens === "number" &&
202
+ typeof report.keptBytes === "number" &&
203
+ typeof report.truncated === "boolean");
204
204
  }
205
205
  function messageText(message) {
206
- return message.content.map((part) => {
206
+ return message.content
207
+ .map((part) => {
207
208
  if (part.type === "text" || part.type === "thinking")
208
209
  return part.text;
209
210
  if (part.type === "tool_result")
@@ -221,15 +222,18 @@ function messageText(message) {
221
222
  if (part.type === "document")
222
223
  return part.transcript ?? part.name ?? part.url ?? part.resourceUri ?? part.mediaType ?? "[document]";
223
224
  return "[content]";
224
- }).join("\n");
225
+ })
226
+ .join("\n");
225
227
  }
226
228
  function contextBlockText(block) {
227
229
  if (typeof block.content === "string")
228
230
  return block.content;
229
- return block.content.map((part) => {
231
+ return block.content
232
+ .map((part) => {
230
233
  if (part.type === "text" || part.type === "thinking")
231
234
  return part.text;
232
235
  return "[content]";
233
- }).join("\n");
236
+ })
237
+ .join("\n");
234
238
  }
235
239
  //# sourceMappingURL=context-budget.js.map
@@ -1,11 +1,11 @@
1
- import type { AgentInput } from "./input.js";
1
+ import type { AudioContent, DocumentContent, FileContent } from "./content.js";
2
2
  import type { ContributionRegistries } from "./contributions.js";
3
+ import type { AgentInput } from "./input.js";
4
+ import type { ManifestContributionDeclaration } from "./manifests.js";
3
5
  import type { Middleware, MiddlewareHookName, MiddlewareRegistry } from "./middleware.js";
4
6
  import type { SecretRedactor } from "./redaction.js";
5
7
  import type { PermissionPolicy, TrustPolicy } from "./security.js";
6
- import type { ManifestContributionDeclaration } from "./manifests.js";
7
8
  import type { ToolValidator } from "./tools.js";
8
- import type { AudioContent, DocumentContent, FileContent } from "./content.js";
9
9
  export type JsonPrimitive = string | number | boolean | null;
10
10
  export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
11
11
  export interface JsonObject {
package/dist/contracts.js CHANGED
@@ -1,6 +1,9 @@
1
1
  export class AgentRunStateError extends Error {
2
2
  code = "ERR_PRISM_AGENT_RUN_STATE";
3
- constructor(message) { super(message); this.name = "AgentRunStateError"; }
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "AgentRunStateError";
6
+ }
4
7
  }
5
8
  export class AgentRunError extends Error {
6
9
  result;
@@ -50,7 +50,11 @@ function parseFrontBlock(lines) {
50
50
  out.set(key, items);
51
51
  }
52
52
  else if (value.startsWith("[") && value.endsWith("]")) {
53
- out.set(key, value.slice(1, -1).split(",").map((s) => s.trim()).filter((s) => s.length > 0));
53
+ out.set(key, value
54
+ .slice(1, -1)
55
+ .split(",")
56
+ .map((s) => s.trim())
57
+ .filter((s) => s.length > 0));
54
58
  }
55
59
  else {
56
60
  out.set(key, value);
@@ -63,7 +67,7 @@ function parseFrontBlock(lines) {
63
67
  // plain string split instead of `node:path`. Expects `.../<name>/SKILL.md`.
64
68
  function parentDirName(path) {
65
69
  const parts = path.split(/[/\\]+/).filter(Boolean);
66
- return parts.length >= 2 ? parts[parts.length - 2] : parts[parts.length - 1] ?? "";
70
+ return parts.length >= 2 ? parts[parts.length - 2] : (parts[parts.length - 1] ?? "");
67
71
  }
68
72
  const NAME_RE = /^[A-Za-z0-9 _-]+$/;
69
73
  /** Parse a `SKILL.md` into a {@link Skill}. Frontmatter keys map to `name`
@@ -56,7 +56,8 @@ export function conversationThreadFromRecord(record) {
56
56
  const branches = [];
57
57
  if (Array.isArray(value.branches)) {
58
58
  for (const item of value.branches) {
59
- if (item && typeof item === "object" &&
59
+ if (item &&
60
+ typeof item === "object" &&
60
61
  typeof item.leafId === "string" &&
61
62
  typeof item.createdAt === "string") {
62
63
  branches.push({
@@ -1,4 +1,4 @@
1
- import type { Credential, CredentialResolver, CredentialRequest, CredentialResolverSource, OAuthCredentialStore, OAuthCredentials, OAuthProvider } from "./contracts.js";
1
+ import type { Credential, CredentialRequest, CredentialResolver, CredentialResolverSource, OAuthCredentialStore, OAuthCredentials, OAuthProvider } from "./contracts.js";
2
2
  export type CredentialValueSource = string | (() => string | undefined | Promise<string | undefined>) | CredentialResolver;
3
3
  export interface CredentialRecord {
4
4
  readonly name: string;
@@ -37,7 +37,9 @@ export function createExplicitCredentialResolver(sources) {
37
37
  export function createEnvCredentialResolver(env, map) {
38
38
  return {
39
39
  resolve(request) {
40
- const envName = map[credentialMapKey(request.name, request.provider)] ?? (request.provider ? map[request.provider] : undefined) ?? map[request.name];
40
+ const envName = map[credentialMapKey(request.name, request.provider)] ??
41
+ (request.provider ? map[request.provider] : undefined) ??
42
+ map[request.name];
41
43
  const value = envName ? env[envName] : undefined;
42
44
  return value ? { type: "api_key", value, metadata: { source: "env", envName } } : undefined;
43
45
  },
@@ -27,9 +27,7 @@ export function createEventMultiplexer(options = {}) {
27
27
  return;
28
28
  }
29
29
  droppedEvents += 1;
30
- const notice = !overflowNotified && options.overflowEvent
31
- ? options.overflowEvent({ droppedEvents, maxQueuedEvents, policy: overflow })
32
- : undefined;
30
+ const notice = !overflowNotified && options.overflowEvent ? options.overflowEvent({ droppedEvents, maxQueuedEvents, policy: overflow }) : undefined;
33
31
  overflowNotified = true;
34
32
  if (overflow === "close") {
35
33
  queue.length = 0;
package/dist/feedback.js CHANGED
@@ -48,10 +48,14 @@ export async function prepareRunFeedback(input, options) {
48
48
  const tags = normalizeList(input.tags, maxTags, MAX_FEEDBACK_TAG_LENGTH, "tag");
49
49
  const scorerIds = normalizeList(input.scorerIds, maxLinks, MAX_FEEDBACK_ID_LENGTH, "scorer id", true);
50
50
  const evaluationIds = normalizeList(input.evaluationIds, maxLinks, MAX_FEEDBACK_ID_LENGTH, "evaluation id", true);
51
- if (input.rating === undefined && input.comment === undefined && tags.length === 0 && scorerIds.length === 0 && evaluationIds.length === 0) {
51
+ if (input.rating === undefined &&
52
+ input.comment === undefined &&
53
+ tags.length === 0 &&
54
+ scorerIds.length === 0 &&
55
+ evaluationIds.length === 0) {
52
56
  throw new RunFeedbackError("feedback requires rating, comment, tag, scorer, or evaluation", "ERR_PRISM_RUN_FEEDBACK_EMPTY");
53
57
  }
54
- const redact = (value) => options.redactor ? options.redactor.redact(value) : value;
58
+ const redact = (value) => (options.redactor ? options.redactor.redact(value) : value);
55
59
  const comment = input.comment === undefined ? undefined : redact(input.comment);
56
60
  const safeTags = Object.freeze(normalizeList(redact(tags), maxTags, MAX_FEEDBACK_TAG_LENGTH, "tag"));
57
61
  const metadata = input.metadata === undefined ? undefined : redact(input.metadata);
@@ -121,18 +125,16 @@ export function runFeedbackPageLimit(limit, maximum = HARD_FEEDBACK_PAGE_SIZE) {
121
125
  return pageLimit(limit, maximum);
122
126
  }
123
127
  function requireOwnership(input) {
124
- if (!input.tenantId?.trim()
125
- || (input.accountId !== undefined && !input.accountId.trim())
126
- || (input.userId !== undefined && !input.userId.trim())
127
- || (!input.accountId && !input.userId)) {
128
+ if (!input.tenantId?.trim() ||
129
+ (input.accountId !== undefined && !input.accountId.trim()) ||
130
+ (input.userId !== undefined && !input.userId.trim()) ||
131
+ (!input.accountId && !input.userId)) {
128
132
  throw new RunFeedbackError("tenantId and non-empty accountId or userId are required", "ERR_PRISM_RUN_FEEDBACK_OWNERSHIP");
129
133
  }
130
134
  return { tenantId: input.tenantId, accountId: input.accountId, userId: input.userId };
131
135
  }
132
136
  function sameOwnership(expected, actual) {
133
- return expected.tenantId === actual.tenantId
134
- && expected.accountId === actual.accountId
135
- && expected.userId === actual.userId;
137
+ return expected.tenantId === actual.tenantId && expected.accountId === actual.accountId && expected.userId === actual.userId;
136
138
  }
137
139
  function requireId(value, label) {
138
140
  if (!value || value.length > MAX_FEEDBACK_ID_LENGTH || !/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(value)) {
@@ -1,4 +1,4 @@
1
- import type { AgentEvent, GuardrailContext, GuardrailRecord, Guardrails, GuardrailStage, GuardrailValue } from "./contracts.js";
1
+ import type { AgentEvent, GuardrailContext, GuardrailRecord, GuardrailStage, Guardrails, GuardrailValue } from "./contracts.js";
2
2
  import type { SecretRedactor } from "./redaction.js";
3
3
  export declare const MAX_GUARDRAIL_CONCURRENCY = 16;
4
4
  export declare class GuardrailError extends Error {
@@ -7,9 +7,7 @@ export class GuardrailError extends Error {
7
7
  constructor(record) {
8
8
  super(record.action === "interrupt" ? "Guardrail interruption is unavailable" : "Guardrail blocked run");
9
9
  this.name = "GuardrailError";
10
- this.code = record.action === "interrupt"
11
- ? "ERR_PRISM_GUARDRAIL_INTERRUPT_UNAVAILABLE"
12
- : "ERR_PRISM_GUARDRAIL_BLOCKED";
10
+ this.code = record.action === "interrupt" ? "ERR_PRISM_GUARDRAIL_INTERRUPT_UNAVAILABLE" : "ERR_PRISM_GUARDRAIL_BLOCKED";
13
11
  this.record = record;
14
12
  }
15
13
  }
@@ -20,9 +18,7 @@ export async function runGuardrails(options) {
20
18
  return { records: [] };
21
19
  const maxConcurrency = resolveConcurrency(options.guardrails?.maxConcurrency);
22
20
  const controller = new AbortController();
23
- const signal = options.context.signal
24
- ? AbortSignal.any([options.context.signal, controller.signal])
25
- : controller.signal;
21
+ const signal = options.context.signal ? AbortSignal.any([options.context.signal, controller.signal]) : controller.signal;
26
22
  const records = new Array(guards.length);
27
23
  let next = 0;
28
24
  let stopped = false;
@@ -66,14 +62,23 @@ function stageGuards(guardrails, stage) {
66
62
  if (!guardrails)
67
63
  return [];
68
64
  switch (stage) {
69
- case "input": return (guardrails.input ?? []);
70
- case "output": return (guardrails.output ?? []);
71
- case "tool_input": return (guardrails.toolInput ?? []);
72
- case "tool_output": return (guardrails.toolOutput ?? []);
65
+ case "input":
66
+ return (guardrails.input ?? []);
67
+ case "output":
68
+ return (guardrails.output ?? []);
69
+ case "tool_input":
70
+ return (guardrails.toolInput ?? []);
71
+ case "tool_output":
72
+ return (guardrails.toolOutput ?? []);
73
73
  }
74
74
  }
75
75
  async function evaluate(guardrail, options, signal) {
76
- if (!guardrail || typeof guardrail.name !== "string" || !guardrail.name || guardrail.name.length > 128 || guardrail.stage !== options.stage || typeof guardrail.evaluate !== "function") {
76
+ if (!guardrail ||
77
+ typeof guardrail.name !== "string" ||
78
+ !guardrail.name ||
79
+ guardrail.name.length > 128 ||
80
+ guardrail.stage !== options.stage ||
81
+ typeof guardrail.evaluate !== "function") {
77
82
  return record(guardrail?.name ?? "invalid", options.stage, "tripwire", "guardrail_invalid", undefined, options.redactor);
78
83
  }
79
84
  try {
@@ -115,9 +120,7 @@ function boundedMetadata(value, redactor) {
115
120
  if (!json || byteLength(json) > MAX_METADATA_BYTES)
116
121
  return { truncated: true };
117
122
  const parsed = JSON.parse(json);
118
- return parsed && typeof parsed === "object" && !Array.isArray(parsed)
119
- ? parsed
120
- : undefined;
123
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : undefined;
121
124
  }
122
125
  catch {
123
126
  return { invalid: true };
package/dist/identity.js CHANGED
@@ -104,9 +104,17 @@ export function narrowIdentity(parent, options) {
104
104
  scopes: Object.freeze([...options.scopes]),
105
105
  credentialRefs: Object.freeze([...(options.credentialRefs ?? parent.credentialRefs ?? [])]),
106
106
  issuedAt: parent.issuedAt,
107
- ...(options.expiresAt !== undefined ? { expiresAt: options.expiresAt } : parent.expiresAt !== undefined ? { expiresAt: parent.expiresAt } : {}),
107
+ ...(options.expiresAt !== undefined
108
+ ? { expiresAt: options.expiresAt }
109
+ : parent.expiresAt !== undefined
110
+ ? { expiresAt: parent.expiresAt }
111
+ : {}),
108
112
  ...(parent.revokedAt !== undefined ? { revokedAt: parent.revokedAt } : {}),
109
- ...(options.metadata !== undefined ? { metadata: options.metadata } : parent.metadata !== undefined ? { metadata: parent.metadata } : {}),
113
+ ...(options.metadata !== undefined
114
+ ? { metadata: options.metadata }
115
+ : parent.metadata !== undefined
116
+ ? { metadata: parent.metadata }
117
+ : {}),
110
118
  verified: true,
111
119
  };
112
120
  assertIdentityActive(child, { limits: options.limits });