@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,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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"}
@@ -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"}
@@ -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,4 @@
1
+ import type { LlmPlugin } from './types.js';
2
+ export declare const ANTHROPIC_FAMILY = "anthropic";
3
+ export declare const anthropicPlugin: LlmPlugin;
4
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -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