@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.
- package/README.md +193 -0
- package/agent-meta/instructions/llm.instructions.md +66 -0
- package/agent-meta/manifest.json +23 -0
- package/agent-meta/skills/llm/SKILL.md +121 -0
- package/build/consts.d.ts +67 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +76 -0
- package/build/consts.js.map +1 -0
- package/build/errors.d.ts +33 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +52 -0
- package/build/errors.js.map +1 -0
- package/build/execution/index.d.ts +4 -0
- package/build/execution/index.d.ts.map +1 -0
- package/build/execution/index.js +3 -0
- package/build/execution/index.js.map +1 -0
- package/build/execution/service.d.ts +21 -0
- package/build/execution/service.d.ts.map +1 -0
- package/build/execution/service.js +129 -0
- package/build/execution/service.js.map +1 -0
- package/build/execution/types.d.ts +119 -0
- package/build/execution/types.d.ts.map +1 -0
- package/build/execution/types.js +2 -0
- package/build/execution/types.js.map +1 -0
- package/build/execution/utils.d.ts +28 -0
- package/build/execution/utils.d.ts.map +1 -0
- package/build/execution/utils.js +60 -0
- package/build/execution/utils.js.map +1 -0
- package/build/helpers/index.d.ts +5 -0
- package/build/helpers/index.d.ts.map +1 -0
- package/build/helpers/index.js +5 -0
- package/build/helpers/index.js.map +1 -0
- package/build/helpers/json.d.ts +24 -0
- package/build/helpers/json.d.ts.map +1 -0
- package/build/helpers/json.js +119 -0
- package/build/helpers/json.js.map +1 -0
- package/build/helpers/messages.d.ts +10 -0
- package/build/helpers/messages.d.ts.map +1 -0
- package/build/helpers/messages.js +9 -0
- package/build/helpers/messages.js.map +1 -0
- package/build/helpers/retry.d.ts +18 -0
- package/build/helpers/retry.d.ts.map +1 -0
- package/build/helpers/retry.js +57 -0
- package/build/helpers/retry.js.map +1 -0
- package/build/helpers/spectate.d.ts +8 -0
- package/build/helpers/spectate.d.ts.map +1 -0
- package/build/helpers/spectate.js +54 -0
- package/build/helpers/spectate.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +11 -0
- package/build/index.js.map +1 -0
- package/build/model.d.ts +12 -0
- package/build/model.d.ts.map +1 -0
- package/build/model.js +297 -0
- package/build/model.js.map +1 -0
- package/build/plugins/anthropic.d.ts +4 -0
- package/build/plugins/anthropic.d.ts.map +1 -0
- package/build/plugins/anthropic.js +86 -0
- package/build/plugins/anthropic.js.map +1 -0
- package/build/plugins/compatible.d.ts +18 -0
- package/build/plugins/compatible.d.ts.map +1 -0
- package/build/plugins/compatible.js +54 -0
- package/build/plugins/compatible.js.map +1 -0
- package/build/plugins/export.d.ts +6 -0
- package/build/plugins/export.d.ts.map +1 -0
- package/build/plugins/export.js +5 -0
- package/build/plugins/export.js.map +1 -0
- package/build/plugins/index.d.ts +18 -0
- package/build/plugins/index.d.ts.map +1 -0
- package/build/plugins/index.js +42 -0
- package/build/plugins/index.js.map +1 -0
- package/build/plugins/openai.d.ts +28 -0
- package/build/plugins/openai.d.ts.map +1 -0
- package/build/plugins/openai.js +89 -0
- package/build/plugins/openai.js.map +1 -0
- package/build/plugins/types.d.ts +80 -0
- package/build/plugins/types.d.ts.map +1 -0
- package/build/plugins/types.js +2 -0
- package/build/plugins/types.js.map +1 -0
- package/build/plugins/utils.d.ts +27 -0
- package/build/plugins/utils.d.ts.map +1 -0
- package/build/plugins/utils.js +33 -0
- package/build/plugins/utils.js.map +1 -0
- package/build/service.d.ts +24 -0
- package/build/service.d.ts.map +1 -0
- package/build/service.js +95 -0
- package/build/service.js.map +1 -0
- package/build/types.d.ts +190 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils/config.d.ts +13 -0
- package/build/utils/config.d.ts.map +1 -0
- package/build/utils/config.js +15 -0
- package/build/utils/config.js.map +1 -0
- package/build/utils/null-report.d.ts +36 -0
- package/build/utils/null-report.d.ts.map +1 -0
- package/build/utils/null-report.js +84 -0
- package/build/utils/null-report.js.map +1 -0
- package/build/utils/prompt.d.ts +15 -0
- package/build/utils/prompt.d.ts.map +1 -0
- package/build/utils/prompt.js +45 -0
- package/build/utils/prompt.js.map +1 -0
- package/build/utils/schema.d.ts +20 -0
- package/build/utils/schema.d.ts.map +1 -0
- package/build/utils/schema.js +28 -0
- package/build/utils/schema.js.map +1 -0
- package/build/utils/stream.d.ts +22 -0
- package/build/utils/stream.d.ts.map +1 -0
- package/build/utils/stream.js +54 -0
- package/build/utils/stream.js.map +1 -0
- package/package.json +65 -0
- package/src/consts.ts +89 -0
- package/src/errors.ts +65 -0
- package/src/execution/index.ts +4 -0
- package/src/execution/service.ts +185 -0
- package/src/execution/types.ts +139 -0
- package/src/execution/utils.ts +79 -0
- package/src/helpers/index.ts +5 -0
- package/src/helpers/json.ts +117 -0
- package/src/helpers/messages.ts +12 -0
- package/src/helpers/retry.ts +59 -0
- package/src/helpers/spectate.ts +67 -0
- package/src/index.ts +13 -0
- package/src/model.ts +379 -0
- package/src/plugins/anthropic.ts +97 -0
- package/src/plugins/compatible.ts +62 -0
- package/src/plugins/export.ts +6 -0
- package/src/plugins/index.ts +53 -0
- package/src/plugins/openai.ts +108 -0
- package/src/plugins/types.ts +92 -0
- package/src/plugins/utils.ts +38 -0
- package/src/service.ts +125 -0
- package/src/types.ts +214 -0
- package/src/utils/config.ts +19 -0
- package/src/utils/null-report.ts +126 -0
- package/src/utils/prompt.ts +46 -0
- package/src/utils/schema.ts +35 -0
- package/src/utils/stream.ts +58 -0
- package/tests/context.ts +110 -0
- package/tests/execution.spec.ts +200 -0
- package/tests/helpers.spec.ts +192 -0
- package/tests/internals.spec.ts +141 -0
- package/tests/model.spec.ts +116 -0
- package/tests/plugins.spec.ts +227 -0
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"}
|
package/build/service.js
ADDED
|
@@ -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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"}
|