@owlmeans/llm 0.1.14

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 (147) hide show
  1. package/README.md +193 -0
  2. package/agent-meta/instructions/llm.instructions.md +66 -0
  3. package/agent-meta/manifest.json +23 -0
  4. package/agent-meta/skills/llm/SKILL.md +121 -0
  5. package/build/consts.d.ts +67 -0
  6. package/build/consts.d.ts.map +1 -0
  7. package/build/consts.js +76 -0
  8. package/build/consts.js.map +1 -0
  9. package/build/errors.d.ts +33 -0
  10. package/build/errors.d.ts.map +1 -0
  11. package/build/errors.js +52 -0
  12. package/build/errors.js.map +1 -0
  13. package/build/execution/index.d.ts +4 -0
  14. package/build/execution/index.d.ts.map +1 -0
  15. package/build/execution/index.js +3 -0
  16. package/build/execution/index.js.map +1 -0
  17. package/build/execution/service.d.ts +21 -0
  18. package/build/execution/service.d.ts.map +1 -0
  19. package/build/execution/service.js +129 -0
  20. package/build/execution/service.js.map +1 -0
  21. package/build/execution/types.d.ts +119 -0
  22. package/build/execution/types.d.ts.map +1 -0
  23. package/build/execution/types.js +2 -0
  24. package/build/execution/types.js.map +1 -0
  25. package/build/execution/utils.d.ts +28 -0
  26. package/build/execution/utils.d.ts.map +1 -0
  27. package/build/execution/utils.js +60 -0
  28. package/build/execution/utils.js.map +1 -0
  29. package/build/helpers/index.d.ts +5 -0
  30. package/build/helpers/index.d.ts.map +1 -0
  31. package/build/helpers/index.js +5 -0
  32. package/build/helpers/index.js.map +1 -0
  33. package/build/helpers/json.d.ts +24 -0
  34. package/build/helpers/json.d.ts.map +1 -0
  35. package/build/helpers/json.js +119 -0
  36. package/build/helpers/json.js.map +1 -0
  37. package/build/helpers/messages.d.ts +10 -0
  38. package/build/helpers/messages.d.ts.map +1 -0
  39. package/build/helpers/messages.js +9 -0
  40. package/build/helpers/messages.js.map +1 -0
  41. package/build/helpers/retry.d.ts +18 -0
  42. package/build/helpers/retry.d.ts.map +1 -0
  43. package/build/helpers/retry.js +57 -0
  44. package/build/helpers/retry.js.map +1 -0
  45. package/build/helpers/spectate.d.ts +8 -0
  46. package/build/helpers/spectate.d.ts.map +1 -0
  47. package/build/helpers/spectate.js +54 -0
  48. package/build/helpers/spectate.js.map +1 -0
  49. package/build/index.d.ts +13 -0
  50. package/build/index.d.ts.map +1 -0
  51. package/build/index.js +11 -0
  52. package/build/index.js.map +1 -0
  53. package/build/model.d.ts +12 -0
  54. package/build/model.d.ts.map +1 -0
  55. package/build/model.js +297 -0
  56. package/build/model.js.map +1 -0
  57. package/build/plugins/anthropic.d.ts +4 -0
  58. package/build/plugins/anthropic.d.ts.map +1 -0
  59. package/build/plugins/anthropic.js +86 -0
  60. package/build/plugins/anthropic.js.map +1 -0
  61. package/build/plugins/compatible.d.ts +18 -0
  62. package/build/plugins/compatible.d.ts.map +1 -0
  63. package/build/plugins/compatible.js +54 -0
  64. package/build/plugins/compatible.js.map +1 -0
  65. package/build/plugins/export.d.ts +6 -0
  66. package/build/plugins/export.d.ts.map +1 -0
  67. package/build/plugins/export.js +5 -0
  68. package/build/plugins/export.js.map +1 -0
  69. package/build/plugins/index.d.ts +18 -0
  70. package/build/plugins/index.d.ts.map +1 -0
  71. package/build/plugins/index.js +42 -0
  72. package/build/plugins/index.js.map +1 -0
  73. package/build/plugins/openai.d.ts +28 -0
  74. package/build/plugins/openai.d.ts.map +1 -0
  75. package/build/plugins/openai.js +89 -0
  76. package/build/plugins/openai.js.map +1 -0
  77. package/build/plugins/types.d.ts +80 -0
  78. package/build/plugins/types.d.ts.map +1 -0
  79. package/build/plugins/types.js +2 -0
  80. package/build/plugins/types.js.map +1 -0
  81. package/build/plugins/utils.d.ts +27 -0
  82. package/build/plugins/utils.d.ts.map +1 -0
  83. package/build/plugins/utils.js +33 -0
  84. package/build/plugins/utils.js.map +1 -0
  85. package/build/service.d.ts +24 -0
  86. package/build/service.d.ts.map +1 -0
  87. package/build/service.js +95 -0
  88. package/build/service.js.map +1 -0
  89. package/build/types.d.ts +190 -0
  90. package/build/types.d.ts.map +1 -0
  91. package/build/types.js +2 -0
  92. package/build/types.js.map +1 -0
  93. package/build/utils/config.d.ts +13 -0
  94. package/build/utils/config.d.ts.map +1 -0
  95. package/build/utils/config.js +15 -0
  96. package/build/utils/config.js.map +1 -0
  97. package/build/utils/null-report.d.ts +36 -0
  98. package/build/utils/null-report.d.ts.map +1 -0
  99. package/build/utils/null-report.js +84 -0
  100. package/build/utils/null-report.js.map +1 -0
  101. package/build/utils/prompt.d.ts +15 -0
  102. package/build/utils/prompt.d.ts.map +1 -0
  103. package/build/utils/prompt.js +45 -0
  104. package/build/utils/prompt.js.map +1 -0
  105. package/build/utils/schema.d.ts +20 -0
  106. package/build/utils/schema.d.ts.map +1 -0
  107. package/build/utils/schema.js +28 -0
  108. package/build/utils/schema.js.map +1 -0
  109. package/build/utils/stream.d.ts +22 -0
  110. package/build/utils/stream.d.ts.map +1 -0
  111. package/build/utils/stream.js +54 -0
  112. package/build/utils/stream.js.map +1 -0
  113. package/package.json +65 -0
  114. package/src/consts.ts +89 -0
  115. package/src/errors.ts +65 -0
  116. package/src/execution/index.ts +4 -0
  117. package/src/execution/service.ts +185 -0
  118. package/src/execution/types.ts +139 -0
  119. package/src/execution/utils.ts +79 -0
  120. package/src/helpers/index.ts +5 -0
  121. package/src/helpers/json.ts +117 -0
  122. package/src/helpers/messages.ts +12 -0
  123. package/src/helpers/retry.ts +59 -0
  124. package/src/helpers/spectate.ts +67 -0
  125. package/src/index.ts +13 -0
  126. package/src/model.ts +379 -0
  127. package/src/plugins/anthropic.ts +97 -0
  128. package/src/plugins/compatible.ts +62 -0
  129. package/src/plugins/export.ts +6 -0
  130. package/src/plugins/index.ts +53 -0
  131. package/src/plugins/openai.ts +108 -0
  132. package/src/plugins/types.ts +92 -0
  133. package/src/plugins/utils.ts +38 -0
  134. package/src/service.ts +125 -0
  135. package/src/types.ts +214 -0
  136. package/src/utils/config.ts +19 -0
  137. package/src/utils/null-report.ts +126 -0
  138. package/src/utils/prompt.ts +46 -0
  139. package/src/utils/schema.ts +35 -0
  140. package/src/utils/stream.ts +58 -0
  141. package/tests/context.ts +110 -0
  142. package/tests/execution.spec.ts +200 -0
  143. package/tests/helpers.spec.ts +192 -0
  144. package/tests/internals.spec.ts +141 -0
  145. package/tests/model.spec.ts +116 -0
  146. package/tests/plugins.spec.ts +227 -0
  147. package/tsconfig.json +19 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/plugins/anthropic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { LlmPlugin } from './types.js';
2
+ /**
3
+ * Any OpenAI-compatible endpoint that is not OpenAI itself — OpenRouter, the
4
+ * HuggingFace router, Together, a self-hosted vLLM, …
5
+ *
6
+ * Differences from the proprietary `openai` plugin:
7
+ * - Structured output defaults to the forced-tool-call hack. Native `response_format`
8
+ * support is inconsistent across the long tail of servers behind these endpoints, and
9
+ * a server that silently ignores it returns prose instead of JSON.
10
+ * - `modelKwargs` forwards aggregator-specific top-level request fields verbatim:
11
+ * `reasoning` (hard-caps/disables thinking per the config) and
12
+ * `provider.require_parameters`, which tells the aggregator to exclude servers that do
13
+ * not honour every parameter in the request — without it a request can be routed to a
14
+ * server that ignores `tool_choice` and answers `finish_reason='stop'` with no tool
15
+ * call, or that sends the final SSE chunk twice.
16
+ */
17
+ export declare const compatiblePlugin: LlmPlugin;
18
+ //# sourceMappingURL=compatible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compatible.d.ts","sourceRoot":"","sources":["../../src/plugins/compatible.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAQ3C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAoC9B,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { ChatOpenAI } from '@langchain/openai';
2
+ import { ModelProvider, StructuredMode } from '@owlmeans/llm-common';
3
+ import { makeConfiguration } from './utils.js';
4
+ import { openAiFamily } from './openai.js';
5
+ /** Aggregators that encode the serving provider as a `model:provider` suffix. */
6
+ const HUGGINGFACE_MARKER = 'huggingface';
7
+ /**
8
+ * Any OpenAI-compatible endpoint that is not OpenAI itself — OpenRouter, the
9
+ * HuggingFace router, Together, a self-hosted vLLM, …
10
+ *
11
+ * Differences from the proprietary `openai` plugin:
12
+ * - Structured output defaults to the forced-tool-call hack. Native `response_format`
13
+ * support is inconsistent across the long tail of servers behind these endpoints, and
14
+ * a server that silently ignores it returns prose instead of JSON.
15
+ * - `modelKwargs` forwards aggregator-specific top-level request fields verbatim:
16
+ * `reasoning` (hard-caps/disables thinking per the config) and
17
+ * `provider.require_parameters`, which tells the aggregator to exclude servers that do
18
+ * not honour every parameter in the request — without it a request can be routed to a
19
+ * server that ignores `tool_choice` and answers `finish_reason='stop'` with no tool
20
+ * call, or that sends the final SSE chunk twice.
21
+ */
22
+ export const compatiblePlugin = {
23
+ ...openAiFamily,
24
+ type: ModelProvider.Compatible,
25
+ structuredMode: (config) => config.structuredOutput === true ? StructuredMode.Native : StructuredMode.Tool,
26
+ build: ({ config, secret, callbacks }) => {
27
+ const baseModel = config.model ??= 'Qwen/Qwen3-235B-A22B-Instruct-2507';
28
+ const baseURL = config.baseUrl;
29
+ const isHuggingFace = baseURL != null && baseURL.includes(HUGGINGFACE_MARKER);
30
+ const model = config.inferenceProvider != null && isHuggingFace
31
+ ? `${baseModel}:${config.inferenceProvider}`
32
+ : baseModel;
33
+ const headers = {
34
+ ...(isHuggingFace && config.organization != null ? { 'X-HF-Bill-To': config.organization } : {}),
35
+ ...config.headers,
36
+ };
37
+ return new ChatOpenAI({
38
+ model,
39
+ apiKey: secret,
40
+ temperature: config.temperature ?? 0,
41
+ maxTokens: config.maxTokens ?? 4096,
42
+ topP: config.topP ?? 0.8,
43
+ maxRetries: 5,
44
+ metadata: { config },
45
+ callbacks,
46
+ modelKwargs: {
47
+ ...(config.reasoning != null ? { reasoning: config.reasoning } : {}),
48
+ provider: { require_parameters: true },
49
+ },
50
+ ...makeConfiguration({ baseURL, headers }),
51
+ });
52
+ },
53
+ };
54
+ //# sourceMappingURL=compatible.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compatible.js","sourceRoot":"","sources":["../../src/plugins/compatible.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAGpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,iFAAiF;AACjF,MAAM,kBAAkB,GAAG,aAAa,CAAA;AAExC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAc;IACzC,GAAG,YAAY;IAEf,IAAI,EAAE,aAAa,CAAC,UAAU;IAE9B,cAAc,EAAE,CAAC,MAAmB,EAAkB,EAAE,CACtD,MAAM,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI;IAEhF,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;QACvC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,KAAK,oCAAoC,CAAA;QACvE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAC9B,MAAM,aAAa,GAAG,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAA;QAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,iBAAiB,IAAI,IAAI,IAAI,aAAa;YAC7D,CAAC,CAAC,GAAG,SAAS,IAAI,MAAM,CAAC,iBAAiB,EAAE;YAC5C,CAAC,CAAC,SAAS,CAAA;QACb,MAAM,OAAO,GAA2B;YACtC,GAAG,CAAC,aAAa,IAAI,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChG,GAAG,MAAM,CAAC,OAAO;SAClB,CAAA;QAED,OAAO,IAAI,UAAU,CAAC;YACpB,KAAK;YACL,MAAM,EAAE,MAAM;YACd,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC;YACpC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;YACnC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,GAAG;YACxB,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,EAAE,MAAM,EAAE;YACpB,SAAS;YACT,WAAW,EAAE;gBACX,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpE,QAAQ,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE;aACvC;YACD,GAAG,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;SAC3C,CAAC,CAAA;IACJ,CAAC;CACF,CAAA"}
@@ -0,0 +1,6 @@
1
+ export type * from './types.js';
2
+ export * from './anthropic.js';
3
+ export * from './compatible.js';
4
+ export * from './openai.js';
5
+ export { plugins, registerLlmPlugin, pluginOf, pluginFor, resolvePlugin } from './index.js';
6
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/plugins/export.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * from './anthropic.js';
2
+ export * from './compatible.js';
3
+ export * from './openai.js';
4
+ export { plugins, registerLlmPlugin, pluginOf, pluginFor, resolvePlugin } from './index.js';
5
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/plugins/export.ts"],"names":[],"mappings":"AAEA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,18 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { LlmPlugin } from './types.js';
3
+ export declare const plugins: Record<string, LlmPlugin>;
4
+ /** Register (or replace) a provider plugin. Later registrations go last in the lookup order. */
5
+ export declare const registerLlmPlugin: (plugin: LlmPlugin) => void;
6
+ /** The plugin registered for `provider`, or `undefined`. */
7
+ export declare const pluginOf: (provider: string | undefined) => LlmPlugin | undefined;
8
+ /** The first registered plugin that recognises this model instance, or `undefined`. */
9
+ export declare const pluginFor: (model: BaseChatModel) => LlmPlugin | undefined;
10
+ /**
11
+ * Resolve the plugin governing a call. The config's `provider` is authoritative; when it
12
+ * is unavailable (a refined instance whose metadata did not survive) the model instance
13
+ * is matched against the registration order.
14
+ */
15
+ export declare const resolvePlugin: (config: {
16
+ provider?: string;
17
+ } | undefined, model?: BaseChatModel) => LlmPlugin;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAA;AAEhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAK3C,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAM,CAAA;AAWpD,gGAAgG;AAChG,eAAO,MAAM,iBAAiB,GAAI,QAAQ,SAAS,KAAG,IAKrD,CAAA;AAMD,4DAA4D;AAC5D,eAAO,MAAM,QAAQ,GAAI,UAAU,MAAM,GAAG,SAAS,KAAG,SAAS,GAAG,SAClB,CAAA;AAElD,uFAAuF;AACvF,eAAO,MAAM,SAAS,GAAI,OAAO,aAAa,KAAG,SAAS,GAAG,SACkB,CAAA;AAE/E;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACzC,QAAQ,aAAa,KACpB,SAMF,CAAA"}
@@ -0,0 +1,42 @@
1
+ import { LlmPluginError } from '../errors.js';
2
+ import { anthropicPlugin } from './anthropic.js';
3
+ import { compatiblePlugin } from './compatible.js';
4
+ import { openAiPlugin } from './openai.js';
5
+ export const plugins = {};
6
+ /**
7
+ * Lookup order for INSTANCE-based resolution (a model whose config metadata is not
8
+ * reachable). The first plugin whose `owns` matches wins, so the conservative member of
9
+ * a client family must come first: `compatible` precedes `openai` because both build a
10
+ * `ChatOpenAI`, and assuming the tool-calling hack for an unlabelled model is safe
11
+ * everywhere, while assuming native JSON-schema support is not.
12
+ */
13
+ const order = [];
14
+ /** Register (or replace) a provider plugin. Later registrations go last in the lookup order. */
15
+ export const registerLlmPlugin = (plugin) => {
16
+ if (plugins[plugin.type] == null) {
17
+ order.push(plugin.type);
18
+ }
19
+ plugins[plugin.type] = plugin;
20
+ };
21
+ registerLlmPlugin(anthropicPlugin);
22
+ registerLlmPlugin(compatiblePlugin);
23
+ registerLlmPlugin(openAiPlugin);
24
+ /** The plugin registered for `provider`, or `undefined`. */
25
+ export const pluginOf = (provider) => provider != null ? plugins[provider] : undefined;
26
+ /** The first registered plugin that recognises this model instance, or `undefined`. */
27
+ export const pluginFor = (model) => order.map(type => plugins[type]).find(plugin => plugin?.owns(model) === true);
28
+ /**
29
+ * Resolve the plugin governing a call. The config's `provider` is authoritative; when it
30
+ * is unavailable (a refined instance whose metadata did not survive) the model instance
31
+ * is matched against the registration order.
32
+ */
33
+ export const resolvePlugin = (config, model) => {
34
+ const byType = pluginOf(config?.provider);
35
+ if (byType != null)
36
+ return byType;
37
+ const byModel = model != null ? pluginFor(model) : undefined;
38
+ if (byModel != null)
39
+ return byModel;
40
+ throw new LlmPluginError(`${LlmPluginError.NO_PLUGIN}:${config?.provider ?? 'unknown'}`);
41
+ };
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,CAAC,MAAM,OAAO,GAA8B,EAAE,CAAA;AAEpD;;;;;;GAMG;AACH,MAAM,KAAK,GAAa,EAAE,CAAA;AAE1B,gGAAgG;AAChG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAiB,EAAQ,EAAE;IAC3D,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAA;AAC/B,CAAC,CAAA;AAED,iBAAiB,CAAC,eAAe,CAAC,CAAA;AAClC,iBAAiB,CAAC,gBAAgB,CAAC,CAAA;AACnC,iBAAiB,CAAC,YAAY,CAAC,CAAA;AAE/B,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAA4B,EAAyB,EAAE,CAC9E,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAElD,uFAAuF;AACvF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAoB,EAAyB,EAAE,CACvE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAA;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,MAAyC,EACzC,KAAqB,EACV,EAAE;IACb,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACzC,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,MAAM,CAAA;IACjC,MAAM,OAAO,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC5D,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,OAAO,CAAA;IACnC,MAAM,IAAI,cAAc,CAAC,GAAG,cAAc,CAAC,SAAS,IAAI,MAAM,EAAE,QAAQ,IAAI,SAAS,EAAE,CAAC,CAAA;AAC1F,CAAC,CAAA"}
@@ -0,0 +1,28 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { LlmPlugin, LlmRefineParams } from './types.js';
3
+ export declare const OPENAI_FAMILY = "openai";
4
+ /** Every plugin that constructs a `ChatOpenAI` shares these instance-level behaviours. */
5
+ export declare const openAiFamily: {
6
+ family: string;
7
+ owns: (model: BaseChatModel) => boolean;
8
+ /**
9
+ * langchain converts the OpenAI-shaped tool DEFINITION for either provider, but the
10
+ * `tool_choice` shape is NOT converted — this is the OpenAI spelling.
11
+ */
12
+ toolChoice: (toolName: string) => unknown;
13
+ /**
14
+ * `strict: false` keeps schemas that do not satisfy OpenAI strict-mode rules
15
+ * acceptable; the model's own ajv validation still enforces conformance afterwards.
16
+ * With `provider.require_parameters` already set, sending `response_format` also makes
17
+ * an aggregator route only to providers that actually support structured outputs.
18
+ */
19
+ responseFormat: (toolName: string, schema: unknown) => Record<string, unknown>;
20
+ refine: ({ base, attempt, temperature, maxOutputCap }: LlmRefineParams) => BaseChatModel;
21
+ };
22
+ /**
23
+ * Proprietary OpenAI endpoint. Defaults to the provider's NATIVE JSON-schema mode for
24
+ * structured output — it is reliable there, unlike on the long tail of
25
+ * OpenAI-compatible endpoints (see the `compatible` plugin).
26
+ */
27
+ export declare const openAiPlugin: LlmPlugin;
28
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/plugins/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAA;AAEhF,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAO5D,eAAO,MAAM,aAAa,WAAW,CAAA;AAErC,0FAA0F;AAC1F,eAAO,MAAM,YAAY;;kBAGT,aAAa,KAAG,OAAO;IAErC;;;OAGG;2BACoB,MAAM,KAAG,OAAO;IAEvC;;;;;OAKG;+BACwB,MAAM,UAAU,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;2DAKrB,eAAe,KAAG,aAAa;CA2BvF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAsC1B,CAAA"}
@@ -0,0 +1,89 @@
1
+ import { ChatOpenAI } from '@langchain/openai';
2
+ import { ModelProvider, StructuredMode } from '@owlmeans/llm-common';
3
+ import { escalateMaxTokens, makeConfiguration } from './utils.js';
4
+ /** Model families served through OpenAI's Responses API rather than chat completions. */
5
+ const RESPONSES_API_PREFIXES = ['gpt-5', 'codex-'];
6
+ export const OPENAI_FAMILY = 'openai';
7
+ /** Every plugin that constructs a `ChatOpenAI` shares these instance-level behaviours. */
8
+ export const openAiFamily = {
9
+ family: OPENAI_FAMILY,
10
+ owns: (model) => model instanceof ChatOpenAI,
11
+ /**
12
+ * langchain converts the OpenAI-shaped tool DEFINITION for either provider, but the
13
+ * `tool_choice` shape is NOT converted — this is the OpenAI spelling.
14
+ */
15
+ toolChoice: (toolName) => ({ type: 'function', function: { name: toolName } }),
16
+ /**
17
+ * `strict: false` keeps schemas that do not satisfy OpenAI strict-mode rules
18
+ * acceptable; the model's own ajv validation still enforces conformance afterwards.
19
+ * With `provider.require_parameters` already set, sending `response_format` also makes
20
+ * an aggregator route only to providers that actually support structured outputs.
21
+ */
22
+ responseFormat: (toolName, schema) => ({
23
+ type: 'json_schema',
24
+ json_schema: { name: toolName, schema, strict: false },
25
+ }),
26
+ refine: ({ base, attempt, temperature, maxOutputCap }) => {
27
+ const model = base;
28
+ const currentTemperature = temperature ?? model.temperature ?? 0;
29
+ const maxTokens = escalateMaxTokens(model.maxTokens, attempt, maxOutputCap);
30
+ const baseKwargs = model.lc_kwargs;
31
+ // The dominant cause of an empty response is a reasoning model spending the whole
32
+ // budget on hidden thinking (finish_reason=length, empty content). The retry already
33
+ // raises maxTokens; ALSO shrink the absolute reasoning cap so the extra budget becomes
34
+ // visible output instead of more reasoning. Only touches `{ max_tokens: N }` reasoning
35
+ // configs — effort/enabled/exclude shapes are left untouched.
36
+ const reasoning = baseKwargs.modelKwargs?.reasoning;
37
+ const modelKwargs = attempt > 0 && typeof reasoning?.max_tokens === 'number'
38
+ ? {
39
+ ...baseKwargs.modelKwargs,
40
+ reasoning: { ...reasoning, max_tokens: Math.max(256, Math.floor(reasoning.max_tokens / Math.pow(2, attempt))) },
41
+ }
42
+ : baseKwargs.modelKwargs;
43
+ return new ChatOpenAI({
44
+ ...baseKwargs,
45
+ temperature: currentTemperature,
46
+ maxTokens,
47
+ ...(modelKwargs != null ? { modelKwargs } : {}),
48
+ });
49
+ },
50
+ };
51
+ /**
52
+ * Proprietary OpenAI endpoint. Defaults to the provider's NATIVE JSON-schema mode for
53
+ * structured output — it is reliable there, unlike on the long tail of
54
+ * OpenAI-compatible endpoints (see the `compatible` plugin).
55
+ */
56
+ export const openAiPlugin = {
57
+ ...openAiFamily,
58
+ type: ModelProvider.OpenAI,
59
+ structuredMode: (config) => config.structuredOutput === false ? StructuredMode.Tool : StructuredMode.Native,
60
+ build: ({ config, secret, callbacks }) => {
61
+ const model = config.model ??= 'gpt-5.4-mini';
62
+ const configuration = makeConfiguration({ baseURL: undefined, headers: config.headers });
63
+ // The Responses API models reject `temperature`/`topP`.
64
+ if (RESPONSES_API_PREFIXES.some(prefix => model.startsWith(prefix))) {
65
+ return new ChatOpenAI({
66
+ model,
67
+ apiKey: secret,
68
+ maxTokens: config.maxTokens ?? 4096,
69
+ maxRetries: 5,
70
+ useResponsesApi: true,
71
+ metadata: { config },
72
+ callbacks,
73
+ ...configuration,
74
+ });
75
+ }
76
+ return new ChatOpenAI({
77
+ model,
78
+ apiKey: secret,
79
+ temperature: config.temperature ?? 0,
80
+ maxTokens: config.maxTokens ?? 4096,
81
+ topP: config.topP ?? 0.8,
82
+ maxRetries: 5,
83
+ metadata: { config },
84
+ callbacks,
85
+ ...configuration,
86
+ });
87
+ },
88
+ };
89
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/plugins/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { BaseCallbackHandler, CallbackHandlerMethods } from '@langchain/core/callbacks/base';
3
+ import type { MessageFieldWithRole } from '@langchain/core/messages';
4
+ import type { StructuredMode } from '@owlmeans/llm-common';
5
+ import type { ModelConfig } from '../types.js';
6
+ export interface LlmBuildParams {
7
+ /** Alias the config was registered under — used only for error reporting. */
8
+ alias: string;
9
+ /**
10
+ * Fully resolved config with the secret already stripped. Whatever the plugin puts
11
+ * on the client as `metadata.config` is what `readConfig` later reads back, so the
12
+ * plugin should apply its model default to this object before building.
13
+ */
14
+ config: ModelConfig;
15
+ secret: string;
16
+ callbacks: (BaseCallbackHandler | CallbackHandlerMethods)[];
17
+ }
18
+ export interface LlmRefineParams {
19
+ /** The model to rebuild — the primary, or the fallback once escalation kicked in. */
20
+ base: BaseChatModel;
21
+ /** 0-based retry attempt; the output budget doubles with it. */
22
+ attempt: number;
23
+ /** Call-site temperature override (`invoke`). */
24
+ temperature?: number | undefined;
25
+ /** Hard ceiling the doubled output budget is clamped to. */
26
+ maxOutputCap: number;
27
+ }
28
+ export interface LlmCacheParams {
29
+ /** The ORIGINAL (unrefined) model — refined instances do not always keep the name. */
30
+ model: BaseChatModel;
31
+ useCache: boolean;
32
+ cacheMax: number;
33
+ }
34
+ /**
35
+ * Everything that differs between inference providers, in one replaceable unit.
36
+ *
37
+ * Registration order matters for instance-based lookup (`resolvePlugin` with no
38
+ * `provider` in the config): the FIRST plugin whose `owns` matches wins, so the
39
+ * conservative member of a family must be registered before the permissive one.
40
+ * See `plugins/index.ts`.
41
+ */
42
+ export interface LlmPlugin {
43
+ /** Provider identifier — a `ModelProvider` value, or a custom string. */
44
+ type: string;
45
+ /**
46
+ * Instance behaviour group. Two plugins that construct the same client class share a
47
+ * family (e.g. `openai` and `compatible` both produce `ChatOpenAI`). The retry
48
+ * escalator refuses to switch to a fallback from a different family, because the
49
+ * structured-output call shape would change mid-call.
50
+ */
51
+ family: string;
52
+ /** Construct the chat client from a resolved config. */
53
+ build: (params: LlmBuildParams) => BaseChatModel;
54
+ /** Does this model instance belong to this plugin's client family? */
55
+ owns: (model: BaseChatModel) => boolean;
56
+ /**
57
+ * Rebuild the model for retry attempt N: raise the output budget toward
58
+ * `maxOutputCap` and apply any provider-specific escalation (e.g. shrinking a
59
+ * reasoning budget so the extra tokens become visible output).
60
+ */
61
+ refine: (params: LlmRefineParams) => BaseChatModel;
62
+ /** How this provider should be asked for schema-conforming output. */
63
+ structuredMode: (config: ModelConfig) => StructuredMode;
64
+ /** Provider-specific `tool_choice` shape that pins the model to `toolName`. */
65
+ toolChoice: (toolName: string) => unknown;
66
+ /** Provider-specific `response_format` for {@link StructuredMode.Native}. */
67
+ responseFormat?: (toolName: string, schema: unknown) => Record<string, unknown>;
68
+ /**
69
+ * Mark leading messages as cacheable in-place. Returns `true` when caching was
70
+ * actually applied (the model may not support it). Omit for providers with no
71
+ * explicit prompt-cache markers.
72
+ */
73
+ patchCache?: (msgs: MessageFieldWithRole[], params: LlmCacheParams) => boolean;
74
+ /**
75
+ * Classify a thrown error as fatal for the retry loop. Return the error to throw
76
+ * immediately, or `null` to let it be retried.
77
+ */
78
+ isFatal?: (e: unknown) => Error | null;
79
+ }
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAA;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACjG,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,CAAC,mBAAmB,GAAG,sBAAsB,CAAC,EAAE,CAAA;CAC5D;AAED,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,IAAI,EAAE,aAAa,CAAA;IACnB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,sFAAsF;IACtF,KAAK,EAAE,aAAa,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAA;IAEd,wDAAwD;IACxD,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,aAAa,CAAA;IAEhD,sEAAsE;IACtE,IAAI,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAA;IAEvC;;;;OAIG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,aAAa,CAAA;IAElD,sEAAsE;IACtE,cAAc,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,cAAc,CAAA;IAEvD,+EAA+E;IAC/E,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAEzC,6EAA6E;IAC7E,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAE/E;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,cAAc,KAAK,OAAO,CAAA;IAE9E;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,KAAK,GAAG,IAAI,CAAA;CACvC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared construction bits for the built-in plugins. Internal to `plugins/` — not
3
+ * part of the package's public surface.
4
+ */
5
+ /**
6
+ * `{ configuration: { baseURL?, defaultHeaders? } }` for the OpenAI-compatible client,
7
+ * or an empty object when there is nothing to set (the client rejects an empty
8
+ * `configuration` in some versions).
9
+ */
10
+ export declare const makeConfiguration: ({ baseURL, headers }: {
11
+ baseURL: string | undefined;
12
+ headers: Record<string, string> | undefined;
13
+ }) => {
14
+ configuration: Record<string, unknown>;
15
+ } | Record<string, never>;
16
+ /** `{ clientOptions: { defaultHeaders } }` for the Anthropic client, or an empty object. */
17
+ export declare const makeClientOptions: ({ headers }: {
18
+ headers: Record<string, string> | undefined;
19
+ }) => {
20
+ clientOptions: Record<string, unknown>;
21
+ } | Record<string, never>;
22
+ /**
23
+ * Output budget for retry attempt N: double the base budget per attempt, clamped to
24
+ * the model's hard ceiling.
25
+ */
26
+ export declare const escalateMaxTokens: (base: number | undefined, attempt: number, cap: number) => number;
27
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/plugins/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,sBAAsB;IAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,KACjG;IAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAUnE,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,GAC5B,aAAa;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,KAC3D;IAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAGnE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,GAAG,SAAS,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,KAAG,MACrC,CAAA"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared construction bits for the built-in plugins. Internal to `plugins/` — not
3
+ * part of the package's public surface.
4
+ */
5
+ /**
6
+ * `{ configuration: { baseURL?, defaultHeaders? } }` for the OpenAI-compatible client,
7
+ * or an empty object when there is nothing to set (the client rejects an empty
8
+ * `configuration` in some versions).
9
+ */
10
+ export const makeConfiguration = ({ baseURL, headers }) => {
11
+ const hasBaseURL = baseURL != null;
12
+ const hasHeaders = headers != null && Object.keys(headers).length > 0;
13
+ if (!hasBaseURL && !hasHeaders)
14
+ return {};
15
+ return {
16
+ configuration: {
17
+ ...(hasBaseURL ? { baseURL } : {}),
18
+ ...(hasHeaders ? { defaultHeaders: headers } : {}),
19
+ }
20
+ };
21
+ };
22
+ /** `{ clientOptions: { defaultHeaders } }` for the Anthropic client, or an empty object. */
23
+ export const makeClientOptions = ({ headers }) => {
24
+ if (headers == null || Object.keys(headers).length === 0)
25
+ return {};
26
+ return { clientOptions: { defaultHeaders: headers } };
27
+ };
28
+ /**
29
+ * Output budget for retry attempt N: double the base budget per attempt, clamped to
30
+ * the model's hard ceiling.
31
+ */
32
+ export const escalateMaxTokens = (base, attempt, cap) => Math.min((base ?? 2048) * Math.pow(2, attempt), cap);
33
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/plugins/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,EAAE,OAAO,EAAE,OAAO,EAAgF,EAC9B,EAAE;IACtE,MAAM,UAAU,GAAG,OAAO,IAAI,IAAI,CAAA;IAClC,MAAM,UAAU,GAAG,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;IACrE,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAA;IACzC,OAAO;QACL,aAAa,EAAE;YACb,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD;KACF,CAAA;AACH,CAAC,CAAA;AAED,4FAA4F;AAC5F,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,EAAE,OAAO,EAAmD,EACQ,EAAE;IACtE,IAAI,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACnE,OAAO,EAAE,aAAa,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,CAAA;AACvD,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAwB,EAAE,OAAe,EAAE,GAAW,EAAU,EAAE,CAClG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA"}
@@ -0,0 +1,24 @@
1
+ import type { BasicConfig, BasicContext } from '@owlmeans/context';
2
+ import type { LlmService, LlmServiceOptions, WithLlmService } from './types.js';
3
+ /** The part of {@link LlmService} this package implements — see {@link llmServiceApi}. */
4
+ export type LlmServiceApi = Pick<LlmService, 'models' | 'callbacks' | 'addCallbacks' | 'getModel' | 'configs'>;
5
+ /**
6
+ * Build the model-factory half of an LLM service, WITHOUT registering it as a context
7
+ * service. Spread it into your own `createService` implementation to publish extra
8
+ * methods (role-named accessors, domain helpers) alongside it:
9
+ *
10
+ * ```ts
11
+ * const service = createService<MyService>(alias, {
12
+ * ...llmServiceApi(options, () => service),
13
+ * getPicker: override => service.getModel(MyRole.Picker, override),
14
+ * } as MyService)
15
+ * ```
16
+ *
17
+ * `self` is a late-bound reference to the finished service, because the methods read
18
+ * mutable state (`models`, `callbacks`) off the registered instance rather than the
19
+ * literal.
20
+ */
21
+ export declare const llmServiceApi: (options: LlmServiceOptions, self: () => LlmService) => LlmServiceApi;
22
+ export declare const makeLlmService: (options: LlmServiceOptions, alias?: string) => LlmService;
23
+ export declare const appendLlmService: <C extends BasicConfig, T extends BasicContext<C>>(ctx: T, options: LlmServiceOptions, alias?: string) => T & WithLlmService;
24
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKlE,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAe,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5F,0FAA0F;AAC1F,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,WAAW,GAAG,cAAc,GAAG,UAAU,GAAG,SAAS,CAAC,CAAA;AAE9G;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,GAAI,SAAS,iBAAiB,EAAE,MAAM,MAAM,UAAU,KAAG,aA2ElF,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,SAAS,iBAAiB,EAAE,QAAO,MAAoB,KAAG,UAMxF,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAC/E,KAAK,CAAC,EACN,SAAS,iBAAiB,EAC1B,QAAO,MAAoB,KAC1B,CAAC,GAAG,cAQN,CAAA"}
@@ -0,0 +1,95 @@
1
+ import { createService } from '@owlmeans/context';
2
+ import { LLM_SERVICE } from './consts.js';
3
+ import { LlmMissconfiguredError } from './errors.js';
4
+ import { resolvePlugin } from './plugins/index.js';
5
+ /**
6
+ * Build the model-factory half of an LLM service, WITHOUT registering it as a context
7
+ * service. Spread it into your own `createService` implementation to publish extra
8
+ * methods (role-named accessors, domain helpers) alongside it:
9
+ *
10
+ * ```ts
11
+ * const service = createService<MyService>(alias, {
12
+ * ...llmServiceApi(options, () => service),
13
+ * getPicker: override => service.getModel(MyRole.Picker, override),
14
+ * } as MyService)
15
+ * ```
16
+ *
17
+ * `self` is a late-bound reference to the finished service, because the methods read
18
+ * mutable state (`models`, `callbacks`) off the registered instance rather than the
19
+ * literal.
20
+ */
21
+ export const llmServiceApi = (options, self) => {
22
+ /** Build one client from a fully-resolved config — no preset/fallback logic here. */
23
+ const buildModel = (alias, config) => {
24
+ if (config.provider == null || config.secret == null) {
25
+ throw new LlmMissconfiguredError(alias);
26
+ }
27
+ const { secret, ...rest } = config;
28
+ return resolvePlugin(rest).build({
29
+ alias, config: rest, secret, callbacks: self().callbacks,
30
+ });
31
+ };
32
+ /**
33
+ * Resolve `alias` → config (inheriting a `preset`, applying `override`) and build it.
34
+ * A declared `fallback` is built as well and attached to the primary as a
35
+ * non-enumerable `__fallbackModel`, which the model's retry escalator reads. The
36
+ * fallback spec is merged OVER the primary config, so it inherits secret/headers.
37
+ */
38
+ const createModel = (alias, override = {}) => {
39
+ const models = options.models();
40
+ const baseConfig = models.find(m => m.alias === alias);
41
+ if (baseConfig == null) {
42
+ throw new LlmMissconfiguredError(alias);
43
+ }
44
+ const config = { ...baseConfig, ...override };
45
+ const preset = config.preset != null
46
+ ? { ...(models.find(m => m.alias === config.preset) ?? {}) }
47
+ : {};
48
+ if (preset.alias != null) {
49
+ delete preset.alias;
50
+ }
51
+ Object.assign(config, preset);
52
+ const { fallback, ...primaryConfig } = config;
53
+ const primary = buildModel(alias, primaryConfig);
54
+ if (fallback != null) {
55
+ const { fallback: _nested, ...fallbackConfig } = { ...primaryConfig, ...fallback };
56
+ Object.defineProperty(primary, '__fallbackModel', {
57
+ value: buildModel(alias, fallbackConfig),
58
+ enumerable: false,
59
+ configurable: true,
60
+ });
61
+ }
62
+ return primary;
63
+ };
64
+ const cacheKey = (alias, override = {}) => `${alias}:${JSON.stringify(override)}`;
65
+ return {
66
+ models: new Map(),
67
+ callbacks: [],
68
+ addCallbacks: callbacks => {
69
+ self().callbacks.push(...callbacks);
70
+ },
71
+ configs: () => options.models(),
72
+ getModel: (alias, override = {}, createNew = false) => {
73
+ const service = self();
74
+ const key = cacheKey(alias, override);
75
+ const model = createNew || !service.models.has(key)
76
+ ? createModel(alias, override)
77
+ : service.models.get(key);
78
+ if (!createNew) {
79
+ service.models.set(key, model);
80
+ }
81
+ return model;
82
+ },
83
+ };
84
+ };
85
+ export const makeLlmService = (options, alias = LLM_SERVICE) => {
86
+ const service = createService(alias, llmServiceApi(options, () => service));
87
+ return service;
88
+ };
89
+ export const appendLlmService = (ctx, options, alias = LLM_SERVICE) => {
90
+ const context = ctx;
91
+ context.registerService(makeLlmService(options, alias));
92
+ context.llm = () => ctx.service(alias);
93
+ return context;
94
+ };
95
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}