@mate-academy/llm-gateway 8.0.0 → 8.2.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 (102) hide show
  1. package/README.md +76 -4
  2. package/dist/LLMGateway.d.ts +2 -2
  3. package/dist/LLMGateway.js.map +1 -1
  4. package/dist/LLMGateway.typedefs.d.ts +2 -2
  5. package/dist/LLMService.typedefs.d.ts +20 -0
  6. package/dist/LLMService.typedefs.js.map +1 -1
  7. package/dist/client/LLMAgent.d.ts +17 -4
  8. package/dist/client/LLMAgent.js +4 -0
  9. package/dist/client/LLMAgent.js.map +1 -1
  10. package/dist/client/LLMClientEngine.d.ts +81 -0
  11. package/dist/client/LLMClientEngine.js +350 -0
  12. package/dist/client/LLMClientEngine.js.map +1 -0
  13. package/dist/client/agentRun.typedefs.d.ts +18 -3
  14. package/dist/client/agentRun.typedefs.js +1 -0
  15. package/dist/client/agentRun.typedefs.js.map +1 -1
  16. package/dist/client/agentRunner.d.ts +38 -3
  17. package/dist/client/agentRunner.js +206 -80
  18. package/dist/client/agentRunner.js.map +1 -1
  19. package/dist/client/codegen/fetchPromptRecords.d.ts +1 -1
  20. package/dist/client/codegen/index.d.ts +1 -0
  21. package/dist/client/codegen/index.js +1 -0
  22. package/dist/client/codegen/index.js.map +1 -1
  23. package/dist/client/codegen/renderSnapshot.constants.d.ts +12 -0
  24. package/dist/client/codegen/renderSnapshot.constants.js +21 -0
  25. package/dist/client/codegen/renderSnapshot.constants.js.map +1 -0
  26. package/dist/client/codegen/renderSnapshot.d.ts +6 -18
  27. package/dist/client/codegen/renderSnapshot.js +152 -125
  28. package/dist/client/codegen/renderSnapshot.js.map +1 -1
  29. package/dist/client/codegen/renderSnapshot.typedefs.d.ts +20 -0
  30. package/dist/client/codegen/renderSnapshot.typedefs.js +3 -0
  31. package/dist/client/codegen/renderSnapshot.typedefs.js.map +1 -0
  32. package/dist/client/coerceToolResult.d.ts +10 -0
  33. package/dist/client/coerceToolResult.js +38 -0
  34. package/dist/client/coerceToolResult.js.map +1 -0
  35. package/dist/client/createLLMClient.d.ts +1 -40
  36. package/dist/client/createLLMClient.js +5 -329
  37. package/dist/client/createLLMClient.js.map +1 -1
  38. package/dist/client/index.d.ts +3 -1
  39. package/dist/client/index.js +3 -1
  40. package/dist/client/index.js.map +1 -1
  41. package/dist/client/llmClient.typedefs.d.ts +180 -0
  42. package/dist/client/{createLLMClient.typedefs.js → llmClient.typedefs.js} +1 -1
  43. package/dist/client/llmClient.typedefs.js.map +1 -0
  44. package/dist/client/plainMessages.d.ts +1 -1
  45. package/dist/client/promptRegistry.runtime.d.ts +2 -2
  46. package/dist/client/promptRegistry.runtime.js.map +1 -1
  47. package/dist/client/promptVariables.d.ts +7 -0
  48. package/dist/client/promptVariables.js +13 -0
  49. package/dist/client/promptVariables.js.map +1 -0
  50. package/dist/client/snapshotRuntime.d.ts +17 -0
  51. package/dist/client/snapshotRuntime.js +42 -0
  52. package/dist/client/snapshotRuntime.js.map +1 -0
  53. package/dist/client/snapshotRuntime.typedefs.d.ts +13 -0
  54. package/dist/client/snapshotRuntime.typedefs.js +3 -0
  55. package/dist/client/snapshotRuntime.typedefs.js.map +1 -0
  56. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.js +6 -0
  57. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.js.map +1 -1
  58. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.js +6 -0
  59. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.js.map +1 -1
  60. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAISpeechToText.service.js +3 -0
  61. package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAISpeechToText.service.js.map +1 -1
  62. package/dist/providers/LLMAPI/services/LLMAPIAssistance.service.d.ts +0 -2
  63. package/dist/providers/LLMAPI/services/LLMAPIAssistance.service.js +43 -25
  64. package/dist/providers/LLMAPI/services/LLMAPIAssistance.service.js.map +1 -1
  65. package/dist/providers/LLMAPI/services/LLMAPICompletion.service.d.ts +0 -2
  66. package/dist/providers/LLMAPI/services/LLMAPICompletion.service.js +18 -17
  67. package/dist/providers/LLMAPI/services/LLMAPICompletion.service.js.map +1 -1
  68. package/dist/providers/LLMAPI/utilities/index.d.ts +1 -1
  69. package/dist/providers/LLMAPI/utilities/index.js +3 -4
  70. package/dist/providers/LLMAPI/utilities/index.js.map +1 -1
  71. package/dist/providers/LLMAPI/utilities/validateStructuredResponse.d.ts +10 -0
  72. package/dist/providers/LLMAPI/utilities/validateStructuredResponse.js +21 -0
  73. package/dist/providers/LLMAPI/utilities/validateStructuredResponse.js.map +1 -0
  74. package/dist/providers/OpenAI/services/OpenAIAssistance.service.js +6 -0
  75. package/dist/providers/OpenAI/services/OpenAIAssistance.service.js.map +1 -1
  76. package/dist/providers/OpenAICompatible/OpenAICompatibleCompletion.service.js +6 -0
  77. package/dist/providers/OpenAICompatible/OpenAICompatibleCompletion.service.js.map +1 -1
  78. package/dist/providers/OpenAICompatible/OpenAICompatibleSpeechToText.service.js +3 -0
  79. package/dist/providers/OpenAICompatible/OpenAICompatibleSpeechToText.service.js.map +1 -1
  80. package/dist/services/LLMBaseService.abstract.d.ts +4 -3
  81. package/dist/services/LLMBaseService.abstract.js +6 -3
  82. package/dist/services/LLMBaseService.abstract.js.map +1 -1
  83. package/dist/utilities/index.d.ts +0 -1
  84. package/dist/utilities/index.js +0 -1
  85. package/dist/utilities/index.js.map +1 -1
  86. package/dist/utilities/llmTracing/llmTracing.constants.d.ts +5 -4
  87. package/dist/utilities/llmTracing/llmTracing.constants.js +6 -5
  88. package/dist/utilities/llmTracing/llmTracing.constants.js.map +1 -1
  89. package/dist/utilities/llmTracing/llmTracing.typedefs.d.ts +18 -9
  90. package/dist/utilities/llmTracing/noopLLMTracing.d.ts +2 -2
  91. package/dist/utilities/llmTracing/noopLLMTracing.js.map +1 -1
  92. package/dist/utilities/tools/LLMTool.d.ts +3 -12
  93. package/dist/utilities/tools/LLMTool.js.map +1 -1
  94. package/package.json +2 -1
  95. package/dist/client/createLLMClient.typedefs.d.ts +0 -91
  96. package/dist/client/createLLMClient.typedefs.js.map +0 -1
  97. package/dist/providers/LLMAPI/utilities/LLMAPIJsonFixer.d.ts +0 -24
  98. package/dist/providers/LLMAPI/utilities/LLMAPIJsonFixer.js +0 -237
  99. package/dist/providers/LLMAPI/utilities/LLMAPIJsonFixer.js.map +0 -1
  100. package/dist/utilities/traceIO.d.ts +0 -17
  101. package/dist/utilities/traceIO.js +0 -48
  102. package/dist/utilities/traceIO.js.map +0 -1
package/README.md CHANGED
@@ -124,10 +124,10 @@ content, model, params, usage, cost) at the same success/error points the metric
124
124
  reporter already wraps — one on success, one (level `ERROR`) on failure;
125
125
  assistance tool loops emit a child `tool` observation per tool call. Calls that
126
126
  carry no per-call trace context (text-to-speech, file and chat management) emit
127
- none, on either branch. Observation input/output are capped by `truncateTraceIO`
128
- before they are stamped, so a large prompt or completion cannot inflate the trace
129
- payload. All of this is fire-and-forget — a tracing failure never blocks or fails
130
- an LLM call.
127
+ none, on either branch. Observation input/output are recorded in full — the
128
+ prompt and the completion are what a trace exists to show, so they are never
129
+ truncated. All of this is fire-and-forget — a tracing failure never blocks or
130
+ fails an LLM call.
131
131
 
132
132
  Pass `traceContext.prompt` (`{ name, version, isFallback }`) to name the
133
133
  observation after the managed prompt and link it to that prompt version in
@@ -135,6 +135,14 @@ Langfuse; a fallback prompt intentionally produces no link. The v2 client builds
135
135
  this context for every call it makes, so `generate` and `runAgent` need nothing
136
136
  at the call site.
137
137
 
138
+ The observation also carries its real time span. Each provider service captures
139
+ `startedAt` (epoch ms) before the provider call and the base service stamps
140
+ `endedAt` when it hands the record to the tracer, so the exported generation has
141
+ the actual call latency instead of a zero-width span. Both fields are required
142
+ on `LLMGenerationTraceRecord`, and `startedAt` is required on the
143
+ `LLMGenerationTrace` a provider builds — a new provider call site cannot compile
144
+ without threading a start timestamp.
145
+
138
146
  To group several calls under one trace, wrap the work so nested gateway calls
139
147
  attach to it automatically:
140
148
 
@@ -307,6 +315,62 @@ if (turn.stopReason === LLMToolLoopStopReasons.TerminalTool) {
307
315
  `[a-zA-Z0-9_-]+` (it is exposed to the model as a tool); an invalid name
308
316
  fails the run upfront with `LLMConfigError` instead of being silently
309
317
  rewritten.
318
+ - **Typed delegation inputs.** A subagent declaring an `inputSchema` is exposed
319
+ to the model with that schema instead of the default single `prompt` string,
320
+ and the arguments the parent model fills join the subagent's own `variables`
321
+ (winning over them), so its prompt can reference them as `{{topicRef}}` and
322
+ the validation gate checks them like any other variable. Use it whenever the
323
+ delegated work needs identifiers the parent must not paraphrase — an entity
324
+ ref, a changeset id, an enum choice. Without `inputSchema` nothing changes:
325
+ one free-form `prompt` argument, which is also the nested run's input.
326
+
327
+ ```typescript
328
+ const theoryWriter = llm.defineAgent({
329
+ prompt: LLMPrompt.ContentEditorWriteTheory,
330
+ name: 'write_theory',
331
+ description: 'Authors one theory document into the current changeset',
332
+ inputSchema: LLMSchema.object({
333
+ topicRef: LLMSchema.string().describe('Changeset entity ref of the topic'),
334
+ audienceLevel: LLMSchema.enum(['beginner', 'intermediate', 'advanced']),
335
+ outline: LLMSchema.array(LLMSchema.string()),
336
+ }),
337
+ variables: { changesetId },
338
+ tools: [getEntityTool, saveTheoryTool],
339
+ });
340
+ ```
341
+ - **One place normalizes tool output.** Every tool result and every delegation
342
+ result passes through the package's coercion before the model sees it, so a
343
+ tool that returns an object, a number or nothing cannot put `[object Object]`
344
+ into the conversation. A client may add its own `normalizeToolResult` on top —
345
+ the natural place to wrap untrusted material (a fetched web page) so no tool
346
+ author can forget to:
347
+
348
+ ```typescript
349
+ const llm = createLLMClient({
350
+ // ...
351
+ normalizeToolResult: ({ tool, result }) => (
352
+ UNTRUSTED_TOOLS.has(tool)
353
+ ? { content: `<untrusted source="${tool}">\n${toText(result)}\n</untrusted>` }
354
+ : result
355
+ ),
356
+ });
357
+ ```
358
+
359
+ The normalized value is what reaches both the model and the
360
+ `tool_call_completed` event, so a persisted run history records exactly what
361
+ the model read.
362
+ - **Preconditions gate a call before it runs.** A tool may declare
363
+ `canExecute(args)` returning `{ allowed: true }` or
364
+ `{ allowed: false, reason }`. It is checked before `execute`, so a refused
365
+ call never has its side effect. A refusal is ordinary control flow, not an
366
+ error: the model is told the reason as that call's result, the run continues,
367
+ and the iteration budget is untouched — so the model can ask the user or take
368
+ another path. The invocation reports `tool_call_denied` instead of
369
+ `tool_call_completed`, and a refused delegation reports the same event with
370
+ `tool` naming the subagent. Use it for permission, quota and state checks that
371
+ depend on the arguments (an authorization check before a write, a stale-hash
372
+ guard, a per-run write budget) — enforcement then lives in the tool's
373
+ definition rather than in prompt instructions the model may ignore.
310
374
 
311
375
  The plain-object form above is complete on its own. `llm.defineAgent` is
312
376
  optional sugar for reusable, composable definitions: it returns an immutable
@@ -366,6 +430,14 @@ fallback. It is gitignored exactly like GraphQL generated files: regenerated
366
430
  locally on demand, in CI before image builds (with a cached-artifact fallback so a
367
431
  Langfuse outage never fails a build), and refreshed non-blocking at API pod boot.
368
432
 
433
+ The emitted file contains declarations only. Its compile helpers delegate to
434
+ `compileTextFromSnapshot` / `compileMessagesFromSnapshot`, imported from this
435
+ package rather than copied into the output as source text, so the substitution
436
+ logic has one implementation with its own tests. The declarations themselves are
437
+ built with ts-morph through its structural API, not by string concatenation —
438
+ ts-morph is a dependency of the `codegen` entry point only, so importing the
439
+ package's main entry never pulls it in.
440
+
369
441
  `generateSnapshot` (exported from `@mate-academy/llm-gateway/codegen`) takes an
370
442
  injected `LLMPromptCatalog` instead of constructing a Langfuse SDK client
371
443
  itself — the caller owns the catalog's credentials and its Langfuse project.
@@ -1,7 +1,7 @@
1
1
  import { type LLMProviders, type LLMPurposes, type LLMServiceByPurpose, type LLMServiceOptions } from './LLMService.typedefs';
2
2
  import { type LLMGatewayOptions } from './LLMGateway.typedefs';
3
3
  import { type LLMReporterInterface } from './utilities/reporter';
4
- import { type LangfuseFallbackMetricDimensions, type LLMGatewayTracer, type LLMTraceContext } from './utilities/llmTracing';
4
+ import { type LLMFallbackMetricDimensions, type LLMGatewayTracer, type LLMTraceContext } from './utilities/llmTracing';
5
5
  /**
6
6
  * An explicitly constructed gateway: every service it hands out is wired to the
7
7
  * tracer this instance was built with. `LLMServiceFactory` stays available for
@@ -25,6 +25,6 @@ export declare class LLMGateway {
25
25
  * long-running API calls it from its shutdown hook only.
26
26
  */
27
27
  flush(): Promise<void>;
28
- emitFallbackServed(dimensions: LangfuseFallbackMetricDimensions): void;
28
+ emitFallbackServed(dimensions: LLMFallbackMetricDimensions): void;
29
29
  private traced;
30
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LLMGateway.js","sourceRoot":"","sources":["../src/LLMGateway.ts"],"names":[],"mappings":";;;AAMA,6DAAyD;AAGzD,uDAOgC;AAMhC;;;;GAIG;AACH,MAAa,UAAU;IACJ,MAAM,CAAmB;IAEzB,qBAAqB,CAAgC;IAEtE,YAAY,UAA6B,EAAE;QACzC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,iCAAoB,CAAC;QACrD,IAAI,CAAC,qBAAqB;cACtB,OAAO,CAAC,qBAAqB,IAAI,sCAAyB,CAAC;IACjE,CAAC;IAED,oBAAoB,CAIlB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,oBAAoB,CAIlB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,sBAAsB,CAIpB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,sBAAsB,CAIpB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,SAAS,CACP,IAAY,EACZ,OAAwB,EACxB,EAAyB;QAEzB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,kBAAkB,CAAC,UAA4C;QAC7D,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAEO,MAAM,CAAmC,OAAgB;QAC/D,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA/ED,gCA+EC"}
1
+ {"version":3,"file":"LLMGateway.js","sourceRoot":"","sources":["../src/LLMGateway.ts"],"names":[],"mappings":";;;AAMA,6DAAyD;AAGzD,uDAOgC;AAMhC;;;;GAIG;AACH,MAAa,UAAU;IACJ,MAAM,CAAmB;IAEzB,qBAAqB,CAA2B;IAEjE,YAAY,UAA6B,EAAE;QACzC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,iCAAoB,CAAC;QACrD,IAAI,CAAC,qBAAqB;cACtB,OAAO,CAAC,qBAAqB,IAAI,sCAAyB,CAAC;IACjE,CAAC;IAED,oBAAoB,CAIlB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,oBAAoB,CAIlB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,sBAAsB,CAIpB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,sBAAsB,CAIpB,OAA8C;QAE9C,OAAO,IAAI,CAAC,MAAM,CAAC,sCAAiB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,SAAS,CACP,IAAY,EACZ,OAAwB,EACxB,EAAyB;QAEzB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,kBAAkB,CAAC,UAAuC;QACxD,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAEO,MAAM,CAAmC,OAAgB;QAC/D,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA/ED,gCA+EC"}
@@ -1,5 +1,5 @@
1
- import { type LangfuseFallbackMetricEmitter, type LLMGatewayTracer } from './utilities/llmTracing';
1
+ import { type LLMFallbackMetricEmitter, type LLMGatewayTracer } from './utilities/llmTracing';
2
2
  export interface LLMGatewayOptions {
3
3
  tracer?: LLMGatewayTracer;
4
- fallbackMetricEmitter?: LangfuseFallbackMetricEmitter;
4
+ fallbackMetricEmitter?: LLMFallbackMetricEmitter;
5
5
  }
@@ -491,11 +491,31 @@ export interface LLMStructuredToolResult {
491
491
  * images.
492
492
  */
493
493
  export type LLMToolResult = string | LLMStructuredToolResult;
494
+ /**
495
+ * The verdict of a tool's `canExecute` precondition. A refusal carries the
496
+ * `reason` the model is told, which is why it is required: a denial the model
497
+ * cannot explain to itself is a denial it will retry blindly.
498
+ */
499
+ export type LLMToolGateResult = {
500
+ allowed: true;
501
+ } | {
502
+ allowed: false;
503
+ reason: string;
504
+ };
494
505
  export interface LLMToolDefinition<Schema extends LLMSchemaInterface = LLMSchemaInterface> {
495
506
  name: string;
496
507
  description: string;
497
508
  parameters: Schema;
498
509
  execute: (args: InferSchema<Schema>) => Promise<LLMToolResult> | LLMToolResult;
510
+ /**
511
+ * Decides whether this call may run, on the arguments the model supplied.
512
+ * Checked before `execute`, so a refused call never has its side effect. A
513
+ * refusal is ordinary control flow, not an error: the model is told the
514
+ * `reason` as the call's result and the run continues with its iteration
515
+ * budget untouched. Use it for permission, quota, and state preconditions
516
+ * that depend on the arguments rather than on the tool being present at all.
517
+ */
518
+ canExecute?: (args: InferSchema<Schema>) => Promise<LLMToolGateResult> | LLMToolGateResult;
499
519
  /**
500
520
  * Ends the turn once this tool runs. The round executes in full (every call
501
521
  * of that round, including parallel ones), but its results are not fed back
@@ -1 +1 @@
1
- {"version":3,"file":"LLMService.typedefs.js","sourceRoot":"","sources":["../src/LLMService.typedefs.ts"],"names":[],"mappings":";;;AAmCA;;GAEG;AACH,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,iCAAiB,CAAA;IACjB,yDAAyC,CAAA;IACzC,iCAAiB,CAAA;AACnB,CAAC,EAJW,YAAY,4BAAZ,YAAY,QAIvB;AAoBD;;GAEG;AACH,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,wCAAyB,CAAA;IACzB,wCAAyB,CAAA;IACzB,8CAA+B,CAAA;IAC/B,8CAA+B,CAAA;AACjC,CAAC,EALW,WAAW,2BAAX,WAAW,QAKtB;AAiLD;;GAEG;AACH,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,yBAAa,CAAA;IACb,mCAAuB,CAAA;AACzB,CAAC,EAHW,QAAQ,wBAAR,QAAQ,QAGnB;AAED;;GAEG;AACH,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,sCAAa,CAAA;IACb,gDAAuB,CAAA;IACvB,kDAAyB,CAAA;AAC3B,CAAC,EAJW,qBAAqB,qCAArB,qBAAqB,QAIhC;AAkLD;;GAEG;AACH,IAAY,sBAeX;AAfD,WAAY,sBAAsB;IAChC,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,iDAAuB,CAAA;IACvB,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,yDAA+B,CAAA;IAC/B,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,oDAA0B,CAAA;IAC1B,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,iDAAuB,CAAA;AACzB,CAAC,EAfW,sBAAsB,sCAAtB,sBAAsB,QAejC;AAwND;;;;;GAKG;AACH,IAAY,sBAIX;AAJD,WAAY,sBAAsB;IAChC,iDAAuB,CAAA;IACvB,0DAAgC,CAAA;IAChC,wDAA8B,CAAA;AAChC,CAAC,EAJW,sBAAsB,sCAAtB,sBAAsB,QAIjC"}
1
+ {"version":3,"file":"LLMService.typedefs.js","sourceRoot":"","sources":["../src/LLMService.typedefs.ts"],"names":[],"mappings":";;;AAmCA;;GAEG;AACH,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,iCAAiB,CAAA;IACjB,yDAAyC,CAAA;IACzC,iCAAiB,CAAA;AACnB,CAAC,EAJW,YAAY,4BAAZ,YAAY,QAIvB;AAoBD;;GAEG;AACH,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,wCAAyB,CAAA;IACzB,wCAAyB,CAAA;IACzB,8CAA+B,CAAA;IAC/B,8CAA+B,CAAA;AACjC,CAAC,EALW,WAAW,2BAAX,WAAW,QAKtB;AAiLD;;GAEG;AACH,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,yBAAa,CAAA;IACb,mCAAuB,CAAA;AACzB,CAAC,EAHW,QAAQ,wBAAR,QAAQ,QAGnB;AAED;;GAEG;AACH,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,sCAAa,CAAA;IACb,gDAAuB,CAAA;IACvB,kDAAyB,CAAA;AAC3B,CAAC,EAJW,qBAAqB,qCAArB,qBAAqB,QAIhC;AAkLD;;GAEG;AACH,IAAY,sBAeX;AAfD,WAAY,sBAAsB;IAChC,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,iDAAuB,CAAA;IACvB,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,yDAA+B,CAAA;IAC/B,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,oDAA0B,CAAA;IAC1B,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,iDAAuB,CAAA;IACvB,mDAAyB,CAAA;IACzB,iDAAuB,CAAA;AACzB,CAAC,EAfW,sBAAsB,sCAAtB,sBAAsB,QAejC;AA4OD;;;;;GAKG;AACH,IAAY,sBAIX;AAJD,WAAY,sBAAsB;IAChC,iDAAuB,CAAA;IACvB,0DAAgC,CAAA;IAChC,wDAA8B,CAAA;AAChC,CAAC,EAJW,sBAAsB,sCAAtB,sBAAsB,QAIjC"}
@@ -1,7 +1,8 @@
1
1
  import { type LLMToolDefinition } from '../LLMService.typedefs';
2
+ import { type LLMSchemaInterface } from '../utilities/schema';
2
3
  import { type LLMPromptRegistry } from '../client/defineLLMPrompts';
3
4
  import { type LLMVariableValue } from '../client/promptSnapshot.typedefs';
4
- import { type LLMPromptVariables } from '../client/createLLMClient.typedefs';
5
+ import { type LLMDelegationGate, type LLMPromptVariables, type LLMSubagentVariableSource } from '../client/llmClient.typedefs';
5
6
  /**
6
7
  * A bounded specialist the root agent may delegate to, as a plain object.
7
8
  * `prompt` names the registry entry whose Langfuse prompt is the subagent's
@@ -15,10 +16,10 @@ export type LLMAgentSubagentDefinition<Registry extends LLMPromptRegistry, Varia
15
16
  prompt: Key;
16
17
  name: string;
17
18
  description: string;
18
- variables: LLMPromptVariables<VariableMap[Key]>;
19
19
  tools?: LLMToolDefinition[];
20
+ canExecute?: LLMDelegationGate;
20
21
  maxToolIterations?: number;
21
- };
22
+ } & LLMSubagentVariableSource<VariableMap[Key]>;
22
23
  }[keyof Registry];
23
24
  /**
24
25
  * Anything accepted in a `subagents` list: a plain definition object or an
@@ -31,7 +32,8 @@ export type LLMAgentSubagent<Registry extends LLMPromptRegistry, VariableMap ext
31
32
  * its model). `name`/`description` are required when the agent is used as a
32
33
  * subagent — the name becomes the delegation tool the parent model calls.
33
34
  * `variables` given here are a base merged under the per-run variables (for a
34
- * subagent they are the only source).
35
+ * subagent they are the only source, unless `inputSchema` lets the parent
36
+ * model supply more).
35
37
  */
36
38
  export interface LLMAgentDefinition<Registry extends LLMPromptRegistry, VariableMap extends Record<keyof Registry, string>, Key extends keyof Registry> {
37
39
  prompt: Key;
@@ -40,6 +42,15 @@ export interface LLMAgentDefinition<Registry extends LLMPromptRegistry, Variable
40
42
  variables?: LLMPromptVariables<VariableMap[Key]>;
41
43
  tools?: LLMToolDefinition[];
42
44
  subagents?: LLMAgentSubagent<Registry, VariableMap>[];
45
+ /**
46
+ * The arguments the parent model must supply when delegating to this agent,
47
+ * replacing the default single `prompt` string. Each argument joins the
48
+ * subagent's prompt variables (over the definition's own), so the delegated
49
+ * prompt can reference them as `{{name}}`. Only meaningful as a subagent.
50
+ */
51
+ inputSchema?: LLMSchemaInterface;
52
+ /** Refuses a delegation call before it runs; see `LLMDelegationGate`. */
53
+ canExecute?: LLMDelegationGate;
43
54
  maxToolIterations?: number;
44
55
  }
45
56
  /**
@@ -58,6 +69,8 @@ export declare class LLMAgent<Registry extends LLMPromptRegistry = LLMPromptRegi
58
69
  readonly variables: Record<string, LLMVariableValue> | undefined;
59
70
  readonly tools: LLMToolDefinition[] | undefined;
60
71
  readonly subagents: LLMAgentSubagent<Registry, VariableMap>[] | undefined;
72
+ readonly inputSchema: LLMSchemaInterface | undefined;
73
+ readonly canExecute: LLMDelegationGate | undefined;
61
74
  readonly maxToolIterations: number | undefined;
62
75
  constructor(definition: LLMAgentDefinition<Registry, VariableMap, Key>);
63
76
  }
@@ -17,6 +17,8 @@ class LLMAgent {
17
17
  variables;
18
18
  tools;
19
19
  subagents;
20
+ inputSchema;
21
+ canExecute;
20
22
  maxToolIterations;
21
23
  constructor(definition) {
22
24
  this.prompt = definition.prompt;
@@ -25,6 +27,8 @@ class LLMAgent {
25
27
  this.variables = definition.variables;
26
28
  this.tools = definition.tools;
27
29
  this.subagents = definition.subagents;
30
+ this.inputSchema = definition.inputSchema;
31
+ this.canExecute = definition.canExecute;
28
32
  this.maxToolIterations = definition.maxToolIterations;
29
33
  }
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LLMAgent.js","sourceRoot":"","sources":["../../src/client/LLMAgent.ts"],"names":[],"mappings":";;;AA8DA;;;;;;;;GAQG;AACH,MAAa,QAAQ;IAMV,MAAM,CAAM;IAEZ,IAAI,CAAqB;IAEzB,WAAW,CAAqB;IAEhC,SAAS,CAA+C;IAExD,KAAK,CAAkC;IAEvC,SAAS,CAAwD;IAEjE,iBAAiB,CAAqB;IAE/C,YAAY,UAA0D;QACpE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;QACtC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;QACtC,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAC;IACxD,CAAC;CACF;AA7BD,4BA6BC"}
1
+ {"version":3,"file":"LLMAgent.js","sourceRoot":"","sources":["../../src/client/LLMAgent.ts"],"names":[],"mappings":";;;AA2EA;;;;;;;;GAQG;AACH,MAAa,QAAQ;IAMV,MAAM,CAAM;IAEZ,IAAI,CAAqB;IAEzB,WAAW,CAAqB;IAEhC,SAAS,CAA+C;IAExD,KAAK,CAAkC;IAEvC,SAAS,CAAwD;IAEjE,WAAW,CAAiC;IAE5C,UAAU,CAAgC;IAE1C,iBAAiB,CAAqB;IAE/C,YAAY,UAA0D;QACpE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;QACtC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;QACtC,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAC;IACxD,CAAC;CACF;AAnCD,4BAmCC"}
@@ -0,0 +1,81 @@
1
+ import { type LLMCallTraceContext, type LLMToolResult } from '../LLMService.typedefs';
2
+ import { type LLMReporterInterface } from '../utilities/reporter';
3
+ import { type LLMSchemaInterface } from '../utilities/schema';
4
+ import { type LLMPromptBinding, type LLMPromptRegistry } from '../client/defineLLMPrompts';
5
+ import { type LLMAgentInlineRunOptions, type LLMAgentRunResult } from '../client/agentRun.typedefs';
6
+ import { LLMAgent, type LLMAgentDefinition } from '../client/LLMAgent';
7
+ import { type LLMAgentCallServices, type LLMPromptResolutionCall } from '../client/agentRunner';
8
+ import { type LLMClientCallContext, type LLMClientEngineConfig, type LLMGenerateOptions, type LLMGenerateResult, type LLMPlainMessage, type LLMPromptDescription, type LLMToolResultContext } from '../client/llmClient.typedefs';
9
+ import { type LLMVariableValue } from '../client/promptSnapshot.typedefs';
10
+ import { type ResolvedPrompt } from '../client/promptRegistry.runtime';
11
+ /**
12
+ * The client's single implementation. `createLLMClient` owns its construction
13
+ * and exposes only the `LLMClient` surface, so every call path — `generate`,
14
+ * `countTokens`, `runAgent`, `describePrompt` — shares one prompt resolution,
15
+ * one credentials lookup, one reporter/trace context, and one error taxonomy.
16
+ */
17
+ export declare class LLMClientEngine<Registry extends LLMPromptRegistry> implements LLMAgentCallServices {
18
+ private readonly gateway;
19
+ private readonly registry;
20
+ private readonly runtime;
21
+ private readonly credentials;
22
+ private readonly reporter;
23
+ private readonly logger;
24
+ private readonly staticContext;
25
+ private readonly mode;
26
+ private readonly toolResultNormalizer;
27
+ private readonly agentRunner;
28
+ constructor(config: LLMClientEngineConfig<Registry>);
29
+ generate<Key extends keyof Registry, Schema extends LLMSchemaInterface = never>(prompt: Key, options: LLMGenerateOptions<Record<string, LLMVariableValue>, Schema>): Promise<unknown>;
30
+ defineAgent<Key extends keyof Registry>(definition: LLMAgentDefinition<Registry, Record<keyof Registry, string>, Key>): LLMAgent<Registry, Record<keyof Registry, string>, Key>;
31
+ runAgent<Key extends keyof Registry>(promptOrAgent: Key | LLMAgent<Registry, Record<keyof Registry, string>>, options: LLMAgentInlineRunOptions<Record<string, LLMVariableValue>, Registry, Record<keyof Registry, string>>): Promise<LLMAgentRunResult<LLMGenerateResult<Registry[Key]>>>;
32
+ countTokens<Key extends keyof Registry>(prompt: Key, options: {
33
+ variables: Record<string, LLMVariableValue>;
34
+ history?: LLMPlainMessage[];
35
+ }): Promise<number>;
36
+ describePrompt<Key extends keyof Registry>(prompt: Key): Promise<LLMPromptDescription>;
37
+ resolvePrompt(promptName: string, binding: LLMPromptBinding, variables: Record<string, LLMVariableValue>, call: LLMPromptResolutionCall): Promise<ResolvedPrompt>;
38
+ /**
39
+ * The single place a tool's return value becomes what the model reads. The
40
+ * package's own coercion always runs first, so a client-supplied normalizer
41
+ * never sees a malformed value and cannot reintroduce one.
42
+ */
43
+ normalizeToolResult(context: LLMToolResultContext): LLMToolResult;
44
+ private runCompletion;
45
+ /**
46
+ * Builds the provider message envelope from the resolved prompt. A `text`
47
+ * prompt is one user message. A `chat` prompt preserves the structure the
48
+ * prompt declares: a leading `system` message maps to `instructions`, the final
49
+ * `user` message is the request, and any messages between them join the
50
+ * call-supplied history in order.
51
+ */
52
+ private buildMessageEnvelope;
53
+ private findLastUserIndex;
54
+ private callProvider;
55
+ unwrapResult(resolved: ResolvedPrompt, schema: LLMSchemaInterface | undefined, sendResult: {
56
+ text?: string;
57
+ data?: unknown;
58
+ parseError?: string;
59
+ }): unknown;
60
+ toTaxonomyError(error: unknown, resolved: ResolvedPrompt, abortSignal?: AbortSignal): Error;
61
+ buildAssistanceService(resolved: ResolvedPrompt, promptName: string): Promise<import("..").LLMAssistanceService<import("../LLMService.typedefs").LLMProviders, LLMReporterInterface<any>>>;
62
+ getBinding(promptName: string): LLMPromptBinding | undefined;
63
+ private buildCompletionService;
64
+ private resolveProviderOptions;
65
+ private buildUserMessage;
66
+ private buildHistory;
67
+ private toCompletionMessage;
68
+ buildReporterContext(resolved: ResolvedPrompt, callContext: LLMClientCallContext | undefined): Record<string, unknown> | undefined;
69
+ /**
70
+ * Builds the per-call trace context every client path threads into the gateway
71
+ * service. The structural `prompt` names the observation and carries the
72
+ * managed prompt version, so the generation the service records on success and
73
+ * on error is the single one Langfuse links to that prompt — the client never
74
+ * records a second observation of its own.
75
+ */
76
+ buildTraceContext(resolved: ResolvedPrompt, callContext: LLMClientCallContext | undefined): LLMCallTraceContext;
77
+ private assertOverridesAllowed;
78
+ private serializeCallContext;
79
+ private extractStatus;
80
+ private isRetryableStatus;
81
+ }