@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,18 @@
|
|
|
1
|
+
import type { FatalErrorResolver, RetryOptions } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register a globally-applicable rule that turns a thrown error into an immediate
|
|
4
|
+
* abort of every retry loop in this package. Use it for conditions no amount of
|
|
5
|
+
* retrying can fix — an exhausted budget, a revoked credential, a cancelled job.
|
|
6
|
+
*
|
|
7
|
+
* Provider plugins contribute their own through `LlmPlugin.isFatal`; both sets are
|
|
8
|
+
* consulted, plus the per-call {@link RetryOptions.fatal}.
|
|
9
|
+
*/
|
|
10
|
+
export declare const registerFatalError: (resolver: FatalErrorResolver) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Run `fn` up to `retries` times, passing the 0-based attempt number so the callee can
|
|
13
|
+
* escalate (a bigger output budget, a stronger model). Every non-fatal error is
|
|
14
|
+
* swallowed and retained as the `cause` of the {@link LlmRetryExceededError} thrown when
|
|
15
|
+
* the attempts run out; a fatal error (see {@link registerFatalError}) is rethrown at once.
|
|
16
|
+
*/
|
|
17
|
+
export declare const withRetry: <T>({ retries, outputErrors, fatal }: RetryOptions, fn: (attempt: number) => Promise<T>) => Promise<T>;
|
|
18
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/helpers/retry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAInE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,kBAAkB,KAAG,IAEjE,CAAA;AAgBD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,EAC/B,kCAA0C,YAAY,EACtD,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAClC,OAAO,CAAC,CAAC,CAiBX,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { LlmRetryExceededError } from '../errors.js';
|
|
2
|
+
import { plugins } from '../plugins/index.js';
|
|
3
|
+
const resolvers = [];
|
|
4
|
+
/**
|
|
5
|
+
* Register a globally-applicable rule that turns a thrown error into an immediate
|
|
6
|
+
* abort of every retry loop in this package. Use it for conditions no amount of
|
|
7
|
+
* retrying can fix — an exhausted budget, a revoked credential, a cancelled job.
|
|
8
|
+
*
|
|
9
|
+
* Provider plugins contribute their own through `LlmPlugin.isFatal`; both sets are
|
|
10
|
+
* consulted, plus the per-call {@link RetryOptions.fatal}.
|
|
11
|
+
*/
|
|
12
|
+
export const registerFatalError = (resolver) => {
|
|
13
|
+
resolvers.push(resolver);
|
|
14
|
+
};
|
|
15
|
+
const resolveFatal = (e, fatal) => {
|
|
16
|
+
const own = fatal?.(e);
|
|
17
|
+
if (own != null)
|
|
18
|
+
return own;
|
|
19
|
+
for (const resolver of resolvers) {
|
|
20
|
+
const found = resolver(e);
|
|
21
|
+
if (found != null)
|
|
22
|
+
return found;
|
|
23
|
+
}
|
|
24
|
+
for (const plugin of Object.values(plugins)) {
|
|
25
|
+
const found = plugin.isFatal?.(e);
|
|
26
|
+
if (found != null)
|
|
27
|
+
return found;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Run `fn` up to `retries` times, passing the 0-based attempt number so the callee can
|
|
33
|
+
* escalate (a bigger output budget, a stronger model). Every non-fatal error is
|
|
34
|
+
* swallowed and retained as the `cause` of the {@link LlmRetryExceededError} thrown when
|
|
35
|
+
* the attempts run out; a fatal error (see {@link registerFatalError}) is rethrown at once.
|
|
36
|
+
*/
|
|
37
|
+
export const withRetry = async ({ retries, outputErrors = false, fatal }, fn) => {
|
|
38
|
+
const exceeded = new LlmRetryExceededError('max-retries');
|
|
39
|
+
for (let i = 0; i < retries; ++i) {
|
|
40
|
+
try {
|
|
41
|
+
return await fn(i);
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
const abort = resolveFatal(e, fatal);
|
|
45
|
+
if (abort != null)
|
|
46
|
+
throw abort;
|
|
47
|
+
exceeded.cause = e;
|
|
48
|
+
exceeded.attempt = i;
|
|
49
|
+
if (outputErrors) {
|
|
50
|
+
console.debug('Retry error on attempt', i);
|
|
51
|
+
console.error(e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
throw exceeded;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/helpers/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,MAAM,SAAS,GAAyB,EAAE,CAAA;AAE1C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAA4B,EAAQ,EAAE;IACvE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AAC1B,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,CAAU,EAAE,KAA0B,EAAgB,EAAE;IAC5E,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;IACtB,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,GAAG,CAAA;IAC3B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,KAAK,CAAA;IACjC,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;QACjC,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,KAAK,CAAA;IACjC,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,EAAE,OAAO,EAAE,YAAY,GAAG,KAAK,EAAE,KAAK,EAAgB,EACtD,EAAmC,EACvB,EAAE;IACd,MAAM,QAAQ,GAAG,IAAI,qBAAqB,CAAC,aAAa,CAAC,CAAA;IACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;QACpB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;YACpC,IAAI,KAAK,IAAI,IAAI;gBAAE,MAAM,KAAK,CAAA;YAC9B,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAA;YAClB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAA;YACpB,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAA;gBAC1C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AIMessage } from '@langchain/core/messages';
|
|
2
|
+
import type { LlmSpectator, ModelInputItem } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Log a completed model call: every prompt message plus the completion, as one entry.
|
|
5
|
+
* A tool-calling completion carries its arguments rather than its (empty) content.
|
|
6
|
+
*/
|
|
7
|
+
export declare const spectate: (spectator: LlmSpectator, callType: string) => (input: ModelInputItem[], message: AIMessage, action: string, retries: number, startedAt?: number) => Promise<import("@owlmeans/llm-common").SpectatorEntryLogged>;
|
|
8
|
+
//# sourceMappingURL=spectate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spectate.d.ts","sourceRoot":"","sources":["../../src/helpers/spectate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAA;AAIjE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AA8B/D;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,WAAW,YAAY,EAAE,UAAU,MAAM,MAE9D,OAAO,cAAc,EAAE,EACvB,SAAS,SAAS,EAClB,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,YAAY,MAAM,iEAsBnB,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
import { SpectatorContentType } from '@owlmeans/llm-common';
|
|
3
|
+
/** Normalize one prompt message into the spectator's storage shape. */
|
|
4
|
+
const describeInput = (msg, callType) => {
|
|
5
|
+
const entry = {
|
|
6
|
+
callType,
|
|
7
|
+
type: 'unknown',
|
|
8
|
+
content: '',
|
|
9
|
+
contentType: SpectatorContentType.Text,
|
|
10
|
+
};
|
|
11
|
+
if (msg instanceof BaseMessage) {
|
|
12
|
+
entry.type = msg.type;
|
|
13
|
+
entry.content = msg.content;
|
|
14
|
+
entry.name = msg.name;
|
|
15
|
+
entry.contentType = typeof msg.content === 'string' ? SpectatorContentType.Text : SpectatorContentType.Json;
|
|
16
|
+
entry.usage = 'usage_metadata' in msg ? msg.usage_metadata : undefined;
|
|
17
|
+
entry.raw = JSON.stringify({ message: msg, content: msg.content, meta: msg.response_metadata });
|
|
18
|
+
}
|
|
19
|
+
else if (typeof msg === 'object' && 'content' in msg) {
|
|
20
|
+
entry.type = msg.role ?? 'unknown';
|
|
21
|
+
entry.content = msg.content ?? msg;
|
|
22
|
+
entry.raw = JSON.stringify(msg);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
entry.content = msg;
|
|
26
|
+
entry.raw = JSON.stringify(msg);
|
|
27
|
+
}
|
|
28
|
+
return entry;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Log a completed model call: every prompt message plus the completion, as one entry.
|
|
32
|
+
* A tool-calling completion carries its arguments rather than its (empty) content.
|
|
33
|
+
*/
|
|
34
|
+
export const spectate = (spectator, callType) => async (input, message, action, retries, startedAt) => {
|
|
35
|
+
const messages = input.map(msg => describeInput(msg, callType));
|
|
36
|
+
const completion = {
|
|
37
|
+
type: message.type,
|
|
38
|
+
callType,
|
|
39
|
+
content: '',
|
|
40
|
+
name: message.name,
|
|
41
|
+
contentType: typeof message.content === 'string' ? SpectatorContentType.Text : SpectatorContentType.Json,
|
|
42
|
+
usage: message.usage_metadata,
|
|
43
|
+
raw: JSON.stringify({ message, content: message.content, meta: message.response_metadata }),
|
|
44
|
+
};
|
|
45
|
+
if (message.tool_calls != null && message.tool_calls.length > 0) {
|
|
46
|
+
completion.content = message.tool_calls;
|
|
47
|
+
completion.contentType = SpectatorContentType.ToolCall;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
completion.content = message.content;
|
|
51
|
+
}
|
|
52
|
+
return spectator.log({ action, retries, startedAt, messages: [...messages, completion] });
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=spectate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spectate.js","sourceRoot":"","sources":["../../src/helpers/spectate.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './consts.js';
|
|
2
|
+
export * from './errors.js';
|
|
3
|
+
export type * from './types.js';
|
|
4
|
+
export * from './model.js';
|
|
5
|
+
export * from './service.js';
|
|
6
|
+
export * from './helpers/index.js';
|
|
7
|
+
export * from './execution/index.js';
|
|
8
|
+
export type * from './plugins/types.js';
|
|
9
|
+
export { plugins, registerLlmPlugin, pluginOf, pluginFor, resolvePlugin } from './plugins/index.js';
|
|
10
|
+
export { anthropicPlugin, ANTHROPIC_FAMILY } from './plugins/anthropic.js';
|
|
11
|
+
export { compatiblePlugin } from './plugins/compatible.js';
|
|
12
|
+
export { openAiPlugin, openAiFamily, OPENAI_FAMILY } from './plugins/openai.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,mBAAmB,oBAAoB,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACnG,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './consts.js';
|
|
2
|
+
export * from './errors.js';
|
|
3
|
+
export * from './model.js';
|
|
4
|
+
export * from './service.js';
|
|
5
|
+
export * from './helpers/index.js';
|
|
6
|
+
export * from './execution/index.js';
|
|
7
|
+
export { plugins, registerLlmPlugin, pluginOf, pluginFor, resolvePlugin } from './plugins/index.js';
|
|
8
|
+
export { anthropicPlugin, ANTHROPIC_FAMILY } from './plugins/anthropic.js';
|
|
9
|
+
export { compatiblePlugin } from './plugins/compatible.js';
|
|
10
|
+
export { openAiPlugin, openAiFamily, OPENAI_FAMILY } from './plugins/openai.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAE3B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AAEpC,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACnG,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
|
package/build/model.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LlmModel, LlmModelOptions, LlmSpectator } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build the four-method model API on top of a LangChain chat model.
|
|
4
|
+
*
|
|
5
|
+
* Everything provider-specific — how the client is refined between retries, how
|
|
6
|
+
* structured output is requested, whether prompt caching exists — is delegated to the
|
|
7
|
+
* `LlmPlugin` resolved for this model (see `plugins/`). The model itself only owns the
|
|
8
|
+
* provider-independent parts: streaming under an idle deadline, retry/fallback
|
|
9
|
+
* escalation, schema validation and coercion, spectator logging, and null diagnostics.
|
|
10
|
+
*/
|
|
11
|
+
export declare const makeLlmModel: ({ model, outputErrors, captureNull, retries, purpose, }: LlmModelOptions, spectator: LlmSpectator) => LlmModel;
|
|
12
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACuB,QAAQ,EAAE,eAAe,EAC1D,YAAY,EACb,MAAM,YAAY,CAAA;AAInB;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GAAI,yDAM1B,eAAe,EAAE,WAAW,YAAY,KAAG,QA6U7C,CAAA"}
|
package/build/model.js
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { Ajv } from 'ajv';
|
|
2
|
+
import { AIMessage } from '@langchain/core/messages';
|
|
3
|
+
import { StructuredMode } from '@owlmeans/llm-common';
|
|
4
|
+
import { DEFAULT_MAX_OUTPUT_CAP, DEFAULT_MODEL_RETRIES, FALLBACK_AFTER_ATTEMPTS, } from './consts.js';
|
|
5
|
+
import { LlmModelError } from './errors.js';
|
|
6
|
+
import { pluginFor, pluginOf } from './plugins/index.js';
|
|
7
|
+
import { coerceToSchema, parseJsonContent } from './helpers/json.js';
|
|
8
|
+
import { normalizeInput } from './helpers/messages.js';
|
|
9
|
+
import { withRetry } from './helpers/retry.js';
|
|
10
|
+
import { spectate } from './helpers/spectate.js';
|
|
11
|
+
import { idleTimeout, readConfig } from './utils/config.js';
|
|
12
|
+
import { reportNull } from './utils/null-report.js';
|
|
13
|
+
import { applyNoThink, ensureJsonMention } from './utils/prompt.js';
|
|
14
|
+
import { resolveSchemaValidator, toToolName, unwrapNamed } from './utils/schema.js';
|
|
15
|
+
import { streamWithDeadline } from './utils/stream.js';
|
|
16
|
+
/**
|
|
17
|
+
* Build the four-method model API on top of a LangChain chat model.
|
|
18
|
+
*
|
|
19
|
+
* Everything provider-specific — how the client is refined between retries, how
|
|
20
|
+
* structured output is requested, whether prompt caching exists — is delegated to the
|
|
21
|
+
* `LlmPlugin` resolved for this model (see `plugins/`). The model itself only owns the
|
|
22
|
+
* provider-independent parts: streaming under an idle deadline, retry/fallback
|
|
23
|
+
* escalation, schema validation and coercion, spectator logging, and null diagnostics.
|
|
24
|
+
*/
|
|
25
|
+
export const makeLlmModel = ({ model, outputErrors = false, captureNull = false, retries = DEFAULT_MODEL_RETRIES, purpose, }, spectator) => {
|
|
26
|
+
const ajv = new Ajv({ strict: false });
|
|
27
|
+
// The original config and its plugin are static per model instance: a REFINED instance
|
|
28
|
+
// is rebuilt from `lc_kwargs` and does not reliably carry the metadata back.
|
|
29
|
+
const config = readConfig(model);
|
|
30
|
+
const plugin = pluginOf(config.provider) ?? pluginFor(model);
|
|
31
|
+
const timeout = idleTimeout(config);
|
|
32
|
+
/** Normalize, then apply every in-place prompt adaptation, in dependency order. */
|
|
33
|
+
const prepare = (input, useCache, cacheMax, json) => {
|
|
34
|
+
const msgs = normalizeInput(input);
|
|
35
|
+
if (json)
|
|
36
|
+
ensureJsonMention(msgs);
|
|
37
|
+
applyNoThink(msgs, config.disableThinking);
|
|
38
|
+
// Cache markers replace string content with content blocks, so they must go last.
|
|
39
|
+
if (plugin?.patchCache?.(msgs, { model, useCache, cacheMax }) === true) {
|
|
40
|
+
console.log(`Prompt caching enabled for ${plugin.type} (up to ${cacheMax} breakpoints)`);
|
|
41
|
+
}
|
|
42
|
+
return msgs;
|
|
43
|
+
};
|
|
44
|
+
const notifyRef = (ref, value) => {
|
|
45
|
+
if (ref != null) {
|
|
46
|
+
ref.value = value;
|
|
47
|
+
void ref.callback?.(value).finally();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Record the diagnostics of a call that produced nothing usable and build the
|
|
52
|
+
* retryable error describing it. The caller throws it, so control flow stays visible.
|
|
53
|
+
*/
|
|
54
|
+
const nullResult = async (kind, p, parsed = false) => {
|
|
55
|
+
await reportNull(spectator, captureNull, { ...p, kind, purpose, config });
|
|
56
|
+
const toolCalls = p.raw?.tool_calls?.length ?? 0;
|
|
57
|
+
const content = JSON.stringify(p.raw?.content ?? null).substring(0, 120);
|
|
58
|
+
return new LlmModelError(`null-output:raw=${p.raw != null}, parsed=${parsed}, toolCalls=${toolCalls}, content=${content}`);
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Rebuild the model for attempt N.
|
|
62
|
+
*
|
|
63
|
+
* Two-layer fallback: once a cheap primary has failed {@link FALLBACK_AFTER_ATTEMPTS}
|
|
64
|
+
* times, escalate to the stronger model the service attached as `__fallbackModel`. The
|
|
65
|
+
* escalation only happens WITHIN one plugin family — rotating providers mid-call would
|
|
66
|
+
* flip the structured-output call shape (tool_choice spelling, native support), so it is
|
|
67
|
+
* better to keep retrying on the primary than to switch families.
|
|
68
|
+
*/
|
|
69
|
+
const refineModel = (attempt, temperature) => {
|
|
70
|
+
const fallbackModel = model.__fallbackModel;
|
|
71
|
+
const sameFamily = fallbackModel != null && plugin != null
|
|
72
|
+
&& plugin.owns(model) && plugin.owns(fallbackModel);
|
|
73
|
+
const base = (sameFamily && attempt >= FALLBACK_AFTER_ATTEMPTS) ? fallbackModel : model;
|
|
74
|
+
if (attempt === FALLBACK_AFTER_ATTEMPTS && fallbackModel != null) {
|
|
75
|
+
if (base !== model) {
|
|
76
|
+
console.warn(`${base.getName()}: switching to fallback model after ${attempt} failed attempts`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
console.warn(`Skipping cross-family fallback (${fallbackModel.getName()}); staying on ${model.getName()}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const baseConfig = readConfig(base);
|
|
83
|
+
const basePlugin = pluginOf(baseConfig.provider) ?? pluginFor(base);
|
|
84
|
+
if (basePlugin == null)
|
|
85
|
+
return base;
|
|
86
|
+
const maxOutputCap = typeof baseConfig.maxTokensCap === 'number' && baseConfig.maxTokensCap > 0
|
|
87
|
+
? baseConfig.maxTokensCap
|
|
88
|
+
: DEFAULT_MAX_OUTPUT_CAP;
|
|
89
|
+
const refined = basePlugin.refine({ base, attempt, temperature, maxOutputCap });
|
|
90
|
+
if (attempt > 0) {
|
|
91
|
+
const maxTokens = refined.maxTokens;
|
|
92
|
+
console.warn(`${refined.getName()}: retry attempt ${attempt}, maxTokens now ${maxTokens}`);
|
|
93
|
+
}
|
|
94
|
+
return refined;
|
|
95
|
+
};
|
|
96
|
+
/** How this model should be asked for schema-conforming output. */
|
|
97
|
+
const structuredMode = () => plugin != null
|
|
98
|
+
? plugin.structuredMode(config)
|
|
99
|
+
: (config.structuredOutput === true ? StructuredMode.Native : StructuredMode.Tool);
|
|
100
|
+
/**
|
|
101
|
+
* Shared structured-output core for `invoke`/`request`. Streams under the idle deadline
|
|
102
|
+
* (whose break-on-`finish_reason` also dedups the duplicate final chunk some providers
|
|
103
|
+
* emit, which would otherwise corrupt accumulated tool-call arguments), accumulates the
|
|
104
|
+
* chunks and extracts the parsed object.
|
|
105
|
+
*
|
|
106
|
+
* `withStructuredOutput` is deliberately NOT used: it buffers the whole raw stream
|
|
107
|
+
* before yielding, which is too late to dedup.
|
|
108
|
+
*/
|
|
109
|
+
const streamStructured = async (refined, msgs, innerSchema, toolName, action) => {
|
|
110
|
+
const responseFormat = structuredMode() === StructuredMode.Native
|
|
111
|
+
? plugin?.responseFormat?.(toolName, innerSchema)
|
|
112
|
+
: undefined;
|
|
113
|
+
// A plugin that declares Native but provides no response_format falls back to tools.
|
|
114
|
+
const mode = responseFormat != null ? StructuredMode.Native : StructuredMode.Tool;
|
|
115
|
+
const start = (signal) => {
|
|
116
|
+
const base = { runName: action, metadata: { purpose }, signal };
|
|
117
|
+
if (mode === StructuredMode.Native) {
|
|
118
|
+
return refined.stream(msgs, { ...base, ...responseFormat && { response_format: responseFormat } });
|
|
119
|
+
}
|
|
120
|
+
// langchain converts the OpenAI-shaped tool DEFINITION for either provider, but the
|
|
121
|
+
// `tool_choice` shape is NOT converted — the plugin supplies the right spelling.
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
123
|
+
const bound = refined.bindTools([{ type: 'function', function: { name: toolName, description: '', parameters: innerSchema } }], { tool_choice: plugin?.toolChoice(toolName) ?? { type: 'function', function: { name: toolName } } });
|
|
124
|
+
return bound.stream(msgs, base);
|
|
125
|
+
};
|
|
126
|
+
let piece = null;
|
|
127
|
+
for await (const rawChunk of streamWithDeadline(start, timeout)) {
|
|
128
|
+
const chunk = rawChunk;
|
|
129
|
+
piece = piece == null ? chunk : piece.concat(chunk);
|
|
130
|
+
}
|
|
131
|
+
let result = null;
|
|
132
|
+
if (mode === StructuredMode.Tool) {
|
|
133
|
+
const rawArgs = piece?.tool_calls?.[0]?.args ?? null;
|
|
134
|
+
result = rawArgs != null
|
|
135
|
+
? (typeof rawArgs === 'string' ? parseJsonContent(rawArgs) : rawArgs)
|
|
136
|
+
: null;
|
|
137
|
+
}
|
|
138
|
+
// Content fallback: some models ignore the pinned tool (or the JSON mode) and emit the
|
|
139
|
+
// schema-shaped JSON as plain content.
|
|
140
|
+
if (result == null && piece != null) {
|
|
141
|
+
const recovered = parseJsonContent(piece.content);
|
|
142
|
+
if (recovered != null)
|
|
143
|
+
result = recovered;
|
|
144
|
+
}
|
|
145
|
+
return { piece, result, mode };
|
|
146
|
+
};
|
|
147
|
+
const helper = {
|
|
148
|
+
ask: async (input, { ref, filter, action, useCache = false, cacheMax = 4 }) => {
|
|
149
|
+
const msgs = prepare(input, useCache, cacheMax, false);
|
|
150
|
+
return withRetry({ retries, outputErrors }, async (i) => {
|
|
151
|
+
const refined = refineModel(i);
|
|
152
|
+
console.log('Use model to ask: ', refined.getName(), refined.lc_kwargs.model);
|
|
153
|
+
const startedAt = Date.now();
|
|
154
|
+
let result = null;
|
|
155
|
+
for await (const chunk of streamWithDeadline(signal => refined.stream(msgs, { runName: action, metadata: { purpose }, signal }), timeout)) {
|
|
156
|
+
result = result == null ? chunk : result.concat(chunk);
|
|
157
|
+
}
|
|
158
|
+
if (result == null) {
|
|
159
|
+
throw await nullResult('ask', { action, attempt: i, startedAt, refined, msgs, raw: result, useCache });
|
|
160
|
+
}
|
|
161
|
+
const message = new AIMessage(result);
|
|
162
|
+
let output = typeof result.content === 'string'
|
|
163
|
+
? result.content
|
|
164
|
+
: Array.isArray(result.content)
|
|
165
|
+
? result.content
|
|
166
|
+
.filter((c) => typeof c === 'object' && c !== null && 'type' in c && c.type === 'text')
|
|
167
|
+
.map(c => c.text)
|
|
168
|
+
.join('') || null
|
|
169
|
+
: null;
|
|
170
|
+
const entry = await spectate(spectator, 'ask')(msgs, message, action, i, startedAt);
|
|
171
|
+
if (ref != null)
|
|
172
|
+
ref.spectatorEntry = entry;
|
|
173
|
+
if (filter != null) {
|
|
174
|
+
output = await filter(output ?? '', message);
|
|
175
|
+
if (output == null) {
|
|
176
|
+
throw new LlmModelError(`filter-rejected:${JSON.stringify(message).substring(0, 50)}...`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else if (output == null || output.trim() === '') {
|
|
180
|
+
throw new LlmModelError(`empty-content:${JSON.stringify(message).substring(0, 50)}...`);
|
|
181
|
+
}
|
|
182
|
+
notifyRef(ref, message);
|
|
183
|
+
return output;
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
talk: async (input, { ref, filter, action, useCache = false, cacheMax = 4 }) => {
|
|
187
|
+
const msgs = prepare(input, useCache, cacheMax, false);
|
|
188
|
+
return withRetry({ retries, outputErrors }, async (i) => {
|
|
189
|
+
const refined = refineModel(i);
|
|
190
|
+
console.log('Use model to talk: ', refined.getName(), refined.lc_kwargs.model);
|
|
191
|
+
const startedAt = Date.now();
|
|
192
|
+
let result = null;
|
|
193
|
+
for await (const chunk of streamWithDeadline(signal => refined.stream(msgs, { runName: action, metadata: { purpose }, signal }), timeout)) {
|
|
194
|
+
result = result == null ? chunk : result.concat(chunk);
|
|
195
|
+
}
|
|
196
|
+
if (result == null) {
|
|
197
|
+
throw await nullResult('talk', { action, attempt: i, startedAt, refined, msgs, raw: result, useCache });
|
|
198
|
+
}
|
|
199
|
+
let message = new AIMessage(result);
|
|
200
|
+
const entry = await spectate(spectator, 'talk')(msgs, message, action, i, startedAt);
|
|
201
|
+
if (ref != null)
|
|
202
|
+
ref.spectatorEntry = entry;
|
|
203
|
+
if (filter != null) {
|
|
204
|
+
message = await filter(message);
|
|
205
|
+
if (message == null) {
|
|
206
|
+
throw new LlmModelError('filter-rejected:talk');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
notifyRef(ref, message);
|
|
210
|
+
return message;
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
invoke: async (input, schema, { temperature, ref, filter, action, useCache = false, cacheMax = 4 }) => {
|
|
214
|
+
const msgs = prepare(input, useCache, cacheMax, true);
|
|
215
|
+
const { name, innerSchema, validate } = resolveSchemaValidator(ajv, schema);
|
|
216
|
+
const toolName = toToolName(innerSchema.title ?? name);
|
|
217
|
+
return withRetry({ retries, outputErrors }, async (i) => {
|
|
218
|
+
const refined = refineModel(i, temperature);
|
|
219
|
+
console.log('Use model invoke: ', refined.getName(), refined.lc_kwargs.model);
|
|
220
|
+
const startedAt = Date.now();
|
|
221
|
+
const { piece, result: collected } = await streamStructured(refined, msgs, innerSchema, toolName, action);
|
|
222
|
+
let result = collected;
|
|
223
|
+
if (piece == null || result == null) {
|
|
224
|
+
throw await nullResult('invoke', {
|
|
225
|
+
action, attempt: i, startedAt, refined, msgs, raw: piece,
|
|
226
|
+
schema: { toolName, innerSchema }, useCache,
|
|
227
|
+
}, result != null);
|
|
228
|
+
}
|
|
229
|
+
const message = new AIMessage(piece);
|
|
230
|
+
const entry = await spectate(spectator, 'invoke')(msgs, message, action, i, startedAt);
|
|
231
|
+
if (ref != null)
|
|
232
|
+
ref.spectatorEntry = entry;
|
|
233
|
+
result = unwrapNamed(result, name);
|
|
234
|
+
result = coerceToSchema(result, innerSchema);
|
|
235
|
+
if (filter != null) {
|
|
236
|
+
const preFilter = result;
|
|
237
|
+
result = await filter(result, message);
|
|
238
|
+
if (result == null) {
|
|
239
|
+
throw new LlmModelError(`filter-rejected:${JSON.stringify(preFilter).substring(0, 200)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (!validate(result)) {
|
|
243
|
+
const err = new LlmModelError(`validation-failed:${JSON.stringify(validate.errors)}`);
|
|
244
|
+
err.cause = validate.errors?.[0];
|
|
245
|
+
throw err;
|
|
246
|
+
}
|
|
247
|
+
notifyRef(ref, message);
|
|
248
|
+
return result;
|
|
249
|
+
});
|
|
250
|
+
},
|
|
251
|
+
request: async (input, schema, { ref, filter, action, useCache = false, cacheMax = 4 }) => {
|
|
252
|
+
const msgs = prepare(input, useCache, cacheMax, true);
|
|
253
|
+
const { name, innerSchema, validate } = resolveSchemaValidator(ajv, schema);
|
|
254
|
+
const toolName = toToolName(innerSchema.title ?? name);
|
|
255
|
+
return withRetry({ retries, outputErrors }, async (i) => {
|
|
256
|
+
const refined = refineModel(i);
|
|
257
|
+
console.log('Use model request: ', refined.getName(), refined.lc_kwargs.model);
|
|
258
|
+
const startedAt = Date.now();
|
|
259
|
+
const { piece, result: collected } = await streamStructured(refined, msgs, innerSchema, toolName, action);
|
|
260
|
+
let result = collected;
|
|
261
|
+
if (piece == null || result == null) {
|
|
262
|
+
throw await nullResult('request', {
|
|
263
|
+
action, attempt: i, startedAt, refined, msgs, raw: piece,
|
|
264
|
+
schema: { toolName, innerSchema }, useCache,
|
|
265
|
+
}, result != null);
|
|
266
|
+
}
|
|
267
|
+
let message = new AIMessage(piece);
|
|
268
|
+
const entry = await spectate(spectator, 'request')(msgs, message, action, i, startedAt);
|
|
269
|
+
if (ref != null)
|
|
270
|
+
ref.spectatorEntry = entry;
|
|
271
|
+
// Structured output delivers the JSON as parsed tool arguments, not as message
|
|
272
|
+
// content. Surface it on `.content` so the AIMessage contract callers rely on holds.
|
|
273
|
+
result = unwrapNamed(result, name);
|
|
274
|
+
result = coerceToSchema(result, innerSchema);
|
|
275
|
+
message.content = JSON.stringify(result);
|
|
276
|
+
if (filter != null) {
|
|
277
|
+
message = await filter(message);
|
|
278
|
+
if (message == null) {
|
|
279
|
+
throw new LlmModelError('filter-rejected:request');
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else if (message.content == null || message.content.toString().trim() === '') {
|
|
283
|
+
throw new LlmModelError(`empty-content:${JSON.stringify(message).substring(0, 50)}...`);
|
|
284
|
+
}
|
|
285
|
+
if (!validate(JSON.parse(`${message.content}`))) {
|
|
286
|
+
const err = new LlmModelError(`validation-failed:${JSON.stringify(validate.errors)}`);
|
|
287
|
+
err.cause = validate.errors?.[0];
|
|
288
|
+
throw err;
|
|
289
|
+
}
|
|
290
|
+
notifyRef(ref, message);
|
|
291
|
+
return message;
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
return helper;
|
|
296
|
+
};
|
|
297
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/plugins/anthropic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAO3C,eAAO,MAAM,gBAAgB,cAAc,CAAA;AAE3C,eAAO,MAAM,eAAe,EAAE,SAmF7B,CAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ChatAnthropic } from '@langchain/anthropic';
|
|
2
|
+
import { BadRequestError } from '@anthropic-ai/sdk';
|
|
3
|
+
import { ModelProvider, StructuredMode } from '@owlmeans/llm-common';
|
|
4
|
+
import { MAX_CACHE_BREAKPOINTS } from '../consts.js';
|
|
5
|
+
import { escalateMaxTokens, makeClientOptions } from './utils.js';
|
|
6
|
+
/** Model-name prefix that supports prompt caching through `cache_control` markers. */
|
|
7
|
+
const CACHEABLE_PREFIX = 'claude-';
|
|
8
|
+
export const ANTHROPIC_FAMILY = 'anthropic';
|
|
9
|
+
export const anthropicPlugin = {
|
|
10
|
+
type: ModelProvider.Anthropic,
|
|
11
|
+
family: ANTHROPIC_FAMILY,
|
|
12
|
+
owns: model => model instanceof ChatAnthropic,
|
|
13
|
+
/**
|
|
14
|
+
* Anthropic has no `response_format: json_schema` mode, so structured output is
|
|
15
|
+
* always the forced-tool-call hack. `ModelConfig.structuredOutput` is ignored.
|
|
16
|
+
*/
|
|
17
|
+
structuredMode: () => StructuredMode.Tool,
|
|
18
|
+
/**
|
|
19
|
+
* Anthropic 400s on the OpenAI spelling: "tool_choice: Input tag 'function' … does not
|
|
20
|
+
* match any of the expected tags: 'auto','any','tool','none'".
|
|
21
|
+
*/
|
|
22
|
+
toolChoice: (toolName) => ({ type: 'tool', name: toolName }),
|
|
23
|
+
build: ({ config, secret, callbacks }) => {
|
|
24
|
+
const model = config.model ??= 'claude-haiku-4-5-20251001';
|
|
25
|
+
const cfg = {
|
|
26
|
+
model,
|
|
27
|
+
apiKey: secret,
|
|
28
|
+
// Neither knob set → pin temperature to 0 for determinism.
|
|
29
|
+
...(config.temperature == null && config.topP == null ? { temperature: 0 } : {}),
|
|
30
|
+
maxTokens: config.maxTokens ?? 4096,
|
|
31
|
+
maxRetries: 5,
|
|
32
|
+
metadata: { config },
|
|
33
|
+
callbacks,
|
|
34
|
+
...(config.temperature != null ? { temperature: config.temperature } : {}),
|
|
35
|
+
...(config.topP != null && config.temperature == null ? { topP: config.topP } : {}),
|
|
36
|
+
...makeClientOptions({ headers: config.headers }),
|
|
37
|
+
};
|
|
38
|
+
// Anthropic rejects temperature and top_p together.
|
|
39
|
+
if (cfg.temperature != null && cfg.topP != null) {
|
|
40
|
+
delete cfg.topP;
|
|
41
|
+
}
|
|
42
|
+
return new ChatAnthropic(cfg);
|
|
43
|
+
},
|
|
44
|
+
refine: ({ base, attempt, temperature, maxOutputCap }) => {
|
|
45
|
+
const model = base;
|
|
46
|
+
const currentTemperature = temperature ?? model.temperature ?? 0;
|
|
47
|
+
const maxTokens = escalateMaxTokens(model.maxTokens, attempt, maxOutputCap);
|
|
48
|
+
const cfg = {
|
|
49
|
+
...model.lc_kwargs, temperature: currentTemperature, maxTokens,
|
|
50
|
+
};
|
|
51
|
+
if (cfg.temperature != null && cfg.temperature > 0 && cfg.topP != null) {
|
|
52
|
+
delete cfg.topP;
|
|
53
|
+
}
|
|
54
|
+
else if (cfg.temperature != null && cfg.temperature <= 0 && cfg.topP != null) {
|
|
55
|
+
delete cfg.temperature;
|
|
56
|
+
}
|
|
57
|
+
return new ChatAnthropic(cfg);
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* Mark the leading messages with an ephemeral `cache_control` breakpoint. Anthropic
|
|
61
|
+
* allows at most {@link MAX_CACHE_BREAKPOINTS}; string content is lifted into a
|
|
62
|
+
* single text block so the marker has somewhere to live.
|
|
63
|
+
*/
|
|
64
|
+
patchCache: (msgs, { model, useCache, cacheMax }) => {
|
|
65
|
+
if (!useCache || !model.modelName?.startsWith(CACHEABLE_PREFIX))
|
|
66
|
+
return false;
|
|
67
|
+
const max = Math.min(cacheMax, MAX_CACHE_BREAKPOINTS);
|
|
68
|
+
let i = 0;
|
|
69
|
+
for (const msg of msgs) {
|
|
70
|
+
msg.content = typeof msg.content === 'string' ? [{
|
|
71
|
+
type: 'text',
|
|
72
|
+
text: msg.content,
|
|
73
|
+
cache_control: { type: 'ephemeral' },
|
|
74
|
+
}] : msg.content;
|
|
75
|
+
if (++i > max - 1)
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* A malformed request (bad schema, unsupported parameter, oversized `max_tokens`)
|
|
82
|
+
* cannot be fixed by retrying — surface it immediately instead of burning the budget.
|
|
83
|
+
*/
|
|
84
|
+
isFatal: e => e instanceof BadRequestError ? e : null,
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=anthropic.js.map
|