@agentskit/adapters 0.12.2 → 0.13.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.
package/dist/index.d.cts CHANGED
@@ -1,82 +1,13 @@
1
+ import { G as GenericAdapterConfig } from './createAdapter-Dfnf3Iio.cjs';
2
+ export { C as CreateAdapterConfig, c as createAdapter } from './createAdapter-Dfnf3Iio.cjs';
1
3
  import * as _agentskit_core from '@agentskit/core';
2
- import { AdapterRequest, StreamChunk, AdapterFactory, StreamSource, AdapterCapabilities, EmbedFn } from '@agentskit/core';
3
-
4
- interface CreateAdapterConfig {
5
- send: (request: AdapterRequest) => Promise<ReadableStream | Response>;
6
- parse: (stream: ReadableStream) => AsyncIterableIterator<StreamChunk>;
7
- abort?: () => void;
8
- }
9
- interface GenericAdapterConfig {
10
- send: (request: AdapterRequest) => Promise<ReadableStream>;
11
- }
12
-
13
- declare function createAdapter(config: CreateAdapterConfig): AdapterFactory;
4
+ import { AdapterFactory, AdapterRequest, DataRegion, AdapterCapabilities, StreamChunk, EmbedFn } from '@agentskit/core';
5
+ export { DataRegion } from '@agentskit/core';
6
+ import { R as RetryOptions } from './utils-ddwu4MN4.cjs';
7
+ export { c as chunkText, f as fetchWithRetry, s as simulateStream } from './utils-ddwu4MN4.cjs';
14
8
 
15
9
  declare function generic(config: GenericAdapterConfig): AdapterFactory;
16
10
 
17
- /**
18
- * Retry knobs for adapter fetches. Tunable per call to createStreamSource.
19
- *
20
- * Default behavior:
21
- * - 3 attempts total (1 initial + 2 retries)
22
- * - exponential backoff: 500ms, 1000ms, 2000ms ... (capped at maxDelayMs)
23
- * - full jitter on each delay
24
- * - retry on HTTP 408, 429, 500, 502, 503, 504
25
- * - retry on network errors (fetch throws)
26
- * - DO NOT retry on 4xx other than 408/429 (those are bad requests / auth)
27
- * - retries only the initial fetch — never mid-stream
28
- * - respects Retry-After header when present
29
- */
30
- interface RetryOptions {
31
- maxAttempts?: number;
32
- baseDelayMs?: number;
33
- maxDelayMs?: number;
34
- jitter?: boolean;
35
- retryOn?: (info: {
36
- error?: unknown;
37
- response?: Response;
38
- attempt: number;
39
- }) => boolean;
40
- /** Hook for tests + logging. Called after every failed attempt. */
41
- onRetry?: (info: {
42
- attempt: number;
43
- delayMs: number;
44
- reason: string;
45
- }) => void;
46
- /** Sleep override for tests. Defaults to setTimeout. */
47
- sleep?: (ms: number) => Promise<void>;
48
- }
49
- /**
50
- * Run a fetch with retries on transient failures. Returns the final
51
- * Response (whether successful or not — caller decides), or throws if
52
- * the AbortSignal fires or all attempts fail with a thrown error.
53
- */
54
- declare function fetchWithRetry(doFetch: (signal: AbortSignal) => Promise<Response>, signal: AbortSignal, retryOpt?: RetryOptions): Promise<Response>;
55
- /**
56
- * Chunk-splitter that turns one large string into N streamable text chunks.
57
- * Useful when a provider returns the full response in one shot and you
58
- * want to feed it to a UI that expects streaming.
59
- *
60
- * Default splits by whitespace boundaries with a target chunk size of ~32
61
- * characters.
62
- */
63
- declare function chunkText(text: string, targetSize?: number): string[];
64
- /**
65
- * Build a StreamSource from a non-streaming fetch. The adapter is
66
- * auto-completing: it fetches once, then yields the text as a sequence
67
- * of chunks so UIs see the same streaming shape they'd see from a
68
- * native streaming provider.
69
- *
70
- * Use this when you're wiring a provider that only has a non-streaming
71
- * endpoint but you want consumers (useChat, the runtime) to get
72
- * identical ergonomics.
73
- */
74
- declare function simulateStream(doFetch: (signal: AbortSignal) => Promise<Response>, extractText: (response: Response) => Promise<string>, errorLabel: string, options?: {
75
- chunkSize?: number;
76
- delayMs?: number;
77
- retry?: RetryOptions;
78
- }): StreamSource;
79
-
80
11
  interface AnthropicConfig {
81
12
  apiKey: string;
82
13
  model: string;
@@ -428,6 +359,8 @@ declare const webllmAdapter: typeof webllm;
428
359
  interface RouterCandidate {
429
360
  id: string;
430
361
  adapter: AdapterFactory;
362
+ /** Data residency region for this adapter endpoint. */
363
+ region?: DataRegion;
431
364
  /**
432
365
  * Relative cost hint (lower wins for policy='cheapest'). Only
433
366
  * relative values matter — use $/1M tokens or any consistent unit.
@@ -443,13 +376,24 @@ interface RouterCandidate {
443
376
  capabilities?: AdapterCapabilities;
444
377
  /** Free-form tags used by classifier routing (e.g. 'fast', 'coding'). */
445
378
  tags?: string[];
379
+ /**
380
+ * Estimated grid CO2 intensity (gCO2eq per 1k tokens) for this
381
+ * adapter+region. Lower wins for `policy='greenest'`. Use
382
+ * `applyCarbonTable()` to populate from `DEFAULT_CARBON_TABLE` or
383
+ * a custom table.
384
+ */
385
+ gCO2PerKtok?: number;
446
386
  }
447
- type RouterPolicy = 'cheapest' | 'fastest' | 'capability-match' | ((input: {
387
+ type RouterPolicy = 'cheapest' | 'fastest' | 'greenest' | 'green-cost' | 'capability-match' | ((input: {
448
388
  request: AdapterRequest;
449
389
  candidates: RouterCandidate[];
450
390
  }) => string | Promise<string>);
451
391
  interface RouterOptions {
452
392
  candidates: RouterCandidate[];
393
+ /** Require all selected adapters to match this data-residency region. */
394
+ region?: DataRegion;
395
+ /** Dynamic region selector. Takes precedence over `region`. */
396
+ regionOf?: (request: AdapterRequest) => DataRegion | undefined;
453
397
  /** Policy when `classify` doesn't pick a candidate. Default 'cheapest'. */
454
398
  policy?: RouterPolicy;
455
399
  /**
@@ -474,6 +418,66 @@ interface RouterOptions {
474
418
  */
475
419
  declare function createRouter(options: RouterOptions): AdapterFactory;
476
420
 
421
+ /**
422
+ * Carbon-aware routing data. Estimated grid CO2 intensity (gCO2eq per
423
+ * 1k tokens) per provider+region. Numbers are best-effort approximations
424
+ * derived from public grid-mix data and provider PUE disclosures — they
425
+ * are good enough to differentiate "very dirty" from "very clean" but
426
+ * are not audited.
427
+ *
428
+ * Sources:
429
+ * - Electricity Maps (electricitymaps.com) for grid carbon intensity.
430
+ * - Provider PUE / efficiency reports (Anthropic, Google, AWS).
431
+ * - LLMCarbon (Faiz et al., 2024) for tok→J coefficients.
432
+ *
433
+ * Pull-requests welcome to refine. The table is community-updateable
434
+ * and ships at compile time; a runtime table can be passed via
435
+ * `applyCarbonTable(candidates, customTable)`.
436
+ *
437
+ * Closes part of issue #209.
438
+ */
439
+ type ProviderRegionKey = `${string}:${string}`;
440
+ type CarbonTable = Record<ProviderRegionKey, number>;
441
+ /**
442
+ * Default carbon table. Keys are `provider:region`; values are
443
+ * estimated gCO2eq per 1k tokens of typical mixed input/output. Lower
444
+ * is greener.
445
+ */
446
+ declare const DEFAULT_CARBON_TABLE: CarbonTable;
447
+ interface ApplyCarbonOptions {
448
+ /** Override the default table. */
449
+ table?: CarbonTable;
450
+ /**
451
+ * How to derive the lookup key for a candidate. Defaults to
452
+ * `${provider}:${region}` where `provider` is the candidate id
453
+ * before the first `-` and `region` is `candidate.region`.
454
+ */
455
+ keyFor?: (candidate: RouterCandidate) => ProviderRegionKey | undefined;
456
+ /** Fallback gCO2eq per 1k tokens when no table entry is found. */
457
+ fallback?: number;
458
+ }
459
+ /**
460
+ * Decorate a list of router candidates with `gCO2PerKtok` from a
461
+ * carbon table. Returns a new list — does not mutate the input.
462
+ *
463
+ * ```ts
464
+ * const candidates = applyCarbonTable([
465
+ * { id: 'openai-eu', adapter: openai({...}), region: 'swedencentral', cost: 0.6 },
466
+ * { id: 'anthropic-us', adapter: anthropic({...}), region: 'us-east-1', cost: 0.5 },
467
+ * ])
468
+ *
469
+ * const router = createRouter({ candidates, policy: 'green-cost' })
470
+ * ```
471
+ */
472
+ declare function applyCarbonTable(candidates: RouterCandidate[], options?: ApplyCarbonOptions): RouterCandidate[];
473
+ /**
474
+ * Estimated CO2 emitted by a single completion (grams). Multiply
475
+ * `gCO2PerKtok` by `tokens / 1000`. Provided as a convenience for
476
+ * dashboards / chargeback reports — runtimes typically derive this
477
+ * from token usage events.
478
+ */
479
+ declare function estimateCO2Grams(gCO2PerKtok: number | undefined, tokens: number): number;
480
+
477
481
  interface EnsembleCandidate {
478
482
  id: string;
479
483
  adapter: AdapterFactory;
@@ -656,4 +660,125 @@ interface KimiEmbedderConfig extends OpenAICompatibleEmbedderConfig {
656
660
  }
657
661
  declare const kimiEmbedder: (config: OpenAICompatibleEmbedderConfig) => _agentskit_core.EmbedFn;
658
662
 
659
- export { type AnthropicConfig, type AzureOpenAIConfig, type BailConfig, type BedrockConfig, type BedrockRuntimeClientLike, type CerebrasConfig, type CohereConfig, type CreateAdapterConfig, type DeepSeekConfig, type DeepSeekEmbedderConfig, type EnsembleAggregator, type EnsembleBranchResult, type EnsembleCandidate, type EnsembleOptions, type FallbackCandidate, type FallbackOptions, type FireworksConfig, type GeminiConfig, type GeminiEmbedderConfig, type GenericAdapterConfig, type GrokConfig, type GrokEmbedderConfig, type GroqConfig, type HuggingFaceConfig, type KimiConfig, type KimiEmbedderConfig, type LMStudioConfig, type LangChainConfig, type LangGraphConfig, type LlamaCppConfig, type MistralConfig, type MockAdapterOptions, type MockResponse, type OllamaConfig, type OllamaEmbedderConfig, type OpenAICompatibleEmbedderConfig, type OpenAIConfig, type OpenAIEmbedderConfig, type OpenRouterConfig, type RecordedTurn, type RecordingFixture, type RecordingSink, type ReplicateConfig, type RetryOptions, type RouterCandidate, type RouterOptions, type RouterPolicy, type TogetherConfig, type VLLMConfig, type VercelAIConfig, type VertexConfig, type WebLlmConfig, type WebLlmEngineLike, anthropic, azureOpenAI, azureOpenAIAdapter, bail, bailAdapter, bedrock, bedrockAdapter, cerebras, cerebrasAdapter, chunkText, cohere, cohereAdapter, createAdapter, createEnsembleAdapter, createFallbackAdapter, createOpenAICompatibleEmbedder, createRouter, deepseek, deepseekEmbedder, fetchWithRetry, fireworks, gemini, geminiEmbedder, generic, grok, grokEmbedder, groq, groqAdapter, huggingface, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, llamacpp, lmstudio, mistral, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, openrouter, qwen, recordingAdapter, replayAdapter, replicate, replicateAdapter, simulateStream, together, vercelAI, vertex, vertexAdapter, vllm, webllm, webllmAdapter };
663
+ /**
664
+ * Provider model deprecation policy. When a provider deprecates a
665
+ * model, today the adapter silently 404s in production. This module
666
+ * lets you ship a deprecation table per provider and pick a behaviour:
667
+ *
668
+ * - `warn` — log once at startup, keep using the model.
669
+ * - `remap` — auto-substitute the configured successor.
670
+ * - `fail` — throw at startup so deploys catch it.
671
+ *
672
+ * The deprecation table is community-updateable: the default export
673
+ * holds known deprecations as of the AgentsKit release; consumers can
674
+ * pass their own table to override or extend.
675
+ *
676
+ * Closes issue #800.
677
+ */
678
+ type DeprecationAction = 'warn' | 'remap' | 'fail';
679
+ interface ModelDeprecation {
680
+ provider: string;
681
+ model: string;
682
+ /** ISO date the provider's sunset takes effect. */
683
+ sunsetOn?: string;
684
+ /** Suggested successor — used when `onDeprecation: 'remap'`. */
685
+ successor?: string;
686
+ /** Optional human-readable reason / link. */
687
+ note?: string;
688
+ }
689
+ interface DeprecationPolicy {
690
+ onDeprecation: DeprecationAction;
691
+ table?: ModelDeprecation[];
692
+ /** Sink for warnings. Defaults to `console.warn`. */
693
+ logger?: (msg: string) => void;
694
+ }
695
+ /**
696
+ * Known deprecations (current as of AgentsKit shipping). Bump on each
697
+ * release; PRs welcome. Successor picks lean towards the same
698
+ * provider's current default unless the entire family is gone.
699
+ */
700
+ declare const DEFAULT_DEPRECATION_TABLE: ModelDeprecation[];
701
+ interface ResolveModelInput {
702
+ provider: string;
703
+ model: string;
704
+ }
705
+ interface ResolveModelResult {
706
+ /** Final model id to use (may differ from input if remapped). */
707
+ model: string;
708
+ remapped: boolean;
709
+ deprecation?: ModelDeprecation;
710
+ }
711
+ declare function resolveModel(input: ResolveModelInput, policy: DeprecationPolicy): ResolveModelResult;
712
+ /**
713
+ * Wrap an `AdapterFactory` so that any model field on its requests is
714
+ * checked against the deprecation policy at startup. Convenience for
715
+ * adapters that don't want to plumb the check into their own code:
716
+ *
717
+ * ```ts
718
+ * const adapter = withDeprecationPolicy(openai({ apiKey, model: 'gpt-3.5-turbo-0301' }), {
719
+ * provider: 'openai',
720
+ * onDeprecation: 'remap',
721
+ * })
722
+ * ```
723
+ *
724
+ * For adapters with internal model state (most), prefer calling
725
+ * `resolveModel()` inside the factory and substituting before the
726
+ * first request — this wrapper is a fallback for opaque adapters.
727
+ */
728
+ declare function withDeprecationPolicy<F extends AdapterFactory>(factory: F, options: {
729
+ provider: string;
730
+ model: string;
731
+ } & DeprecationPolicy): F;
732
+
733
+ /**
734
+ * Credential rotation hook for adapters. Today rotating a provider key
735
+ * means bouncing the runtime — unacceptable for 24/7 production.
736
+ *
737
+ * Adapters opt in by accepting `apiKey` as either a `string`, a
738
+ * `() => string | Promise<string>`, or a `RotatingCredentials` holder.
739
+ * The holder lets external code (Vault, AWS Secrets Manager, KMS)
740
+ * push a new value without restart, and `refreshCredentials()` is the
741
+ * one-call API that performs the swap and emits an audit event.
742
+ *
743
+ * Closes issue #799.
744
+ */
745
+ type CredentialResolver = () => string | Promise<string>;
746
+ interface RotatingCredentials {
747
+ /** Resolve the current secret. Adapters call this on every request. */
748
+ current: CredentialResolver;
749
+ /** Replace the in-memory secret. Returns the new value. */
750
+ rotate: (next: string) => Promise<string>;
751
+ /** Subscribe to rotation events. Returns an unsubscribe handle. */
752
+ onRotate: (handler: (event: CredentialRotationEvent) => void) => () => void;
753
+ }
754
+ interface CredentialRotationEvent {
755
+ /** ISO timestamp of the rotation. */
756
+ rotatedAt: string;
757
+ /** Stable id (e.g. provider name) for audit-log correlation. */
758
+ id: string;
759
+ /** Last 4 chars of the new secret — useful for "did the rotation actually happen?" without leaking the key. */
760
+ fingerprint: string;
761
+ }
762
+ interface CredentialRefreshable {
763
+ /**
764
+ * Adapters that support credential rotation expose this method.
765
+ * Calling it replaces the in-memory secret. The next request uses
766
+ * the new value; in-flight requests are unaffected.
767
+ */
768
+ refreshCredentials: (next: string) => Promise<void>;
769
+ }
770
+ declare function createRotatingCredentials(initial: string, options: {
771
+ id: string;
772
+ }): RotatingCredentials;
773
+ /**
774
+ * Refresh credentials on any object that implements
775
+ * `CredentialRefreshable`. A no-op (with a debug log) if the adapter
776
+ * doesn't support rotation, so callers can run the rotation playbook
777
+ * across a heterogeneous set of adapters without branching.
778
+ */
779
+ declare function refreshCredentials(adapter: unknown, next: string, options?: {
780
+ id?: string;
781
+ logger?: (msg: string) => void;
782
+ }): Promise<boolean>;
783
+
784
+ export { type AnthropicConfig, type ApplyCarbonOptions, type AzureOpenAIConfig, type BailConfig, type BedrockConfig, type BedrockRuntimeClientLike, type CarbonTable, type CerebrasConfig, type CohereConfig, type CredentialRefreshable, DEFAULT_CARBON_TABLE, DEFAULT_DEPRECATION_TABLE, type DeepSeekConfig, type DeepSeekEmbedderConfig, type DeprecationAction, type DeprecationPolicy, type EnsembleAggregator, type EnsembleBranchResult, type EnsembleCandidate, type EnsembleOptions, type FallbackCandidate, type FallbackOptions, type FireworksConfig, type GeminiConfig, type GeminiEmbedderConfig, GenericAdapterConfig, type GrokConfig, type GrokEmbedderConfig, type GroqConfig, type HuggingFaceConfig, type KimiConfig, type KimiEmbedderConfig, type LMStudioConfig, type LangChainConfig, type LangGraphConfig, type LlamaCppConfig, type MistralConfig, type MockAdapterOptions, type MockResponse, type ModelDeprecation, type OllamaConfig, type OllamaEmbedderConfig, type OpenAICompatibleEmbedderConfig, type OpenAIConfig, type OpenAIEmbedderConfig, type OpenRouterConfig, type ProviderRegionKey, type RecordedTurn, type RecordingFixture, type RecordingSink, type ReplicateConfig, type ResolveModelInput, type ResolveModelResult, RetryOptions, type RotatingCredentials, type RouterCandidate, type RouterOptions, type RouterPolicy, type TogetherConfig, type VLLMConfig, type VercelAIConfig, type VertexConfig, type WebLlmConfig, type WebLlmEngineLike, anthropic, applyCarbonTable, azureOpenAI, azureOpenAIAdapter, bail, bailAdapter, bedrock, bedrockAdapter, cerebras, cerebrasAdapter, cohere, cohereAdapter, createEnsembleAdapter, createFallbackAdapter, createOpenAICompatibleEmbedder, createRotatingCredentials, createRouter, deepseek, deepseekEmbedder, estimateCO2Grams, fireworks, gemini, geminiEmbedder, generic, grok, grokEmbedder, groq, groqAdapter, huggingface, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, llamacpp, lmstudio, mistral, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, openrouter, qwen, recordingAdapter, refreshCredentials, replayAdapter, replicate, replicateAdapter, resolveModel, together, vercelAI, vertex, vertexAdapter, vllm, webllm, webllmAdapter, withDeprecationPolicy };
package/dist/index.d.ts CHANGED
@@ -1,82 +1,13 @@
1
+ import { G as GenericAdapterConfig } from './createAdapter-Dfnf3Iio.js';
2
+ export { C as CreateAdapterConfig, c as createAdapter } from './createAdapter-Dfnf3Iio.js';
1
3
  import * as _agentskit_core from '@agentskit/core';
2
- import { AdapterRequest, StreamChunk, AdapterFactory, StreamSource, AdapterCapabilities, EmbedFn } from '@agentskit/core';
3
-
4
- interface CreateAdapterConfig {
5
- send: (request: AdapterRequest) => Promise<ReadableStream | Response>;
6
- parse: (stream: ReadableStream) => AsyncIterableIterator<StreamChunk>;
7
- abort?: () => void;
8
- }
9
- interface GenericAdapterConfig {
10
- send: (request: AdapterRequest) => Promise<ReadableStream>;
11
- }
12
-
13
- declare function createAdapter(config: CreateAdapterConfig): AdapterFactory;
4
+ import { AdapterFactory, AdapterRequest, DataRegion, AdapterCapabilities, StreamChunk, EmbedFn } from '@agentskit/core';
5
+ export { DataRegion } from '@agentskit/core';
6
+ import { R as RetryOptions } from './utils-ddwu4MN4.js';
7
+ export { c as chunkText, f as fetchWithRetry, s as simulateStream } from './utils-ddwu4MN4.js';
14
8
 
15
9
  declare function generic(config: GenericAdapterConfig): AdapterFactory;
16
10
 
17
- /**
18
- * Retry knobs for adapter fetches. Tunable per call to createStreamSource.
19
- *
20
- * Default behavior:
21
- * - 3 attempts total (1 initial + 2 retries)
22
- * - exponential backoff: 500ms, 1000ms, 2000ms ... (capped at maxDelayMs)
23
- * - full jitter on each delay
24
- * - retry on HTTP 408, 429, 500, 502, 503, 504
25
- * - retry on network errors (fetch throws)
26
- * - DO NOT retry on 4xx other than 408/429 (those are bad requests / auth)
27
- * - retries only the initial fetch — never mid-stream
28
- * - respects Retry-After header when present
29
- */
30
- interface RetryOptions {
31
- maxAttempts?: number;
32
- baseDelayMs?: number;
33
- maxDelayMs?: number;
34
- jitter?: boolean;
35
- retryOn?: (info: {
36
- error?: unknown;
37
- response?: Response;
38
- attempt: number;
39
- }) => boolean;
40
- /** Hook for tests + logging. Called after every failed attempt. */
41
- onRetry?: (info: {
42
- attempt: number;
43
- delayMs: number;
44
- reason: string;
45
- }) => void;
46
- /** Sleep override for tests. Defaults to setTimeout. */
47
- sleep?: (ms: number) => Promise<void>;
48
- }
49
- /**
50
- * Run a fetch with retries on transient failures. Returns the final
51
- * Response (whether successful or not — caller decides), or throws if
52
- * the AbortSignal fires or all attempts fail with a thrown error.
53
- */
54
- declare function fetchWithRetry(doFetch: (signal: AbortSignal) => Promise<Response>, signal: AbortSignal, retryOpt?: RetryOptions): Promise<Response>;
55
- /**
56
- * Chunk-splitter that turns one large string into N streamable text chunks.
57
- * Useful when a provider returns the full response in one shot and you
58
- * want to feed it to a UI that expects streaming.
59
- *
60
- * Default splits by whitespace boundaries with a target chunk size of ~32
61
- * characters.
62
- */
63
- declare function chunkText(text: string, targetSize?: number): string[];
64
- /**
65
- * Build a StreamSource from a non-streaming fetch. The adapter is
66
- * auto-completing: it fetches once, then yields the text as a sequence
67
- * of chunks so UIs see the same streaming shape they'd see from a
68
- * native streaming provider.
69
- *
70
- * Use this when you're wiring a provider that only has a non-streaming
71
- * endpoint but you want consumers (useChat, the runtime) to get
72
- * identical ergonomics.
73
- */
74
- declare function simulateStream(doFetch: (signal: AbortSignal) => Promise<Response>, extractText: (response: Response) => Promise<string>, errorLabel: string, options?: {
75
- chunkSize?: number;
76
- delayMs?: number;
77
- retry?: RetryOptions;
78
- }): StreamSource;
79
-
80
11
  interface AnthropicConfig {
81
12
  apiKey: string;
82
13
  model: string;
@@ -428,6 +359,8 @@ declare const webllmAdapter: typeof webllm;
428
359
  interface RouterCandidate {
429
360
  id: string;
430
361
  adapter: AdapterFactory;
362
+ /** Data residency region for this adapter endpoint. */
363
+ region?: DataRegion;
431
364
  /**
432
365
  * Relative cost hint (lower wins for policy='cheapest'). Only
433
366
  * relative values matter — use $/1M tokens or any consistent unit.
@@ -443,13 +376,24 @@ interface RouterCandidate {
443
376
  capabilities?: AdapterCapabilities;
444
377
  /** Free-form tags used by classifier routing (e.g. 'fast', 'coding'). */
445
378
  tags?: string[];
379
+ /**
380
+ * Estimated grid CO2 intensity (gCO2eq per 1k tokens) for this
381
+ * adapter+region. Lower wins for `policy='greenest'`. Use
382
+ * `applyCarbonTable()` to populate from `DEFAULT_CARBON_TABLE` or
383
+ * a custom table.
384
+ */
385
+ gCO2PerKtok?: number;
446
386
  }
447
- type RouterPolicy = 'cheapest' | 'fastest' | 'capability-match' | ((input: {
387
+ type RouterPolicy = 'cheapest' | 'fastest' | 'greenest' | 'green-cost' | 'capability-match' | ((input: {
448
388
  request: AdapterRequest;
449
389
  candidates: RouterCandidate[];
450
390
  }) => string | Promise<string>);
451
391
  interface RouterOptions {
452
392
  candidates: RouterCandidate[];
393
+ /** Require all selected adapters to match this data-residency region. */
394
+ region?: DataRegion;
395
+ /** Dynamic region selector. Takes precedence over `region`. */
396
+ regionOf?: (request: AdapterRequest) => DataRegion | undefined;
453
397
  /** Policy when `classify` doesn't pick a candidate. Default 'cheapest'. */
454
398
  policy?: RouterPolicy;
455
399
  /**
@@ -474,6 +418,66 @@ interface RouterOptions {
474
418
  */
475
419
  declare function createRouter(options: RouterOptions): AdapterFactory;
476
420
 
421
+ /**
422
+ * Carbon-aware routing data. Estimated grid CO2 intensity (gCO2eq per
423
+ * 1k tokens) per provider+region. Numbers are best-effort approximations
424
+ * derived from public grid-mix data and provider PUE disclosures — they
425
+ * are good enough to differentiate "very dirty" from "very clean" but
426
+ * are not audited.
427
+ *
428
+ * Sources:
429
+ * - Electricity Maps (electricitymaps.com) for grid carbon intensity.
430
+ * - Provider PUE / efficiency reports (Anthropic, Google, AWS).
431
+ * - LLMCarbon (Faiz et al., 2024) for tok→J coefficients.
432
+ *
433
+ * Pull-requests welcome to refine. The table is community-updateable
434
+ * and ships at compile time; a runtime table can be passed via
435
+ * `applyCarbonTable(candidates, customTable)`.
436
+ *
437
+ * Closes part of issue #209.
438
+ */
439
+ type ProviderRegionKey = `${string}:${string}`;
440
+ type CarbonTable = Record<ProviderRegionKey, number>;
441
+ /**
442
+ * Default carbon table. Keys are `provider:region`; values are
443
+ * estimated gCO2eq per 1k tokens of typical mixed input/output. Lower
444
+ * is greener.
445
+ */
446
+ declare const DEFAULT_CARBON_TABLE: CarbonTable;
447
+ interface ApplyCarbonOptions {
448
+ /** Override the default table. */
449
+ table?: CarbonTable;
450
+ /**
451
+ * How to derive the lookup key for a candidate. Defaults to
452
+ * `${provider}:${region}` where `provider` is the candidate id
453
+ * before the first `-` and `region` is `candidate.region`.
454
+ */
455
+ keyFor?: (candidate: RouterCandidate) => ProviderRegionKey | undefined;
456
+ /** Fallback gCO2eq per 1k tokens when no table entry is found. */
457
+ fallback?: number;
458
+ }
459
+ /**
460
+ * Decorate a list of router candidates with `gCO2PerKtok` from a
461
+ * carbon table. Returns a new list — does not mutate the input.
462
+ *
463
+ * ```ts
464
+ * const candidates = applyCarbonTable([
465
+ * { id: 'openai-eu', adapter: openai({...}), region: 'swedencentral', cost: 0.6 },
466
+ * { id: 'anthropic-us', adapter: anthropic({...}), region: 'us-east-1', cost: 0.5 },
467
+ * ])
468
+ *
469
+ * const router = createRouter({ candidates, policy: 'green-cost' })
470
+ * ```
471
+ */
472
+ declare function applyCarbonTable(candidates: RouterCandidate[], options?: ApplyCarbonOptions): RouterCandidate[];
473
+ /**
474
+ * Estimated CO2 emitted by a single completion (grams). Multiply
475
+ * `gCO2PerKtok` by `tokens / 1000`. Provided as a convenience for
476
+ * dashboards / chargeback reports — runtimes typically derive this
477
+ * from token usage events.
478
+ */
479
+ declare function estimateCO2Grams(gCO2PerKtok: number | undefined, tokens: number): number;
480
+
477
481
  interface EnsembleCandidate {
478
482
  id: string;
479
483
  adapter: AdapterFactory;
@@ -656,4 +660,125 @@ interface KimiEmbedderConfig extends OpenAICompatibleEmbedderConfig {
656
660
  }
657
661
  declare const kimiEmbedder: (config: OpenAICompatibleEmbedderConfig) => _agentskit_core.EmbedFn;
658
662
 
659
- export { type AnthropicConfig, type AzureOpenAIConfig, type BailConfig, type BedrockConfig, type BedrockRuntimeClientLike, type CerebrasConfig, type CohereConfig, type CreateAdapterConfig, type DeepSeekConfig, type DeepSeekEmbedderConfig, type EnsembleAggregator, type EnsembleBranchResult, type EnsembleCandidate, type EnsembleOptions, type FallbackCandidate, type FallbackOptions, type FireworksConfig, type GeminiConfig, type GeminiEmbedderConfig, type GenericAdapterConfig, type GrokConfig, type GrokEmbedderConfig, type GroqConfig, type HuggingFaceConfig, type KimiConfig, type KimiEmbedderConfig, type LMStudioConfig, type LangChainConfig, type LangGraphConfig, type LlamaCppConfig, type MistralConfig, type MockAdapterOptions, type MockResponse, type OllamaConfig, type OllamaEmbedderConfig, type OpenAICompatibleEmbedderConfig, type OpenAIConfig, type OpenAIEmbedderConfig, type OpenRouterConfig, type RecordedTurn, type RecordingFixture, type RecordingSink, type ReplicateConfig, type RetryOptions, type RouterCandidate, type RouterOptions, type RouterPolicy, type TogetherConfig, type VLLMConfig, type VercelAIConfig, type VertexConfig, type WebLlmConfig, type WebLlmEngineLike, anthropic, azureOpenAI, azureOpenAIAdapter, bail, bailAdapter, bedrock, bedrockAdapter, cerebras, cerebrasAdapter, chunkText, cohere, cohereAdapter, createAdapter, createEnsembleAdapter, createFallbackAdapter, createOpenAICompatibleEmbedder, createRouter, deepseek, deepseekEmbedder, fetchWithRetry, fireworks, gemini, geminiEmbedder, generic, grok, grokEmbedder, groq, groqAdapter, huggingface, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, llamacpp, lmstudio, mistral, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, openrouter, qwen, recordingAdapter, replayAdapter, replicate, replicateAdapter, simulateStream, together, vercelAI, vertex, vertexAdapter, vllm, webllm, webllmAdapter };
663
+ /**
664
+ * Provider model deprecation policy. When a provider deprecates a
665
+ * model, today the adapter silently 404s in production. This module
666
+ * lets you ship a deprecation table per provider and pick a behaviour:
667
+ *
668
+ * - `warn` — log once at startup, keep using the model.
669
+ * - `remap` — auto-substitute the configured successor.
670
+ * - `fail` — throw at startup so deploys catch it.
671
+ *
672
+ * The deprecation table is community-updateable: the default export
673
+ * holds known deprecations as of the AgentsKit release; consumers can
674
+ * pass their own table to override or extend.
675
+ *
676
+ * Closes issue #800.
677
+ */
678
+ type DeprecationAction = 'warn' | 'remap' | 'fail';
679
+ interface ModelDeprecation {
680
+ provider: string;
681
+ model: string;
682
+ /** ISO date the provider's sunset takes effect. */
683
+ sunsetOn?: string;
684
+ /** Suggested successor — used when `onDeprecation: 'remap'`. */
685
+ successor?: string;
686
+ /** Optional human-readable reason / link. */
687
+ note?: string;
688
+ }
689
+ interface DeprecationPolicy {
690
+ onDeprecation: DeprecationAction;
691
+ table?: ModelDeprecation[];
692
+ /** Sink for warnings. Defaults to `console.warn`. */
693
+ logger?: (msg: string) => void;
694
+ }
695
+ /**
696
+ * Known deprecations (current as of AgentsKit shipping). Bump on each
697
+ * release; PRs welcome. Successor picks lean towards the same
698
+ * provider's current default unless the entire family is gone.
699
+ */
700
+ declare const DEFAULT_DEPRECATION_TABLE: ModelDeprecation[];
701
+ interface ResolveModelInput {
702
+ provider: string;
703
+ model: string;
704
+ }
705
+ interface ResolveModelResult {
706
+ /** Final model id to use (may differ from input if remapped). */
707
+ model: string;
708
+ remapped: boolean;
709
+ deprecation?: ModelDeprecation;
710
+ }
711
+ declare function resolveModel(input: ResolveModelInput, policy: DeprecationPolicy): ResolveModelResult;
712
+ /**
713
+ * Wrap an `AdapterFactory` so that any model field on its requests is
714
+ * checked against the deprecation policy at startup. Convenience for
715
+ * adapters that don't want to plumb the check into their own code:
716
+ *
717
+ * ```ts
718
+ * const adapter = withDeprecationPolicy(openai({ apiKey, model: 'gpt-3.5-turbo-0301' }), {
719
+ * provider: 'openai',
720
+ * onDeprecation: 'remap',
721
+ * })
722
+ * ```
723
+ *
724
+ * For adapters with internal model state (most), prefer calling
725
+ * `resolveModel()` inside the factory and substituting before the
726
+ * first request — this wrapper is a fallback for opaque adapters.
727
+ */
728
+ declare function withDeprecationPolicy<F extends AdapterFactory>(factory: F, options: {
729
+ provider: string;
730
+ model: string;
731
+ } & DeprecationPolicy): F;
732
+
733
+ /**
734
+ * Credential rotation hook for adapters. Today rotating a provider key
735
+ * means bouncing the runtime — unacceptable for 24/7 production.
736
+ *
737
+ * Adapters opt in by accepting `apiKey` as either a `string`, a
738
+ * `() => string | Promise<string>`, or a `RotatingCredentials` holder.
739
+ * The holder lets external code (Vault, AWS Secrets Manager, KMS)
740
+ * push a new value without restart, and `refreshCredentials()` is the
741
+ * one-call API that performs the swap and emits an audit event.
742
+ *
743
+ * Closes issue #799.
744
+ */
745
+ type CredentialResolver = () => string | Promise<string>;
746
+ interface RotatingCredentials {
747
+ /** Resolve the current secret. Adapters call this on every request. */
748
+ current: CredentialResolver;
749
+ /** Replace the in-memory secret. Returns the new value. */
750
+ rotate: (next: string) => Promise<string>;
751
+ /** Subscribe to rotation events. Returns an unsubscribe handle. */
752
+ onRotate: (handler: (event: CredentialRotationEvent) => void) => () => void;
753
+ }
754
+ interface CredentialRotationEvent {
755
+ /** ISO timestamp of the rotation. */
756
+ rotatedAt: string;
757
+ /** Stable id (e.g. provider name) for audit-log correlation. */
758
+ id: string;
759
+ /** Last 4 chars of the new secret — useful for "did the rotation actually happen?" without leaking the key. */
760
+ fingerprint: string;
761
+ }
762
+ interface CredentialRefreshable {
763
+ /**
764
+ * Adapters that support credential rotation expose this method.
765
+ * Calling it replaces the in-memory secret. The next request uses
766
+ * the new value; in-flight requests are unaffected.
767
+ */
768
+ refreshCredentials: (next: string) => Promise<void>;
769
+ }
770
+ declare function createRotatingCredentials(initial: string, options: {
771
+ id: string;
772
+ }): RotatingCredentials;
773
+ /**
774
+ * Refresh credentials on any object that implements
775
+ * `CredentialRefreshable`. A no-op (with a debug log) if the adapter
776
+ * doesn't support rotation, so callers can run the rotation playbook
777
+ * across a heterogeneous set of adapters without branching.
778
+ */
779
+ declare function refreshCredentials(adapter: unknown, next: string, options?: {
780
+ id?: string;
781
+ logger?: (msg: string) => void;
782
+ }): Promise<boolean>;
783
+
784
+ export { type AnthropicConfig, type ApplyCarbonOptions, type AzureOpenAIConfig, type BailConfig, type BedrockConfig, type BedrockRuntimeClientLike, type CarbonTable, type CerebrasConfig, type CohereConfig, type CredentialRefreshable, DEFAULT_CARBON_TABLE, DEFAULT_DEPRECATION_TABLE, type DeepSeekConfig, type DeepSeekEmbedderConfig, type DeprecationAction, type DeprecationPolicy, type EnsembleAggregator, type EnsembleBranchResult, type EnsembleCandidate, type EnsembleOptions, type FallbackCandidate, type FallbackOptions, type FireworksConfig, type GeminiConfig, type GeminiEmbedderConfig, GenericAdapterConfig, type GrokConfig, type GrokEmbedderConfig, type GroqConfig, type HuggingFaceConfig, type KimiConfig, type KimiEmbedderConfig, type LMStudioConfig, type LangChainConfig, type LangGraphConfig, type LlamaCppConfig, type MistralConfig, type MockAdapterOptions, type MockResponse, type ModelDeprecation, type OllamaConfig, type OllamaEmbedderConfig, type OpenAICompatibleEmbedderConfig, type OpenAIConfig, type OpenAIEmbedderConfig, type OpenRouterConfig, type ProviderRegionKey, type RecordedTurn, type RecordingFixture, type RecordingSink, type ReplicateConfig, type ResolveModelInput, type ResolveModelResult, RetryOptions, type RotatingCredentials, type RouterCandidate, type RouterOptions, type RouterPolicy, type TogetherConfig, type VLLMConfig, type VercelAIConfig, type VertexConfig, type WebLlmConfig, type WebLlmEngineLike, anthropic, applyCarbonTable, azureOpenAI, azureOpenAIAdapter, bail, bailAdapter, bedrock, bedrockAdapter, cerebras, cerebrasAdapter, cohere, cohereAdapter, createEnsembleAdapter, createFallbackAdapter, createOpenAICompatibleEmbedder, createRotatingCredentials, createRouter, deepseek, deepseekEmbedder, estimateCO2Grams, fireworks, gemini, geminiEmbedder, generic, grok, grokEmbedder, groq, groqAdapter, huggingface, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, llamacpp, lmstudio, mistral, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, openrouter, qwen, recordingAdapter, refreshCredentials, replayAdapter, replicate, replicateAdapter, resolveModel, together, vercelAI, vertex, vertexAdapter, vllm, webllm, webllmAdapter, withDeprecationPolicy };