@node-llm/core 1.17.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +1 -0
  2. package/dist/agent/Agent.d.ts +24 -11
  3. package/dist/agent/Agent.d.ts.map +1 -1
  4. package/dist/agent/Agent.js +1 -3
  5. package/dist/aliases.d.ts +826 -467
  6. package/dist/aliases.d.ts.map +1 -1
  7. package/dist/aliases.js +881 -522
  8. package/dist/chat/Chat.d.ts +14 -10
  9. package/dist/chat/Chat.d.ts.map +1 -1
  10. package/dist/chat/Chat.js +20 -5
  11. package/dist/chat/ChatOptions.d.ts +12 -11
  12. package/dist/chat/ChatOptions.d.ts.map +1 -1
  13. package/dist/chat/Tool.d.ts +26 -5
  14. package/dist/chat/Tool.d.ts.map +1 -1
  15. package/dist/chat/Tool.js +25 -3
  16. package/dist/chat/ToolCallOutcome.d.ts +6 -6
  17. package/dist/chat/ToolCallOutcome.d.ts.map +1 -1
  18. package/dist/chat/ToolHandler.d.ts +2 -2
  19. package/dist/chat/ToolHandler.d.ts.map +1 -1
  20. package/dist/chat/ToolHandler.js +15 -1
  21. package/dist/config.d.ts +12 -2
  22. package/dist/config.d.ts.map +1 -1
  23. package/dist/config.js +18 -1
  24. package/dist/constants.d.ts +8 -0
  25. package/dist/constants.d.ts.map +1 -1
  26. package/dist/constants.js +6 -1
  27. package/dist/errors/index.d.ts +3 -1
  28. package/dist/errors/index.d.ts.map +1 -1
  29. package/dist/errors/index.js +4 -1
  30. package/dist/executor/Executor.d.ts +6 -0
  31. package/dist/executor/Executor.d.ts.map +1 -1
  32. package/dist/executor/Executor.js +19 -2
  33. package/dist/index.d.ts +9 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +3 -0
  36. package/dist/judge/Judge.d.ts +107 -0
  37. package/dist/judge/Judge.d.ts.map +1 -0
  38. package/dist/judge/Judge.js +104 -0
  39. package/dist/judge/Judgment.d.ts +116 -0
  40. package/dist/judge/Judgment.d.ts.map +1 -0
  41. package/dist/judge/Judgment.js +159 -0
  42. package/dist/judge/Question.d.ts +91 -0
  43. package/dist/judge/Question.d.ts.map +1 -0
  44. package/dist/judge/Question.js +180 -0
  45. package/dist/llm.d.ts +46 -0
  46. package/dist/llm.d.ts.map +1 -1
  47. package/dist/llm.js +105 -5
  48. package/dist/models/ModelRegistry.d.ts +11 -18
  49. package/dist/models/ModelRegistry.d.ts.map +1 -1
  50. package/dist/models/ModelRegistry.js +6 -0
  51. package/dist/models/models.json +16534 -10534
  52. package/dist/providers/BaseProvider.d.ts +2 -1
  53. package/dist/providers/BaseProvider.d.ts.map +1 -1
  54. package/dist/providers/BaseProvider.js +3 -0
  55. package/dist/providers/Provider.d.ts +37 -0
  56. package/dist/providers/Provider.d.ts.map +1 -1
  57. package/dist/providers/anthropic/Models.d.ts.map +1 -1
  58. package/dist/providers/anthropic/Models.js +4 -2
  59. package/dist/providers/deepseek/Models.d.ts.map +1 -1
  60. package/dist/providers/deepseek/Models.js +4 -2
  61. package/dist/providers/gemini/Embeddings.d.ts.map +1 -1
  62. package/dist/providers/gemini/Embeddings.js +4 -2
  63. package/dist/providers/gemini/Image.d.ts.map +1 -1
  64. package/dist/providers/gemini/Image.js +4 -2
  65. package/dist/providers/gemini/Models.d.ts.map +1 -1
  66. package/dist/providers/gemini/Models.js +4 -2
  67. package/dist/providers/gemini/Transcription.d.ts.map +1 -1
  68. package/dist/providers/gemini/Transcription.js +4 -2
  69. package/dist/providers/mistral/Embedding.d.ts.map +1 -1
  70. package/dist/providers/mistral/Embedding.js +4 -2
  71. package/dist/providers/mistral/Models.d.ts.map +1 -1
  72. package/dist/providers/mistral/Models.js +4 -2
  73. package/dist/providers/openai/Models.d.ts.map +1 -1
  74. package/dist/providers/openai/Models.js +4 -2
  75. package/dist/providers/openrouter/Models.d.ts.map +1 -1
  76. package/dist/providers/openrouter/Models.js +4 -2
  77. package/dist/providers/registry.d.ts +2 -1
  78. package/dist/providers/registry.d.ts.map +1 -1
  79. package/dist/providers/registry.js +2 -1
  80. package/dist/providers/typesafe/SystemOne.d.ts +11 -0
  81. package/dist/providers/typesafe/SystemOne.d.ts.map +1 -0
  82. package/dist/providers/typesafe/SystemOne.js +171 -0
  83. package/dist/providers/typesafe/TypeSafeProvider.d.ts +27 -0
  84. package/dist/providers/typesafe/TypeSafeProvider.d.ts.map +1 -0
  85. package/dist/providers/typesafe/TypeSafeProvider.js +76 -0
  86. package/dist/providers/typesafe/index.d.ts +4 -0
  87. package/dist/providers/typesafe/index.d.ts.map +1 -0
  88. package/dist/providers/typesafe/index.js +19 -0
  89. package/dist/types/Middleware.d.ts +9 -0
  90. package/dist/types/Middleware.d.ts.map +1 -1
  91. package/dist/utils/Binary.d.ts.map +1 -1
  92. package/dist/utils/Binary.js +11 -0
  93. package/dist/utils/FileLoader.d.ts.map +1 -1
  94. package/dist/utils/FileLoader.js +21 -2
  95. package/dist/utils/logger.d.ts.map +1 -1
  96. package/dist/utils/logger.js +8 -1
  97. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAMhC;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,QAAQ;aAGlB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,OAAO;aACb,QAAQ,CAAC,EAAE,MAAM;aACjB,KAAK,CAAC,EAAE,MAAM;gBAJ9B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,KAAK,CAAC,EAAE,MAAM,YAAA;CAIjC;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9E;AAED;;GAEG;AACH,qBAAa,0BAA2B,SAAQ,eAAe;gBACjD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9E;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM;CAI9D;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM;CAI9D;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM;CAI9D;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM;CAI9E;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9E;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,cAAc;gBAC5C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9E;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,QAAQ;gBAC3B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9F;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,WAAW;gBAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9F;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,QAAQ;gBAEvC,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAY,EACpB,IAAI,GAAE,OAAc,EACpB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM;CAKjB;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAI9E;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM;CAG5B;AAED;;GAEG;AACH,qBAAa,0BAA2B,SAAQ,QAAQ;;CAIvD;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,QAAQ;aAEjC,QAAQ,EAAE,MAAM;aAChB,OAAO,EAAE,MAAM;gBADf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM;CAIlC;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;aAE9B,KAAK,EAAE,MAAM;aACb,UAAU,EAAE,MAAM;gBADlB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM;CAIrC;AACD;;GAEG;AACH,qBAAa,SAAU,SAAQ,QAAQ;aAGnB,QAAQ,CAAC,EAAE,MAAM;aACjB,KAAK,EAAE,OAAO;gBAF9B,OAAO,EAAE,MAAM,EACC,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,KAAK,GAAE,OAAe;CAKzC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"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"}
@@ -99,9 +99,12 @@ export class AuthenticationError extends APIError {
99
99
  * 429 - Rate limit exceeded
100
100
  */
101
101
  export class RateLimitError extends APIError {
102
- constructor(message, body, provider, model) {
102
+ /** Seconds to wait before retrying, parsed from a `Retry-After` response header when present. */
103
+ retryAfter;
104
+ constructor(message, body, provider, model, retryAfter) {
103
105
  super(message, 429, body, provider, model);
104
106
  this.name = "RateLimitError";
107
+ this.retryAfter = retryAfter;
105
108
  }
106
109
  }
107
110
  /**
@@ -7,5 +7,11 @@ export declare class Executor {
7
7
  delayMs: number;
8
8
  });
9
9
  executeChat(request: ChatRequest): Promise<ChatResponse>;
10
+ /**
11
+ * Computes the wait before the next retry. Honors a server-provided
12
+ * `Retry-After` (via RateLimitError.retryAfter) when present; otherwise uses
13
+ * exponential backoff with full jitter to avoid synchronized retry storms.
14
+ */
15
+ private backoffDelay;
10
16
  }
11
17
  //# sourceMappingURL=Executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Executor.d.ts","sourceRoot":"","sources":["../../src/executor/Executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG/E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAGzD,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA4B/D"}
1
+ {"version":3,"file":"Executor.d.ts","sourceRoot":"","sources":["../../src/executor/Executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG/E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAGzD,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA8B9D;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAYrB"}
@@ -22,11 +22,28 @@ export class Executor {
22
22
  if (!isRetryable || attempt >= this.retry.attempts) {
23
23
  throw error;
24
24
  }
25
- if (this.retry.delayMs > 0) {
26
- await new Promise((r) => setTimeout(r, this.retry.delayMs));
25
+ const delay = this.backoffDelay(attempt, error);
26
+ if (delay > 0) {
27
+ await new Promise((r) => setTimeout(r, delay));
27
28
  }
28
29
  }
29
30
  }
30
31
  throw lastError;
31
32
  }
33
+ /**
34
+ * Computes the wait before the next retry. Honors a server-provided
35
+ * `Retry-After` (via RateLimitError.retryAfter) when present; otherwise uses
36
+ * exponential backoff with full jitter to avoid synchronized retry storms.
37
+ */
38
+ backoffDelay(attempt, error) {
39
+ if (error instanceof RateLimitError && typeof error.retryAfter === "number") {
40
+ return Math.max(0, error.retryAfter * 1000);
41
+ }
42
+ const base = this.retry.delayMs > 0 ? this.retry.delayMs : 0;
43
+ if (base === 0)
44
+ return 0;
45
+ // Exponential: base * 2^(attempt-1), capped at 30s, with full jitter.
46
+ const exponential = Math.min(base * 2 ** (attempt - 1), 30_000);
47
+ return Math.floor(Math.random() * exponential);
48
+ }
32
49
  }
package/dist/index.d.ts CHANGED
@@ -8,7 +8,13 @@ export * from "./chat/ChatStream.js";
8
8
  export * from "./streaming/Stream.js";
9
9
  export * from "./errors/index.js";
10
10
  export { Agent, defineAgent } from "./agent/Agent.js";
11
- export type { AgentConfig } from "./agent/Agent.js";
11
+ export { Judge, defineJudge } from "./judge/Judge.js";
12
+ export type { JudgeCallOptions, QuestionsOf } from "./judge/Judge.js";
13
+ export { probability, choice, score } from "./judge/Question.js";
14
+ export type { Description, JsonValue, ProbabilityCriteria, ProbabilityQuestion, ChoiceQuestion, ScoreQuestion, QuestionDefinition, QuestionMap } from "./judge/Question.js";
15
+ export { Judgment, ProbabilityAnswer, ChoiceAnswer, ScoreAnswer } from "./judge/Judgment.js";
16
+ export type { Answer, AnswerFor, AnswersOf, JudgmentResult } from "./judge/Judgment.js";
17
+ export type { AgentConfig, DefinedAgent } from "./agent/Agent.js";
12
18
  export type { Middleware, MiddlewareContext } from "./types/Middleware.js";
13
19
  export * from "./middlewares/index.js";
14
20
  export { z } from "zod";
@@ -18,9 +24,10 @@ export type { NodeLLMConfig } from "./config.js";
18
24
  export { providerRegistry, ProviderInterceptor } from "./providers/registry.js";
19
25
  export { Schema } from "./schema/Schema.js";
20
26
  export { BaseProvider } from "./providers/BaseProvider.js";
21
- export { Provider, ProviderCapabilities, ChatRequest, ChatResponse, ChatChunk, ThinkingConfig, ThinkingResult, Usage, ImageRequest, ImageResponse, TranscriptionRequest, TranscriptionResponse, TranscriptionSegment, TranscriptionWord, ModerationRequest, ModerationResponse, ModerationResult, EmbeddingRequest, EmbeddingResponse, ToolChoice } from "./providers/Provider.js";
27
+ export { Provider, ProviderCapabilities, ChatRequest, ChatResponse, ChatChunk, ThinkingConfig, ThinkingResult, Usage, ImageRequest, ImageResponse, TranscriptionRequest, TranscriptionResponse, TranscriptionSegment, TranscriptionWord, ModerationRequest, ModerationResponse, ModerationResult, EmbeddingRequest, EmbeddingResponse, JudgmentRequest, JudgmentResponse, JudgmentInput, JudgmentAnswerData, ToolChoice } from "./providers/Provider.js";
22
28
  export { resolveModelAlias } from "./model_aliases.js";
23
29
  export { default as MODEL_ALIASES } from "./aliases.js";
30
+ export type { ToolExecutionModeInput } from "./constants.js";
24
31
  export { ToolExecutionMode, DEFAULT_MAX_TOOL_CALLS, DEFAULT_MAX_RETRIES, DEFAULT_TOOL_EXECUTION, DEFAULT_OLLAMA_BASE_URL, DEFAULT_MODELS } from "./constants.js";
25
32
  export { fetchWithTimeout } from "./utils/fetch.js";
26
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,OAAO,EACP,aAAa,EACb,SAAS,EACT,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,EACT,aAAa,EACb,eAAe,EAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,cAAc,EACd,cAAc,EACd,KAAK,EACL,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EACV,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC7F,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxF,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,cAAc,wBAAwB,CAAC;AAEvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,OAAO,EACP,aAAa,EACb,SAAS,EACT,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,EACT,aAAa,EACb,eAAe,EAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,cAAc,EACd,cAAc,EACd,KAAK,EACL,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -8,6 +8,9 @@ export * from "./chat/ChatStream.js";
8
8
  export * from "./streaming/Stream.js";
9
9
  export * from "./errors/index.js";
10
10
  export { Agent, defineAgent } from "./agent/Agent.js";
11
+ export { Judge, defineJudge } from "./judge/Judge.js";
12
+ export { probability, choice, score } from "./judge/Question.js";
13
+ export { Judgment, ProbabilityAnswer, ChoiceAnswer, ScoreAnswer } from "./judge/Judgment.js";
11
14
  export * from "./middlewares/index.js";
12
15
  export { z } from "zod";
13
16
  export { NodeLLM, LegacyNodeLLM, createLLM, NodeLLMCore, Transcription, Moderation, Embedding, ModelRegistry, PricingRegistry } from "./llm.js";
@@ -0,0 +1,107 @@
1
+ import { NodeLLMCore } from "../llm.js";
2
+ import { JudgmentInput } from "../providers/Provider.js";
3
+ import { LazyValue } from "../agent/Agent.js";
4
+ import { QuestionMap } from "./Question.js";
5
+ import { JudgmentResult } from "./Judgment.js";
6
+ /** The questions a Judge class declares, once resolved. */
7
+ export type QuestionsOf<T> = T extends {
8
+ questions: infer Q;
9
+ } ? Q extends (...args: never[]) => infer R ? R extends QuestionMap ? R : never : Q extends QuestionMap ? Q : never : never;
10
+ export interface JudgeCallOptions<I = Record<string, unknown>> {
11
+ /** Values for the inputs the judge declares; available to lazy settings. */
12
+ inputs?: I;
13
+ /** Overrides the judge's model for this call. */
14
+ model?: string;
15
+ /** Overrides the judge's provider for this call. */
16
+ provider?: string;
17
+ /** Merged over the judge's own providerOptions. */
18
+ providerOptions?: Record<string, unknown>;
19
+ requestTimeout?: number;
20
+ /** The NodeLLM instance to judge with. Defaults to the global NodeLLM. */
21
+ llm?: NodeLLMCore;
22
+ }
23
+ /**
24
+ * A reusable set of typed questions about your application data.
25
+ *
26
+ * Subclass it and declare `questions`; call `judge` with the input. Answers are
27
+ * typed from the declaration, so a choice's answer is a union of its options.
28
+ *
29
+ * @example
30
+ * class TicketTriage extends Judge {
31
+ * static questions = {
32
+ * urgent: probability("Does this need attention today?"),
33
+ * department: choice("Which team should handle this?", {
34
+ * billing: "Payments and refunds",
35
+ * technical: "Bugs and integrations",
36
+ * other: null
37
+ * }),
38
+ * frustration: score("How frustrated is the customer?", ["Calm", "Frustrated", "Angry"])
39
+ * };
40
+ * }
41
+ *
42
+ * const judgment = await TicketTriage.judge("Please refund the duplicate charge today.");
43
+ * judgment.urgent.probability; // number
44
+ * judgment.department.choice; // "billing" | "technical" | "other"
45
+ *
46
+ * Settings can depend on runtime data. Declare the inputs a judge needs and
47
+ * pass them to `judge`; `questions`, `model` and `providerOptions` may be
48
+ * functions of those inputs, resolved once per judgment.
49
+ *
50
+ * @example
51
+ * class TeamRouter extends Judge {
52
+ * static inputs = ["teams"] as const;
53
+ * static questions = ({ teams }: { teams: Team[] }) => ({
54
+ * team: choice("Which team should handle this?",
55
+ * Object.fromEntries(teams.map((t) => [t.slug, t.description])))
56
+ * });
57
+ * }
58
+ * await TeamRouter.judge(ticket.body, { inputs: { teams } });
59
+ */
60
+ export declare abstract class Judge {
61
+ /** The judgment model. Defaults to the instance default, then `jev-latest`. */
62
+ static model?: LazyValue<string, never>;
63
+ /** Routes to a specific provider; normally inferred from the model. */
64
+ static provider?: string;
65
+ /** Names of the inputs `judge` must be given. */
66
+ static inputs?: readonly string[];
67
+ /** The questions, or a function of the declared inputs returning them. */
68
+ static questions: LazyValue<QuestionMap, never>;
69
+ /** Provider-specific request fields, or a function of the inputs. */
70
+ static providerOptions?: LazyValue<Record<string, unknown>, never>;
71
+ /**
72
+ * Judges the input and returns typed answers. The input is text, an object,
73
+ * or an array of JSON-compatible values - or a function of the inputs that
74
+ * returns one.
75
+ */
76
+ static judge<T extends typeof Judge, I extends Record<string, unknown> = Record<string, unknown>>(this: T, input: LazyValue<JudgmentInput, I>, options?: JudgeCallOptions<I>): Promise<JudgmentResult<QuestionsOf<T>>>;
77
+ }
78
+ /**
79
+ * Defines a judge without a class, mirroring `defineAgent`.
80
+ *
81
+ * @example
82
+ * const Urgency = defineJudge({
83
+ * questions: { urgent: probability("Does this need attention today?") }
84
+ * });
85
+ * (await Urgency.judge("The site is down")).urgent.probability;
86
+ */
87
+ export declare function defineJudge<const Q extends QuestionMap>(definition: {
88
+ questions: LazyValue<Q, never>;
89
+ model?: LazyValue<string, never>;
90
+ provider?: string;
91
+ inputs?: readonly string[];
92
+ providerOptions?: LazyValue<Record<string, unknown>, never>;
93
+ }): {
94
+ new (): {};
95
+ questions: LazyValue<Q, never>;
96
+ model: LazyValue<string, never> | undefined;
97
+ provider: string | undefined;
98
+ inputs: readonly string[] | undefined;
99
+ providerOptions: LazyValue<Record<string, unknown>, never> | undefined;
100
+ /**
101
+ * Judges the input and returns typed answers. The input is text, an object,
102
+ * or an array of JSON-compatible values - or a function of the inputs that
103
+ * returns one.
104
+ */
105
+ judge<T extends typeof Judge, I extends Record<string, unknown> = Record<string, unknown>>(this: T, input: LazyValue<JudgmentInput, I>, options?: JudgeCallOptions<I>): Promise<JudgmentResult<QuestionsOf<T>>>;
106
+ };
107
+ //# sourceMappingURL=Judge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Judge.d.ts","sourceRoot":"","sources":["../../src/judge/Judge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { NodeLLM } from "../llm.js";
2
+ /**
3
+ * A reusable set of typed questions about your application data.
4
+ *
5
+ * Subclass it and declare `questions`; call `judge` with the input. Answers are
6
+ * typed from the declaration, so a choice's answer is a union of its options.
7
+ *
8
+ * @example
9
+ * class TicketTriage extends Judge {
10
+ * static questions = {
11
+ * urgent: probability("Does this need attention today?"),
12
+ * department: choice("Which team should handle this?", {
13
+ * billing: "Payments and refunds",
14
+ * technical: "Bugs and integrations",
15
+ * other: null
16
+ * }),
17
+ * frustration: score("How frustrated is the customer?", ["Calm", "Frustrated", "Angry"])
18
+ * };
19
+ * }
20
+ *
21
+ * const judgment = await TicketTriage.judge("Please refund the duplicate charge today.");
22
+ * judgment.urgent.probability; // number
23
+ * judgment.department.choice; // "billing" | "technical" | "other"
24
+ *
25
+ * Settings can depend on runtime data. Declare the inputs a judge needs and
26
+ * pass them to `judge`; `questions`, `model` and `providerOptions` may be
27
+ * functions of those inputs, resolved once per judgment.
28
+ *
29
+ * @example
30
+ * class TeamRouter extends Judge {
31
+ * static inputs = ["teams"] as const;
32
+ * static questions = ({ teams }: { teams: Team[] }) => ({
33
+ * team: choice("Which team should handle this?",
34
+ * Object.fromEntries(teams.map((t) => [t.slug, t.description])))
35
+ * });
36
+ * }
37
+ * await TeamRouter.judge(ticket.body, { inputs: { teams } });
38
+ */
39
+ export class Judge {
40
+ /** The judgment model. Defaults to the instance default, then `jev-latest`. */
41
+ static model;
42
+ /** Routes to a specific provider; normally inferred from the model. */
43
+ static provider;
44
+ /** Names of the inputs `judge` must be given. */
45
+ static inputs;
46
+ /** The questions, or a function of the declared inputs returning them. */
47
+ static questions;
48
+ /** Provider-specific request fields, or a function of the inputs. */
49
+ static providerOptions;
50
+ /**
51
+ * Judges the input and returns typed answers. The input is text, an object,
52
+ * or an array of JSON-compatible values - or a function of the inputs that
53
+ * returns one.
54
+ */
55
+ static async judge(input, options = {}) {
56
+ const inputs = (options.inputs ?? {});
57
+ checkInputs(this, inputs);
58
+ const resolve = (value) => typeof value === "function" ? value(inputs) : value;
59
+ const questions = resolve(this.questions);
60
+ if (!questions) {
61
+ throw new Error(`${this.name} declares no questions`);
62
+ }
63
+ const declaredOptions = resolve(this.providerOptions);
64
+ const providerOptions = declaredOptions || options.providerOptions
65
+ ? { ...declaredOptions, ...options.providerOptions }
66
+ : undefined;
67
+ const llm = options.llm ?? NodeLLM;
68
+ return llm.judge(resolve(input), {
69
+ questions: questions,
70
+ model: options.model ?? resolve(this.model),
71
+ provider: options.provider ?? this.provider,
72
+ providerOptions,
73
+ requestTimeout: options.requestTimeout
74
+ });
75
+ }
76
+ }
77
+ function checkInputs(judge, inputs) {
78
+ const declared = judge.inputs ?? [];
79
+ const given = Object.keys(inputs);
80
+ const missing = declared.filter((name) => !(name in inputs));
81
+ const unknown = given.filter((name) => !declared.includes(name));
82
+ if (missing.length > 0)
83
+ throw new Error(`${judge.name} is missing inputs: ${missing.join(", ")}`);
84
+ if (unknown.length > 0)
85
+ throw new Error(`${judge.name} does not declare inputs: ${unknown.join(", ")}`);
86
+ }
87
+ /**
88
+ * Defines a judge without a class, mirroring `defineAgent`.
89
+ *
90
+ * @example
91
+ * const Urgency = defineJudge({
92
+ * questions: { urgent: probability("Does this need attention today?") }
93
+ * });
94
+ * (await Urgency.judge("The site is down")).urgent.probability;
95
+ */
96
+ export function defineJudge(definition) {
97
+ return class extends Judge {
98
+ static questions = definition.questions;
99
+ static model = definition.model;
100
+ static provider = definition.provider;
101
+ static inputs = definition.inputs;
102
+ static providerOptions = definition.providerOptions;
103
+ };
104
+ }
@@ -0,0 +1,116 @@
1
+ import { JudgmentResponse, Usage } from "../providers/Provider.js";
2
+ import { ChoiceQuestion, Description, ProbabilityQuestion, NamedQuestion, QuestionDefinition, QuestionMap, ScoreQuestion } from "./Question.js";
3
+ /** The probability that a yes/no statement holds, between 0 and 1. */
4
+ export declare class ProbabilityAnswer {
5
+ readonly probability: number;
6
+ readonly type: "probability";
7
+ constructor(probability: number);
8
+ toJSON(): {
9
+ type: "probability";
10
+ probability: number;
11
+ };
12
+ }
13
+ /**
14
+ * The selected option, with a probability for every option. `confidence`
15
+ * describes how concentrated the distribution is; it is not a guarantee that
16
+ * the choice is correct.
17
+ */
18
+ export declare class ChoiceAnswer<K extends string = string> {
19
+ readonly choice: K;
20
+ readonly probabilities: Readonly<Record<K, number>>;
21
+ readonly confidence: number;
22
+ readonly type: "choice";
23
+ constructor(choice: K, probabilities: Readonly<Record<K, number>>, confidence: number);
24
+ toJSON(): {
25
+ type: "choice";
26
+ choice: K;
27
+ probabilities: Readonly<Record<K, number>>;
28
+ confidence: number;
29
+ };
30
+ }
31
+ /**
32
+ * A probability-weighted position on an ordered scale. Level 0 is the first
33
+ * level, so with three levels the score runs from 0 to 2 and can fall between
34
+ * them. `probabilities` is keyed by level index.
35
+ */
36
+ export declare class ScoreAnswer {
37
+ readonly score: number;
38
+ readonly levels: readonly Description[];
39
+ readonly probabilities: Readonly<Record<number, number>>;
40
+ readonly confidence: number;
41
+ readonly type: "score";
42
+ constructor(score: number, levels: readonly Description[], probabilities: Readonly<Record<number, number>>, confidence: number);
43
+ toJSON(): {
44
+ type: "score";
45
+ score: number;
46
+ levels: readonly Description[];
47
+ probabilities: Readonly<Record<number, number>>;
48
+ confidence: number;
49
+ };
50
+ }
51
+ export type Answer = ProbabilityAnswer | ChoiceAnswer | ScoreAnswer;
52
+ /** The answer type a question produces. */
53
+ export type AnswerFor<D extends QuestionDefinition> = D extends ProbabilityQuestion ? ProbabilityAnswer : D extends ChoiceQuestion<infer K> ? ChoiceAnswer<K> : D extends ScoreQuestion ? ScoreAnswer : never;
54
+ /** Answers keyed by question name, typed from the questions asked. */
55
+ export type AnswersOf<Q extends QuestionMap> = {
56
+ readonly [N in keyof Q]: AnswerFor<Q[N]>;
57
+ };
58
+ /**
59
+ * The typed answers to a set of questions, with the model that answered them
60
+ * and the tokens it used.
61
+ *
62
+ * Answers are available by name - `judgment.urgent.probability` - and through
63
+ * `judgment.answers`. A question named like one of Judgment's own members
64
+ * (`model`, `usage`, `get`, ...) is only reachable through `answers` or `get`.
65
+ */
66
+ export declare class Judgment<Q extends QuestionMap = QuestionMap> {
67
+ readonly answers: AnswersOf<Q>;
68
+ /** The model that answered, as reported by the provider. */
69
+ readonly model: string;
70
+ /** Token usage. `cost` is present only when the model has known pricing. */
71
+ readonly usage: Usage;
72
+ /** The provider's raw response. */
73
+ readonly raw?: unknown | undefined;
74
+ constructor(answers: AnswersOf<Q>,
75
+ /** The model that answered, as reported by the provider. */
76
+ model: string,
77
+ /** Token usage. `cost` is present only when the model has known pricing. */
78
+ usage: Usage,
79
+ /** The provider's raw response. */
80
+ raw?: unknown | undefined);
81
+ /** Returns the named answer, or undefined when there is none. */
82
+ get<N extends keyof Q & string>(name: N): AnswersOf<Q>[N] | undefined;
83
+ /** Returns the named answer, throwing when there is none. */
84
+ fetch<N extends keyof Q & string>(name: N): AnswersOf<Q>[N];
85
+ [Symbol.iterator](): IterableIterator<[keyof Q & string, Answer]>;
86
+ toJSON(): {
87
+ model: string;
88
+ answers: {
89
+ [k: string]: {
90
+ type: "probability";
91
+ probability: number;
92
+ } | {
93
+ type: "score";
94
+ score: number;
95
+ levels: readonly Description[];
96
+ probabilities: Readonly<Record<number, number>>;
97
+ confidence: number;
98
+ } | {
99
+ type: "choice";
100
+ choice: string;
101
+ probabilities: Readonly<Record<string, number>>;
102
+ confidence: number;
103
+ };
104
+ };
105
+ usage: Usage;
106
+ };
107
+ }
108
+ /** A Judgment whose answers can also be read directly by question name. */
109
+ export type JudgmentResult<Q extends QuestionMap = QuestionMap> = Judgment<Q> & Omit<AnswersOf<Q>, keyof Judgment<Q>>;
110
+ /**
111
+ * Wraps a provider's answers in typed, frozen answer objects. Every question
112
+ * must come back answered with the type it was asked as; anything else means
113
+ * the provider and the request disagree, and is reported rather than guessed.
114
+ */
115
+ export declare function buildJudgment<Q extends QuestionMap>(response: JudgmentResponse, questions: NamedQuestion[]): JudgmentResult<Q>;
116
+ //# sourceMappingURL=Judgment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Judgment.d.ts","sourceRoot":"","sources":["../../src/judge/Judgment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ /** The probability that a yes/no statement holds, between 0 and 1. */
2
+ export class ProbabilityAnswer {
3
+ probability;
4
+ type = "probability";
5
+ constructor(probability) {
6
+ this.probability = probability;
7
+ Object.freeze(this);
8
+ }
9
+ toJSON() {
10
+ return { type: this.type, probability: this.probability };
11
+ }
12
+ }
13
+ /**
14
+ * The selected option, with a probability for every option. `confidence`
15
+ * describes how concentrated the distribution is; it is not a guarantee that
16
+ * the choice is correct.
17
+ */
18
+ export class ChoiceAnswer {
19
+ choice;
20
+ probabilities;
21
+ confidence;
22
+ type = "choice";
23
+ constructor(choice, probabilities, confidence) {
24
+ this.choice = choice;
25
+ this.probabilities = probabilities;
26
+ this.confidence = confidence;
27
+ Object.freeze(this.probabilities);
28
+ Object.freeze(this);
29
+ }
30
+ toJSON() {
31
+ return {
32
+ type: this.type,
33
+ choice: this.choice,
34
+ probabilities: this.probabilities,
35
+ confidence: this.confidence
36
+ };
37
+ }
38
+ }
39
+ /**
40
+ * A probability-weighted position on an ordered scale. Level 0 is the first
41
+ * level, so with three levels the score runs from 0 to 2 and can fall between
42
+ * them. `probabilities` is keyed by level index.
43
+ */
44
+ export class ScoreAnswer {
45
+ score;
46
+ levels;
47
+ probabilities;
48
+ confidence;
49
+ type = "score";
50
+ constructor(score, levels, probabilities, confidence) {
51
+ this.score = score;
52
+ this.levels = levels;
53
+ this.probabilities = probabilities;
54
+ this.confidence = confidence;
55
+ Object.freeze(this.levels);
56
+ Object.freeze(this.probabilities);
57
+ Object.freeze(this);
58
+ }
59
+ toJSON() {
60
+ return {
61
+ type: this.type,
62
+ score: this.score,
63
+ levels: this.levels,
64
+ probabilities: this.probabilities,
65
+ confidence: this.confidence
66
+ };
67
+ }
68
+ }
69
+ /**
70
+ * The typed answers to a set of questions, with the model that answered them
71
+ * and the tokens it used.
72
+ *
73
+ * Answers are available by name - `judgment.urgent.probability` - and through
74
+ * `judgment.answers`. A question named like one of Judgment's own members
75
+ * (`model`, `usage`, `get`, ...) is only reachable through `answers` or `get`.
76
+ */
77
+ export class Judgment {
78
+ answers;
79
+ model;
80
+ usage;
81
+ raw;
82
+ constructor(answers,
83
+ /** The model that answered, as reported by the provider. */
84
+ model,
85
+ /** Token usage. `cost` is present only when the model has known pricing. */
86
+ usage,
87
+ /** The provider's raw response. */
88
+ raw) {
89
+ this.answers = answers;
90
+ this.model = model;
91
+ this.usage = usage;
92
+ this.raw = raw;
93
+ Object.freeze(this.answers);
94
+ for (const name of Object.keys(answers)) {
95
+ if (name in this)
96
+ continue;
97
+ Object.defineProperty(this, name, {
98
+ value: answers[name],
99
+ enumerable: false
100
+ });
101
+ }
102
+ Object.freeze(this);
103
+ }
104
+ /** Returns the named answer, or undefined when there is none. */
105
+ get(name) {
106
+ return Object.prototype.hasOwnProperty.call(this.answers, name)
107
+ ? this.answers[name]
108
+ : undefined;
109
+ }
110
+ /** Returns the named answer, throwing when there is none. */
111
+ fetch(name) {
112
+ const answer = this.get(name);
113
+ if (answer === undefined)
114
+ throw new Error(`No answer named '${name}' in this judgment`);
115
+ return answer;
116
+ }
117
+ *[Symbol.iterator]() {
118
+ for (const [name, answer] of Object.entries(this.answers)) {
119
+ yield [name, answer];
120
+ }
121
+ }
122
+ toJSON() {
123
+ return {
124
+ model: this.model,
125
+ answers: Object.fromEntries(Object.entries(this.answers).map(([name, answer]) => [name, answer.toJSON()])),
126
+ usage: this.usage
127
+ };
128
+ }
129
+ }
130
+ /**
131
+ * Wraps a provider's answers in typed, frozen answer objects. Every question
132
+ * must come back answered with the type it was asked as; anything else means
133
+ * the provider and the request disagree, and is reported rather than guessed.
134
+ */
135
+ export function buildJudgment(response, questions) {
136
+ const answers = {};
137
+ for (const question of questions) {
138
+ const data = response.answers[question.name];
139
+ if (!data)
140
+ throw new Error(`The provider returned no answer for '${question.name}'`);
141
+ if (data.type !== question.type) {
142
+ throw new Error(`The provider answered '${question.name}' as a ${data.type}, but it was asked as a ${question.type}`);
143
+ }
144
+ switch (data.type) {
145
+ case "probability":
146
+ answers[question.name] = new ProbabilityAnswer(data.probability);
147
+ break;
148
+ case "choice":
149
+ answers[question.name] = new ChoiceAnswer(data.choice, { ...data.probabilities }, data.confidence);
150
+ break;
151
+ case "score":
152
+ // Copy the levels: the answer is frozen, and freezing the caller's own
153
+ // question definition would be a surprising side effect.
154
+ answers[question.name] = new ScoreAnswer(data.score, structuredClone(question.levels), { ...data.probabilities }, data.confidence);
155
+ break;
156
+ }
157
+ }
158
+ return new Judgment(answers, response.model, response.usage, response.raw);
159
+ }