@oh-my-pi/pi-catalog 18.4.4 → 18.4.6
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/CHANGELOG.md +31 -0
- package/dist/types/compat/auth-ids.d.ts +2 -2
- package/dist/types/compat/axes.d.ts +3 -1
- package/dist/types/compat/factory-droid.d.ts +65 -0
- package/dist/types/compat/provider-ids.d.ts +1 -1
- package/dist/types/compat/resolve.d.ts +8 -2
- package/dist/types/compat/types.d.ts +26 -1
- package/dist/types/discovery/cursor-proto.d.ts +284 -0
- package/dist/types/discovery/cursor.d.ts +12 -6
- package/dist/types/discovery/factory-droid.d.ts +28 -0
- package/dist/types/discovery/index.d.ts +1 -0
- package/dist/types/discovery/protobuf.d.ts +3 -3
- package/dist/types/model-manager.d.ts +10 -0
- package/dist/types/models.d.ts +5 -1
- package/dist/types/provider-models/cache-provider-id.d.ts +2 -1
- package/dist/types/provider-models/descriptor-types.d.ts +2 -1
- package/dist/types/provider-models/openai-compat.d.ts +21 -0
- package/dist/types/provider-models/special.d.ts +2 -0
- package/dist/types/types.d.ts +100 -3
- package/dist/types/wire/cursor.d.ts +20 -0
- package/dist/types/wire/factory-droid.d.ts +45 -0
- package/package.json +4 -4
- package/src/build.ts +21 -0
- package/src/compat/auth-ids.ts +4 -0
- package/src/compat/axes.ts +113 -2
- package/src/compat/cascade.ts +8 -1
- package/src/compat/collapse.ts +3 -0
- package/src/compat/factory-droid.ts +170 -0
- package/src/compat/provider-ids.ts +2 -0
- package/src/compat/resolve.ts +47 -5
- package/src/compat/rules/README.md +18 -8
- package/src/compat/rules/auth/_order.kdl +2 -2
- package/src/compat/rules/auth/factory-droid.kdl +28 -0
- package/src/compat/rules/auth/helmcode.kdl +9 -0
- package/src/compat/rules/classes/anthropic.kdl +195 -80
- package/src/compat/rules/providers/commandcode.kdl +21 -5
- package/src/compat/rules/providers/cursor.kdl +29 -17
- package/src/compat/rules/providers/factory-droid.kdl +1166 -0
- package/src/compat/rules/providers/helmcode.kdl +120 -0
- package/src/compat/rules/runtime/behavior.kdl +65 -4
- package/src/compat/rules/taxonomy/_collapse.kdl +36 -14
- package/src/compat/rules.json +1 -1
- package/src/compat/types.ts +27 -1
- package/src/discovery/cursor-models.proto +261 -0
- package/src/discovery/cursor-proto.ts +471 -0
- package/src/discovery/cursor.ts +817 -88
- package/src/discovery/devin.ts +1 -3
- package/src/discovery/factory-droid.ts +296 -0
- package/src/discovery/index.ts +1 -0
- package/src/discovery/protobuf.ts +16 -7
- package/src/model-manager.ts +13 -0
- package/src/models.json +1 -1
- package/src/models.ts +13 -0
- package/src/provider-models/cache-provider-id.ts +37 -6
- package/src/provider-models/descriptor-types.ts +2 -1
- package/src/provider-models/descriptors.ts +4 -0
- package/src/provider-models/openai-compat.ts +83 -17
- package/src/provider-models/special.ts +26 -2
- package/src/types.ts +112 -1
- package/src/wire/cursor.ts +32 -0
- package/src/wire/factory-droid.ts +130 -0
|
@@ -21,12 +21,12 @@ export interface ProtoMessage {
|
|
|
21
21
|
}
|
|
22
22
|
/** A bidirectional codec for one protobuf message type. */
|
|
23
23
|
export interface MessageCodec<T extends ProtoMessage = ProtoMessage> {
|
|
24
|
-
(value: T): Uint8Array
|
|
24
|
+
(value: T): Uint8Array<ArrayBuffer>;
|
|
25
25
|
(value: Uint8Array): T;
|
|
26
26
|
/** Creates a message with protobuf defaults for omitted fields. */
|
|
27
27
|
create(value?: Partial<T>): T;
|
|
28
28
|
/** Encodes one message into protobuf wire bytes. */
|
|
29
|
-
encode(value: T): Uint8Array
|
|
29
|
+
encode(value: T): Uint8Array<ArrayBuffer>;
|
|
30
30
|
/** Decodes one protobuf message from wire bytes. */
|
|
31
31
|
decode(value: Uint8Array): T;
|
|
32
32
|
/** Converts a message to its protobuf JSON representation. */
|
|
@@ -91,7 +91,7 @@ export declare function pb<T extends ProtoMessage = ProtoMessage>(typeName: stri
|
|
|
91
91
|
/** Creates a message using its codec's protobuf defaults. */
|
|
92
92
|
export declare function create<TMessage extends ProtoMessage>(codec: MessageCodec<TMessage>, value?: Partial<TMessage>): TMessage;
|
|
93
93
|
/** Encodes a message using its codec. */
|
|
94
|
-
export declare function toBinary<TMessage extends ProtoMessage>(codec: MessageCodec<TMessage>, value: TMessage): Uint8Array
|
|
94
|
+
export declare function toBinary<TMessage extends ProtoMessage>(codec: MessageCodec<TMessage>, value: TMessage): Uint8Array<ArrayBuffer>;
|
|
95
95
|
/** Decodes wire bytes using a message codec. */
|
|
96
96
|
export declare function fromBinary<TMessage extends ProtoMessage>(codec: MessageCodec<TMessage>, value: Uint8Array): TMessage;
|
|
97
97
|
/** Converts a message to protobuf JSON using its codec. */
|
|
@@ -35,6 +35,16 @@ export interface ModelManagerOptions<TApi extends Api = Api, TModelsDevPayload =
|
|
|
35
35
|
cacheTtlMs?: number;
|
|
36
36
|
/** When true, a successful dynamic fetch is the complete provider catalog and prunes static-only models. */
|
|
37
37
|
dynamicModelsAuthoritative?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* When true, a fresh cache never satisfies an online-eligible refresh: the
|
|
40
|
+
* dynamic fetch always runs (an explicit `"offline"` strategy is still
|
|
41
|
+
* honored), and the cache serves only as the fetch-failure fallback. For
|
|
42
|
+
* providers whose dynamic result encodes fast-changing live state that a
|
|
43
|
+
* TTL cache would replay wrongly — e.g. Factory discovery includes live
|
|
44
|
+
* organization model policy and upstream blocks. Cached eligibility is
|
|
45
|
+
* an offline snapshot, not current entitlement.
|
|
46
|
+
*/
|
|
47
|
+
alwaysRefetchDynamicModels?: boolean;
|
|
38
48
|
/** Cached model ids whose presence forces refresh when the static or migration-policy fingerprint changes. */
|
|
39
49
|
dropCachedModelIdsOnStaticMismatch?: readonly string[];
|
|
40
50
|
/**
|
package/dist/types/models.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import MODELS from "./models.json";
|
|
2
|
-
import type { Api, KnownProvider, Model, ModelCost, Usage } from "./types.js";
|
|
2
|
+
import type { Api, KnownProvider, Model, ModelCost, ModelPricingStatus, Usage } from "./types.js";
|
|
3
3
|
export type GeneratedProvider = keyof typeof MODELS;
|
|
4
|
+
/** Whether `provider` has bundled rows in models.json (e.g. a provider id authored in KDL). */
|
|
5
|
+
export declare function isGeneratedProvider(provider: string): provider is GeneratedProvider;
|
|
4
6
|
export declare function getBundledModel<TApi extends Api = Api>(provider: GeneratedProvider, modelId: string): Model<TApi>;
|
|
5
7
|
export declare function getBundledProviders(): KnownProvider[];
|
|
6
8
|
export declare function getBundledModels(provider: GeneratedProvider): Model<Api>[];
|
|
9
|
+
/** Resolve display semantics without mistaking an absent rate card for a free model. */
|
|
10
|
+
export declare function getModelPricingStatus(model: Pick<Model<Api>, "cost" | "pricingStatus">): ModelPricingStatus;
|
|
7
11
|
/** Return the recurring UTC tariff period, independently of its monetary multiplier. */
|
|
8
12
|
export declare function getTimeBasedPricingPeriod(cost: ModelCost, timestamp?: number): "peak" | "off-peak" | undefined;
|
|
9
13
|
/** Return the next actual peak/off-peak change strictly after the Unix-ms timestamp. */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { CompiledProviderDiscovery } from "../compat/types.js";
|
|
2
2
|
import type { ModelManagerOptions } from "../model-manager.js";
|
|
3
3
|
import type { Api, FetchImpl } from "../types.js";
|
|
4
|
+
import type { AccountScope } from "../wire/factory-droid.js";
|
|
4
5
|
/** Config passed to a provider's runtime model-manager factory. */
|
|
5
|
-
export type ModelManagerConfig = {
|
|
6
|
+
export type ModelManagerConfig = AccountScope & {
|
|
6
7
|
apiKey?: string;
|
|
7
8
|
baseUrl?: string;
|
|
8
9
|
fetch?: FetchImpl;
|
|
@@ -106,6 +106,27 @@ export interface HuggingfaceModelManagerConfig {
|
|
|
106
106
|
fetch?: FetchImpl;
|
|
107
107
|
}
|
|
108
108
|
export declare function huggingfaceModelManagerOptions(config?: HuggingfaceModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
109
|
+
export interface HelmcodeModelManagerConfig {
|
|
110
|
+
apiKey?: string;
|
|
111
|
+
baseUrl?: string;
|
|
112
|
+
fetch?: FetchImpl;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Helmcode model manager: OpenAI-compatible chat completions at
|
|
116
|
+
* `api.helmcode.com/v1`. `/v1/models` also lists embedding, rerank, TTS, and
|
|
117
|
+
* STT models; the exclusion policy lives in `runtime/behavior.kdl`
|
|
118
|
+
* (`exclude-models provider="helmcode"`).
|
|
119
|
+
*
|
|
120
|
+
* `/v1/models` carries no capability data. Resold frontier ids (Claude, GPT,
|
|
121
|
+
* Gemini) take only capability facts from the first-party vendor's bundled
|
|
122
|
+
* row: reasoning, modalities, context window, output cap, and list price. The
|
|
123
|
+
* rest of that row (thinking shape, compat, native web search, tool dialects,
|
|
124
|
+
* cache semantics) describes the vendor's own API, not this chat-completions
|
|
125
|
+
* proxy; the host's `reasoning_effort` ladders and cache-write pricing live in
|
|
126
|
+
* `providers/helmcode.kdl`. Ids with no Helmcode or vendor row (e.g. a new
|
|
127
|
+
* open-weight model) inherit nothing from other gateways.
|
|
128
|
+
*/
|
|
129
|
+
export declare function helmcodeModelManagerOptions(config?: HelmcodeModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
109
130
|
export interface NvidiaModelManagerConfig {
|
|
110
131
|
apiKey?: string;
|
|
111
132
|
baseUrl?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DevinModelDiscoveryOptions } from "../discovery/devin.js";
|
|
2
|
+
import { type FactoryDroidModelDiscoveryOptions } from "../discovery/factory-droid.js";
|
|
2
3
|
import type { ModelManagerOptions } from "../model-manager.js";
|
|
3
4
|
import type { Api, FetchImpl, Model } from "../types.js";
|
|
4
5
|
/** One Codex OAuth account to fetch a catalog for. */
|
|
@@ -55,6 +56,7 @@ export interface DevinModelManagerConfig {
|
|
|
55
56
|
fetch?: DevinModelDiscoveryOptions["fetch"];
|
|
56
57
|
}
|
|
57
58
|
export declare function devinModelManagerOptions(config?: DevinModelManagerConfig): ModelManagerOptions<"devin-agent">;
|
|
59
|
+
export declare function factoryDroidModelManagerOptions(config?: FactoryDroidModelDiscoveryOptions): ModelManagerOptions<"factory-droid-agent">;
|
|
58
60
|
export declare function localModelManagerOptions(): ModelManagerOptions<"local-inference">;
|
|
59
61
|
export declare function webModelManagerOptions(): ModelManagerOptions<"web-search">;
|
|
60
62
|
/** Credentials and endpoint overrides for the TypeSafe catalog manager. */
|
package/dist/types/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ModelIdentity } from "./compat/types.js";
|
|
|
2
2
|
import type { Effort } from "./effort.js";
|
|
3
3
|
export type { FetchImpl } from "@oh-my-pi/pi-utils";
|
|
4
4
|
export type { KnownProvider } from "./provider-models/descriptors.js";
|
|
5
|
-
export type KnownApi = "openai-completions" | "openai-responses" | "openrouter" | "openai-codex-responses" | "azure-openai-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-gemini-cli" | "google-vertex" | "ollama-chat" | "cursor-agent" | "gitlab-duo-agent" | "devin-agent" | "apple-foundation-models";
|
|
5
|
+
export type KnownApi = "openai-completions" | "openai-responses" | "openrouter" | "openai-codex-responses" | "azure-openai-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-gemini-cli" | "google-vertex" | "ollama-chat" | "cursor-agent" | "factory-droid-agent" | "gitlab-duo-agent" | "devin-agent" | "apple-foundation-models";
|
|
6
6
|
export type Api = KnownApi | (string & {});
|
|
7
7
|
/** Catalog kinds used to isolate role-specific runners from session chat models. */
|
|
8
8
|
export declare const MODEL_KINDS: readonly ["chat", "tiny", "image", "tts", "stt", "search", "judge", "embedding", "rerank", "video"];
|
|
@@ -206,12 +206,21 @@ export interface OpenAICompat {
|
|
|
206
206
|
thinkingKeep?: "all" | false;
|
|
207
207
|
/** Which reasoning content field to emit on assistant messages. Default: auto-detected. */
|
|
208
208
|
reasoningContentField?: "reasoning_content" | "reasoning" | "reasoning_text";
|
|
209
|
+
/** Decode Mistral thinking parts in streamed content and replay them as typed assistant content. */
|
|
210
|
+
mistralReasoningContentParts?: boolean;
|
|
209
211
|
/** Whether assistant tool-call messages must include reasoning content. Default: false. */
|
|
210
212
|
requiresReasoningContentForToolCalls?: boolean;
|
|
211
213
|
/** Whether all assistant messages must include reasoning content. Default: false. */
|
|
212
214
|
requiresReasoningContentForAllAssistantTurns?: boolean;
|
|
213
215
|
/** Whether the provider accepts a synthetic placeholder (e.g. ".") for missing reasoning_content on tool-call turns. Default: true. Set to false for providers like DeepSeek that validate the exact reasoning_content value. */
|
|
214
216
|
allowsSyntheticReasoningContentForToolCalls?: boolean;
|
|
217
|
+
/**
|
|
218
|
+
* Value emitted for the reasoning field on tool-call turns when the provider
|
|
219
|
+
* requires it (`requiresReasoningContentForToolCalls`) but no reasoning was
|
|
220
|
+
* captured. Default: "". Some upstreams validate the exact value — the droid
|
|
221
|
+
* proxy's DeepSeek family requires a single space.
|
|
222
|
+
*/
|
|
223
|
+
syntheticReasoningContentFallback?: string;
|
|
215
224
|
/**
|
|
216
225
|
* Replay preserved thinking blocks as `reasoning_content` (or the configured
|
|
217
226
|
* `reasoningContentField`) on EVERY assistant turn that carried reasoning,
|
|
@@ -594,6 +603,25 @@ export interface AnthropicCompat {
|
|
|
594
603
|
stripImageInput?: boolean;
|
|
595
604
|
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
596
605
|
thinkingLoopGuard?: "gemini" | "deepseek" | "xai";
|
|
606
|
+
/**
|
|
607
|
+
* Drop the enabled `thinking` config and replayed thinking blocks when the
|
|
608
|
+
* conversation is not thinking-led (a proxy contract for non-interleaved
|
|
609
|
+
* budget models). Default: false.
|
|
610
|
+
*/
|
|
611
|
+
stripThinkingHistory?: boolean;
|
|
612
|
+
/**
|
|
613
|
+
* Send the `effort-2025-11-24` beta exactly when `output_config.effort`
|
|
614
|
+
* rides the request. Unset keeps the transport's legacy heuristic.
|
|
615
|
+
*/
|
|
616
|
+
effortBeta?: boolean;
|
|
617
|
+
/**
|
|
618
|
+
* Wire form of a disabled-thinking turn: omit the field, send
|
|
619
|
+
* `{ type: "disabled" }`, or keep adaptive thinking. Unset keeps the
|
|
620
|
+
* direct-provider behavior.
|
|
621
|
+
*/
|
|
622
|
+
disabledThinking?: "omit" | "disabled" | "adaptive";
|
|
623
|
+
/** The model is a fast-mode SKU: send `speed: "fast"` with the fast-mode beta. Default: false. */
|
|
624
|
+
fastMode?: boolean;
|
|
597
625
|
}
|
|
598
626
|
/**
|
|
599
627
|
* Compatibility settings for Bedrock Converse prompt caching. Cache pricing is
|
|
@@ -623,6 +651,12 @@ export interface BedrockCompat {
|
|
|
623
651
|
* `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS` alias, then the 300s default.
|
|
624
652
|
*/
|
|
625
653
|
streamIdleTimeoutMs?: number;
|
|
654
|
+
/**
|
|
655
|
+
* Whether the model accepts a forced `toolChoice` (`any` / `tool`). Claude
|
|
656
|
+
* Opus/Sonnet 5.5 reject it outright; the request builder downgrades forced
|
|
657
|
+
* choices to `auto` when this is false. Default: true.
|
|
658
|
+
*/
|
|
659
|
+
supportsForcedToolChoice?: boolean;
|
|
626
660
|
}
|
|
627
661
|
/** Fully-resolved Bedrock Converse prompt-cache capabilities, materialized once by `buildModel`. */
|
|
628
662
|
export interface ResolvedBedrockCompat {
|
|
@@ -632,6 +666,7 @@ export interface ResolvedBedrockCompat {
|
|
|
632
666
|
supportsLongPromptCacheRetention: boolean;
|
|
633
667
|
promptCacheMinimumTokens: number;
|
|
634
668
|
promptCacheMaximumCheckpoints: number;
|
|
669
|
+
supportsForcedToolChoice: boolean;
|
|
635
670
|
/**
|
|
636
671
|
* Stream-watchdog idle-timeout fallback in ms for hosts with no keepalive
|
|
637
672
|
* events; 0 disables the idle watchdog. Undefined defers to
|
|
@@ -695,9 +730,12 @@ export interface ResolvedOpenAISharedCompat {
|
|
|
695
730
|
supportsForcedToolChoice: boolean;
|
|
696
731
|
supportsNamedToolChoice: boolean;
|
|
697
732
|
reasoningContentField?: OpenAICompat["reasoningContentField"];
|
|
733
|
+
mistralReasoningContentParts?: boolean;
|
|
698
734
|
requiresReasoningContentForToolCalls: boolean;
|
|
699
735
|
requiresReasoningContentForAllAssistantTurns: boolean;
|
|
700
736
|
allowsSyntheticReasoningContentForToolCalls: boolean;
|
|
737
|
+
/** See {@link OpenAICompat.syntheticReasoningContentFallback}. */
|
|
738
|
+
syntheticReasoningContentFallback?: string;
|
|
701
739
|
replayReasoningContent: boolean;
|
|
702
740
|
qwenPreserveThinking: boolean;
|
|
703
741
|
qwenTemplateReasoningEffort: boolean;
|
|
@@ -750,7 +788,7 @@ export interface ResolvedOpenAISharedCompat {
|
|
|
750
788
|
* `buildModel`; request handlers read fields and never detect, resolve, or
|
|
751
789
|
* allocate.
|
|
752
790
|
*/
|
|
753
|
-
export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "reasoningEffortMap" | "supportsReasoningParams" | "supportsReasoningSummary" | "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "thinkingFormat" | "kimiApiFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "disableReasoningWithTools" | "supportsToolChoice" | "supportsForcedToolChoice" | "supportsNamedToolChoice" | "reasoningContentField" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "replayReasoningContent" | "qwenPreserveThinking" | "qwenTemplateReasoningEffort" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "supportsPromptCacheBreakpoints" | "promptCacheBreakpointTtl" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "clampOutputToModelMax" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "streamRevision" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "supportsConfigurationUpdate" | "supportsSteering" | "stripImageInput" | "thinkingLoopGuard" | "whenThinking">> & {
|
|
791
|
+
export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "reasoningEffortMap" | "supportsReasoningParams" | "supportsReasoningSummary" | "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "thinkingFormat" | "kimiApiFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "disableReasoningWithTools" | "supportsToolChoice" | "supportsForcedToolChoice" | "supportsNamedToolChoice" | "reasoningContentField" | "mistralReasoningContentParts" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "syntheticReasoningContentFallback" | "replayReasoningContent" | "qwenPreserveThinking" | "qwenTemplateReasoningEffort" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "supportsPromptCacheBreakpoints" | "promptCacheBreakpointTtl" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "clampOutputToModelMax" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "streamRevision" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "supportsConfigurationUpdate" | "supportsSteering" | "stripImageInput" | "thinkingLoopGuard" | "whenThinking">> & {
|
|
754
792
|
vercelGatewayRouting?: OpenAICompat["vercelGatewayRouting"];
|
|
755
793
|
extraBody?: OpenAICompat["extraBody"];
|
|
756
794
|
cacheControlFormat?: OpenAICompat["cacheControlFormat"];
|
|
@@ -820,7 +858,15 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
|
|
|
820
858
|
*/
|
|
821
859
|
export type ResolvedOpenRouterCompat = ResolvedOpenAICompat & ResolvedOpenAIResponsesCompat;
|
|
822
860
|
/** Fully-resolved anthropic-messages compat view (same contract as `ResolvedOpenAICompat`). */
|
|
823
|
-
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi">> & {
|
|
861
|
+
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi" | "effortBeta" | "disabledThinking" | "stripThinkingHistory" | "fastMode">> & {
|
|
862
|
+
/** Effort-beta override; undefined keeps the transport's legacy heuristic. */
|
|
863
|
+
effortBeta?: AnthropicCompat["effortBeta"];
|
|
864
|
+
/** Disabled-thinking wire form; undefined keeps the direct-provider behavior. */
|
|
865
|
+
disabledThinking?: AnthropicCompat["disabledThinking"];
|
|
866
|
+
/** Strip thinking history on non-thinking-led turns; undefined behaves as false. */
|
|
867
|
+
stripThinkingHistory?: AnthropicCompat["stripThinkingHistory"];
|
|
868
|
+
/** Fast-mode SKU; undefined behaves as false. */
|
|
869
|
+
fastMode?: AnthropicCompat["fastMode"];
|
|
824
870
|
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
825
871
|
thinkingLoopGuard?: AnthropicCompat["thinkingLoopGuard"];
|
|
826
872
|
/**
|
|
@@ -945,6 +991,8 @@ export interface TokenCost {
|
|
|
945
991
|
cacheRead: number;
|
|
946
992
|
cacheWrite: number;
|
|
947
993
|
}
|
|
994
|
+
/** User-facing interpretation of a model's token-rate card. */
|
|
995
|
+
export type ModelPricingStatus = "fixed" | "free" | "included" | "variable" | "unknown";
|
|
948
996
|
/**
|
|
949
997
|
* Rates applied to the full request when its prompt exceeds `inputThreshold`,
|
|
950
998
|
* or reaches it when `inputThresholdInclusive` is true. Prompt input is the
|
|
@@ -1002,6 +1050,17 @@ export interface ModelAccountAccess {
|
|
|
1002
1050
|
*/
|
|
1003
1051
|
cyberPrograms?: readonly string[];
|
|
1004
1052
|
}
|
|
1053
|
+
/** One Cursor `RequestedModel.parameters` entry recovered from rich discovery. */
|
|
1054
|
+
export interface CursorModelParameter {
|
|
1055
|
+
id: string;
|
|
1056
|
+
value: string;
|
|
1057
|
+
}
|
|
1058
|
+
/** Cursor wire target selected after local effort/variant routing. */
|
|
1059
|
+
export interface CursorModelRoute {
|
|
1060
|
+
modelId: string;
|
|
1061
|
+
parameters: readonly CursorModelParameter[];
|
|
1062
|
+
maxMode?: boolean;
|
|
1063
|
+
}
|
|
1005
1064
|
export interface Model<TApi extends Api = Api> {
|
|
1006
1065
|
id: string;
|
|
1007
1066
|
/** Role-specific runner capability; omitted for ordinary chat models. */
|
|
@@ -1110,6 +1169,29 @@ export interface Model<TApi extends Api = Api> {
|
|
|
1110
1169
|
* bundled/config rows and on single-account discovery.
|
|
1111
1170
|
*/
|
|
1112
1171
|
accountAccess?: Readonly<Record<string, ModelAccountAccess>>;
|
|
1172
|
+
/** Cursor `RequestedModel.parameters` for this model's default variant. */
|
|
1173
|
+
cursorModelParameters?: readonly CursorModelParameter[];
|
|
1174
|
+
/**
|
|
1175
|
+
* Per-wire-id Cursor routes recovered from `AvailableModels`. Generic effort
|
|
1176
|
+
* collapse retains these while routing selects one key at request time.
|
|
1177
|
+
*/
|
|
1178
|
+
cursorModelRoutes?: Readonly<Record<string, CursorModelRoute>>;
|
|
1179
|
+
/** Cursor's account-relative model price/multiplier; not a per-token USD rate. */
|
|
1180
|
+
cursorPrice?: number;
|
|
1181
|
+
/** Cursor requires data retention to invoke this model. */
|
|
1182
|
+
cursorRequiresDataRetention?: boolean;
|
|
1183
|
+
/** Cursor explicitly reports support for its Agent surface. */
|
|
1184
|
+
cursorSupportsAgent?: boolean;
|
|
1185
|
+
/** Cursor explicitly reports support for sandboxed execution. */
|
|
1186
|
+
cursorSupportsSandboxing?: boolean;
|
|
1187
|
+
/** Factory Droid: account-resolved upstream rotation (first entry is the default `x-api-provider`). */
|
|
1188
|
+
factoryDroidApiProviders?: string[];
|
|
1189
|
+
/** Factory Droid: `configured_order` when live routing chose the rotation; absent means registry order. */
|
|
1190
|
+
factoryDroidRoutingSource?: "configured_order";
|
|
1191
|
+
/** Factory Droid Standard Credits base rate (relative per-token weight, not dollars). */
|
|
1192
|
+
factoryDroidCredits?: number;
|
|
1193
|
+
/** Canonical organization resolved during Factory discovery. */
|
|
1194
|
+
factoryDroidOrgId?: string;
|
|
1113
1195
|
cost: ModelCost;
|
|
1114
1196
|
/**
|
|
1115
1197
|
* Prompt-cache entry lifetime per retention tier, in seconds. Populated only
|
|
@@ -1119,9 +1201,22 @@ export interface Model<TApi extends Api = Api> {
|
|
|
1119
1201
|
* Custom models and provider overrides opt in via models.yml `promptCache`.
|
|
1120
1202
|
*/
|
|
1121
1203
|
promptCache?: ModelPromptCache;
|
|
1204
|
+
/**
|
|
1205
|
+
* Verbatim configured lifetimes (models.yml, `modelOverrides`, runtime
|
|
1206
|
+
* registrations). `buildModel` applies them over catalog `prompt-cache`
|
|
1207
|
+
* rules on every rebuild; `{}` keeps warming disabled.
|
|
1208
|
+
*/
|
|
1209
|
+
promptCacheConfig?: ModelPromptCache;
|
|
1210
|
+
/**
|
|
1211
|
+
* Interpretation of an all-zero token-rate card. Omitted zero-rate cards
|
|
1212
|
+
* are unknown; any non-zero rate is always treated as fixed pricing.
|
|
1213
|
+
*/
|
|
1214
|
+
pricingStatus?: Exclude<ModelPricingStatus, "fixed">;
|
|
1122
1215
|
/** Premium Copilot requests charged per user-initiated request (defaults to 1). */
|
|
1123
1216
|
premiumMultiplier?: number;
|
|
1124
1217
|
contextWindow: number | null;
|
|
1218
|
+
/** Preserve the host's supplied window instead of applying inferred expansion or reference-price caps. */
|
|
1219
|
+
contextWindowAuthoritative?: boolean;
|
|
1125
1220
|
/** Optional larger prompt window available when extended context is enabled. */
|
|
1126
1221
|
maxContextWindow?: number;
|
|
1127
1222
|
maxTokens: number | null;
|
|
@@ -1194,6 +1289,8 @@ export interface Model<TApi extends Api = Api> {
|
|
|
1194
1289
|
isNew?: boolean;
|
|
1195
1290
|
/** Upstream marks this model as beta / preview quality. */
|
|
1196
1291
|
isBeta?: boolean;
|
|
1292
|
+
/** Authenticated provider catalog marks this as the account's default model. */
|
|
1293
|
+
isProviderDefault?: boolean;
|
|
1197
1294
|
/** Upstream marks this model as one of its recommended picks. */
|
|
1198
1295
|
isRecommended?: boolean;
|
|
1199
1296
|
/** Canonical thinking capability metadata for this model. */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor wire constants shared by authenticated catalog discovery, the pi-ai
|
|
3
|
+
* provider, and account usage. Keep the announced client build aligned with the
|
|
4
|
+
* released Cursor agent CLI because the service gates protocol features on it.
|
|
5
|
+
*/
|
|
6
|
+
/** Default host for Cursor's Connect RPCs and account API. */
|
|
7
|
+
export declare const CURSOR_DEFAULT_BASE_URL = "https://api2.cursor.sh";
|
|
8
|
+
/** Released Cursor agent CLI build whose protocol surface this client mirrors. */
|
|
9
|
+
export declare const CURSOR_CLIENT_VERSION = "cli-2026.09.02-c22c1a3";
|
|
10
|
+
export declare const CURSOR_RUN_PATH = "/agent.v1.AgentService/Run";
|
|
11
|
+
export declare const CURSOR_RUN_SSE_PATH = "/agent.v1.AgentService/RunSSE";
|
|
12
|
+
export declare const CURSOR_BIDI_APPEND_PATH = "/aiserver.v1.BidiService/BidiAppend";
|
|
13
|
+
export declare const CURSOR_GET_USABLE_MODELS_PATH = "/agent.v1.AgentService/GetUsableModels";
|
|
14
|
+
export declare const CURSOR_GET_DEFAULT_MODEL_PATH = "/agent.v1.AgentService/GetDefaultModelForCli";
|
|
15
|
+
export declare const CURSOR_AVAILABLE_MODELS_PATH = "/aiserver.v1.AiService/AvailableModels";
|
|
16
|
+
/** Headers shared by Cursor's authenticated CLI RPCs. */
|
|
17
|
+
export declare function cursorClientHeaders(apiKey: string, options?: {
|
|
18
|
+
clientVersion?: string;
|
|
19
|
+
contentType?: "application/proto" | "application/connect+proto";
|
|
20
|
+
}): Record<string, string>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client version reported to Factory's API. When bumping it, recapture the
|
|
3
|
+
* native request corpus with `packages/ai/scripts/capture-factory-droid-native.ts`
|
|
4
|
+
* against the matching CLI binary and make `factory-droid-native-parity.test.ts` pass.
|
|
5
|
+
*/
|
|
6
|
+
export declare const FACTORY_DROID_CLIENT_VERSION = "0.230.0";
|
|
7
|
+
/** Wire protocols the Factory proxy multiplexes; `api-routes provider="factory-droid"` picks one per model. */
|
|
8
|
+
export declare const FACTORY_DROID_WIRES: readonly ["openai-completions", "openai-responses", "anthropic-messages", "google-generate"];
|
|
9
|
+
/** Wire protocol used by the Factory proxy for each model. */
|
|
10
|
+
export type FactoryDroidWire = (typeof FACTORY_DROID_WIRES)[number];
|
|
11
|
+
/**
|
|
12
|
+
* Upstream routers the proxy dispatches to, sent as the `x-api-provider`
|
|
13
|
+
* header. The KDL compiler validates the rotation and region axes against it.
|
|
14
|
+
*/
|
|
15
|
+
export declare const FACTORY_DROID_UPSTREAMS: readonly ["fireworks", "baseten", "mistral", "anthropic", "azure_anthropic", "vertex_anthropic", "bedrock_anthropic", "openai", "azure_openai", "bedrock_openai", "google", "xai", "snowflake", "databricks"];
|
|
16
|
+
/** Inference serving region; independent from account/API-host residency. */
|
|
17
|
+
export type FactoryDroidRegion = "global" | "us" | "eu";
|
|
18
|
+
/**
|
|
19
|
+
* Account scope a Factory credential resolves to. Residency (`region`) selects
|
|
20
|
+
* the API host; `inferenceRegion` selects eligible upstreams and capacities.
|
|
21
|
+
* An EU-host account can legitimately have global inference.
|
|
22
|
+
*/
|
|
23
|
+
export interface AccountScope {
|
|
24
|
+
region?: string;
|
|
25
|
+
inferenceRegion?: FactoryDroidRegion;
|
|
26
|
+
orgId?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Inference region for an account: explicit scope wins, else EU residency infers EU, else global. */
|
|
29
|
+
export declare function resolveFactoryDroidInferenceRegion(scope: {
|
|
30
|
+
region?: string;
|
|
31
|
+
inferenceRegion?: FactoryDroidRegion;
|
|
32
|
+
}): FactoryDroidRegion;
|
|
33
|
+
/** Factory API host per residency region; EU accounts are served from the EU region. */
|
|
34
|
+
export declare function factoryDroidApiBaseUrl(region: string | undefined): string;
|
|
35
|
+
/** Per-wire base URL for an account region; the stream layer appends the path suffix. */
|
|
36
|
+
export declare function factoryDroidWireBaseUrl(wire: FactoryDroidWire, region: string | undefined): string;
|
|
37
|
+
/**
|
|
38
|
+
* Client identity headers shared by discovery, usage and inference requests.
|
|
39
|
+
* Callers add their own auth, `Accept`, routing and SDK headers.
|
|
40
|
+
*/
|
|
41
|
+
export declare function factoryDroidClientHeaders(orgId: string | undefined): Record<string, string>;
|
|
42
|
+
/** Model-cache namespace for a Factory credential and its account scope. */
|
|
43
|
+
export declare function factoryDroidModelCacheProviderId(options: {
|
|
44
|
+
apiKey?: string;
|
|
45
|
+
} & AccountScope): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-catalog",
|
|
3
|
-
"version": "18.4.
|
|
3
|
+
"version": "18.4.6",
|
|
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.4.
|
|
97
|
-
"@oh-my-pi/pi-utils": "18.4.
|
|
96
|
+
"@oh-my-pi/omptype": "18.4.6",
|
|
97
|
+
"@oh-my-pi/pi-utils": "18.4.6"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@bgotink/kdl": "0.4.0",
|
|
101
|
-
"@oh-my-pi/pi-ai": "18.4.
|
|
101
|
+
"@oh-my-pi/pi-ai": "18.4.6",
|
|
102
102
|
"@types/bun": "^1.3.14"
|
|
103
103
|
},
|
|
104
104
|
"engines": {
|
package/src/build.ts
CHANGED
|
@@ -76,6 +76,11 @@ function isInputModalities(value: unknown): value is ("text" | "image")[] {
|
|
|
76
76
|
function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog: Record<string, unknown>): void {
|
|
77
77
|
const kind = MODEL_KINDS.find(value => value === catalog.kind);
|
|
78
78
|
if (kind !== undefined) model.kind = kind;
|
|
79
|
+
if (catalog.contextWindowAuthoritative === true) {
|
|
80
|
+
model.contextWindowAuthoritative = true;
|
|
81
|
+
} else {
|
|
82
|
+
delete model.contextWindowAuthoritative;
|
|
83
|
+
}
|
|
79
84
|
const webSearch = catalog.webSearch;
|
|
80
85
|
if (
|
|
81
86
|
webSearch === "gemini" ||
|
|
@@ -120,6 +125,15 @@ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog:
|
|
|
120
125
|
if (editPromptVariant === "full" || editPromptVariant === "compact") {
|
|
121
126
|
model.editPromptVariant = editPromptVariant;
|
|
122
127
|
}
|
|
128
|
+
const pricingStatus = catalog.pricingStatus;
|
|
129
|
+
if (
|
|
130
|
+
pricingStatus === "free" ||
|
|
131
|
+
pricingStatus === "included" ||
|
|
132
|
+
pricingStatus === "variable" ||
|
|
133
|
+
pricingStatus === "unknown"
|
|
134
|
+
) {
|
|
135
|
+
model.pricingStatus = pricingStatus;
|
|
136
|
+
}
|
|
123
137
|
const requiresCursorToolSchemaProjection = catalog.requiresCursorToolSchemaProjection;
|
|
124
138
|
if (requiresCursorToolSchemaProjection === true) {
|
|
125
139
|
model.requiresCursorToolSchemaProjection = true;
|
|
@@ -137,6 +151,11 @@ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog:
|
|
|
137
151
|
} else {
|
|
138
152
|
delete model.supportsAssistantPrefill;
|
|
139
153
|
}
|
|
154
|
+
// The same KDL output-cap contract gates host options and the Responses
|
|
155
|
+
// transport. Materialize it because the transport consumes the model field.
|
|
156
|
+
if (typeof catalog.omitMaxOutputTokens === "boolean" && model.omitMaxOutputTokens === undefined) {
|
|
157
|
+
model.omitMaxOutputTokens = catalog.omitMaxOutputTokens;
|
|
158
|
+
}
|
|
140
159
|
const contextPromotionTarget = catalog.contextPromotionTarget;
|
|
141
160
|
if (typeof contextPromotionTarget === "string" && model.contextPromotionTarget === undefined) {
|
|
142
161
|
model.contextPromotionTarget = contextPromotionTarget;
|
|
@@ -344,5 +363,7 @@ export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi>
|
|
|
344
363
|
};
|
|
345
364
|
applyCatalogAssignments(model, policy.catalog);
|
|
346
365
|
applyCatalogCorrections(model, policy.catalog);
|
|
366
|
+
// Configured lifetimes replace catalog lifetimes rather than merging with them.
|
|
367
|
+
if (spec.promptCacheConfig !== undefined) model.promptCache = { ...spec.promptCacheConfig };
|
|
347
368
|
return model;
|
|
348
369
|
}
|
package/src/compat/auth-ids.ts
CHANGED
|
@@ -24,6 +24,7 @@ export type AuthProviderId =
|
|
|
24
24
|
| "deepseek"
|
|
25
25
|
| "devin"
|
|
26
26
|
| "exa"
|
|
27
|
+
| "factory-droid"
|
|
27
28
|
| "firepass"
|
|
28
29
|
| "fireworks"
|
|
29
30
|
| "github-copilot"
|
|
@@ -35,6 +36,7 @@ export type AuthProviderId =
|
|
|
35
36
|
| "google-gemini-cli"
|
|
36
37
|
| "google-vertex"
|
|
37
38
|
| "groq"
|
|
39
|
+
| "helmcode"
|
|
38
40
|
| "huggingface"
|
|
39
41
|
| "kagi"
|
|
40
42
|
| "kilo"
|
|
@@ -113,6 +115,7 @@ export type LoginProviderId =
|
|
|
113
115
|
| "deepseek"
|
|
114
116
|
| "devin"
|
|
115
117
|
| "exa"
|
|
118
|
+
| "factory-droid"
|
|
116
119
|
| "firepass"
|
|
117
120
|
| "fireworks"
|
|
118
121
|
| "github-copilot"
|
|
@@ -121,6 +124,7 @@ export type LoginProviderId =
|
|
|
121
124
|
| "gmi-cloud"
|
|
122
125
|
| "google-antigravity"
|
|
123
126
|
| "google-gemini-cli"
|
|
127
|
+
| "helmcode"
|
|
124
128
|
| "huggingface"
|
|
125
129
|
| "kagi"
|
|
126
130
|
| "kilo"
|