@oh-my-pi/pi-catalog 18.3.0 → 18.3.2

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.
@@ -175,6 +175,11 @@ export function resolveModelCacheProviderId(providerId: string, options: ModelCa
175
175
  const baseUrl = options.baseUrl ?? getDefaultModelDiscoveryBaseUrl(providerId)!;
176
176
  return `vllm:models-v2:${Bun.hash(baseUrl).toString(36)}`;
177
177
  }
178
+ case "devin":
179
+ // v2: rows cached before Fusion pairings carried their lead uid as
180
+ // `requestModelId` send the composite uid and fail with
181
+ // `permission_denied: no API providers are available`.
182
+ return "devin:models-v2";
178
183
  default:
179
184
  return providerId;
180
185
  }
@@ -4710,8 +4710,8 @@ export function sakanaModelManagerOptions(config?: SakanaModelManagerConfig): Mo
4710
4710
 
4711
4711
  const AIAND_DEFAULT_BASE_URL = "https://api.aiand.com/v1";
4712
4712
 
4713
- /** `reasoning_efforts` wire values ai& reports, mapped onto pi effort levels. */
4714
- const AIAND_EFFORT_BY_WIRE_VALUE: Record<string, Effort> = {
4713
+ /** Effort wire values discovery endpoints report (`reasoning_efforts`, `thinking`), mapped onto pi effort levels. */
4714
+ const EFFORT_BY_WIRE_VALUE: Record<string, Effort> = {
4715
4715
  minimal: Effort.Minimal,
4716
4716
  low: Effort.Low,
4717
4717
  medium: Effort.Medium,
@@ -4728,18 +4728,23 @@ function normalizeAiandBaseUrl(baseUrl: string | undefined): string {
4728
4728
 
4729
4729
  const AIAND_STATIC_MODEL_IDS = seedModels("aiand").map(model => model.id);
4730
4730
 
4731
- function mapAiandThinking(entry: OpenAICompatibleModelRecord): ThinkingConfig | undefined {
4732
- const efforts = Array.isArray(entry.reasoning_efforts)
4733
- ? entry.reasoning_efforts.flatMap(value =>
4734
- typeof value === "string" && AIAND_EFFORT_BY_WIRE_VALUE[value] ? [AIAND_EFFORT_BY_WIRE_VALUE[value]] : [],
4731
+ /** Parse a discovered effort list, dropping unknown wire values; empty when absent or unrecognized. */
4732
+ function parseWireEfforts(value: unknown): Effort[] {
4733
+ return Array.isArray(value)
4734
+ ? value.flatMap(item =>
4735
+ typeof item === "string" && EFFORT_BY_WIRE_VALUE[item] ? [EFFORT_BY_WIRE_VALUE[item]] : [],
4735
4736
  )
4736
4737
  : [];
4738
+ }
4739
+
4740
+ function mapAiandThinking(entry: OpenAICompatibleModelRecord): ThinkingConfig | undefined {
4741
+ const efforts = parseWireEfforts(entry.reasoning_efforts);
4737
4742
  if (efforts.length === 0) {
4738
4743
  return undefined;
4739
4744
  }
4740
4745
  const defaultLevel =
4741
4746
  typeof entry.reasoning_effort_default === "string"
4742
- ? AIAND_EFFORT_BY_WIRE_VALUE[entry.reasoning_effort_default]
4747
+ ? EFFORT_BY_WIRE_VALUE[entry.reasoning_effort_default]
4743
4748
  : undefined;
4744
4749
  return {
4745
4750
  mode: "effort",
@@ -4896,8 +4901,26 @@ function mapYoloAutoModel(
4896
4901
  reference: ModelSpec<"openai-completions"> | undefined,
4897
4902
  ): ModelSpec<"openai-completions"> {
4898
4903
  const model = mapWithBundledReference(entry, defaults, reference);
4904
+ // `/v1/models` advertises each reasoning model's accepted effort ladder in
4905
+ // `thinking`; it is authoritative over the seed/reference ladder. Rows
4906
+ // without the field (e.g. `yolo-small`) keep the reference surface.
4907
+ const efforts = parseWireEfforts(entry.thinking);
4908
+ const thinking: ThinkingConfig | undefined =
4909
+ efforts.length > 0
4910
+ ? {
4911
+ ...model.thinking,
4912
+ mode: model.thinking?.mode ?? "effort",
4913
+ efforts,
4914
+ defaultLevel:
4915
+ model.thinking?.defaultLevel && efforts.includes(model.thinking.defaultLevel)
4916
+ ? model.thinking.defaultLevel
4917
+ : undefined,
4918
+ }
4919
+ : model.thinking;
4899
4920
  return {
4900
4921
  ...model,
4922
+ ...(efforts.length > 0 && { reasoning: true }),
4923
+ thinking,
4901
4924
  // Flat-rate and no-store are provider-wide: they must win whether the
4902
4925
  // reference came from the yolo bundle, the global index, or nowhere.
4903
4926
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
@@ -345,6 +345,7 @@ export function devinModelManagerOptions(config: DevinModelManagerConfig = {}):
345
345
  const staticModels = seedModels<"devin-agent">("devin");
346
346
  return {
347
347
  providerId: "devin",
348
+ cacheProviderId: resolveModelCacheProviderId("devin"),
348
349
  // A configured host serves its own Cascade deployment; keep the seed on it.
349
350
  staticModels:
350
351
  baseUrl === undefined || baseUrl === DEVIN_DEFAULT_BASE_URL
package/src/types.ts CHANGED
@@ -479,6 +479,13 @@ export interface OpenAICompat {
479
479
  * sent as the top-level `reasoning.effort`.
480
480
  */
481
481
  supportsConfigurationUpdate?: boolean;
482
+ /**
483
+ * Whether the Responses WebSocket accepts `response.steer`, which queues user
484
+ * input into the in-flight response (GPT-6 family). Default: rule-detected.
485
+ * Set `false` for proxies that reject the event; steering then waits for the
486
+ * next request boundary.
487
+ */
488
+ supportsSteering?: boolean;
482
489
  /** Whether streamed reasoning deltas for the same field may repeat the full cumulative text snapshot. Default: false. */
483
490
  reasoningDeltasMayBeCumulative?: boolean;
484
491
  /** Strip leaked DeepSeek chat-template special tokens from visible content deltas. Default: auto-detected. */
@@ -875,6 +882,7 @@ export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat &
875
882
  | "strictResponsesPairing"
876
883
  | "supportsImageDetailOriginal"
877
884
  | "supportsConfigurationUpdate"
885
+ | "supportsSteering"
878
886
  | "stripImageInput"
879
887
  | "thinkingLoopGuard"
880
888
  | "whenThinking"
@@ -914,6 +922,11 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
914
922
  * the item type with 400.
915
923
  */
916
924
  supportsConfigurationUpdate: boolean;
925
+ /**
926
+ * Whether the WebSocket transport may send `response.steer` to deliver user
927
+ * input into the in-flight response. Rule-owned: GPT-6 family.
928
+ */
929
+ supportsSteering: boolean;
917
930
  /** Inject the `# Juice: 0 !important` developer item when reasoning is forced off (gpt-5.6+). */
918
931
  requiresReasoningOffJuiceInstruction: boolean;
919
932
  /**