@charming_groot/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 (61) hide show
  1. package/dist/auth/auth-resolver.d.ts +9 -0
  2. package/dist/auth/auth-resolver.d.ts.map +1 -0
  3. package/dist/auth/auth-resolver.js +200 -0
  4. package/dist/auth/auth-resolver.js.map +1 -0
  5. package/dist/auth/index.d.ts +2 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +2 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/base-provider.d.ts +10 -0
  10. package/dist/base-provider.d.ts.map +1 -0
  11. package/dist/base-provider.js +8 -0
  12. package/dist/base-provider.js.map +1 -0
  13. package/dist/circuit-breaker.d.ts +42 -0
  14. package/dist/circuit-breaker.d.ts.map +1 -0
  15. package/dist/circuit-breaker.js +116 -0
  16. package/dist/circuit-breaker.js.map +1 -0
  17. package/dist/claude-provider.d.ts +15 -0
  18. package/dist/claude-provider.d.ts.map +1 -0
  19. package/dist/claude-provider.js +171 -0
  20. package/dist/claude-provider.js.map +1 -0
  21. package/dist/index.d.ts +10 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +9 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/openai-provider.d.ts +16 -0
  26. package/dist/openai-provider.d.ts.map +1 -0
  27. package/dist/openai-provider.js +196 -0
  28. package/dist/openai-provider.js.map +1 -0
  29. package/dist/provider-factory.d.ts +17 -0
  30. package/dist/provider-factory.d.ts.map +1 -0
  31. package/dist/provider-factory.js +36 -0
  32. package/dist/provider-factory.js.map +1 -0
  33. package/dist/retry-provider.d.ts +25 -0
  34. package/dist/retry-provider.d.ts.map +1 -0
  35. package/dist/retry-provider.js +92 -0
  36. package/dist/retry-provider.js.map +1 -0
  37. package/dist/thinking-parser.d.ts +28 -0
  38. package/dist/thinking-parser.d.ts.map +1 -0
  39. package/dist/thinking-parser.js +40 -0
  40. package/dist/thinking-parser.js.map +1 -0
  41. package/package.json +34 -0
  42. package/src/auth/auth-resolver.ts +261 -0
  43. package/src/auth/index.ts +1 -0
  44. package/src/base-provider.ts +28 -0
  45. package/src/circuit-breaker.ts +157 -0
  46. package/src/claude-provider.ts +215 -0
  47. package/src/index.ts +13 -0
  48. package/src/openai-provider.ts +239 -0
  49. package/src/provider-factory.ts +48 -0
  50. package/src/retry-provider.ts +135 -0
  51. package/src/thinking-parser.ts +50 -0
  52. package/tests/auth-resolver.test.ts +204 -0
  53. package/tests/circuit-breaker.test.ts +220 -0
  54. package/tests/claude-provider.test.ts +35 -0
  55. package/tests/openai-provider.test.ts +35 -0
  56. package/tests/provider-factory.test.ts +73 -0
  57. package/tests/retry-provider-new.test.ts +166 -0
  58. package/tests/retry-provider.test.ts +118 -0
  59. package/tests/thinking-parser.test.ts +73 -0
  60. package/tsconfig.json +10 -0
  61. package/vitest.config.ts +15 -0
@@ -0,0 +1,9 @@
1
+ import type { AuthConfig, ResolvedCredential } from '@charming_groot/core';
2
+ /**
3
+ * Synchronously extract a token/apiKey from an AuthConfig.
4
+ * For auth types that require async token exchange (OAuth client_credentials, Azure AD),
5
+ * the caller should use resolveAuth() first and pass the accessToken.
6
+ */
7
+ export declare function extractToken(auth: AuthConfig): string;
8
+ export declare function resolveAuth(auth: AuthConfig): Promise<ResolvedCredential>;
9
+ //# sourceMappingURL=auth-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-resolver.d.ts","sourceRoot":"","sources":["../../src/auth/auth-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG3E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAiBrD;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmB/E"}
@@ -0,0 +1,200 @@
1
+ import { ProviderError } from '@charming_groot/core';
2
+ /**
3
+ * Synchronously extract a token/apiKey from an AuthConfig.
4
+ * For auth types that require async token exchange (OAuth client_credentials, Azure AD),
5
+ * the caller should use resolveAuth() first and pass the accessToken.
6
+ */
7
+ export function extractToken(auth) {
8
+ switch (auth.type) {
9
+ case 'no-auth':
10
+ return 'no-auth';
11
+ case 'api-key':
12
+ return auth.apiKey;
13
+ case 'oauth':
14
+ return auth.accessToken ?? '';
15
+ case 'azure-ad':
16
+ return auth.accessToken ?? '';
17
+ case 'aws-iam':
18
+ return auth.accessKeyId ?? '';
19
+ case 'gcp-service-account':
20
+ return auth.accessToken ?? '';
21
+ case 'credential-file':
22
+ return '';
23
+ }
24
+ }
25
+ export async function resolveAuth(auth) {
26
+ switch (auth.type) {
27
+ case 'no-auth':
28
+ return { type: 'no-auth', headers: {}, token: undefined };
29
+ case 'api-key':
30
+ return resolveApiKey(auth);
31
+ case 'oauth':
32
+ return resolveOAuth(auth);
33
+ case 'azure-ad':
34
+ return resolveAzureAd(auth);
35
+ case 'aws-iam':
36
+ return resolveAwsIam(auth);
37
+ case 'gcp-service-account':
38
+ return resolveGcp(auth);
39
+ case 'credential-file':
40
+ return resolveCredentialFile(auth);
41
+ default:
42
+ throw new ProviderError(`Unsupported auth type: ${auth.type}`);
43
+ }
44
+ }
45
+ function resolveApiKey(auth) {
46
+ return {
47
+ type: 'api-key',
48
+ headers: { Authorization: `Bearer ${auth.apiKey}` },
49
+ token: auth.apiKey,
50
+ };
51
+ }
52
+ async function resolveOAuth(auth) {
53
+ // If we already have a valid access token, use it
54
+ if (auth.accessToken) {
55
+ return {
56
+ type: 'oauth',
57
+ headers: { Authorization: `Bearer ${auth.accessToken}` },
58
+ token: auth.accessToken,
59
+ };
60
+ }
61
+ // Client credentials flow
62
+ const params = new URLSearchParams({
63
+ grant_type: auth.refreshToken ? 'refresh_token' : 'client_credentials',
64
+ client_id: auth.clientId,
65
+ client_secret: auth.clientSecret,
66
+ });
67
+ if (auth.refreshToken) {
68
+ params.set('refresh_token', auth.refreshToken);
69
+ }
70
+ if (auth.scopes && auth.scopes.length > 0) {
71
+ params.set('scope', auth.scopes.join(' '));
72
+ }
73
+ const response = await fetch(auth.tokenUrl, {
74
+ method: 'POST',
75
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
76
+ body: params.toString(),
77
+ });
78
+ if (!response.ok) {
79
+ const body = await response.text();
80
+ throw new ProviderError(`OAuth token request failed (${response.status}): ${body}`);
81
+ }
82
+ const data = await response.json();
83
+ const expiresAt = data.expires_in
84
+ ? new Date(Date.now() + data.expires_in * 1000)
85
+ : undefined;
86
+ return {
87
+ type: 'oauth',
88
+ headers: { Authorization: `Bearer ${data.access_token}` },
89
+ token: data.access_token,
90
+ expiresAt,
91
+ };
92
+ }
93
+ async function resolveAzureAd(auth) {
94
+ if (auth.accessToken) {
95
+ return {
96
+ type: 'azure-ad',
97
+ headers: { Authorization: `Bearer ${auth.accessToken}` },
98
+ token: auth.accessToken,
99
+ };
100
+ }
101
+ if (!auth.clientSecret) {
102
+ throw new ProviderError('Azure AD auth requires either accessToken or clientSecret');
103
+ }
104
+ const tokenUrl = `https://login.microsoftonline.com/${auth.tenantId}/oauth2/v2.0/token`;
105
+ const params = new URLSearchParams({
106
+ grant_type: 'client_credentials',
107
+ client_id: auth.clientId,
108
+ client_secret: auth.clientSecret,
109
+ scope: 'https://cognitiveservices.azure.com/.default',
110
+ });
111
+ const response = await fetch(tokenUrl, {
112
+ method: 'POST',
113
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
114
+ body: params.toString(),
115
+ });
116
+ if (!response.ok) {
117
+ const body = await response.text();
118
+ throw new ProviderError(`Azure AD token request failed (${response.status}): ${body}`);
119
+ }
120
+ const data = await response.json();
121
+ const expiresAt = data.expires_in
122
+ ? new Date(Date.now() + data.expires_in * 1000)
123
+ : undefined;
124
+ return {
125
+ type: 'azure-ad',
126
+ headers: {
127
+ Authorization: `Bearer ${data.access_token}`,
128
+ 'api-key': data.access_token,
129
+ },
130
+ token: data.access_token,
131
+ expiresAt,
132
+ };
133
+ }
134
+ async function resolveAwsIam(auth) {
135
+ // If explicit credentials provided, use them directly
136
+ // Real AWS Bedrock signing would use AWS SDK's SigV4
137
+ // This provides the credential structure for consumers to use
138
+ const headers = {};
139
+ if (auth.accessKeyId && auth.secretAccessKey) {
140
+ headers['x-aws-access-key-id'] = auth.accessKeyId;
141
+ headers['x-aws-region'] = auth.region;
142
+ if (auth.sessionToken) {
143
+ headers['x-aws-session-token'] = auth.sessionToken;
144
+ }
145
+ }
146
+ return {
147
+ type: 'aws-iam',
148
+ headers,
149
+ token: auth.accessKeyId,
150
+ };
151
+ }
152
+ async function resolveGcp(auth) {
153
+ if (auth.accessToken) {
154
+ return {
155
+ type: 'gcp-service-account',
156
+ headers: { Authorization: `Bearer ${auth.accessToken}` },
157
+ token: auth.accessToken,
158
+ };
159
+ }
160
+ // When keyFilePath is provided, consumers should use Google Auth Library
161
+ // This returns a placeholder that signals ADC should be used
162
+ return {
163
+ type: 'gcp-service-account',
164
+ headers: {},
165
+ token: undefined,
166
+ };
167
+ }
168
+ async function resolveCredentialFile(auth) {
169
+ const { readFile } = await import('node:fs/promises');
170
+ let content;
171
+ try {
172
+ content = await readFile(auth.filePath, 'utf-8');
173
+ }
174
+ catch (error) {
175
+ throw new ProviderError(`Failed to read credential file: ${auth.filePath}`, error instanceof Error ? error : undefined);
176
+ }
177
+ try {
178
+ const credentials = JSON.parse(content);
179
+ const profile = auth.profile ?? 'default';
180
+ const entry = credentials[profile];
181
+ if (!entry) {
182
+ throw new ProviderError(`Profile '${profile}' not found in credential file`);
183
+ }
184
+ const apiKey = entry['api_key'] ?? entry['apiKey'] ?? entry['token'];
185
+ if (!apiKey) {
186
+ throw new ProviderError(`No api_key/apiKey/token found in profile '${profile}'`);
187
+ }
188
+ return {
189
+ type: 'credential-file',
190
+ headers: { Authorization: `Bearer ${apiKey}` },
191
+ token: apiKey,
192
+ };
193
+ }
194
+ catch (error) {
195
+ if (error instanceof ProviderError)
196
+ throw error;
197
+ throw new ProviderError(`Failed to parse credential file: ${auth.filePath}`, error instanceof Error ? error : undefined);
198
+ }
199
+ }
200
+ //# sourceMappingURL=auth-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-resolver.js","sourceRoot":"","sources":["../../src/auth/auth-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { resolveAuth, extractToken } from './auth-resolver.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { resolveAuth, extractToken } from './auth-resolver.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ILlmProvider, Message, LlmResponse, StreamEvent, ToolDescription } from '@charming_groot/core';
2
+ import type { AgentLogger } from '@charming_groot/core';
3
+ export declare abstract class BaseProvider implements ILlmProvider {
4
+ abstract readonly providerId: string;
5
+ protected readonly logger: AgentLogger;
6
+ constructor(loggerName: string);
7
+ abstract chat(messages: readonly Message[], tools?: readonly ToolDescription[]): Promise<LlmResponse>;
8
+ abstract stream(messages: readonly Message[], tools?: readonly ToolDescription[]): AsyncIterable<StreamEvent>;
9
+ }
10
+ //# sourceMappingURL=base-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../src/base-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,8BAAsB,YAAa,YAAW,YAAY;IACxD,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;gBAE3B,UAAU,EAAE,MAAM;IAI9B,QAAQ,CAAC,IAAI,CACX,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,GACjC,OAAO,CAAC,WAAW,CAAC;IAEvB,QAAQ,CAAC,MAAM,CACb,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,GACjC,aAAa,CAAC,WAAW,CAAC;CAC9B"}
@@ -0,0 +1,8 @@
1
+ import { createChildLogger } from '@charming_groot/core';
2
+ export class BaseProvider {
3
+ logger;
4
+ constructor(loggerName) {
5
+ this.logger = createChildLogger(loggerName);
6
+ }
7
+ }
8
+ //# sourceMappingURL=base-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-provider.js","sourceRoot":"","sources":["../src/base-provider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,OAAgB,YAAY;IAEb,MAAM,CAAc;IAEvC,YAAY,UAAkB;QAC5B,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC;CAWF"}
@@ -0,0 +1,42 @@
1
+ import type { ILlmProvider, Message, LlmResponse, StreamEvent, ToolDescription } from '@charming_groot/core';
2
+ export interface CircuitBreakerConfig {
3
+ /** Consecutive failures before opening the circuit (default: 5) */
4
+ failureThreshold?: number;
5
+ /** Consecutive successes in HALF_OPEN to close the circuit (default: 2) */
6
+ successThreshold?: number;
7
+ /** Ms to stay OPEN before allowing a probe request (default: 60_000) */
8
+ openTimeoutMs?: number;
9
+ }
10
+ type State = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
11
+ /**
12
+ * Circuit breaker wrapping an ILlmProvider.
13
+ *
14
+ * CLOSED → normal operation, counts failures
15
+ * OPEN → rejects immediately, waits openTimeoutMs then probes
16
+ * HALF_OPEN → allows one request; success → CLOSED, failure → OPEN
17
+ *
18
+ * Wrap inside RetryProvider for best results:
19
+ * createProvider() → RetryProvider → CircuitBreakerProvider
20
+ */
21
+ export declare class CircuitBreakerProvider implements ILlmProvider {
22
+ readonly providerId: string;
23
+ private readonly inner;
24
+ private readonly failureThreshold;
25
+ private readonly successThreshold;
26
+ private readonly openTimeoutMs;
27
+ private readonly logger;
28
+ private state;
29
+ private failureCount;
30
+ private successCount;
31
+ private openedAt;
32
+ constructor(provider: ILlmProvider, config?: CircuitBreakerConfig);
33
+ get currentState(): State;
34
+ chat(messages: readonly Message[], tools?: readonly ToolDescription[]): Promise<LlmResponse>;
35
+ stream(messages: readonly Message[], tools?: readonly ToolDescription[]): AsyncIterable<StreamEvent>;
36
+ private guardOrThrow;
37
+ private onSuccess;
38
+ private onFailure;
39
+ private transitionTo;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAe,EAEhB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,KAAK,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7C;;;;;;;;;GASG;AACH,qBAAa,sBAAuB,YAAW,YAAY;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IAErC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,QAAQ,CAAU;gBAEd,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,oBAAoB;IASjE,IAAI,YAAY,IAAI,KAAK,CAExB;IAEK,IAAI,CACR,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,GACjC,OAAO,CAAC,WAAW,CAAC;IAYhB,MAAM,CACX,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,GACjC,aAAa,CAAC,WAAW,CAAC;IAa7B,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,YAAY;CAwBrB"}
@@ -0,0 +1,116 @@
1
+ import { ProviderError, createChildLogger } from '@charming_groot/core';
2
+ /**
3
+ * Circuit breaker wrapping an ILlmProvider.
4
+ *
5
+ * CLOSED → normal operation, counts failures
6
+ * OPEN → rejects immediately, waits openTimeoutMs then probes
7
+ * HALF_OPEN → allows one request; success → CLOSED, failure → OPEN
8
+ *
9
+ * Wrap inside RetryProvider for best results:
10
+ * createProvider() → RetryProvider → CircuitBreakerProvider
11
+ */
12
+ export class CircuitBreakerProvider {
13
+ providerId;
14
+ inner;
15
+ failureThreshold;
16
+ successThreshold;
17
+ openTimeoutMs;
18
+ logger;
19
+ state = 'CLOSED';
20
+ failureCount = 0;
21
+ successCount = 0;
22
+ openedAt = 0;
23
+ constructor(provider, config) {
24
+ this.inner = provider;
25
+ this.providerId = provider.providerId;
26
+ this.failureThreshold = config?.failureThreshold ?? 5;
27
+ this.successThreshold = config?.successThreshold ?? 2;
28
+ this.openTimeoutMs = config?.openTimeoutMs ?? 60_000;
29
+ this.logger = createChildLogger('circuit-breaker');
30
+ }
31
+ get currentState() {
32
+ return this.state;
33
+ }
34
+ async chat(messages, tools) {
35
+ this.guardOrThrow();
36
+ try {
37
+ const result = await this.inner.chat(messages, tools);
38
+ this.onSuccess();
39
+ return result;
40
+ }
41
+ catch (error) {
42
+ this.onFailure(error);
43
+ throw error;
44
+ }
45
+ }
46
+ async *stream(messages, tools) {
47
+ this.guardOrThrow();
48
+ try {
49
+ yield* this.inner.stream(messages, tools);
50
+ this.onSuccess();
51
+ }
52
+ catch (error) {
53
+ this.onFailure(error);
54
+ throw error;
55
+ }
56
+ }
57
+ // ── Internal state machine ───────────────────────────────────────────────
58
+ guardOrThrow() {
59
+ if (this.state === 'CLOSED' || this.state === 'HALF_OPEN')
60
+ return;
61
+ // OPEN: check if timeout has elapsed
62
+ const elapsed = Date.now() - this.openedAt;
63
+ if (elapsed >= this.openTimeoutMs) {
64
+ this.transitionTo('HALF_OPEN');
65
+ return; // allow this probe request through
66
+ }
67
+ const remaining = Math.ceil((this.openTimeoutMs - elapsed) / 1000);
68
+ throw new ProviderError(`Circuit breaker OPEN for provider '${this.providerId}' — retry in ${remaining}s`);
69
+ }
70
+ onSuccess() {
71
+ if (this.state === 'HALF_OPEN') {
72
+ this.successCount++;
73
+ if (this.successCount >= this.successThreshold) {
74
+ this.transitionTo('CLOSED');
75
+ }
76
+ }
77
+ else {
78
+ this.failureCount = 0; // reset on any success in CLOSED
79
+ }
80
+ }
81
+ onFailure(error) {
82
+ const msg = error instanceof Error ? error.message : String(error);
83
+ this.logger.warn({ state: this.state, error: msg }, 'Circuit breaker recorded failure');
84
+ if (this.state === 'HALF_OPEN') {
85
+ // Probe failed → back to OPEN
86
+ this.transitionTo('OPEN');
87
+ return;
88
+ }
89
+ this.failureCount++;
90
+ if (this.failureCount >= this.failureThreshold) {
91
+ this.transitionTo('OPEN');
92
+ }
93
+ }
94
+ transitionTo(next) {
95
+ const prev = this.state;
96
+ this.state = next;
97
+ if (next === 'OPEN') {
98
+ this.openedAt = Date.now();
99
+ this.successCount = 0;
100
+ this.logger.error({ failureCount: this.failureCount, openTimeoutMs: this.openTimeoutMs }, `Circuit breaker OPENED for provider '${this.providerId}'`);
101
+ }
102
+ else if (next === 'HALF_OPEN') {
103
+ this.successCount = 0;
104
+ this.logger.warn({}, `Circuit breaker HALF_OPEN — probing provider '${this.providerId}'`);
105
+ }
106
+ else {
107
+ this.failureCount = 0;
108
+ this.logger.info({}, `Circuit breaker CLOSED for provider '${this.providerId}'`);
109
+ }
110
+ if (prev !== next) {
111
+ // Allow external inspection of state transitions
112
+ this.logger.debug({ from: prev, to: next }, 'Circuit breaker state transition');
113
+ }
114
+ }
115
+ }
116
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Message, LlmResponse, StreamEvent, ToolDescription, ProviderConfig } from '@charming_groot/core';
2
+ import { BaseProvider } from './base-provider.js';
3
+ export declare class ClaudeProvider extends BaseProvider {
4
+ readonly providerId = "claude";
5
+ private readonly client;
6
+ private readonly model;
7
+ private readonly maxTokens;
8
+ constructor(config: ProviderConfig);
9
+ chat(messages: readonly Message[], tools?: readonly ToolDescription[]): Promise<LlmResponse>;
10
+ stream(messages: readonly Message[], tools?: readonly ToolDescription[]): AsyncIterable<StreamEvent>;
11
+ private toAnthropicMessages;
12
+ private toAnthropicTools;
13
+ private parseResponse;
14
+ }
15
+ //# sourceMappingURL=claude-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-provider.d.ts","sourceRoot":"","sources":["../src/claude-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAe,EAEf,cAAc,EACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAclD,qBAAa,cAAe,SAAQ,YAAY;IAC9C,QAAQ,CAAC,UAAU,YAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,EAAE,cAAc;IAQ5B,IAAI,CACR,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,GACjC,OAAO,CAAC,WAAW,CAAC;IAsBhB,MAAM,CACX,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,GACjC,aAAa,CAAC,WAAW,CAAC;IA0C7B,OAAO,CAAC,mBAAmB;IAsC3B,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,aAAa;CAiDtB"}
@@ -0,0 +1,171 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { ProviderError } from '@charming_groot/core';
3
+ import { BaseProvider } from './base-provider.js';
4
+ import { extractToken } from './auth/auth-resolver.js';
5
+ import { extractThinkTag, estimateThinkingMs } from './thinking-parser.js';
6
+ export class ClaudeProvider extends BaseProvider {
7
+ providerId = 'claude';
8
+ client;
9
+ model;
10
+ maxTokens;
11
+ constructor(config) {
12
+ super('claude-provider');
13
+ const apiKey = extractToken(config.auth);
14
+ this.client = new Anthropic({ apiKey, baseURL: config.baseUrl });
15
+ this.model = config.model;
16
+ this.maxTokens = config.maxTokens;
17
+ }
18
+ async chat(messages, tools) {
19
+ try {
20
+ const systemMsg = messages.find((m) => m.role === 'system');
21
+ const nonSystemMsgs = messages.filter((m) => m.role !== 'system');
22
+ const response = await this.client.messages.create({
23
+ model: this.model,
24
+ max_tokens: this.maxTokens,
25
+ system: systemMsg?.content,
26
+ messages: this.toAnthropicMessages(nonSystemMsgs),
27
+ tools: tools ? this.toAnthropicTools(tools) : undefined,
28
+ });
29
+ return this.parseResponse(response);
30
+ }
31
+ catch (error) {
32
+ throw new ProviderError(`Claude API error: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
33
+ }
34
+ }
35
+ async *stream(messages, tools) {
36
+ try {
37
+ const systemMsg = messages.find((m) => m.role === 'system');
38
+ const nonSystemMsgs = messages.filter((m) => m.role !== 'system');
39
+ const stream = this.client.messages.stream({
40
+ model: this.model,
41
+ max_tokens: this.maxTokens,
42
+ system: systemMsg?.content,
43
+ messages: this.toAnthropicMessages(nonSystemMsgs),
44
+ tools: tools ? this.toAnthropicTools(tools) : undefined,
45
+ });
46
+ for await (const event of stream) {
47
+ if (event.type === 'content_block_delta') {
48
+ const delta = event.delta;
49
+ if (delta.type === 'text_delta' && delta.text) {
50
+ yield { type: 'text_delta', content: delta.text };
51
+ }
52
+ else if (delta.type === 'input_json_delta' && delta.partial_json) {
53
+ yield { type: 'tool_call_delta', content: delta.partial_json };
54
+ }
55
+ }
56
+ else if (event.type === 'content_block_start') {
57
+ const block = event.content_block;
58
+ if (block.type === 'tool_use') {
59
+ yield {
60
+ type: 'tool_call_start',
61
+ toolCall: { id: block.id, name: block.name },
62
+ };
63
+ }
64
+ }
65
+ else if (event.type === 'message_stop') {
66
+ const finalMessage = await stream.finalMessage();
67
+ yield { type: 'done', response: this.parseResponse(finalMessage) };
68
+ }
69
+ }
70
+ }
71
+ catch (error) {
72
+ throw new ProviderError(`Claude stream error: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
73
+ }
74
+ }
75
+ toAnthropicMessages(messages) {
76
+ return messages.map((msg) => {
77
+ if (msg.toolResults && msg.toolResults.length > 0) {
78
+ return {
79
+ role: 'user',
80
+ content: msg.toolResults.map((tr) => ({
81
+ type: 'tool_result',
82
+ tool_use_id: tr.toolCallId,
83
+ content: tr.content,
84
+ })),
85
+ };
86
+ }
87
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
88
+ const content = [];
89
+ if (msg.content) {
90
+ content.push({ type: 'text', text: msg.content });
91
+ }
92
+ for (const tc of msg.toolCalls) {
93
+ content.push({
94
+ type: 'tool_use',
95
+ id: tc.id,
96
+ name: tc.name,
97
+ input: JSON.parse(tc.arguments),
98
+ });
99
+ }
100
+ return { role: 'assistant', content };
101
+ }
102
+ return {
103
+ role: msg.role,
104
+ content: msg.content,
105
+ };
106
+ });
107
+ }
108
+ toAnthropicTools(tools) {
109
+ return tools.map((tool) => ({
110
+ name: tool.name,
111
+ description: tool.description,
112
+ input_schema: {
113
+ type: 'object',
114
+ properties: Object.fromEntries(tool.parameters.map((p) => [
115
+ p.name,
116
+ { type: p.type, description: p.description },
117
+ ])),
118
+ required: tool.parameters
119
+ .filter((p) => p.required)
120
+ .map((p) => p.name),
121
+ },
122
+ }));
123
+ }
124
+ parseResponse(response) {
125
+ let content = '';
126
+ const toolCalls = [];
127
+ let thinkingMs;
128
+ for (const block of response.content) {
129
+ if (block.type === 'thinking') {
130
+ // Anthropic extended thinking block — estimate duration from token count
131
+ // (no direct timing from API, but the block existing means thinking occurred)
132
+ const thinkingBlock = block;
133
+ thinkingMs = estimateThinkingMs(thinkingBlock.thinking);
134
+ }
135
+ else if (block.type === 'text') {
136
+ content += block.text;
137
+ }
138
+ else if (block.type === 'tool_use') {
139
+ toolCalls.push({
140
+ id: block.id,
141
+ name: block.name,
142
+ arguments: JSON.stringify(block.input),
143
+ });
144
+ }
145
+ }
146
+ // Fallback: parse <think>...</think> tags from text content (DeepSeek, etc.)
147
+ const parsed = extractThinkTag(content);
148
+ if (parsed.thinkContent) {
149
+ content = parsed.cleanContent;
150
+ if (!thinkingMs) {
151
+ thinkingMs = estimateThinkingMs(parsed.thinkContent);
152
+ }
153
+ }
154
+ const stopReason = response.stop_reason === 'tool_use'
155
+ ? 'tool_use'
156
+ : response.stop_reason === 'max_tokens'
157
+ ? 'max_tokens'
158
+ : 'end_turn';
159
+ return {
160
+ content,
161
+ stopReason,
162
+ toolCalls,
163
+ usage: {
164
+ inputTokens: response.usage.input_tokens,
165
+ outputTokens: response.usage.output_tokens,
166
+ thinkingMs,
167
+ },
168
+ };
169
+ }
170
+ }
171
+ //# sourceMappingURL=claude-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-provider.js","sourceRoot":"","sources":["../src/claude-provider.ts"],"names":[],"mappings":"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"}