@oh-my-pi/pi-catalog 18.12.6 → 18.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/types/compat/anthropic.d.ts +20 -0
  3. package/dist/types/compat/behavior.d.ts +2 -0
  4. package/dist/types/compat/catalog-policy.d.ts +2 -2
  5. package/dist/types/compat/collapse.d.ts +10 -0
  6. package/dist/types/compat/factory-droid.d.ts +2 -0
  7. package/dist/types/compat/resolve.d.ts +2 -2
  8. package/dist/types/compat/types.d.ts +2 -0
  9. package/dist/types/discovery/antigravity.d.ts +7 -2
  10. package/dist/types/discovery/devin.d.ts +1 -1
  11. package/dist/types/provider-models/google.d.ts +2 -0
  12. package/dist/types/provider-models/openai-compat.d.ts +5 -0
  13. package/dist/types/types.d.ts +58 -3
  14. package/dist/types/wire/devin.d.ts +2 -2
  15. package/dist/types/wire/gemini-headers.d.ts +41 -22
  16. package/dist/types/wire/xiaomi-token-plan.d.ts +2 -0
  17. package/package.json +4 -4
  18. package/src/build.ts +47 -1
  19. package/src/compat/anthropic.ts +47 -0
  20. package/src/compat/axes.ts +10 -3
  21. package/src/compat/behavior.ts +5 -0
  22. package/src/compat/catalog-policy.ts +10 -8
  23. package/src/compat/collapse.ts +63 -2
  24. package/src/compat/factory-droid.ts +3 -0
  25. package/src/compat/resolve.ts +7 -5
  26. package/src/compat/rules/README.md +13 -5
  27. package/src/compat/rules/auth/google-antigravity.kdl +2 -1
  28. package/src/compat/rules/auth/llama.cpp.kdl +1 -1
  29. package/src/compat/rules/auth/xiaomi-token-plan-ams.kdl +1 -1
  30. package/src/compat/rules/auth/xiaomi-token-plan-cn.kdl +1 -1
  31. package/src/compat/rules/auth/xiaomi-token-plan-sgp.kdl +1 -1
  32. package/src/compat/rules/classes/anthropic.kdl +6 -1
  33. package/src/compat/rules/classes/minimax.kdl +10 -0
  34. package/src/compat/rules/providers/anthropic.kdl +15 -1
  35. package/src/compat/rules/providers/deepseek.kdl +13 -10
  36. package/src/compat/rules/providers/factory-droid.kdl +48 -0
  37. package/src/compat/rules/providers/google-antigravity.kdl +7 -0
  38. package/src/compat/rules/providers/kimi-code.kdl +20 -0
  39. package/src/compat/rules/providers/moonshot.kdl +25 -0
  40. package/src/compat/rules/providers/muse-code.kdl +1 -1
  41. package/src/compat/rules/providers/openai-codex.kdl +17 -4
  42. package/src/compat/rules/providers/openai.kdl +23 -2
  43. package/src/compat/rules/providers/opencode-go.kdl +38 -3
  44. package/src/compat/rules/providers/opencode-zen.kdl +7 -0
  45. package/src/compat/rules/providers/xiaomi-token-plan-ams.kdl +1 -1
  46. package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +1 -1
  47. package/src/compat/rules/providers/xiaomi-token-plan-sgp.kdl +1 -1
  48. package/src/compat/rules/providers/xiaomi.kdl +1 -1
  49. package/src/compat/rules/runtime/behavior.kdl +28 -12
  50. package/src/compat/rules/taxonomy/kimi.kdl +7 -0
  51. package/src/compat/rules.json +1 -1
  52. package/src/compat/types.ts +2 -0
  53. package/src/discovery/antigravity.ts +41 -6
  54. package/src/discovery/cursor.ts +0 -6
  55. package/src/discovery/devin.ts +9 -3
  56. package/src/discovery/factory-droid.ts +38 -6
  57. package/src/model-cache.ts +4 -2
  58. package/src/models.json +1 -1
  59. package/src/provider-models/cache-provider-id.ts +5 -2
  60. package/src/provider-models/google.ts +13 -1
  61. package/src/provider-models/openai-compat.ts +40 -10
  62. package/src/types.ts +63 -1
  63. package/src/wire/devin.ts +2 -2
  64. package/src/wire/gemini-headers.ts +68 -24
  65. package/src/wire/xiaomi-token-plan.ts +4 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,58 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.13.1] - 2026-10-27
6
+
7
+ ### Added
8
+
9
+ - Added GPT-6.1 Terra: `openai/gpt-6.1-terra` ships bundled ($1/$5, $0.05 cached, >272K long-context tier, 1.05M window), and Codex-discovered `gpt-6.1-terra`/`-wm` get API-equivalent pricing, the 922K extended-context maximum, and routing to Plus-or-higher accounts.
10
+ - Added Kimi K3.1 Pro and K3.1 Pro Highspeed support on Kimi Code (`k3.1-pro`, `k3.1-pro-highspeed`) and the Moonshot API (`kimi-k3.1-pro`, `kimi-k3.1-pro-highspeed`): official pricing ($2/$10 and $4/$20 per MTok), a 131K output cap, and K3's reasoning and wire contract ([#16901](https://github.com/can1357/oh-my-pi/pull/16901) by [@eggpeat](https://github.com/eggpeat))
11
+
12
+ ## [18.13.0] - 2026-10-26
13
+
14
+ ### Breaking Changes
15
+
16
+ - Renamed the `task-sibling-prompt-cache` axis to `shared-prompt-cache` (catalog field `sharedPromptCache`); it now also covers forks and explicit prompt-cache keys ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
17
+
18
+ ### Added
19
+
20
+ - Added the `requiresThinkingPresence` model compat (KDL `requires-thinking-presence`) for Anthropic-compatible endpoints that reject a thinking-mode request whose current turn has an assistant message without a `thinking` block ([#16739](https://github.com/can1357/oh-my-pi/pull/16739) by [@lz37](https://github.com/lz37))
21
+ - Added `resolveAnthropicApiVersion()`: Anthropic model discovery sends API version 2026-10-21 to the official API when `PI_ANTHROPIC_API_VERSION=2026-10-21` is set ([#16706](https://github.com/can1357/oh-my-pi/pull/16706) by [@H4vC](https://github.com/H4vC))
22
+ - OpenCode Go `muse-spark-1.3-contributor`, `muse-spark-1.2-contributor`, `gpt-5.6-luna`, `gpt-6-luna`, `grok-4.6` (Responses) and `deepseek-v4-pro`, `omen-alpha` (Completions) opt into shared prompt caching; lanes that warmed under any key stay off ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
23
+ - Added `CatalogPolicyInputs` so catalog-policy lookups accept a reduced model view ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
24
+ - Added a catalog conformance test that fails the build when a `bundle="always"` seed row is missing from the bundled `models.json`, so a stale-snapshot regeneration can no longer silently drop an engine the way `web/deepseek` was lost in 18.12.2 ([#16610](https://github.com/can1357/oh-my-pi/issues/16610), [#17053](https://github.com/can1357/oh-my-pi/pull/17053) by [@ouyangjiahong26](https://github.com/ouyangjiahong26))
25
+
26
+ ### Changed
27
+
28
+ - llama.cpp login instructions now list both default local base URLs (`http://127.0.0.1:8080`, then `http://127.0.0.1:9931`) ([#16675](https://github.com/can1357/oh-my-pi/pull/16675) by [@bartbroere](https://github.com/bartbroere))
29
+ - Devin requests now identify as Devin CLI 3000.11.205, the current stable release, instead of 3000.11.3 ([#16906](https://github.com/can1357/oh-my-pi/pull/16906) by [@will-bogusz](https://github.com/will-bogusz))
30
+ - Google Antigravity login now uses PKCE and requests the `aicode` scope like the official client; existing logins keep working, and the new scope applies at the next `/login` ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
31
+ - Antigravity requests identify as client 2.26.0 when the release manifest is unreachable (previously 2.19.1), and model discovery sends the account's project like the official client ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
32
+ - Antigravity's `User-Agent` now reports the native Antigravity build for the host OS (Linux `linux`/`amd64`, Windows `windows`/`amd64`) instead of always claiming macOS `darwin`/`arm64` ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
33
+ - Antigravity model discovery now keeps each account's per-tier `model_enum`, output cap and thinking level or budget, and the bundled Antigravity models carry them for offline use; cached Antigravity model lists are refreshed once so they pick them up ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
34
+
35
+ ### Fixed
36
+
37
+ - Fixed OpenCode Go `gemini-4-argon` requests failing with an unsupported protocol; discovered models now use native Gemini routing and low, medium, or high thinking ([#17031](https://github.com/can1357/oh-my-pi/issues/17031))
38
+ - Fixed DeepSeek V4 Pro cost estimates using Flash rates after September 14 despite Pro billing remaining unchanged ([#16875](https://github.com/can1357/oh-my-pi/issues/16875)).
39
+ - Anthropic refusal fallbacks from Claude Opus 5.5, Opus 5 and Sonnet 5.5 to their documented target models (Opus 4.8 and Opus 5, Opus 4.8, and Sonnet 5) now redeem fallback credit: the retry is no longer billed as a full cache write, and it is no longer skipped when the conversation holds signed thinking ([#17034](https://github.com/can1357/oh-my-pi/pull/17034) by [@sjawhar](https://github.com/sjawhar))
40
+ - Fixed Step 5 Preview reasoning choices on OpenCode Go and Zen to offer only low, medium, and high ([#14987](https://github.com/can1357/oh-my-pi/issues/14987), [#16669](https://github.com/can1357/oh-my-pi/pull/16669) by [@SheetHappiness](https://github.com/SheetHappiness))
41
+ - Fixed GPT-6 Sol/Luna API and MiniMax-M3 long-context usage estimates above their published input thresholds ([#16711](https://github.com/can1357/oh-my-pi/issues/16711))
42
+ - Fixed Xiaomi Token Plan login and default model selection after the V2.5 retirement by using MiMo V2.6 Flash ([#16727](https://github.com/can1357/oh-my-pi/pull/16727) by [@LiPu-jpg](https://github.com/LiPu-jpg))
43
+ - Fixed Xiaomi model discovery sending `ttp-` Token Plan keys to the pay-as-you-go host, which rejects them ([#17045](https://github.com/can1357/oh-my-pi/issues/17045))
44
+ - Fixed GPT-5.6 Sol requests over 272K input tokens (`openai` and `openai-codex`) being priced at the retired $10/$45 long-context card instead of $8/$30 ([#16742](https://github.com/can1357/oh-my-pi/issues/16742))
45
+ - Fixed DeepSeek's official vision requests being held to the 5-image unknown-host floor: the catalog endpoint now carries DeepSeek's documented 600-image and 40 MiB inline-image budgets, while a custom `baseUrl` keeps the conservative floor ([vision limits](https://api-docs.deepseek.com/guides/vision#limits); [#16737](https://github.com/can1357/oh-my-pi/pull/16737) by [@Fun10165](https://github.com/Fun10165))
46
+ - Fixed Devin model discovery falling back to the two SWE-1.6 seed models when the catalog takes longer than 5s to respond; it now waits up to 15s ([#16668](https://github.com/can1357/oh-my-pi/pull/16668) by [@DusKing1](https://github.com/DusKing1))
47
+ - Fixed Go Task keeping stale prompt-cache affinity after a model's wire model changed ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
48
+ - Fixed Devin models all showing a 200K context window: each model now reports its own (1M for Claude Opus 5.5 and the `-1m` lanes, 262K for SWE-2), and GPT and Grok models with a long-context price tier start at that tier's threshold, with `/extended-context on` opening their full window ([#16905](https://github.com/can1357/oh-my-pi/pull/16905) by [@will-bogusz](https://github.com/will-bogusz))
49
+ - Added the `extended-cache-ttl-beta` compat axis so a route can opt out of the `extended-cache-ttl-2025-04-11` beta (Factory Droid does), and prompt-cache lifetimes and long-retention support for Factory Droid's Claude models ([#16296](https://github.com/can1357/oh-my-pi/pull/16296) by [@will-bogusz](https://github.com/will-bogusz))
50
+ - Added Factory Droid's image models (GPT Image 2.5, GPT Image 2.5 Flare, Gemini 3 Pro Image) to the `image` role's choices, listed only while your Factory organization allows image generation and that model ([#16316](https://github.com/can1357/oh-my-pi/pull/16316) by [@will-bogusz](https://github.com/will-bogusz))
51
+ - Fixed LiteLLM model groups with `mode: decisions` being listed as chat models; they now route to `openai-decisions` as judge models ([#16939](https://github.com/can1357/oh-my-pi/issues/16939))
52
+ - Removed retired Anthropic models (Claude 3.x, Opus 4/4.1, Sonnet 4) from the bundled catalog and discovery ([#16755](https://github.com/can1357/oh-my-pi/issues/16755))
53
+ - Fixed Kimi Code K3 and K3 256K (`k3`, `k3-256k`) pricing to include Kimi's $3/MTok cache-write rate, matching the Moonshot API `kimi-k3` card ([#16508](https://github.com/can1357/oh-my-pi/issues/16508), [#16903](https://github.com/can1357/oh-my-pi/pull/16903) by [@eggpeat](https://github.com/eggpeat))
54
+ - Fixed Devin models all showing a 200K context window: each model now reports its own (1M for Claude Opus 5.5 and the `-1m` lanes, 262K for SWE-2), and GPT and Grok models with a long-context price tier start at that tier's threshold, with `/extended-context on` opening their full window ([#16905](https://github.com/can1357/oh-my-pi/pull/16905) by [@will-bogusz](https://github.com/will-bogusz))
55
+ - Fixed Cursor Auto (`cursor/default`) being metered against the third-party ("Other Models") pool instead of the Cursor Models pool it bills to ([#17048](https://github.com/can1357/oh-my-pi/pull/17048) by [@trukhinyuri](https://github.com/trukhinyuri))
56
+
5
57
  ## [18.12.6] - 2026-10-21
6
58
 
7
59
  ### Added
@@ -6,6 +6,26 @@
6
6
  * prefix check would accept lookalikes like `https://api.anthropic.com.evil.com`.
7
7
  */
8
8
  export declare function isOfficialAnthropicApiUrl(baseUrl?: string): boolean;
9
+ /** `anthropic-version` values this codebase knows how to speak. */
10
+ export declare const ANTHROPIC_API_VERSIONS: readonly ["2023-06-01", "2026-10-21"];
11
+ export type AnthropicApiVersion = (typeof ANTHROPIC_API_VERSIONS)[number];
12
+ /** Version every non-official Anthropic-compatible endpoint receives. */
13
+ export declare const LEGACY_ANTHROPIC_API_VERSION: AnthropicApiVersion;
14
+ /**
15
+ * `anthropic-version` for a request to `baseUrl`. `PI_ANTHROPIC_API_VERSION`
16
+ * opts the official first-party API into a newer version; every other host
17
+ * (Copilot, Bedrock, Foundry, Cloudflare, third-party compatibles) stays on
18
+ * {@link LEGACY_ANTHROPIC_API_VERSION} because those deployments gate newer
19
+ * versions on their own schedule (Bedrock accepts 2026-10-21 only for 4.7+).
20
+ * Read per call so a flipped environment takes effect without a restart.
21
+ */
22
+ export declare function resolveAnthropicApiVersion(baseUrl?: string): AnthropicApiVersion;
23
+ /**
24
+ * Whether Messages requests on `version` may carry `temperature`, `top_p`,
25
+ * or `top_k`. API version 2026-10-21 rejects all three with a 400, even at
26
+ * their default values.
27
+ */
28
+ export declare function anthropicApiVersionAcceptsSamplingParams(version: AnthropicApiVersion): boolean;
9
29
  /**
10
30
  * Amazon Bedrock's Anthropic Messages API: the `/anthropic` path on the
11
31
  * bedrock-runtime or bedrock-mantle endpoint. It rejects the tool `strict`
@@ -71,6 +71,8 @@ export declare function isRetiredProvider(provider: string): boolean;
71
71
  * model that happens to advertise the same bare id.
72
72
  */
73
73
  export declare function isBareIdReferenceProvider(provider: string): boolean;
74
+ /** Whether a host's prefix cache should use append-only conversation context by default. */
75
+ export declare function prefersAppendOnlyContext(provider: string): boolean;
74
76
  /** The declared subscription tier required to use a provider model id, if any. */
75
77
  export declare function planRequirementFor(provider: string, model: string): string | undefined;
76
78
  /** Cross-provider pricing-peer resolution for one provider model id. */
@@ -1,7 +1,7 @@
1
- import type { Model } from "../types.js";
1
+ import type { CatalogPolicyInputs } from "../types.js";
2
2
  /**
3
3
  * The `catalog` axis bag authored in the KDL cascade rules for a model,
4
4
  * memoized per distinct model. Frozen: the bag is shared across callers, so it
5
5
  * must stay read-only — extract the value you need rather than handing it on.
6
6
  */
7
- export declare function resolveCatalogPolicy(model: Model): Readonly<Record<string, unknown>>;
7
+ export declare function resolveCatalogPolicy(model: CatalogPolicyInputs): Readonly<Record<string, unknown>>;
@@ -139,6 +139,16 @@ export declare function isCollapsedVariantSpec(spec: VariantSpecLike): boolean;
139
139
  * and for routes live discovery never advertised.
140
140
  */
141
141
  export declare function isCursorMaxModeWireId(wireModelId: string): boolean;
142
+ /**
143
+ * Whether `wireModelId` is one tier of a reviewed `provider` family that serves
144
+ * different efforts from distinct sibling SKUs (`-low`/`-medium`/`-high`), so
145
+ * the SKU, not the effort, fixes the thinking strength. Decided from the
146
+ * declared family routes, not a collapsed row's routing: an account roster
147
+ * listing one tier collapses to a row routing every effort to it, yet that SKU
148
+ * still advertises its own fixed thinking. Families routing every effort to
149
+ * one `-thinking` SKU keep the effort's own budget or level.
150
+ */
151
+ export declare function isReviewedTierVariantWireId(provider: string, wireModelId: string): boolean;
142
152
  /**
143
153
  * Collapse a full mixed-provider list: per provider, the compiled reviewed table, Cursor's
144
154
  * conservative live effort-sibling rule, and the automatic `X`/`X-thinking`
@@ -45,6 +45,8 @@ export interface FactoryDroidModelPolicy {
45
45
  entitlement: FactoryDroidEntitlement;
46
46
  /** Native default with no caller effort is thinking off. */
47
47
  defaultReasoningOff: boolean;
48
+ /** A `generate_image` model: gated by the org's image-generation settings, served through Factory's image routes. */
49
+ image: boolean;
48
50
  }
49
51
  /** One registry model: its roster row and resolved policy. */
50
52
  export interface FactoryDroidRegistryModel {
@@ -1,4 +1,4 @@
1
- import type { Api, CompatOf, ModelSpec, ThinkingConfig } from "../types.js";
1
+ import type { Api, CatalogPolicyInputs, CompatOf, ModelSpec, ThinkingConfig } from "../types.js";
2
2
  import type { ModelIdentity, RequestPolicy } from "./types.js";
3
3
  /** Result of resolving one model spec through the compat engine. */
4
4
  export interface ResolvedModelPolicy<TApi extends Api = Api> {
@@ -21,7 +21,7 @@ export declare function resolveDiscoveryApi(spec: ModelSpec<Api>, providerType:
21
21
  * {@link resolveModelPolicy} without resolving the compat and thinking
22
22
  * policies, which dominate its cost on catalog-wide scans.
23
23
  */
24
- export declare function resolveCatalogAxes(spec: ModelSpec<Api>): Record<string, unknown>;
24
+ export declare function resolveCatalogAxes(spec: CatalogPolicyInputs): Record<string, unknown>;
25
25
  /**
26
26
  * Resolves the full policy surface for one model spec: structured identity,
27
27
  * complete compat record, thinking metadata, and catalog-data corrections.
@@ -327,6 +327,8 @@ export interface CompiledBehavior {
327
327
  pricingPeers: CompiledPricingPeer[];
328
328
  retryResetTimezones: CompiledRetryResetTimezone[];
329
329
  retiredProviders: string[];
330
+ /** Hosts whose prefix caches benefit from a stable append-only conversation. */
331
+ appendOnlyContextProviders: string[];
330
332
  referenceIsolatedProviders: string[];
331
333
  /** Built-in model selector chains per agent role, keyed by role in declaration order. */
332
334
  roleDefaults: Record<string, string[]>;
@@ -11,6 +11,8 @@ export interface AntigravityDiscoveryApiModel {
11
11
  supportsImages?: boolean;
12
12
  supportsThinking?: boolean;
13
13
  thinkingBudget?: number;
14
+ /** SKU thinking level: 1 low, 2 medium, 3 high. */
15
+ thinkingLevel?: number;
14
16
  recommended?: boolean;
15
17
  maxTokens?: number;
16
18
  maxOutputTokens?: number;
@@ -55,8 +57,11 @@ export interface FetchAntigravityDiscoveryModelsOptions {
55
57
  token: string;
56
58
  /** Optional endpoint override. Defaults to Antigravity fallback endpoints. */
57
59
  endpoint?: string;
58
- /** Deprecated and ignored for antigravity discovery parity. */
59
- project?: string;
60
+ /**
61
+ * Cloud Code Assist project the account is onboarded to. Sent as the body's
62
+ * `project` field like the native client; the body is `{}` when absent.
63
+ */
64
+ projectId?: string;
60
65
  /** Optional user agent override. */
61
66
  userAgent?: string;
62
67
  /** Optional abort signal for request cancellation. */
@@ -7,7 +7,7 @@ export interface DevinModelDiscoveryOptions {
7
7
  apiKey?: string;
8
8
  /** Optional Codeium API base URL override. */
9
9
  baseUrl?: string;
10
- /** Optional request timeout in milliseconds (default 5000). */
10
+ /** Optional request timeout in milliseconds (default 15000). */
11
11
  timeoutMs?: number;
12
12
  /** Optional caller abort signal, combined with the internal timeout. */
13
13
  signal?: AbortSignal;
@@ -21,6 +21,8 @@ export interface GoogleAntigravityAccount {
21
21
  * When any account lacks one, no model records per-account access.
22
22
  */
23
23
  accountKey?: string;
24
+ /** Cloud Code Assist project of the credential, sent with roster discovery like the native client. */
25
+ projectId?: string;
24
26
  }
25
27
  export interface GoogleAntigravityModelManagerConfig {
26
28
  /**
@@ -560,6 +560,11 @@ export declare const OPENAI_COMPAT_DISCOVERY_DEFAULT_MAX_TOKENS = 32768;
560
560
  /** Exclude only known non-conversational modes; unknown and non-string modes remain selectable for aliases. */
561
561
  export declare function isSelectableLiteLLMModelMode(mode: unknown): boolean;
562
562
  export declare function normalizeLiteLLMManagementBaseUrl(baseUrl: string): string;
563
+ /**
564
+ * Transport for a LiteLLM model group: `mode: "decisions"` answers only on the
565
+ * proxy's `/v1/decisions` route, OpenAI-backed groups use Responses, and every
566
+ * other group uses `fallbackApi`.
567
+ */
563
568
  export declare function resolveLiteLLMApi(entry: Record<string, unknown> | undefined, id: string, fallbackApi?: Api): Api;
564
569
  export declare function fetchLiteLLMRichModels<TApi extends Api>(options: FetchLiteLLMRichModelsOptions<TApi>): Promise<ModelSpec<TApi>[] | null>;
565
570
  export declare function litellmModelManagerOptions(config?: LiteLLMModelManagerConfig): ModelManagerOptions<Api>;
@@ -20,12 +20,12 @@ export declare const RUNNER_API_KINDS: Record<Exclude<(typeof RUNNER_APIS)[numbe
20
20
  /** Kind a runner API serves; `undefined` for chat transports and multi-kind `local-inference`. */
21
21
  export declare function runnerApiKind(api: Api): ModelKind | undefined;
22
22
  /** Catalog APIs `generate_image` runs through a pi-ai image client; the hosted Responses pair needs a carrier model. */
23
- export declare const IMAGE_GENERATION_APIS: readonly ["openai-images", "openrouter-images", "google-generative-ai", "google-gemini-cli", "openai-responses", "openai-codex-responses"];
23
+ export declare const IMAGE_GENERATION_APIS: readonly ["openai-images", "openrouter-images", "google-generative-ai", "google-gemini-cli", "openai-responses", "openai-codex-responses", "factory-droid-agent"];
24
24
  export type ImageGenerationApi = (typeof IMAGE_GENERATION_APIS)[number];
25
25
  /**
26
26
  * Kinds a model on `api` may declare: a runner api serves its own kind; a chat
27
27
  * transport serves `chat` and `tiny`, plus `image` when `generate_image` runs it
28
- * (hosted Responses image tool, Gemini image models). `undefined` for
28
+ * (hosted Responses image tool, Gemini and Factory Droid image models). `undefined` for
29
29
  * `local-inference`, which hosts several kinds chosen by the model itself.
30
30
  */
31
31
  export declare function servedKinds(api: Api): readonly ModelKind[] | undefined;
@@ -550,6 +550,8 @@ export interface AnthropicCompat {
550
550
  supportsEagerToolInputStreaming?: boolean;
551
551
  /** Whether long prompt-cache retention (`ttl: "1h"`) is supported. Default: true for canonical Anthropic API. */
552
552
  supportsLongCacheRetention?: boolean;
553
+ /** Whether a `ttl: "1h"` breakpoint on API-key requests adds the `extended-cache-ttl-2025-04-11` beta. Unset: true (Vertex rawPredict URLs never send it). */
554
+ extendedCacheTtlBeta?: boolean;
553
555
  /**
554
556
  * Whether mid-conversation `role: "system"` messages are accepted in the
555
557
  * `messages` array. When unset, auto-detected from model and deployment policy.
@@ -608,6 +610,21 @@ export interface AnthropicCompat {
608
610
  * Default: auto-detected from provider/baseUrl and `model.reasoning`.
609
611
  */
610
612
  replayUnsignedThinking?: boolean;
613
+ /**
614
+ * Whether a thinking-mode history must carry a `thinking` block on EVERY
615
+ * assistant turn of the current turn. DeepSeek's Anthropic endpoint rejects
616
+ * the whole request (`The content[].thinking in the thinking mode must be
617
+ * passed back to the API.`) when any assistant turn after the last user text
618
+ * lacks one, including turns another upstream in the same gateway model group
619
+ * produced without reasoning. Presence is all it validates (the block text may
620
+ * be a placeholder, the signature may be empty), and only `thinking` counts —
621
+ * `redacted_thinking` does not, and that endpoint rejects the block outright.
622
+ * A model group that may fail over to such an endpoint must set this: the
623
+ * stricter member defines the replay contract for the group.
624
+ * Default: false (official Anthropic and lax proxies tolerate a turn without
625
+ * thinking and the block is not invented for them).
626
+ */
627
+ requiresThinkingPresence?: boolean;
611
628
  /**
612
629
  * Whether the endpoint requires `thinking.type: "enabled"` whenever the
613
630
  * model reasons. Use for models that reject omitted or disabled thinking.
@@ -975,9 +992,11 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
975
992
  */
976
993
  export type ResolvedOpenRouterCompat = ResolvedOpenAICompat & ResolvedOpenAIResponsesCompat;
977
994
  /** Fully-resolved anthropic-messages compat view (same contract as `ResolvedOpenAICompat`). */
978
- export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi" | "effortBeta" | "disabledThinking" | "betweenToolsEffort" | "stripThinkingHistory" | "fastMode" | "maxImageDimension" | "maxImagePayloadBytes">> & {
995
+ export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi" | "effortBeta" | "extendedCacheTtlBeta" | "disabledThinking" | "betweenToolsEffort" | "stripThinkingHistory" | "fastMode" | "maxImageDimension" | "maxImagePayloadBytes">> & {
979
996
  /** Effort-beta override; undefined keeps the transport's legacy heuristic. */
980
997
  effortBeta?: AnthropicCompat["effortBeta"];
998
+ /** Extended-cache-ttl beta opt-out; undefined sends it where a 1h breakpoint needs it. */
999
+ extendedCacheTtlBeta?: AnthropicCompat["extendedCacheTtlBeta"];
981
1000
  /** Disabled-thinking wire form; undefined keeps the direct-provider behavior. */
982
1001
  disabledThinking?: AnthropicCompat["disabledThinking"];
983
1002
  /** Effort pinned on `between_tools` turns; undefined leaves effort untouched. */
@@ -1204,6 +1223,13 @@ export interface ModelAccountAccess {
1204
1223
  * Absent when the backend reported no program metadata.
1205
1224
  */
1206
1225
  cyberPrograms?: readonly string[];
1226
+ /**
1227
+ * Antigravity request constants this account's `fetchAvailableModels`
1228
+ * roster advertised, keyed by upstream SKU id. Takes precedence over
1229
+ * {@link Model.antigravityWireProfiles}, which keeps only the first
1230
+ * account's values when multi-account rosters are unioned.
1231
+ */
1232
+ antigravityWireProfiles?: Readonly<Record<string, AntigravityModelWireProfile>>;
1207
1233
  }
1208
1234
  /** One Cursor `RequestedModel.parameters` entry recovered from rich discovery. */
1209
1235
  export interface CursorModelParameter {
@@ -1216,6 +1242,20 @@ export interface CursorModelRoute {
1216
1242
  parameters: readonly CursorModelParameter[];
1217
1243
  maxMode?: boolean;
1218
1244
  }
1245
+ /**
1246
+ * Antigravity Cloud Code Assist request constants for one upstream SKU, as the
1247
+ * native client sends them; see {@link Model.antigravityWireProfiles}.
1248
+ */
1249
+ export interface AntigravityModelWireProfile {
1250
+ /** Opaque `labels.model_enum` token (`fetchAvailableModels` `model`). */
1251
+ modelEnum?: string;
1252
+ /** Fixed `generationConfig.maxOutputTokens` the client always sends. */
1253
+ maxOutputTokens?: number;
1254
+ /** SKU thinking level; the native client sends it in preference to a budget. */
1255
+ thinkingLevel?: "LOW" | "MEDIUM" | "HIGH";
1256
+ /** SKU thinking budget (`-1` is dynamic), sent when no level is advertised. */
1257
+ thinkingBudget?: number;
1258
+ }
1219
1259
  export interface Model<TApi extends Api = Api> {
1220
1260
  id: string;
1221
1261
  /** Role-specific runner capability; omitted for ordinary chat models. */
@@ -1329,6 +1369,13 @@ export interface Model<TApi extends Api = Api> {
1329
1369
  * their single wire id) and on bundled snapshots that predate discovery.
1330
1370
  */
1331
1371
  cursorMaxModeRoutes?: Readonly<Record<string, boolean>>;
1372
+ /**
1373
+ * Per-wire-id Antigravity request constants recorded from the account's
1374
+ * `fetchAvailableModels` roster, keyed by upstream SKU id. A collapsed row
1375
+ * carries one entry per member it routes to; a raw row carries its own.
1376
+ * Absent on bundled snapshots that predate discovery.
1377
+ */
1378
+ antigravityWireProfiles?: Readonly<Record<string, AntigravityModelWireProfile>>;
1332
1379
  /**
1333
1380
  * Per-account availability recorded by multi-account discovery: provider
1334
1381
  * account key (Codex: ChatGPT `chatgpt_account_id`; Antigravity: login
@@ -1525,3 +1572,11 @@ export interface ModelSpec<TApi extends Api = Api> extends Omit<Model<TApi>, "co
1525
1572
  /** Sparse compatibility overrides; resolved into `Model.compat` by `buildModel`. */
1526
1573
  compat?: CompatConfigOf<TApi>;
1527
1574
  }
1575
+ /**
1576
+ * The model facts the catalog policy cascade reads: the resolve-target inputs
1577
+ * (`providerType ?? provider`, the request adapter, the wire model id, the
1578
+ * reasoning flag) plus the unverified-thinking correction applied before the
1579
+ * cascade. Callers holding a reduced model view — request adapters that only
1580
+ * need policy — supply exactly these instead of asserting a full `Model`.
1581
+ */
1582
+ export type CatalogPolicyInputs = Pick<ModelSpec<Api>, "provider" | "providerType" | "api" | "id" | "reasoning" | "requestModelId" | "thinking">;
@@ -13,9 +13,9 @@ export declare const DEVIN_DEFAULT_BASE_URL = "https://server.codeium.com";
13
13
  export declare function devinCliMetadata(apiKey: string | undefined, userJwt?: string): {
14
14
  ideName: "devin-cli";
15
15
  ideType: "chisel";
16
- ideVersion: "3000.11.3";
16
+ ideVersion: "3000.11.205";
17
17
  extensionName: "chisel";
18
- extensionVersion: "3000.11.3";
18
+ extensionVersion: "3000.11.205";
19
19
  locale: "en";
20
20
  os: "darwin" | "linux" | "windows";
21
21
  apiKey: string;
@@ -1,4 +1,5 @@
1
1
  import type { FetchImpl } from "@oh-my-pi/pi-utils";
2
+ import type { AntigravityModelWireProfile } from "../types.js";
2
3
  /**
3
4
  * Build a User-Agent string that identifies as Gemini CLI to unlock higher rate limits.
4
5
  * Uses the same format as the official Gemini CLI (v0.35+):
@@ -15,16 +16,19 @@ export declare const getGeminiCliHeaders: (modelId?: string) => {
15
16
  * (and its @google/genai → google-auth-library dependency chain) into the startup
16
17
  * parse graph.
17
18
  *
18
- * Format captured from the real 2.8.0 `antigravity/hub` client:
19
- * `antigravity/hub/2.8.0 (aidev_client; os_type=darwin; arch=arm64; cl=963137146)`.
19
+ * Format captured from the real 2.26.0 `antigravity/hub` client:
20
+ * `antigravity/hub/2.26.0 (aidev_client; os_type=darwin; arch=arm64; cl=1005016104)`.
20
21
  * The backend gates newer models (e.g. gemini-3.7-flash) on the client version,
21
22
  * so the version tracks the latest Antigravity release via the update manifest
22
23
  * (see {@link ensureAntigravityVersion}) with `DEFAULT_ANTIGRAVITY_VERSION` as
23
- * the offline fallback. os_type/arch are pinned to the darwin/arm64 reference
24
- * client the version and manifest are captured from, independent of the host
25
- * platform. Overrides: PI_AI_ANTIGRAVITY_VERSION / _CL / _OS / _ARCH.
24
+ * the offline fallback. os_type/arch name the native build for the host OS:
25
+ * each 2.26.0 installer ships one language-server build whose Go target is
26
+ * stamped into the header (macOS darwin/arm64, Linux linux/amd64, Windows
27
+ * windows/amd64; no other OS/arch builds exist); see
28
+ * {@link getAntigravityPlatform}. The changelist is identical across those
29
+ * builds. Overrides: PI_AI_ANTIGRAVITY_VERSION / _CL / _OS / _ARCH.
26
30
  */
27
- export declare const DEFAULT_ANTIGRAVITY_VERSION = "2.19.1";
31
+ export declare const DEFAULT_ANTIGRAVITY_VERSION = "2.26.0";
28
32
  /** Current Antigravity client version: env override → manifest-discovered → pinned fallback. */
29
33
  export declare function getAntigravityVersion(): string;
30
34
  /**
@@ -42,24 +46,39 @@ export declare function parseAntigravityManifestVersion(yamlText: string): strin
42
46
  * timeout; `signal` ends this caller's wait without cancelling the lookup.
43
47
  */
44
48
  export declare function ensureAntigravityVersion(fetcher?: FetchImpl, signal?: AbortSignal): Promise<void>;
49
+ /**
50
+ * Native build the host would run. OSes without a native build report the
51
+ * Linux build, the closest client that exists.
52
+ */
53
+ export declare function getAntigravityPlatform(platform?: NodeJS.Platform): {
54
+ os: string;
55
+ arch: string;
56
+ };
45
57
  /** Antigravity `User-Agent` header value; rebuilt when the discovered version changes. */
46
58
  export declare function getAntigravityUserAgent(): string;
47
59
  /**
48
- * Per-wire-id Antigravity Cloud Code Assist request constants, captured from the
49
- * real `antigravity/hub` client against `daily-cloudcode-pa`. `modelEnum` is the
50
- * opaque `labels.model_enum` token the client tags each request with — optional
51
- * because Anthropic-backed wire ids (e.g. `claude-sonnet-4-6`,
52
- * `claude-opus-4-6-thinking`) are accepted without one; the label is purely
53
- * telemetry. `maxOutputTokens` is the fixed `generationConfig.maxOutputTokens`
54
- * the backend enforces regardless of the thinking budget (Claude caps at
55
- * 64000, Gemini accepts the discovered cap). Keyed by the routed upstream wire
56
- * id (post effort-routing), not the collapsed logical id. Checkpoint-only ids
57
- * (e.g. `gemini-3.1-flash-lite`) are intentionally absent — this provider only
58
- * emits agent requests.
60
+ * Client headers for every Antigravity Cloud Code Assist request. The native
61
+ * client is Go `net/http`, which offers `Accept-Encoding: gzip` and no `Accept`;
62
+ * pinning the encoding replaces the runtime's `gzip, deflate, br, zstd` (Bun
63
+ * still decompresses the gzip body). Bun always adds `Accept: *\/*` itself, so
64
+ * callers must not set a more specific `Accept`.
65
+ */
66
+ export declare function getAntigravityHeaders(userAgent?: string): {
67
+ "User-Agent": string;
68
+ "Accept-Encoding": string;
69
+ };
70
+ /**
71
+ * Offline fallback for {@link Model.antigravityWireProfiles}: per-SKU request
72
+ * constants for rows that carry no discovered profile. Keyed by the routed
73
+ * upstream wire id (post effort-routing), not the collapsed logical id.
74
+ * `modelEnum` is the opaque `labels.model_enum` token; the backend accepts
75
+ * requests without it. Discovery (and the bundled snapshot baked from it)
76
+ * owns current SKUs; do not extend this table.
59
77
  */
60
- export interface AntigravityModelWireProfile {
61
- modelEnum?: string;
62
- maxOutputTokens: number;
63
- }
64
78
  export declare const ANTIGRAVITY_MODEL_WIRE_PROFILES: Readonly<Record<string, AntigravityModelWireProfile>>;
65
- export declare function getAntigravityModelWireProfile(wireModelId: string): AntigravityModelWireProfile | undefined;
79
+ /**
80
+ * Request constants for `wireModelId`: the first discovered profile map that
81
+ * lists it (callers pass the serving account's before the row's), else the
82
+ * offline fallback table.
83
+ */
84
+ export declare function getAntigravityModelWireProfile(wireModelId: string, ...discovered: (Readonly<Record<string, AntigravityModelWireProfile>> | undefined)[]): AntigravityModelWireProfile | undefined;
@@ -0,0 +1,2 @@
1
+ /** Identifies Xiaomi Token Plan keys so login and discovery use regional hosts instead of the pay-as-you-go host. */
2
+ export declare function isXiaomiTokenPlanKey(apiKey: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-catalog",
3
- "version": "18.12.6",
3
+ "version": "18.13.1",
4
4
  "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
5
5
  "keywords": [
6
6
  "ai",
@@ -93,12 +93,12 @@
93
93
  "gen:proto": "bun scripts/generate-protocols.ts"
94
94
  },
95
95
  "dependencies": {
96
- "@oh-my-pi/omptype": "18.12.6",
97
- "@oh-my-pi/pi-utils": "18.12.6"
96
+ "@oh-my-pi/omptype": "18.13.1",
97
+ "@oh-my-pi/pi-utils": "18.13.1"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@bgotink/kdl": "0.4.0",
101
- "@oh-my-pi/pi-ai": "18.12.6",
101
+ "@oh-my-pi/pi-ai": "18.13.1",
102
102
  "@types/bun": "^1.3.14"
103
103
  },
104
104
  "engines": {
package/src/build.ts CHANGED
@@ -19,7 +19,16 @@ import {
19
19
  NO_RECURRING_TARIFF,
20
20
  parseDatedCostCards,
21
21
  } from "./pricing";
22
- import { type Api, type EffectiveTokenCost, MODEL_KINDS, type Model, type ModelCost, type ModelSpec } from "./types";
22
+ import {
23
+ type AntigravityModelWireProfile,
24
+ type Api,
25
+ type EffectiveTokenCost,
26
+ MODEL_KINDS,
27
+ type Model,
28
+ type ModelAccountAccess,
29
+ type ModelCost,
30
+ type ModelSpec,
31
+ } from "./types";
23
32
  import { cleanModelName } from "./utils";
24
33
 
25
34
  function numberField(source: object, key: string): number | undefined {
@@ -353,6 +362,42 @@ export function applyCatalogCorrections(
353
362
  }
354
363
  }
355
364
 
365
+ /**
366
+ * Lower discovered Antigravity per-SKU output caps to the host's
367
+ * `max-tokens-ceiling`. The transport sends a profile's `maxOutputTokens`
368
+ * verbatim, so a roster value above the ceiling (Claude 4.x advertises 65,536;
369
+ * Cloud Code Assist 400s past 64,000, #3067) must be corrected here as the
370
+ * row's `maxTokens` is.
371
+ */
372
+ function capAntigravityWireProfiles(
373
+ model: Pick<Model<Api>, "antigravityWireProfiles" | "accountAccess">,
374
+ ceiling: unknown,
375
+ ): void {
376
+ if (typeof ceiling !== "number") return;
377
+ const cap = (
378
+ profiles: Readonly<Record<string, AntigravityModelWireProfile>> | undefined,
379
+ ): Readonly<Record<string, AntigravityModelWireProfile>> | undefined => {
380
+ if (profiles === undefined) return undefined;
381
+ let capped: Record<string, AntigravityModelWireProfile> | undefined;
382
+ for (const [wireId, profile] of Object.entries(profiles)) {
383
+ if (profile.maxOutputTokens === undefined || profile.maxOutputTokens <= ceiling) continue;
384
+ capped ??= { ...profiles };
385
+ capped[wireId] = { ...profile, maxOutputTokens: ceiling };
386
+ }
387
+ return capped ?? profiles;
388
+ };
389
+ model.antigravityWireProfiles = cap(model.antigravityWireProfiles);
390
+ if (model.accountAccess === undefined) return;
391
+ let accountAccess: Record<string, ModelAccountAccess> | undefined;
392
+ for (const [accountKey, access] of Object.entries(model.accountAccess)) {
393
+ const profiles = cap(access.antigravityWireProfiles);
394
+ if (profiles === access.antigravityWireProfiles) continue;
395
+ accountAccess ??= { ...model.accountAccess };
396
+ accountAccess[accountKey] = { ...access, antigravityWireProfiles: profiles };
397
+ }
398
+ if (accountAccess !== undefined) model.accountAccess = accountAccess;
399
+ }
400
+
356
401
  /**
357
402
  * Direct first-party OpenAI Responses endpoints (api.openai.com, Azure OpenAI
358
403
  * deployments). Gates GA computer-use detection; identity supplies the model
@@ -445,6 +490,7 @@ export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi>
445
490
  };
446
491
  applyCatalogAssignments(model, policy.catalog);
447
492
  applyCatalogCorrections(model, policy.catalog);
493
+ capAntigravityWireProfiles(model, policy.catalog.maxTokensCeiling);
448
494
  // Configured kinds and lifetimes replace catalog values rather than merging with them.
449
495
  if (spec.kindConfig !== undefined) model.kind = spec.kindConfig;
450
496
  if (spec.promptCacheConfig !== undefined) model.promptCache = { ...spec.promptCacheConfig };
@@ -5,6 +5,7 @@
5
5
  * pi-ai both consume these; URL matching is the one detection surface that
6
6
  * stays in code.
7
7
  */
8
+ import { $env, logger } from "@oh-my-pi/pi-utils";
8
9
  import { hostMatchesUrl, isBedrockRouteUrl } from "../hosts";
9
10
 
10
11
  const OFFICIAL_ANTHROPIC_URL = "https://api.anthropic.com";
@@ -22,6 +23,52 @@ export function isOfficialAnthropicApiUrl(baseUrl?: string): boolean {
22
23
  return lower === OFFICIAL_ANTHROPIC_URL || lower.startsWith(`${OFFICIAL_ANTHROPIC_URL}/`);
23
24
  }
24
25
 
26
+ /** `anthropic-version` values this codebase knows how to speak. */
27
+ export const ANTHROPIC_API_VERSIONS = ["2023-06-01", "2026-10-21"] as const;
28
+ export type AnthropicApiVersion = (typeof ANTHROPIC_API_VERSIONS)[number];
29
+
30
+ /** Version every non-official Anthropic-compatible endpoint receives. */
31
+ export const LEGACY_ANTHROPIC_API_VERSION: AnthropicApiVersion = "2023-06-01";
32
+
33
+ let warnedInvalidApiVersion: string | undefined;
34
+
35
+ function isAnthropicApiVersion(value: string): value is AnthropicApiVersion {
36
+ return (ANTHROPIC_API_VERSIONS as readonly string[]).includes(value);
37
+ }
38
+
39
+ /**
40
+ * `anthropic-version` for a request to `baseUrl`. `PI_ANTHROPIC_API_VERSION`
41
+ * opts the official first-party API into a newer version; every other host
42
+ * (Copilot, Bedrock, Foundry, Cloudflare, third-party compatibles) stays on
43
+ * {@link LEGACY_ANTHROPIC_API_VERSION} because those deployments gate newer
44
+ * versions on their own schedule (Bedrock accepts 2026-10-21 only for 4.7+).
45
+ * Read per call so a flipped environment takes effect without a restart.
46
+ */
47
+ export function resolveAnthropicApiVersion(baseUrl?: string): AnthropicApiVersion {
48
+ if (!isOfficialAnthropicApiUrl(baseUrl)) return LEGACY_ANTHROPIC_API_VERSION;
49
+ const configured = $env.PI_ANTHROPIC_API_VERSION?.trim();
50
+ if (!configured) return LEGACY_ANTHROPIC_API_VERSION;
51
+ if (isAnthropicApiVersion(configured)) return configured;
52
+ if (warnedInvalidApiVersion !== configured) {
53
+ warnedInvalidApiVersion = configured;
54
+ logger.warn("anthropic: unsupported PI_ANTHROPIC_API_VERSION; using legacy version", {
55
+ configured,
56
+ supported: ANTHROPIC_API_VERSIONS,
57
+ using: LEGACY_ANTHROPIC_API_VERSION,
58
+ });
59
+ }
60
+ return LEGACY_ANTHROPIC_API_VERSION;
61
+ }
62
+
63
+ /**
64
+ * Whether Messages requests on `version` may carry `temperature`, `top_p`,
65
+ * or `top_k`. API version 2026-10-21 rejects all three with a 400, even at
66
+ * their default values.
67
+ */
68
+ export function anthropicApiVersionAcceptsSamplingParams(version: AnthropicApiVersion): boolean {
69
+ return version === "2023-06-01";
70
+ }
71
+
25
72
  const CLOUDFLARE_ANTHROPIC_GATEWAY_URL_MARKER = /gateway\.ai\.cloudflare\.com\/.+\/anthropic(?:\/|$)/i;
26
73
  const VERTEX_ANTHROPIC_URL_MARKER = /aiplatform\.googleapis\.com\/.+\/publishers\/anthropic\//i;
27
74
  const BEDROCK_ANTHROPIC_URL_MARKER = /(?:^|\/\/|\.)bedrock-runtime\.[a-z0-9-]+\.amazonaws\.com/i;