@sprucelabs/sprucebot-llm 14.0.0 → 14.1.1

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.
@@ -1,7 +1,15 @@
1
- export default class LlmAdapterLoader {
1
+ import { LlmAdapter } from '../../llm.types';
2
+ export default class LlmAdapterLoaderImpl implements LlmAdapterLoader {
3
+ static Class?: new (adapterName: ValidAdapterName) => LlmAdapterLoader;
2
4
  static VALID_ADAPTERS: string[];
3
5
  private adapterName;
4
- private constructor();
6
+ protected constructor(adapterName: ValidAdapterName);
5
7
  static Loader(): LlmAdapterLoader;
6
- Adapter(): import("../../llm.types").LlmAdapter;
8
+ Adapter(): LlmAdapter;
9
+ private constructorsByName;
7
10
  }
11
+ export interface LlmAdapterLoader {
12
+ Adapter(): LlmAdapter;
13
+ }
14
+ type ValidAdapterName = 'openai' | 'anthropic' | 'ollama';
15
+ export {};
@@ -8,8 +8,30 @@ const SpruceError_1 = __importDefault(require("../../errors/SpruceError"));
8
8
  const AnthropicAdapter_1 = __importDefault(require("./AnthropicAdapter"));
9
9
  const OllamaAdapter_1 = __importDefault(require("./OllamaAdapter"));
10
10
  const OpenAiAdapter_1 = __importDefault(require("./OpenAiAdapter"));
11
- class LlmAdapterLoader {
11
+ class LlmAdapterLoaderImpl {
12
12
  constructor(adapterName) {
13
+ this.constructorsByName = {
14
+ openai: (key, options) => {
15
+ return OpenAiAdapter_1.default.Adapter(key, {
16
+ ...options,
17
+ reasoningEffort: process.env
18
+ .SPRUCE_LLM_REASONING_EFFORT,
19
+ });
20
+ },
21
+ anthropic: (key, options) => {
22
+ return AnthropicAdapter_1.default.Adapter(key, {
23
+ ...options,
24
+ thinking: process.env.SPRUCE_LLM_THINKING === 'true',
25
+ maxTokens: parseInt(process.env.SPRUCE_LLM_MAX_TOKENS, 10),
26
+ });
27
+ },
28
+ ollama: (_key, options) => {
29
+ return OllamaAdapter_1.default.Adapter({
30
+ ...options,
31
+ think: process.env.SPRUCE_LLM_THINKING === 'true',
32
+ });
33
+ },
34
+ };
13
35
  this.adapterName = adapterName;
14
36
  }
15
37
  static Loader() {
@@ -17,7 +39,7 @@ class LlmAdapterLoader {
17
39
  env: process.env,
18
40
  }, ['env.SPRUCE_LLM_ADAPTER']);
19
41
  const name = SPRUCE_LLM_ADAPTER.toLowerCase();
20
- if (!LlmAdapterLoader.VALID_ADAPTERS.includes(name)) {
42
+ if (!LlmAdapterLoaderImpl.VALID_ADAPTERS.includes(name)) {
21
43
  throw new SpruceError_1.default({
22
44
  code: 'INVALID_LLM_ADAPTER',
23
45
  adapter: SPRUCE_LLM_ADAPTER,
@@ -28,7 +50,7 @@ class LlmAdapterLoader {
28
50
  env: process.env,
29
51
  }, ['env.SPRUCE_LLM_MAX_TOKENS']);
30
52
  }
31
- return new this(name);
53
+ return new (this.Class ?? this)(name);
32
54
  }
33
55
  Adapter() {
34
56
  const key = process.env.SPRUCE_LLM_API_KEY;
@@ -39,23 +61,8 @@ class LlmAdapterLoader {
39
61
  model: process.env.SPRUCE_LLM_MODEL,
40
62
  baseUrl: process.env.SPRUCE_LLM_BASE_URL,
41
63
  };
42
- const thinking = process.env.SPRUCE_LLM_THINKING === 'true';
43
- if (this.adapterName === 'anthropic') {
44
- return AnthropicAdapter_1.default.Adapter(key, {
45
- ...options,
46
- thinking,
47
- maxTokens: parseInt(process.env.SPRUCE_LLM_MAX_TOKENS, 10),
48
- });
49
- }
50
- if (this.adapterName === 'ollama') {
51
- return OllamaAdapter_1.default.Adapter({ ...options, think: thinking });
52
- }
53
- return OpenAiAdapter_1.default.Adapter(key, {
54
- ...options,
55
- reasoningEffort: process.env
56
- .SPRUCE_LLM_REASONING_EFFORT,
57
- });
64
+ return this.constructorsByName[this.adapterName](key, options);
58
65
  }
59
66
  }
60
- LlmAdapterLoader.VALID_ADAPTERS = ['openai', 'anthropic', 'ollama'];
61
- exports.default = LlmAdapterLoader;
67
+ LlmAdapterLoaderImpl.VALID_ADAPTERS = ['openai', 'anthropic', 'ollama'];
68
+ exports.default = LlmAdapterLoaderImpl;
@@ -1,7 +1,15 @@
1
- export default class LlmAdapterLoader {
1
+ import { LlmAdapter } from '../../llm.types';
2
+ export default class LlmAdapterLoaderImpl implements LlmAdapterLoader {
3
+ static Class?: new (adapterName: ValidAdapterName) => LlmAdapterLoader;
2
4
  static VALID_ADAPTERS: string[];
3
5
  private adapterName;
4
- private constructor();
6
+ protected constructor(adapterName: ValidAdapterName);
5
7
  static Loader(): LlmAdapterLoader;
6
- Adapter(): import("../../llm.types").LlmAdapter;
8
+ Adapter(): LlmAdapter;
9
+ private constructorsByName;
7
10
  }
11
+ export interface LlmAdapterLoader {
12
+ Adapter(): LlmAdapter;
13
+ }
14
+ type ValidAdapterName = 'openai' | 'anthropic' | 'ollama';
15
+ export {};
@@ -3,16 +3,29 @@ import SpruceError from '../../errors/SpruceError.js';
3
3
  import AnthropicAdapter from './AnthropicAdapter.js';
4
4
  import OllamaAdapter from './OllamaAdapter.js';
5
5
  import OpenAiAdapter from './OpenAiAdapter.js';
6
- class LlmAdapterLoader {
6
+ class LlmAdapterLoaderImpl {
7
7
  constructor(adapterName) {
8
+ this.constructorsByName = {
9
+ openai: (key, options) => {
10
+ return OpenAiAdapter.Adapter(key, Object.assign(Object.assign({}, options), { reasoningEffort: process.env
11
+ .SPRUCE_LLM_REASONING_EFFORT }));
12
+ },
13
+ anthropic: (key, options) => {
14
+ return AnthropicAdapter.Adapter(key, Object.assign(Object.assign({}, options), { thinking: process.env.SPRUCE_LLM_THINKING === 'true', maxTokens: parseInt(process.env.SPRUCE_LLM_MAX_TOKENS, 10) }));
15
+ },
16
+ ollama: (_key, options) => {
17
+ return OllamaAdapter.Adapter(Object.assign(Object.assign({}, options), { think: process.env.SPRUCE_LLM_THINKING === 'true' }));
18
+ },
19
+ };
8
20
  this.adapterName = adapterName;
9
21
  }
10
22
  static Loader() {
23
+ var _a;
11
24
  const { env: { SPRUCE_LLM_ADAPTER }, } = assertOptions({
12
25
  env: process.env,
13
26
  }, ['env.SPRUCE_LLM_ADAPTER']);
14
27
  const name = SPRUCE_LLM_ADAPTER.toLowerCase();
15
- if (!LlmAdapterLoader.VALID_ADAPTERS.includes(name)) {
28
+ if (!LlmAdapterLoaderImpl.VALID_ADAPTERS.includes(name)) {
16
29
  throw new SpruceError({
17
30
  code: 'INVALID_LLM_ADAPTER',
18
31
  adapter: SPRUCE_LLM_ADAPTER,
@@ -23,7 +36,7 @@ class LlmAdapterLoader {
23
36
  env: process.env,
24
37
  }, ['env.SPRUCE_LLM_MAX_TOKENS']);
25
38
  }
26
- return new this(name);
39
+ return new ((_a = this.Class) !== null && _a !== void 0 ? _a : this)(name);
27
40
  }
28
41
  Adapter() {
29
42
  const key = process.env.SPRUCE_LLM_API_KEY;
@@ -34,16 +47,8 @@ class LlmAdapterLoader {
34
47
  model: process.env.SPRUCE_LLM_MODEL,
35
48
  baseUrl: process.env.SPRUCE_LLM_BASE_URL,
36
49
  };
37
- const thinking = process.env.SPRUCE_LLM_THINKING === 'true';
38
- if (this.adapterName === 'anthropic') {
39
- return AnthropicAdapter.Adapter(key, Object.assign(Object.assign({}, options), { thinking, maxTokens: parseInt(process.env.SPRUCE_LLM_MAX_TOKENS, 10) }));
40
- }
41
- if (this.adapterName === 'ollama') {
42
- return OllamaAdapter.Adapter(Object.assign(Object.assign({}, options), { think: thinking }));
43
- }
44
- return OpenAiAdapter.Adapter(key, Object.assign(Object.assign({}, options), { reasoningEffort: process.env
45
- .SPRUCE_LLM_REASONING_EFFORT }));
50
+ return this.constructorsByName[this.adapterName](key, options);
46
51
  }
47
52
  }
48
- LlmAdapterLoader.VALID_ADAPTERS = ['openai', 'anthropic', 'ollama'];
49
- export default LlmAdapterLoader;
53
+ LlmAdapterLoaderImpl.VALID_ADAPTERS = ['openai', 'anthropic', 'ollama'];
54
+ export default LlmAdapterLoaderImpl;
@@ -13,3 +13,5 @@ export * from './bots/adapters/OllamaAdapter';
13
13
  export { default as AthropicAdapter } from './bots/adapters/AnthropicAdapter';
14
14
  export * from './bots/adapters/AnthropicAdapter';
15
15
  export { default as LlmAdapterLoader } from './bots/adapters/LlmAdapterLoader';
16
+ export * from './bots/adapters/LlmAdapterLoader';
17
+ export { default as MockAdapterLoader } from './tests/MockAdapterLoader';
@@ -13,3 +13,5 @@ export * from './bots/adapters/OllamaAdapter.js';
13
13
  export { default as AthropicAdapter } from './bots/adapters/AnthropicAdapter.js';
14
14
  export * from './bots/adapters/AnthropicAdapter.js';
15
15
  export { default as LlmAdapterLoader } from './bots/adapters/LlmAdapterLoader.js';
16
+ export * from './bots/adapters/LlmAdapterLoader.js';
17
+ export { default as MockAdapterLoader } from './tests/MockAdapterLoader.js';
@@ -0,0 +1,10 @@
1
+ import { LlmAdapterLoader } from '../bots/adapters/LlmAdapterLoader';
2
+ import { LlmAdapter } from '../llm.types';
3
+ export default class MockAdapterLoader implements LlmAdapterLoader {
4
+ static instance: MockAdapterLoader;
5
+ lastAdapter?: LlmAdapter;
6
+ constructor();
7
+ static assertWasCreated(): void;
8
+ Adapter(): LlmAdapter;
9
+ static reset(): void;
10
+ }
@@ -0,0 +1,18 @@
1
+ import { assert } from '@sprucelabs/test-utils';
2
+ import SpyLlmAdapter from './SpyAdapter.js';
3
+ export default class MockAdapterLoader {
4
+ constructor() {
5
+ MockAdapterLoader.instance = this;
6
+ }
7
+ static assertWasCreated() {
8
+ assert.isTruthy(this.instance, 'Did not create an instance of LlmAdapterLoader using LllmAdapterLoaderImpl.Loader()');
9
+ }
10
+ Adapter() {
11
+ this.lastAdapter = new SpyLlmAdapter('***');
12
+ return this.lastAdapter;
13
+ }
14
+ static reset() {
15
+ //@ts-ignore
16
+ this.instance = undefined;
17
+ }
18
+ }
package/build/index.d.ts CHANGED
@@ -13,3 +13,5 @@ export * from './bots/adapters/OllamaAdapter';
13
13
  export { default as AthropicAdapter } from './bots/adapters/AnthropicAdapter';
14
14
  export * from './bots/adapters/AnthropicAdapter';
15
15
  export { default as LlmAdapterLoader } from './bots/adapters/LlmAdapterLoader';
16
+ export * from './bots/adapters/LlmAdapterLoader';
17
+ export { default as MockAdapterLoader } from './tests/MockAdapterLoader';
package/build/index.js CHANGED
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.LlmAdapterLoader = exports.AthropicAdapter = exports.OllamaAdapter = exports.SpyOpenAiApi = exports.SpyLlmAdapter = exports.SpyLllmBot = exports.MockLlmSkill = exports.SprucebotLlmError = exports.OpenAiAdapter = exports.SprucebotLlmSkillImpl = exports.SprucebotLlmBotImpl = exports.SprucebotLlmFactory = void 0;
20
+ exports.MockAdapterLoader = exports.LlmAdapterLoader = exports.AthropicAdapter = exports.OllamaAdapter = exports.SpyOpenAiApi = exports.SpyLlmAdapter = exports.SpyLllmBot = exports.MockLlmSkill = exports.SprucebotLlmError = exports.OpenAiAdapter = exports.SprucebotLlmSkillImpl = exports.SprucebotLlmBotImpl = exports.SprucebotLlmFactory = void 0;
21
21
  var SprucebotLlmFactory_1 = require("./bots/SprucebotLlmFactory");
22
22
  Object.defineProperty(exports, "SprucebotLlmFactory", { enumerable: true, get: function () { return __importDefault(SprucebotLlmFactory_1).default; } });
23
23
  var SprucebotLlmBotImpl_1 = require("./bots/SprucebotLlmBotImpl");
@@ -45,3 +45,6 @@ Object.defineProperty(exports, "AthropicAdapter", { enumerable: true, get: funct
45
45
  __exportStar(require("./bots/adapters/AnthropicAdapter"), exports);
46
46
  var LlmAdapterLoader_1 = require("./bots/adapters/LlmAdapterLoader");
47
47
  Object.defineProperty(exports, "LlmAdapterLoader", { enumerable: true, get: function () { return __importDefault(LlmAdapterLoader_1).default; } });
48
+ __exportStar(require("./bots/adapters/LlmAdapterLoader"), exports);
49
+ var MockAdapterLoader_1 = require("./tests/MockAdapterLoader");
50
+ Object.defineProperty(exports, "MockAdapterLoader", { enumerable: true, get: function () { return __importDefault(MockAdapterLoader_1).default; } });
@@ -0,0 +1,10 @@
1
+ import { LlmAdapterLoader } from '../bots/adapters/LlmAdapterLoader';
2
+ import { LlmAdapter } from '../llm.types';
3
+ export default class MockAdapterLoader implements LlmAdapterLoader {
4
+ static instance: MockAdapterLoader;
5
+ lastAdapter?: LlmAdapter;
6
+ constructor();
7
+ static assertWasCreated(): void;
8
+ Adapter(): LlmAdapter;
9
+ static reset(): void;
10
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const test_utils_1 = require("@sprucelabs/test-utils");
7
+ const SpyAdapter_1 = __importDefault(require("./SpyAdapter"));
8
+ class MockAdapterLoader {
9
+ constructor() {
10
+ MockAdapterLoader.instance = this;
11
+ }
12
+ static assertWasCreated() {
13
+ test_utils_1.assert.isTruthy(this.instance, 'Did not create an instance of LlmAdapterLoader using LllmAdapterLoaderImpl.Loader()');
14
+ }
15
+ Adapter() {
16
+ this.lastAdapter = new SpyAdapter_1.default('***');
17
+ return this.lastAdapter;
18
+ }
19
+ static reset() {
20
+ //@ts-ignore
21
+ this.instance = undefined;
22
+ }
23
+ }
24
+ exports.default = MockAdapterLoader;
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "eta"
9
9
  ]
10
10
  },
11
- "version": "14.0.0",
11
+ "version": "14.1.1",
12
12
  "files": [
13
13
  "build"
14
14
  ],
@@ -65,12 +65,12 @@
65
65
  "chat.images": "node ./build/chatWithImages.js"
66
66
  },
67
67
  "dependencies": {
68
- "@anthropic-ai/sdk": "^0.76.0",
69
- "@sprucelabs/error": "^8.1.9",
70
- "@sprucelabs/mercury-event-emitter": "^46.1.7",
71
- "@sprucelabs/mercury-types": "^49.1.9",
72
- "@sprucelabs/schema": "^33.2.6",
73
- "@sprucelabs/spruce-skill-utils": "^34.0.14",
68
+ "@anthropic-ai/sdk": "^0.78.0",
69
+ "@sprucelabs/error": "^8.1.10",
70
+ "@sprucelabs/mercury-event-emitter": "^46.1.8",
71
+ "@sprucelabs/mercury-types": "^49.1.10",
72
+ "@sprucelabs/schema": "^33.2.7",
73
+ "@sprucelabs/spruce-skill-utils": "^34.0.15",
74
74
  "eta": "3.5.0",
75
75
  "openai": "^6.22.0"
76
76
  },
@@ -80,17 +80,17 @@
80
80
  "devDependencies": {
81
81
  "@regressionproof/cli": "^0.9.1",
82
82
  "@regressionproof/jest-reporter": "^0.9.1",
83
- "@sprucelabs/esm-postbuild": "^9.0.17",
84
- "@sprucelabs/jest-json-reporter": "^10.0.25",
85
- "@sprucelabs/resolve-path-aliases": "^4.0.17",
83
+ "@sprucelabs/esm-postbuild": "^9.0.18",
84
+ "@sprucelabs/jest-json-reporter": "^10.0.26",
85
+ "@sprucelabs/resolve-path-aliases": "^4.0.18",
86
86
  "@sprucelabs/semantic-release": "^6.0.0",
87
- "@sprucelabs/test": "^11.1.4",
88
- "@sprucelabs/test-utils": "^7.2.12",
89
- "@types/node": "^25.2.3",
87
+ "@sprucelabs/test": "^11.1.5",
88
+ "@sprucelabs/test-utils": "^7.2.13",
89
+ "@types/node": "^25.3.0",
90
90
  "chokidar-cli": "^3.0.0",
91
91
  "dotenv": "^17.3.1",
92
- "eslint": "^10.0.0",
93
- "eslint-config-spruce": "^11.2.33",
92
+ "eslint": "^10.0.1",
93
+ "eslint-config-spruce": "^11.2.34",
94
94
  "jest": "^30.2.0",
95
95
  "jest-circus": "^30.2.0",
96
96
  "prettier": "^3.8.1",