@propio-ai/providers 0.1.0

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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +85 -0
  3. package/dist/config.d.ts +91 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +2 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/configFile.d.ts +22 -0
  8. package/dist/configFile.d.ts.map +1 -0
  9. package/dist/configFile.js +33 -0
  10. package/dist/configFile.js.map +1 -0
  11. package/dist/configValidation.d.ts +34 -0
  12. package/dist/configValidation.d.ts.map +1 -0
  13. package/dist/configValidation.js +185 -0
  14. package/dist/configValidation.js.map +1 -0
  15. package/dist/diagnostics.d.ts +29 -0
  16. package/dist/diagnostics.d.ts.map +1 -0
  17. package/dist/diagnostics.js +9 -0
  18. package/dist/diagnostics.js.map +1 -0
  19. package/dist/factory.d.ts +56 -0
  20. package/dist/factory.d.ts.map +1 -0
  21. package/dist/factory.js +162 -0
  22. package/dist/factory.js.map +1 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +9 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/interface.d.ts +36 -0
  28. package/dist/interface.d.ts.map +1 -0
  29. package/dist/interface.js +2 -0
  30. package/dist/interface.js.map +1 -0
  31. package/dist/internal/baseProvider.d.ts +20 -0
  32. package/dist/internal/baseProvider.d.ts.map +1 -0
  33. package/dist/internal/baseProvider.js +13 -0
  34. package/dist/internal/baseProvider.js.map +1 -0
  35. package/dist/internal/capabilities.d.ts +4 -0
  36. package/dist/internal/capabilities.d.ts.map +1 -0
  37. package/dist/internal/capabilities.js +12 -0
  38. package/dist/internal/capabilities.js.map +1 -0
  39. package/dist/internal/jsonFile.d.ts +11 -0
  40. package/dist/internal/jsonFile.d.ts.map +1 -0
  41. package/dist/internal/jsonFile.js +78 -0
  42. package/dist/internal/jsonFile.js.map +1 -0
  43. package/dist/internal/openAiCompatibleProvider.d.ts +44 -0
  44. package/dist/internal/openAiCompatibleProvider.d.ts.map +1 -0
  45. package/dist/internal/openAiCompatibleProvider.js +93 -0
  46. package/dist/internal/openAiCompatibleProvider.js.map +1 -0
  47. package/dist/internal/openAiStream.d.ts +13 -0
  48. package/dist/internal/openAiStream.d.ts.map +1 -0
  49. package/dist/internal/openAiStream.js +85 -0
  50. package/dist/internal/openAiStream.js.map +1 -0
  51. package/dist/internal/shared.d.ts +79 -0
  52. package/dist/internal/shared.d.ts.map +1 -0
  53. package/dist/internal/shared.js +250 -0
  54. package/dist/internal/shared.js.map +1 -0
  55. package/dist/internal/withRetry.d.ts +25 -0
  56. package/dist/internal/withRetry.d.ts.map +1 -0
  57. package/dist/internal/withRetry.js +46 -0
  58. package/dist/internal/withRetry.js.map +1 -0
  59. package/dist/providers/anthropic.d.ts +32 -0
  60. package/dist/providers/anthropic.d.ts.map +1 -0
  61. package/dist/providers/anthropic.js +435 -0
  62. package/dist/providers/anthropic.js.map +1 -0
  63. package/dist/providers/bedrock.d.ts +67 -0
  64. package/dist/providers/bedrock.d.ts.map +1 -0
  65. package/dist/providers/bedrock.js +442 -0
  66. package/dist/providers/bedrock.js.map +1 -0
  67. package/dist/providers/cloudflare.d.ts +40 -0
  68. package/dist/providers/cloudflare.d.ts.map +1 -0
  69. package/dist/providers/cloudflare.js +115 -0
  70. package/dist/providers/cloudflare.js.map +1 -0
  71. package/dist/providers/gemini.d.ts +57 -0
  72. package/dist/providers/gemini.d.ts.map +1 -0
  73. package/dist/providers/gemini.js +359 -0
  74. package/dist/providers/gemini.js.map +1 -0
  75. package/dist/providers/ollama.d.ts +67 -0
  76. package/dist/providers/ollama.d.ts.map +1 -0
  77. package/dist/providers/ollama.js +241 -0
  78. package/dist/providers/ollama.js.map +1 -0
  79. package/dist/providers/openrouter.d.ts +76 -0
  80. package/dist/providers/openrouter.d.ts.map +1 -0
  81. package/dist/providers/openrouter.js +571 -0
  82. package/dist/providers/openrouter.js.map +1 -0
  83. package/dist/providers/xai.d.ts +45 -0
  84. package/dist/providers/xai.d.ts.map +1 -0
  85. package/dist/providers/xai.js +371 -0
  86. package/dist/providers/xai.js.map +1 -0
  87. package/dist/types.d.ts +166 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +60 -0
  90. package/dist/types.js.map +1 -0
  91. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Isaac Heist
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # @propio-ai/providers
2
+
3
+ Provider adapters for LLM APIs with a unified streaming chat interface. Supports Anthropic (Claude), AWS Bedrock, Ollama, OpenRouter, Google Gemini, xAI (Grok), and Cloudflare Workers AI.
4
+
5
+ Extracted from [propio-agent](https://github.com/esack7/propio-agent), which uses it as its provider layer.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @propio-ai/providers
11
+ ```
12
+
13
+ Requires Node.js >= 20. ESM only.
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { createProvider, type ChatStreamEvent } from "@propio-ai/providers";
19
+
20
+ const provider = createProvider({
21
+ name: "claude",
22
+ type: "anthropic",
23
+ models: [
24
+ {
25
+ name: "Claude Sonnet",
26
+ key: "claude-sonnet-4-6",
27
+ contextWindowTokens: 200000,
28
+ },
29
+ ],
30
+ defaultModel: "claude-sonnet-4-6",
31
+ apiKey: process.env.ANTHROPIC_API_KEY,
32
+ });
33
+
34
+ for await (const event of provider.streamChat({
35
+ model: "claude-sonnet-4-6",
36
+ messages: [{ role: "user", content: "Hello!" }],
37
+ })) {
38
+ if ("type" in event && event.type === "assistant_text") {
39
+ process.stdout.write(event.delta);
40
+ }
41
+ }
42
+ ```
43
+
44
+ ## API
45
+
46
+ ### Factory
47
+
48
+ - `createProvider(config, modelKey?, onDiagnosticEvent?, debugLoggingEnabled?, retryConfig?)` — instantiate an `LLMProvider` from a `ProviderConfig`
49
+ - `extractModelFromConfig(config)` — read the default model key from a provider config
50
+
51
+ ### Provider contract
52
+
53
+ `LLMProvider` exposes `name`, `getCapabilities()`, and `streamChat(request)`, which yields `ChatStreamEvent` values (`assistant_text`, `thinking_delta`, `tool_calls`, `status`, `reasoning_summary`, `terminal`).
54
+
55
+ `ProviderCapabilities.supportsSyntheticToolCallHistory` is `false` for providers (currently Gemini) that reject caller-fabricated assistant tool-call history; callers should inline such content into a user message instead.
56
+
57
+ ### Configuration
58
+
59
+ - `validateProvidersConfig(value)` — validate an arbitrary parsed value as a `ProvidersConfig`
60
+ - `resolveProvider(config, name?)` / `resolveModelKey(provider, key?)`
61
+ - `getDefaultProviderModelSelection(config)` / `updateDefaultProviderModelSelection(config, providerName, modelKey?)`
62
+ - `loadProvidersConfig(filePath, options?)` / `loadProvidersConfigAsync(filePath, options?)` — load + validate from an explicit file path; `options.missingMessage` customizes the missing-file error
63
+ - `writeProvidersConfig(filePath, config)` — atomic write
64
+ - `updateDefaultProviderModelSelectionInFile(filePath, providerName, modelKey?)`
65
+
66
+ ### Errors
67
+
68
+ `ProviderError` and subclasses `ProviderAuthenticationError`, `ProviderRateLimitError`, `ProviderCapacityError`, `ProviderModelNotFoundError`, `ProviderContextLengthError`.
69
+
70
+ ### Diagnostics
71
+
72
+ Pass a `ProviderDiagnosticListener` to `createProvider` to receive `ProviderDiagnosticEvent`s (currently `provider_retry`, emitted when a request is retried).
73
+
74
+ ## Development
75
+
76
+ ```bash
77
+ npm install
78
+ npm test # unit tests
79
+ npm run test:integration # live-API tests (needs provider credentials)
80
+ npm run build
81
+ ```
82
+
83
+ ## License
84
+
85
+ MIT
@@ -0,0 +1,91 @@
1
+ /**
2
+ * A model entry containing both human-readable name and technical key.
3
+ * contextWindowTokens is required because providers do not maintain
4
+ * hardcoded per-model capability tables.
5
+ */
6
+ export interface Model {
7
+ name: string;
8
+ key: string;
9
+ contextWindowTokens: number;
10
+ }
11
+ /**
12
+ * Base provider configuration with common fields
13
+ */
14
+ export interface BaseProviderConfig {
15
+ name: string;
16
+ type: string;
17
+ models: Model[];
18
+ defaultModel: string;
19
+ }
20
+ /**
21
+ * Ollama provider configuration with flat structure
22
+ */
23
+ export interface OllamaProviderConfig extends BaseProviderConfig {
24
+ type: "ollama";
25
+ host?: string;
26
+ }
27
+ /**
28
+ * Bedrock provider configuration with flat structure
29
+ */
30
+ export interface BedrockProviderConfig extends BaseProviderConfig {
31
+ type: "bedrock";
32
+ region?: string;
33
+ }
34
+ /**
35
+ * OpenRouter provider configuration with flat structure
36
+ */
37
+ export interface OpenRouterRoutingConfig {
38
+ allowFallbacks?: boolean;
39
+ order?: string[];
40
+ requireParameters?: boolean;
41
+ }
42
+ export interface OpenRouterProviderConfig extends BaseProviderConfig {
43
+ type: "openrouter";
44
+ apiKey?: string;
45
+ httpReferer?: string;
46
+ xTitle?: string;
47
+ provider?: OpenRouterRoutingConfig;
48
+ fallbackModels?: string[];
49
+ debugEchoUpstreamBody?: boolean;
50
+ }
51
+ /**
52
+ * xAI (Grok) provider configuration using the OpenAI-compatible API at api.x.ai
53
+ */
54
+ export interface XaiProviderConfig extends BaseProviderConfig {
55
+ type: "xai";
56
+ apiKey?: string;
57
+ }
58
+ /**
59
+ * Cloudflare Workers AI provider configuration using the OpenAI-compatible API.
60
+ */
61
+ export interface CloudflareProviderConfig extends BaseProviderConfig {
62
+ type: "cloudflare";
63
+ apiKey?: string;
64
+ accountId?: string;
65
+ }
66
+ /**
67
+ * Gemini provider configuration using Google's OpenAI-compatible API.
68
+ */
69
+ export interface GeminiProviderConfig extends BaseProviderConfig {
70
+ type: "gemini";
71
+ apiKey?: string;
72
+ }
73
+ /**
74
+ * Anthropic (Claude API) provider configuration
75
+ */
76
+ export interface AnthropicProviderConfig extends BaseProviderConfig {
77
+ type: "anthropic";
78
+ apiKey?: string;
79
+ }
80
+ /**
81
+ * Configuration for a single LLM provider (discriminated union)
82
+ */
83
+ export type ProviderConfig = OllamaProviderConfig | BedrockProviderConfig | OpenRouterProviderConfig | GeminiProviderConfig | XaiProviderConfig | CloudflareProviderConfig | AnthropicProviderConfig;
84
+ /**
85
+ * Multi-provider configuration
86
+ */
87
+ export interface ProvidersConfig {
88
+ default: string;
89
+ providers: ProviderConfig[];
90
+ }
91
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAClE,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,IAAI,EAAE,KAAK,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAClE,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,kBAAkB;IACjE,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,qBAAqB,GACrB,wBAAwB,GACxB,oBAAoB,GACpB,iBAAiB,GACjB,wBAAwB,GACxB,uBAAuB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B"}
package/dist/config.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { ProvidersConfig } from "./config.js";
2
+ export interface LoadProvidersConfigOptions {
3
+ /**
4
+ * Message thrown when the config file does not exist. Defaults to a
5
+ * generic "Configuration file not found" message; consumers can inject
6
+ * application-specific guidance here.
7
+ */
8
+ readonly missingMessage?: string;
9
+ }
10
+ /**
11
+ * Load and validate a ProvidersConfig from a JSON file
12
+ *
13
+ * @param filePath - Path to the providers config JSON file
14
+ * @param options - Optional overrides such as the missing-file message
15
+ * @returns ProvidersConfig object with all validation completed
16
+ * @throws Error if file not found, invalid JSON, validation fails, or references are invalid
17
+ */
18
+ export declare function loadProvidersConfig(filePath: string, options?: LoadProvidersConfigOptions): ProvidersConfig;
19
+ export declare function loadProvidersConfigAsync(filePath: string, options?: LoadProvidersConfigOptions): Promise<ProvidersConfig>;
20
+ export declare function writeProvidersConfig(filePath: string, config: ProvidersConfig): void;
21
+ export declare function updateDefaultProviderModelSelectionInFile(filePath: string, providerName: string, modelKey?: string): ProvidersConfig;
22
+ //# sourceMappingURL=configFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configFile.d.ts","sourceRoot":"","sources":["../src/configFile.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM9C,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAWD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,0BAA0B,GACnC,eAAe,CAIjB;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,eAAe,CAAC,CAI1B;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,GACtB,IAAI,CAEN;AAED,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,eAAe,CASjB"}
@@ -0,0 +1,33 @@
1
+ import { readJsonFile, readJsonFileAsync, writeJsonFileAtomic, } from "./internal/jsonFile.js";
2
+ import { validateProvidersConfig, updateDefaultProviderModelSelection, } from "./configValidation.js";
3
+ function readOptions(filePath, options) {
4
+ return {
5
+ invalidJsonPrefix: "Invalid JSON in configuration file",
6
+ missingMessage: options?.missingMessage ?? `Configuration file not found: ${filePath}`,
7
+ readErrorPrefix: "Failed to read configuration file",
8
+ };
9
+ }
10
+ /**
11
+ * Load and validate a ProvidersConfig from a JSON file
12
+ *
13
+ * @param filePath - Path to the providers config JSON file
14
+ * @param options - Optional overrides such as the missing-file message
15
+ * @returns ProvidersConfig object with all validation completed
16
+ * @throws Error if file not found, invalid JSON, validation fails, or references are invalid
17
+ */
18
+ export function loadProvidersConfig(filePath, options) {
19
+ return validateProvidersConfig(readJsonFile(filePath, readOptions(filePath, options)));
20
+ }
21
+ export async function loadProvidersConfigAsync(filePath, options) {
22
+ return validateProvidersConfig(await readJsonFileAsync(filePath, readOptions(filePath, options)));
23
+ }
24
+ export function writeProvidersConfig(filePath, config) {
25
+ writeJsonFileAtomic(filePath, "providers", config);
26
+ }
27
+ export function updateDefaultProviderModelSelectionInFile(filePath, providerName, modelKey) {
28
+ const config = loadProvidersConfig(filePath);
29
+ const updatedConfig = updateDefaultProviderModelSelection(config, providerName, modelKey);
30
+ writeProvidersConfig(filePath, updatedConfig);
31
+ return updatedConfig;
32
+ }
33
+ //# sourceMappingURL=configFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configFile.js","sourceRoot":"","sources":["../src/configFile.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,uBAAuB,EACvB,mCAAmC,GACpC,MAAM,uBAAuB,CAAC;AAW/B,SAAS,WAAW,CAAC,QAAgB,EAAE,OAAoC;IACzE,OAAO;QACL,iBAAiB,EAAE,oCAAoC;QACvD,cAAc,EACZ,OAAO,EAAE,cAAc,IAAI,iCAAiC,QAAQ,EAAE;QACxE,eAAe,EAAE,mCAAmC;KACrD,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,OAAoC;IAEpC,OAAO,uBAAuB,CAC5B,YAAY,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CACvD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,QAAgB,EAChB,OAAoC;IAEpC,OAAO,uBAAuB,CAC5B,MAAM,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,QAAgB,EAChB,MAAuB;IAEvB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,yCAAyC,CACvD,QAAgB,EAChB,YAAoB,EACpB,QAAiB;IAEjB,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAG,mCAAmC,CACvD,MAAM,EACN,YAAY,EACZ,QAAQ,CACT,CAAC;IACF,oBAAoB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC9C,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { ProvidersConfig, ProviderConfig } from "./config.js";
2
+ export interface ProviderModelSelection {
3
+ readonly providerName: string;
4
+ readonly modelKey: string;
5
+ }
6
+ /**
7
+ * Validate an arbitrary value as a ProvidersConfig
8
+ *
9
+ * @param config - The parsed configuration value to validate
10
+ * @returns ProvidersConfig object with all validation completed
11
+ * @throws Error if validation fails or references are invalid
12
+ */
13
+ export declare function validateProvidersConfig(config: unknown): ProvidersConfig;
14
+ /**
15
+ * Resolve a provider from ProvidersConfig by name
16
+ *
17
+ * @param config - The providers configuration
18
+ * @param providerName - Optional provider name. If not provided, uses config.default
19
+ * @returns The resolved ProviderConfig
20
+ * @throws Error if provider not found
21
+ */
22
+ export declare function resolveProvider(config: ProvidersConfig, providerName?: string): ProviderConfig;
23
+ /**
24
+ * Resolve a model key from a ProviderConfig
25
+ *
26
+ * @param provider - The provider configuration
27
+ * @param modelKey - Optional model key. If not provided, uses provider.defaultModel
28
+ * @returns The resolved model key
29
+ * @throws Error if model key not found
30
+ */
31
+ export declare function resolveModelKey(provider: ProviderConfig, modelKey?: string): string;
32
+ export declare function getDefaultProviderModelSelection(config: ProvidersConfig): ProviderModelSelection;
33
+ export declare function updateDefaultProviderModelSelection(config: ProvidersConfig, providerName: string, modelKey?: string): ProvidersConfig;
34
+ //# sourceMappingURL=configValidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configValidation.d.ts","sourceRoot":"","sources":["../src/configValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe,CAoCxE;AAwKD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,YAAY,CAAC,EAAE,MAAM,GACpB,cAAc,CAYhB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAYR;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,eAAe,GACtB,sBAAsB,CAMxB;AAED,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,eAAe,CAejB"}
@@ -0,0 +1,185 @@
1
+ import { validateContextWindowTokens } from "./internal/capabilities.js";
2
+ function isNonEmptyString(value) {
3
+ return typeof value === "string" && value.trim().length > 0;
4
+ }
5
+ function isNonEmptyStringArray(value) {
6
+ return (Array.isArray(value) &&
7
+ value.length > 0 &&
8
+ value.every((item) => isNonEmptyString(item)));
9
+ }
10
+ function isPlainObject(value) {
11
+ return typeof value === "object" && value !== null && !Array.isArray(value);
12
+ }
13
+ /**
14
+ * Validate an arbitrary value as a ProvidersConfig
15
+ *
16
+ * @param config - The parsed configuration value to validate
17
+ * @returns ProvidersConfig object with all validation completed
18
+ * @throws Error if validation fails or references are invalid
19
+ */
20
+ export function validateProvidersConfig(config) {
21
+ if (!isPlainObject(config)) {
22
+ throw new Error("Configuration root must be a JSON object");
23
+ }
24
+ const candidate = config;
25
+ // Validate required fields exist
26
+ if (!candidate.providers) {
27
+ throw new Error('Configuration must include a "providers" array');
28
+ }
29
+ if (candidate.default === undefined) {
30
+ throw new Error('Configuration must include a "default" field specifying default provider');
31
+ }
32
+ // Validate that default references an existing provider
33
+ const defaultProviderExists = candidate.providers.some((p) => p.name === candidate.default);
34
+ if (!defaultProviderExists) {
35
+ const availableProviders = candidate.providers
36
+ .map((p) => p.name)
37
+ .join(", ");
38
+ throw new Error(`Default provider "${candidate.default}" not found in providers list. Available: ${availableProviders}`);
39
+ }
40
+ // Validate each provider
41
+ const seenNames = new Set();
42
+ for (const provider of candidate.providers) {
43
+ validateProviderConfig(provider, seenNames);
44
+ }
45
+ return candidate;
46
+ }
47
+ /**
48
+ * Validate a single provider configuration
49
+ */
50
+ function validateProviderConfig(provider, seenNames) {
51
+ validateProviderRequiredFields(provider);
52
+ validateUniqueProviderName(provider.name, seenNames);
53
+ validateProviderModels(provider);
54
+ if (provider.type === "openrouter") {
55
+ validateOpenRouterProviderConfig(provider);
56
+ }
57
+ validateDefaultModel(provider);
58
+ }
59
+ function validateProviderRequiredFields(provider) {
60
+ const requiredFields = ["name", "type", "models", "defaultModel"];
61
+ const missingFields = requiredFields.filter((field) => !provider[field]);
62
+ if (missingFields.length > 0) {
63
+ throw new Error(`Provider is missing required fields: ${missingFields.join(", ")}`);
64
+ }
65
+ }
66
+ function validateUniqueProviderName(providerName, seenNames) {
67
+ if (seenNames.has(providerName)) {
68
+ throw new Error(`Duplicate provider name: "${providerName}". Provider names must be unique.`);
69
+ }
70
+ seenNames.add(providerName);
71
+ }
72
+ function validateProviderModels(provider) {
73
+ if (!Array.isArray(provider.models) || provider.models.length === 0) {
74
+ throw new Error(`Provider "${provider.name}" must have at least one model in the models array`);
75
+ }
76
+ const seenModelKeys = new Set();
77
+ for (const model of provider.models) {
78
+ validateProviderModel(provider.name, model, seenModelKeys);
79
+ }
80
+ }
81
+ function validateProviderModel(providerName, model, seenModelKeys) {
82
+ validateModelRequiredFields(providerName, model);
83
+ validateContextWindowTokens(model.contextWindowTokens, `Provider "${providerName}" model "${model.key}" contextWindowTokens`);
84
+ validateUniqueModelKey(providerName, model.key, seenModelKeys);
85
+ }
86
+ function validateModelRequiredFields(providerName, model) {
87
+ if (!model.name || !model.key) {
88
+ throw new Error(`Provider "${providerName}" has model missing required fields: each model must have "name", "key", and "contextWindowTokens"`);
89
+ }
90
+ if (model.contextWindowTokens === undefined) {
91
+ throw new Error(`Provider "${providerName}" model "${model.key}" is missing required field "contextWindowTokens"`);
92
+ }
93
+ }
94
+ function validateUniqueModelKey(providerName, modelKey, seenModelKeys) {
95
+ if (seenModelKeys.has(modelKey)) {
96
+ throw new Error(`Provider "${providerName}" has duplicate model key: "${modelKey}". Model keys must be unique within a provider.`);
97
+ }
98
+ seenModelKeys.add(modelKey);
99
+ }
100
+ function validateDefaultModel(provider) {
101
+ const defaultModelExists = provider.models.some((m) => m.key === provider.defaultModel);
102
+ if (!defaultModelExists) {
103
+ const availableModels = provider.models.map((m) => m.key).join(", ");
104
+ throw new Error(`Provider "${provider.name}" defaultModel "${provider.defaultModel}" not found in models list. Available: ${availableModels}`);
105
+ }
106
+ }
107
+ function validateOpenRouterProviderConfig(provider) {
108
+ if (provider.provider !== undefined) {
109
+ validateOpenRouterRoutingConfig(provider.name, provider.provider);
110
+ }
111
+ validateOptionalStringArray(provider.name, "fallbackModels", provider.fallbackModels);
112
+ validateOptionalBoolean(provider.name, "debugEchoUpstreamBody", provider.debugEchoUpstreamBody);
113
+ }
114
+ function validateOpenRouterRoutingConfig(providerName, routing) {
115
+ if (!isPlainObject(routing)) {
116
+ throw new Error(`Provider "${providerName}" OpenRouter "provider" field must be an object`);
117
+ }
118
+ validateOptionalBoolean(providerName, "provider.allowFallbacks", routing.allowFallbacks);
119
+ validateOptionalBoolean(providerName, "provider.requireParameters", routing.requireParameters);
120
+ validateOptionalStringArray(providerName, "provider.order", routing.order);
121
+ }
122
+ function validateOptionalBoolean(providerName, fieldName, value) {
123
+ if (value !== undefined && typeof value !== "boolean") {
124
+ throw new Error(`Provider "${providerName}" OpenRouter "${fieldName}" must be a boolean`);
125
+ }
126
+ }
127
+ function validateOptionalStringArray(providerName, fieldName, value) {
128
+ if (value !== undefined && !isNonEmptyStringArray(value)) {
129
+ throw new Error(`Provider "${providerName}" OpenRouter "${fieldName}" must be a non-empty array of non-empty strings`);
130
+ }
131
+ }
132
+ /**
133
+ * Resolve a provider from ProvidersConfig by name
134
+ *
135
+ * @param config - The providers configuration
136
+ * @param providerName - Optional provider name. If not provided, uses config.default
137
+ * @returns The resolved ProviderConfig
138
+ * @throws Error if provider not found
139
+ */
140
+ export function resolveProvider(config, providerName) {
141
+ const name = providerName || config.default;
142
+ const provider = config.providers.find((p) => p.name === name);
143
+ if (!provider) {
144
+ const availableProviders = config.providers.map((p) => p.name).join(", ");
145
+ throw new Error(`Unknown provider: "${name}". Available providers: ${availableProviders}`);
146
+ }
147
+ return provider;
148
+ }
149
+ /**
150
+ * Resolve a model key from a ProviderConfig
151
+ *
152
+ * @param provider - The provider configuration
153
+ * @param modelKey - Optional model key. If not provided, uses provider.defaultModel
154
+ * @returns The resolved model key
155
+ * @throws Error if model key not found
156
+ */
157
+ export function resolveModelKey(provider, modelKey) {
158
+ const key = modelKey || provider.defaultModel;
159
+ const model = provider.models.find((m) => m.key === key);
160
+ if (!model) {
161
+ const availableModels = provider.models.map((m) => m.key).join(", ");
162
+ throw new Error(`Invalid model key: "${key}" for provider "${provider.name}". Available models: ${availableModels}`);
163
+ }
164
+ return key;
165
+ }
166
+ export function getDefaultProviderModelSelection(config) {
167
+ const provider = resolveProvider(config);
168
+ return {
169
+ providerName: provider.name,
170
+ modelKey: provider.defaultModel,
171
+ };
172
+ }
173
+ export function updateDefaultProviderModelSelection(config, providerName, modelKey) {
174
+ const provider = resolveProvider(config, providerName);
175
+ const resolvedModelKey = resolveModelKey(provider, modelKey);
176
+ const updatedConfig = {
177
+ ...config,
178
+ default: provider.name,
179
+ providers: config.providers.map((entry) => entry.name === provider.name
180
+ ? { ...entry, defaultModel: resolvedModelKey }
181
+ : entry),
182
+ };
183
+ return validateProvidersConfig(updatedConfig);
184
+ }
185
+ //# sourceMappingURL=configValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configValidation.js","sourceRoot":"","sources":["../src/configValidation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Diagnostic events emitted by providers.
3
+ *
4
+ * Providers report operational events (currently only retries) through an
5
+ * optional listener callback. Consumers can forward these into their own
6
+ * diagnostics pipelines; the event shapes are stable, provider-owned types.
7
+ */
8
+ /**
9
+ * Emitted when a provider retries a failed request.
10
+ */
11
+ export interface ProviderRetryDiagnosticEvent {
12
+ type: "provider_retry";
13
+ provider: string;
14
+ model: string;
15
+ iteration: number;
16
+ reason: string;
17
+ attemptNumber: number;
18
+ delayMs: number;
19
+ }
20
+ export type ProviderDiagnosticEvent = ProviderRetryDiagnosticEvent;
21
+ export type ProviderDiagnosticListener = (event: ProviderDiagnosticEvent) => void;
22
+ /**
23
+ * Retry behavior configuration accepted by providers and the factory.
24
+ */
25
+ export interface ProviderRetryConfig {
26
+ maxRetries: number;
27
+ consecutive529Limit: number;
28
+ }
29
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,4BAA4B,CAAC;AAEnE,MAAM,MAAM,0BAA0B,GAAG,CACvC,KAAK,EAAE,uBAAuB,KAC3B,IAAI,CAAC;AAEV;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;CAC7B"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Diagnostic events emitted by providers.
3
+ *
4
+ * Providers report operational events (currently only retries) through an
5
+ * optional listener callback. Consumers can forward these into their own
6
+ * diagnostics pipelines; the event shapes are stable, provider-owned types.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,56 @@
1
+ import { LLMProvider } from "./interface.js";
2
+ import { ProviderConfig } from "./config.js";
3
+ import type { ProviderDiagnosticListener, ProviderRetryConfig } from "./diagnostics.js";
4
+ /**
5
+ * Factory function to create LLM provider instances from configuration.
6
+ *
7
+ * This factory encapsulates provider instantiation logic, allowing new providers to be added
8
+ * without modifying the Agent class. The factory uses a switch statement on type field
9
+ * to determine which provider class to instantiate.
10
+ *
11
+ * @param config - Provider configuration containing type field and provider-specific settings
12
+ * @param modelKey - Optional model key override. If provided, uses this instead of config.defaultModel
13
+ * @returns An LLMProvider interface instance configured according to the provided config
14
+ * @throws Error if the provider type is unknown or unsupported
15
+ *
16
+ * @example
17
+ * // Create an Ollama provider
18
+ * const ollamaProvider = createProvider({
19
+ * name: 'local-ollama',
20
+ * type: 'ollama',
21
+ * models: [{ name: 'Llama', key: 'llama3.2', contextWindowTokens: 8192 }],
22
+ * defaultModel: 'llama3.2',
23
+ * host: 'http://localhost:11434'
24
+ * });
25
+ *
26
+ * @example
27
+ * // Create a Bedrock provider with specific model
28
+ * const bedrockProvider = createProvider({
29
+ * name: 'bedrock',
30
+ * type: 'bedrock',
31
+ * models: [{ name: 'Claude 3.5', key: 'anthropic.claude-3-5-sonnet-20241022-v2:0', contextWindowTokens: 200000 }],
32
+ * defaultModel: 'anthropic.claude-3-5-sonnet-20241022-v2:0',
33
+ * region: 'us-west-2'
34
+ * }, 'anthropic.claude-3-5-sonnet-20241022-v2:0');
35
+ */
36
+ export declare function createProvider(config: ProviderConfig, modelKey?: string, onDiagnosticEvent?: ProviderDiagnosticListener, debugLoggingEnabled?: boolean, retryConfig?: ProviderRetryConfig): LLMProvider;
37
+ /**
38
+ * Extract the default model name from a provider configuration.
39
+ *
40
+ * This utility function provides a centralized way to extract the default model name from any
41
+ * provider configuration type. All provider configs now have a top-level defaultModel field.
42
+ *
43
+ * @param config - The provider configuration object
44
+ * @returns The default model key string
45
+ *
46
+ * @example
47
+ * const model = extractModelFromConfig({
48
+ * name: 'ollama',
49
+ * type: 'ollama',
50
+ * models: [{ name: 'Llama', key: 'llama3.2', contextWindowTokens: 8192 }],
51
+ * defaultModel: 'llama3.2'
52
+ * });
53
+ * console.log(model); // 'llama3.2'
54
+ */
55
+ export declare function extractModelFromConfig(config: ProviderConfig): string;
56
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACL,cAAc,EASf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,0BAA0B,EAC1B,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAS1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,cAAc,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,0BAA0B,EAC9C,mBAAmB,UAAQ,EAC3B,WAAW,CAAC,EAAE,mBAAmB,GAChC,WAAW,CA0Gb;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAErE"}