@jeffreycao/copilot-api 2.7.10 → 2.7.12

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.
@@ -1,9 +1,9 @@
1
1
  import { D as state, E as isGitHubCopilotEnabled, O as HTTPError, S as PATHS, a as getAnthropicApiKey, c as getConfig, d as getUpstreamTransportConfig, g as isResponsesApiWebSocketEnabled, h as isResponsesApiWebSearchEnabled, i as getAlphaSearchModel, j as forwardError, l as getMessageApiWebSearchModel, m as isMessagesApiEnabled, o as getClaudeAutoModel, p as isAlphaSearchCodexPriorityEnabled, s as getClaudeTokenMultiplier, u as getOpencodeModelContextWindow, w as GITHUB_COPILOT_PROVIDER, y as reloadConfig } from "./config-store-C6GAtKLz.js";
2
- import { C as isContextManagementEnabledForResponses, E as setModelMappings, S as isContextManagementEnabledForMessages, T as resolveMappedModel, _ as getModelMappings, b as getSmallModel, d as getOpencodeGoModelConfig, f as getOpencodeGoModelIds, g as getExtraPromptForModel, i as listEnabledProviders, l as getModelsDevModel, n as getRawProviderConfig, o as resolveEffectiveProviderType, p as getOpencodeGoModelRecords, s as resolveProviderConfigForModel, t as getProviderConfig, u as getModelsDevModelMaxOutputTokens, v as getModelResponsesApiCompactThreshold$1, w as isGpt56OrAbove, x as getSmallModelForProvider, y as getReasoningEffortForModel } from "./config-Cd0U5gXz.js";
3
- import { $ as resolveTraceId$1, C as isOpencodeOauthApp, E as prepareMessageProxyHeaders, G as XAI_API_BASE_URL, J as CODEX_API_BASE_URL, L as getXaiAccessToken, M as compactTextOnlyGuard, N as createAuthMiddleware, O as compactAutoContinuePromptStarts, P as getConfiguredAdminApiKeys, Q as requestContext, S as copilotWebSocketHeaders, T as prepareInteractionHeaders, U as readGitHubToken, W as readGitHubTokenFromEnv, X as forwardCodexResponses, Y as buildCodexRequestHeaders, Z as generateTraceId, _ as parseUserIdMetadata, at as createPooledWebSocketStream, b as copilotHeaders, ct as stripInternalRequestHeaders, d as generateRequestIdFromPayload, et as fetchUpstreamWithLifecycle, f as getRootSessionId, g as isResponsesStream, h as isNullish, it as getResponsesStreamTerminalDisposition, j as compactSystemPromptStarts, k as compactMessageSections, m as isAsyncIterable, n as invalidateCodexRuntime, nt as createResponsesSafeStream, ot as createWebSocketUrl, p as getUUID, rt as encodePoolKeyPart, s as setupCodexToken, tt as createResponsesHttpEventStream, u as stopCopilotRefreshLoop, v as getCopilotUsage, w as prepareForCompact, y as copilotBaseUrl } from "./token-kSGCOmTG.js";
2
+ import { A as resolveMappedModel, C as getModelResponsesApiCompactThreshold$1, D as isContextManagementEnabledForMessages, E as getSmallModelForProvider, O as isContextManagementEnabledForResponses, S as getModelMappings, T as getSmallModel, _ as getModelsDevModelMaxOutputTokens, d as isProviderModelVisible, f as resolveProviderModelsDevId, g as getModelsDevModel, h as getBuiltinProviderModelRecords, i as listEnabledProviders, j as setModelMappings, k as isGpt56OrAbove, l as getLocalProviderModelRecords, m as builtinProviderModelRegistry, n as getRawProviderConfig, o as resolveEffectiveProviderType, p as usesModelsDevModelCatalog, s as resolveProviderConfigForModel, t as getProviderConfig, u as getProviderModelConfig, v as getModelsDevModelPricing, w as getReasoningEffortForModel, x as getExtraPromptForModel } from "./config-Cs3Ol5sJ.js";
3
+ import { $ as resolveTraceId$1, C as isOpencodeOauthApp, E as prepareMessageProxyHeaders, G as XAI_API_BASE_URL, J as CODEX_API_BASE_URL, L as getXaiAccessToken, M as compactTextOnlyGuard, N as createAuthMiddleware, O as compactAutoContinuePromptStarts, P as getConfiguredAdminApiKeys, Q as requestContext, S as copilotWebSocketHeaders, T as prepareInteractionHeaders, U as readGitHubToken, W as readGitHubTokenFromEnv, X as forwardCodexResponses, Y as buildCodexRequestHeaders, Z as generateTraceId, _ as parseUserIdMetadata, at as createPooledWebSocketStream, b as copilotHeaders, ct as stripInternalRequestHeaders, d as generateRequestIdFromPayload, et as fetchUpstreamWithLifecycle, f as getRootSessionId, g as isResponsesStream, h as isNullish, it as getResponsesStreamTerminalDisposition, j as compactSystemPromptStarts, k as compactMessageSections, m as isAsyncIterable, n as invalidateCodexRuntime, nt as createResponsesSafeStream, ot as createWebSocketUrl, p as getUUID, rt as encodePoolKeyPart, s as setupCodexToken, tt as createResponsesHttpEventStream, u as stopCopilotRefreshLoop, v as getCopilotUsage, w as prepareForCompact, y as copilotBaseUrl } from "./token-C7R7Vd9b.js";
4
4
  import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-CcvaqM03.js";
5
5
  import { n as isProviderAgentModelVisible, t as getProviderAgentModels } from "./provider-management-DOfLC7WX.js";
6
- import { n as stopModelsRefreshLoop, t as setupCopilotRuntime } from "./copilot-runtime-Dg3ywZkl.js";
6
+ import { n as stopModelsRefreshLoop, t as setupCopilotRuntime } from "./copilot-runtime-DhtRP9zU.js";
7
7
  import consola from "consola";
8
8
  import { createHash, randomUUID } from "node:crypto";
9
9
  import fs, { createWriteStream, readFileSync, rmSync } from "node:fs";
@@ -469,434 +469,6 @@ var EventBus = class {
469
469
  }
470
470
  };
471
471
  //#endregion
472
- //#region src/lib/token-usage/peak-windows.ts
473
- const deepseekPeakWindows = [{
474
- endMinuteUtc: 240,
475
- startMinuteUtc: 60,
476
- weekdays: [
477
- 1,
478
- 2,
479
- 3,
480
- 4,
481
- 5
482
- ]
483
- }, {
484
- endMinuteUtc: 600,
485
- startMinuteUtc: 360,
486
- weekdays: [
487
- 1,
488
- 2,
489
- 3,
490
- 4,
491
- 5
492
- ]
493
- }];
494
- const dashscopePeakWindows = [{
495
- endMinuteUtc: 840,
496
- startMinuteUtc: 0
497
- }];
498
- //#endregion
499
- //#region src/lib/builtin-provider-models.ts
500
- const CODEX_LUNA_PRICING = { tiers: [{
501
- cacheCreationInput: .125,
502
- cachedInput: .01,
503
- input: .1,
504
- maxInputTokens: 272e3,
505
- output: .5
506
- }, {
507
- cacheCreationInput: .25,
508
- cachedInput: .02,
509
- input: .2,
510
- output: .75
511
- }] };
512
- const builtinProviderModelRegistry = new class BuiltinProviderModelRegistry {
513
- static catalog = {
514
- xai: { "grok-4.7": {
515
- contextWindow: 5e5,
516
- maxOutputTokens: 5e5,
517
- inputModalities: ["text", "image"],
518
- reasoningEfforts: [
519
- "low",
520
- "medium",
521
- "high",
522
- "xhigh"
523
- ],
524
- defaultReasoningEffort: "high",
525
- pricing: { tiers: [{
526
- cachedInput: .5,
527
- input: 2,
528
- output: 6,
529
- maxInputTokens: 2e5
530
- }, {
531
- cachedInput: 1,
532
- input: 4,
533
- output: 12
534
- }] }
535
- } },
536
- codex: {
537
- "codex-auto-review": { pricing: CODEX_LUNA_PRICING },
538
- "gpt-reserve": { pricing: CODEX_LUNA_PRICING },
539
- "gpt-5.5": { pricing: { tiers: [{
540
- cachedInput: .5,
541
- input: 5,
542
- maxInputTokens: 272e3,
543
- output: 30
544
- }, {
545
- cachedInput: 1,
546
- input: 10,
547
- output: 45
548
- }] } },
549
- "gpt-5.6-sol": { pricing: { tiers: [{
550
- cacheCreationInput: 5,
551
- cachedInput: .4,
552
- input: 4,
553
- maxInputTokens: 272e3,
554
- output: 20
555
- }, {
556
- cacheCreationInput: 10,
557
- cachedInput: .8,
558
- input: 8,
559
- output: 30
560
- }] } },
561
- "gpt-5.6-terra": { pricing: { tiers: [{
562
- cacheCreationInput: 2.5,
563
- cachedInput: .2,
564
- input: 2,
565
- maxInputTokens: 272e3,
566
- output: 12
567
- }, {
568
- cacheCreationInput: 5,
569
- cachedInput: .4,
570
- input: 4,
571
- output: 18
572
- }] } },
573
- "gpt-5.6-luna": { pricing: { tiers: [{
574
- cacheCreationInput: .25,
575
- cachedInput: .02,
576
- input: .2,
577
- maxInputTokens: 272e3,
578
- output: 1.2
579
- }, {
580
- cacheCreationInput: .5,
581
- cachedInput: .04,
582
- input: .4,
583
- output: 1.8
584
- }] } },
585
- "gpt-6-astra": { pricing: { tiers: [{
586
- cacheCreationInput: 12.5,
587
- cachedInput: 1,
588
- input: 10,
589
- maxInputTokens: 272e3,
590
- output: 50
591
- }, {
592
- cacheCreationInput: 25,
593
- cachedInput: 2,
594
- input: 20,
595
- output: 75
596
- }] } },
597
- "gpt-6-luna": { pricing: CODEX_LUNA_PRICING },
598
- "gpt-6-sol": { pricing: { tiers: [{
599
- cacheCreationInput: 2.5,
600
- cachedInput: .2,
601
- input: 2,
602
- maxInputTokens: 272e3,
603
- output: 10
604
- }, {
605
- cacheCreationInput: 5,
606
- cachedInput: .4,
607
- input: 4,
608
- output: 15
609
- }] } },
610
- "gpt-6.1-sol": { pricing: { tiers: [{
611
- cacheCreationInput: 2.5,
612
- cachedInput: .1,
613
- input: 2,
614
- maxInputTokens: 272e3,
615
- output: 10
616
- }, {
617
- cacheCreationInput: 5,
618
- cachedInput: .2,
619
- input: 4,
620
- output: 15
621
- }] } }
622
- },
623
- dashscope: {
624
- "glm-5.3": {
625
- contextWindow: 1e6,
626
- inputModalities: ["text"],
627
- maxOutputTokens: 64e3,
628
- pricing: {
629
- cachedInput: 2,
630
- input: 8,
631
- output: 28
632
- },
633
- reasoningEfforts: [
634
- "low",
635
- "high",
636
- "max"
637
- ]
638
- },
639
- "deepseek-v4.1-flash": {
640
- contextWindow: 1e6,
641
- defaultReasoningEffort: "high",
642
- inputModalities: ["text", "image"],
643
- maxOutputTokens: 393216,
644
- pricing: {
645
- cachedInput: .2,
646
- input: 2,
647
- offPeak: {
648
- cachedInput: .1,
649
- input: 1,
650
- output: 4
651
- },
652
- output: 8,
653
- peakWindows: dashscopePeakWindows
654
- },
655
- reasoningEfforts: [
656
- "low",
657
- "high",
658
- "max"
659
- ]
660
- },
661
- "qwen3.8-max": {
662
- contextWindow: 1e6,
663
- defaultReasoningEffort: "xhigh",
664
- inputModalities: ["text", "image"],
665
- maxOutputTokens: 64e3,
666
- pricing: {
667
- cachedInput: 1.5,
668
- cacheCreationInput: 15,
669
- explicitCachedInput: 1,
670
- input: 12,
671
- output: 36
672
- },
673
- reasoningEfforts: [
674
- "low",
675
- "medium",
676
- "xhigh"
677
- ]
678
- },
679
- "qwen3.8-max-0902": {
680
- contextWindow: 1e6,
681
- defaultReasoningEffort: "xhigh",
682
- inputModalities: ["text", "image"],
683
- maxOutputTokens: 131072,
684
- pricing: {
685
- cachedInput: 1.5,
686
- cacheCreationInput: 15,
687
- explicitCachedInput: 1,
688
- input: 12,
689
- output: 36
690
- },
691
- reasoningEfforts: [
692
- "low",
693
- "medium",
694
- "xhigh"
695
- ]
696
- },
697
- "qwen3.8-flash": {
698
- contextWindow: 1e6,
699
- defaultReasoningEffort: "xhigh",
700
- inputModalities: ["text", "image"],
701
- maxOutputTokens: 131072,
702
- pricing: {
703
- cachedInput: .1,
704
- cacheCreationInput: 1.25,
705
- explicitCachedInput: .1,
706
- input: .8,
707
- output: 2.7
708
- },
709
- reasoningEfforts: [
710
- "low",
711
- "medium",
712
- "xhigh"
713
- ]
714
- },
715
- "qwen3.7-plus": {
716
- contextWindow: 1e6,
717
- defaultReasoningEffort: "xhigh",
718
- inputModalities: ["text", "image"],
719
- maxOutputTokens: 64e3,
720
- pricing: { tiers: [{
721
- cachedInput: .4,
722
- cacheCreationInput: 2.5,
723
- explicitCachedInput: .2,
724
- input: 2,
725
- maxInputTokens: 256e3,
726
- output: 8
727
- }, {
728
- cachedInput: 1.2,
729
- cacheCreationInput: 7.5,
730
- explicitCachedInput: .6,
731
- input: 6,
732
- maxInputTokens: 1e6,
733
- output: 24
734
- }] },
735
- reasoningEfforts: [
736
- "low",
737
- "medium",
738
- "xhigh"
739
- ]
740
- },
741
- "kimi/kimi-k3": {
742
- contextWindow: 1048576,
743
- defaultReasoningEffort: "max",
744
- inputModalities: ["text", "image"],
745
- maxOutputTokens: 64e3,
746
- pricing: {
747
- cachedInput: 2,
748
- input: 20,
749
- output: 100
750
- },
751
- reasoningEfforts: ["max"]
752
- },
753
- "ZHIPU/GLM-5.3": {
754
- contextWindow: 1048576,
755
- inputModalities: ["text"],
756
- maxOutputTokens: 131072,
757
- pricing: {
758
- cachedInput: 2,
759
- input: 8,
760
- output: 28
761
- },
762
- reasoningEfforts: [
763
- "low",
764
- "high",
765
- "max"
766
- ]
767
- },
768
- "ZHIPU/GLM-5.3-Flash": {
769
- contextWindow: 1048576,
770
- inputModalities: ["text", "image"],
771
- maxOutputTokens: 131072,
772
- pricing: {
773
- cachedInput: .23,
774
- input: .8,
775
- output: 2.8
776
- },
777
- reasoningEfforts: [
778
- "low",
779
- "high",
780
- "max"
781
- ]
782
- },
783
- "ZHIPU/GLM-5.3-FlashX": {
784
- contextWindow: 1048576,
785
- inputModalities: ["text", "image"],
786
- maxOutputTokens: 131072,
787
- pricing: {
788
- cachedInput: .57,
789
- input: 2,
790
- output: 7
791
- },
792
- reasoningEfforts: [
793
- "low",
794
- "high",
795
- "max"
796
- ]
797
- }
798
- },
799
- deepseek: {
800
- "deepseek-flash": {
801
- contextWindow: 1e6,
802
- inputModalities: ["text", "image"],
803
- maxOutputTokens: 384e3,
804
- pricing: {
805
- cachedInput: .04,
806
- input: 2,
807
- offPeak: {
808
- cachedInput: .02,
809
- input: 1,
810
- output: 4
811
- },
812
- output: 8,
813
- peakWindows: deepseekPeakWindows
814
- },
815
- reasoningEfforts: [
816
- "low",
817
- "high",
818
- "max"
819
- ]
820
- },
821
- "deepseek-v4-pro": {
822
- contextWindow: 1e6,
823
- inputModalities: ["text"],
824
- maxOutputTokens: 64e3,
825
- pricing: {
826
- cachedInput: .3,
827
- input: 9,
828
- offPeak: {
829
- cachedInput: .15,
830
- input: 4.5,
831
- output: 13.5
832
- },
833
- output: 27,
834
- peakWindows: deepseekPeakWindows
835
- },
836
- reasoningEfforts: [
837
- "low",
838
- "high",
839
- "max"
840
- ]
841
- }
842
- },
843
- kimi: {
844
- k3: {
845
- contextWindow: 1048576,
846
- inputModalities: ["text", "image"],
847
- maxOutputTokens: 64e3,
848
- pricing: {
849
- cachedInput: .3,
850
- input: 3,
851
- output: 15
852
- }
853
- },
854
- "k3-256k": {
855
- contextWindow: 262144,
856
- inputModalities: ["text", "image"],
857
- maxOutputTokens: 64e3,
858
- pricing: {
859
- cachedInput: .3,
860
- input: 3,
861
- output: 15
862
- }
863
- }
864
- }
865
- };
866
- modelCatalog;
867
- constructor() {
868
- this.modelCatalog = BuiltinProviderModelRegistry.catalog;
869
- }
870
- getModelConfig(providerName, modelName) {
871
- const provider = this.normalizeKey(providerName);
872
- if (provider === "opencode-go") return getOpencodeGoModelConfig(modelName);
873
- const models = this.modelCatalog[provider];
874
- return models?.[modelName.trim()] ?? models?.[this.normalizeKey(modelName)];
875
- }
876
- getModelIds(providerName) {
877
- const provider = this.normalizeKey(providerName);
878
- if (provider === "opencode-go") return getOpencodeGoModelIds();
879
- return Object.keys(this.modelCatalog[provider] ?? {});
880
- }
881
- normalizeKey(value) {
882
- return value.trim().toLowerCase();
883
- }
884
- }();
885
- function getBuiltinProviderModelRecords(provider) {
886
- return builtinProviderModelRegistry.getModelIds(provider).map((id) => {
887
- const config = builtinProviderModelRegistry.getModelConfig(provider, id);
888
- return {
889
- id,
890
- name: id,
891
- object: "model",
892
- context_window: config?.contextWindow,
893
- max_output_tokens: config?.maxOutputTokens,
894
- input_modalities: config?.inputModalities,
895
- reasoning_efforts: config?.reasoningEfforts
896
- };
897
- });
898
- }
899
- //#endregion
900
472
  //#region src/lib/sqlite.ts
901
473
  const MINIMUM_NODE_SQLITE_VERSION = "22.13.0";
902
474
  const isBunRuntime = () => Boolean(globalThis.Bun);
@@ -1613,7 +1185,7 @@ function resolveTokenUsageCost(input) {
1613
1185
  const resolvedPricing = resolveProviderPricing(providerName, input.model, input.pricing);
1614
1186
  if (!resolvedPricing) return null;
1615
1187
  const pricing = resolvePricingTier(resolvedPricing.pricing, getInputTokenTotal(input), resolvePricingTime(input.at));
1616
- const currency = resolveProviderCurrency(providerName, input.pricingCurrency);
1188
+ const currency = resolvedPricing.currency ?? resolveProviderCurrency(providerName, input.pricingCurrency);
1617
1189
  if (!currency) return null;
1618
1190
  const inputPrice = normalizePrice(pricing.input);
1619
1191
  const outputPrice = normalizePrice(pricing.output);
@@ -1664,6 +1236,14 @@ function resolveProviderPricing(providerName, model, configuredPricing) {
1664
1236
  pricing: configuredPricing,
1665
1237
  source: "config"
1666
1238
  };
1239
+ if (usesModelsDevModelCatalog(providerName)) {
1240
+ const pricing = getModelsDevModelPricing(resolveProviderModelsDevId(providerName), model);
1241
+ if (pricing) return {
1242
+ pricing,
1243
+ source: "models.dev",
1244
+ currency: "USD"
1245
+ };
1246
+ }
1667
1247
  const pricingModel = providerName.toLowerCase() === "codex" && model.trim().toLowerCase() === "gpt-5.6" ? "gpt-5.6-sol" : model;
1668
1248
  const builtinPricing = builtinProviderModelRegistry.getModelConfig(providerName, pricingModel)?.pricing;
1669
1249
  if (!builtinPricing) return null;
@@ -3267,7 +2847,7 @@ const applyMissingExtraBody = (payload, options) => {
3267
2847
  const normalizeProviderResponsesReasoningEffort = (payload, providerConfig) => {
3268
2848
  if (!payload.reasoning || typeof payload.reasoning.effort !== "string") return;
3269
2849
  const modelConfig = providerConfig.models?.[payload.model];
3270
- const builtinModelConfig = builtinProviderModelRegistry.getModelConfig(providerConfig.name, payload.model);
2850
+ const builtinModelConfig = getProviderModelConfig(providerConfig.name, payload.model, providerConfig);
3271
2851
  const configuredEfforts = modelConfig?.reasoningEfforts;
3272
2852
  const supportedEfforts = configuredEfforts && configuredEfforts.length > 0 ? configuredEfforts : builtinModelConfig?.reasoningEfforts;
3273
2853
  const resolvedEffort = resolveSupportedReasoningEffort(payload.reasoning.effort, supportedEfforts);
@@ -4083,6 +3663,25 @@ const imageRoutes = new Hono();
4083
3663
  imageRoutes.post("/generations", handleImagesGenerations);
4084
3664
  imageRoutes.post("/edits", handleImagesEdits);
4085
3665
  //#endregion
3666
+ //#region src/lib/model-pdf-support.ts
3667
+ function resolveModelPdfSupport(provider, options) {
3668
+ if (options.supportPdf !== void 0) return options.supportPdf;
3669
+ return options.builtinSupportPdf === true || provider === "github-copilot" && Array.isArray(options.supportedMediaTypes) && options.supportedMediaTypes.includes("application/pdf") || Array.isArray(options.catalogInputModalities) && options.catalogInputModalities.includes("pdf");
3670
+ }
3671
+ function getProviderModelPdfSupport(modelId, provider, selectedModel) {
3672
+ const rawId = selectedModel?.id ?? modelId;
3673
+ const modelConfig = provider.models?.[rawId] ?? provider.models?.[modelId];
3674
+ const catalogProvider = resolveProviderModelsDevId(provider.name, provider);
3675
+ const catalog = getModelsDevModel(catalogProvider, rawId) ?? getModelsDevModel(catalogProvider, modelId);
3676
+ const builtin = builtinProviderModelRegistry.getModelConfig(provider.name, rawId);
3677
+ return resolveModelPdfSupport(provider.name, {
3678
+ supportPdf: modelConfig?.supportPdf,
3679
+ catalogInputModalities: catalog?.modalities?.input,
3680
+ supportedMediaTypes: selectedModel?.capabilities.limits.vision?.supported_media_types,
3681
+ builtinSupportPdf: builtin?.supportPdf ?? builtinProviderModelRegistry.getProviderDefaults(provider.name)?.supportPdf
3682
+ });
3683
+ }
3684
+ //#endregion
4086
3685
  //#region src/lib/claude-models.ts
4087
3686
  const DISCOVERY_MODEL_PREFIX = "my-claude-";
4088
3687
  const DISCOVERY_MODEL_SUFFIX = "[1m]";
@@ -5168,10 +4767,11 @@ async function handleProviderCountTokensForProvider(c, options) {
5168
4767
  type: "invalid_request_error"
5169
4768
  } }, 404);
5170
4769
  const modelConfig = providerConfig.models?.[modelId];
5171
- const openAIPayload = translateToOpenAI(anthropicPayload, providerConfig.type === "openai-compatible" || providerConfig.type === "openai-responses" ? {
5172
- supportPdf: modelConfig?.supportPdf,
5173
- toolContentSupportType: modelConfig?.toolContentSupportType ?? []
5174
- } : void 0);
4770
+ const effectiveType = resolveEffectiveProviderType(providerConfig, modelId);
4771
+ const openAIPayload = translateToOpenAI(anthropicPayload, {
4772
+ supportPdf: getProviderModelPdfSupport(modelId, providerConfig),
4773
+ ...effectiveType === "openai-compatible" && { toolContentSupportType: modelConfig?.toolContentSupportType ?? [] }
4774
+ });
5175
4775
  const selectedModel = createFallbackModel(modelId);
5176
4776
  const tokenCount = await getTokenCount(openAIPayload, selectedModel);
5177
4777
  const finalTokenCount = tokenCount.input + tokenCount.output;
@@ -5247,11 +4847,14 @@ async function handleCountTokens(c) {
5247
4847
  const anthropicResult = await countTokensViaAnthropic(c, anthropicPayload);
5248
4848
  if (anthropicResult) return anthropicResult;
5249
4849
  const anthropicBeta = c.req.header("anthropic-beta");
5250
- const openAIPayload = translateToOpenAI(anthropicPayload);
5251
4850
  const requestedModel = anthropicPayload.model;
5252
4851
  const resolve = resolveCountTokensModel(requestedModel);
5253
4852
  const selectedModel = resolve.model;
5254
4853
  anthropicPayload.model = selectedModel.id;
4854
+ const openAIPayload = translateToOpenAI(anthropicPayload, { supportPdf: getProviderModelPdfSupport(requestedModel, {
4855
+ ...getRawProviderConfig(GITHUB_COPILOT_PROVIDER),
4856
+ name: GITHUB_COPILOT_PROVIDER
4857
+ }, selectedModel) });
5255
4858
  if (resolve.fallback) consola.warn(`Model '${requestedModel}' not found, using o200k_base fallback tokenizer`);
5256
4859
  const tokenCount = await getTokenCount(openAIPayload, selectedModel);
5257
4860
  if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {
@@ -6877,8 +6480,8 @@ function translateResponsesToMessages(payload, options) {
6877
6480
  function resolveDefaultMaxOutputTokens(model) {
6878
6481
  const alias = parseProviderModelAlias(model);
6879
6482
  const providerConfig = alias ? getRawProviderConfig(alias.provider) : null;
6880
- const catalogMaxOutputTokens = alias ? getModelsDevModelMaxOutputTokens(providerConfig?.modelsDevProviderId || alias.provider, alias.model) : void 0;
6881
- const builtinModelConfig = alias ? builtinProviderModelRegistry.getModelConfig(alias.provider, alias.model) : void 0;
6483
+ const catalogMaxOutputTokens = alias ? getModelsDevModelMaxOutputTokens(resolveProviderModelsDevId(alias.provider, providerConfig), alias.model) : void 0;
6484
+ const builtinModelConfig = alias ? getProviderModelConfig(alias.provider, alias.model, providerConfig) : void 0;
6882
6485
  return (alias && (providerConfig || builtinModelConfig || catalogMaxOutputTokens) ? [
6883
6486
  providerConfig?.models?.[alias.model]?.maxOutputTokens,
6884
6487
  catalogMaxOutputTokens,
@@ -7585,6 +7188,22 @@ const REDACTED_IMAGE_PLACEHOLDER_DATA_URL = "data:image/png;base64," + [
7585
7188
  "OAuj2SEAAAAASUVORK5CYII="
7586
7189
  ].join("");
7587
7190
  const COPILOT_UNSUPPORTED_INPUT_ITEM_FIELDS = ["internal_chat_message_metadata_passthrough"];
7191
+ const isInputAgentMessage = (item) => item.type === "agent_message";
7192
+ const normalizeGuardianAgentMessages = (payload) => {
7193
+ if (!payload.prompt_cache_key?.startsWith("guardia") || payload.text?.format?.type !== "json_schema" || !Array.isArray(payload.input)) return 0;
7194
+ let normalizedCount = 0;
7195
+ payload.input = payload.input.map((item) => {
7196
+ if (!isInputAgentMessage(item)) return item;
7197
+ const agentMessage = item;
7198
+ normalizedCount += 1;
7199
+ return {
7200
+ type: "message",
7201
+ role: "user",
7202
+ content: agentMessage.content.filter((part) => part.type !== "encrypted_content")
7203
+ };
7204
+ });
7205
+ return normalizedCount;
7206
+ };
7588
7207
  const sanitizeUnsupportedInputFields = (payload) => {
7589
7208
  if (!Array.isArray(payload.input)) return 0;
7590
7209
  let removedFieldCount = 0;
@@ -8512,7 +8131,7 @@ const handleOpenAICompatibleProviderMessages = async (c, options) => {
8512
8131
  };
8513
8132
  const createOpenAICompatiblePayload = (payload, modelConfig, providerConfig) => {
8514
8133
  const openAIPayload = translateToOpenAI(payload, {
8515
- supportPdf: modelConfig?.supportPdf,
8134
+ supportPdf: getProviderModelPdfSupport(payload.model, providerConfig),
8516
8135
  toolContentSupportType: modelConfig?.toolContentSupportType ?? []
8517
8136
  });
8518
8137
  const isDashScopeProvider = isDashScopeAliyunProvider(providerConfig);
@@ -8550,7 +8169,7 @@ const applyMiMoThinking = (payload, source) => {
8550
8169
  if (shouldEnableThinking) payload.thinking = { type: "enabled" };
8551
8170
  };
8552
8171
  const normalizeOpenAICompatibleReasoningContent = (payload, options) => {
8553
- const reasoningField = options.modelConfig?.reasoningField ?? builtinProviderModelRegistry.getModelConfig(options.providerConfig.name, payload.model)?.reasoningField ?? "reasoning_content";
8172
+ const reasoningField = options.modelConfig?.reasoningField ?? getProviderModelConfig(options.providerConfig.name, payload.model, options.providerConfig)?.reasoningField ?? "reasoning_content";
8554
8173
  for (const message of payload.messages) {
8555
8174
  if (message.role !== "assistant") continue;
8556
8175
  const reasoningText = message.reasoning_text ?? message.reasoning_content ?? message.reasoning;
@@ -8890,7 +8509,9 @@ const allowedAnthropicBetas = /* @__PURE__ */ new Set([
8890
8509
  INTERLEAVED_THINKING_BETA,
8891
8510
  "context-management-2025-06-27",
8892
8511
  "advanced-tool-use-2025-11-20",
8893
- "extended-cache-ttl-2025-04-11"
8512
+ "extended-cache-ttl-2025-04-11",
8513
+ "mid-conversation-output-config-2026-07-01",
8514
+ "per-turn-control-2026-07-01"
8894
8515
  ]);
8895
8516
  const buildAnthropicBetaHeader = (anthropicBetaHeader, thinking, _model) => {
8896
8517
  const isAdaptiveThinking = thinking?.type === "adaptive";
@@ -8955,6 +8576,10 @@ const messagesApiFlowDependencies = {
8955
8576
  const handleWithChatCompletions = async (c, anthropicPayload, options) => {
8956
8577
  const { logger, selectedModel, subagentMarker, requestId, sessionId, compactType } = options;
8957
8578
  const openAIPayload = translateToOpenAI(anthropicPayload, {
8579
+ supportPdf: getProviderModelPdfSupport(anthropicPayload.model, {
8580
+ ...getRawProviderConfig(GITHUB_COPILOT_PROVIDER),
8581
+ name: GITHUB_COPILOT_PROVIDER
8582
+ }, selectedModel),
8958
8583
  validateReasoningEffort: true,
8959
8584
  reasoningEffortSupport: selectedModel?.capabilities.supports.reasoning_effort
8960
8585
  });
@@ -9418,11 +9043,27 @@ const EPOCH_ISO = (/* @__PURE__ */ new Date(0)).toISOString();
9418
9043
  function isRecord(value) {
9419
9044
  return typeof value === "object" && value !== null && !Array.isArray(value);
9420
9045
  }
9046
+ function firstPositiveInteger(...values) {
9047
+ for (const value of values) if (typeof value === "number" && Number.isFinite(value) && value >= 1) return Math.floor(value);
9048
+ }
9049
+ function normalizeModelCapabilities(model) {
9050
+ if (!isRecord(model.capabilities)) return model;
9051
+ const limits = getRecordField(model.capabilities, "limits");
9052
+ const supports = getRecordField(model.capabilities, "supports");
9053
+ return {
9054
+ context_window: firstPositiveInteger(limits?.max_context_window_tokens, limits?.max_prompt_tokens),
9055
+ max_output_tokens: limits?.max_output_tokens,
9056
+ input_limit: limits?.max_prompt_tokens,
9057
+ input_modalities: typeof supports?.vision === "boolean" ? ["text", ...supports.vision ? ["image"] : []] : void 0,
9058
+ reasoning_efforts: supports?.reasoning_effort,
9059
+ ...model
9060
+ };
9061
+ }
9421
9062
  function normalizeCopilotModel(model) {
9422
9063
  const clientId = toClientModelId(model.id);
9423
9064
  return {
9424
9065
  claude_model_id: `${clientId}[1m]`,
9425
- ...withModelDisplayName(model, GITHUB_COPILOT_PROVIDER),
9066
+ ...withModelDisplayName(normalizeModelCapabilities(model), GITHUB_COPILOT_PROVIDER),
9426
9067
  id: clientId,
9427
9068
  object: "model",
9428
9069
  type: "model",
@@ -9439,15 +9080,13 @@ function getRecordField(model, field) {
9439
9080
  const value = model?.[field];
9440
9081
  return isRecord(value) ? value : void 0;
9441
9082
  }
9442
- function getFirstPositiveNumber(model, fields) {
9443
- if (!model) return void 0;
9444
- for (const field of fields) {
9445
- const value = model[field];
9446
- if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
9447
- }
9083
+ function getStringList(value) {
9084
+ if (!Array.isArray(value)) return void 0;
9085
+ const strings = [...new Set(value.filter((item) => typeof item === "string"))];
9086
+ return strings.length > 0 ? strings : void 0;
9448
9087
  }
9449
9088
  function getFallbackProviderModelRecords(provider, reason, details = {}) {
9450
- const fallbackModels = getBuiltinProviderModelRecords(provider);
9089
+ const fallbackModels = getLocalProviderModelRecords(provider, getRawProviderConfig(provider)) ?? getBuiltinProviderModelRecords(provider);
9451
9090
  logger$9.warn(`models.provider.fallback_${reason}`, {
9452
9091
  provider,
9453
9092
  ...details,
@@ -9455,10 +9094,10 @@ function getFallbackProviderModelRecords(provider, reason, details = {}) {
9455
9094
  });
9456
9095
  return fallbackModels;
9457
9096
  }
9458
- function normalizeProviderModel(provider, model) {
9097
+ function normalizeProviderModel(provider, model, config) {
9459
9098
  if (!isRecord(model)) return null;
9460
9099
  const rawId = getStringField(model, "id");
9461
- if (!rawId) return null;
9100
+ if (!rawId || !isProviderModelVisible(provider, rawId, config)) return null;
9462
9101
  const id = `${provider}/${rawId}`;
9463
9102
  const ownedBy = getStringField(model, "owned_by") ?? getStringField(model, "vendor") ?? provider;
9464
9103
  return {
@@ -9471,18 +9110,18 @@ function normalizeProviderModel(provider, model) {
9471
9110
  owned_by: ownedBy
9472
9111
  };
9473
9112
  }
9474
- function normalizeProviderModels(provider, models) {
9475
- return models.map((model) => normalizeProviderModel(provider, model)).filter((model) => model !== null);
9113
+ function normalizeProviderModels(provider, models, config) {
9114
+ return models.map((model) => normalizeProviderModel(provider, model, config)).filter((model) => model !== null);
9476
9115
  }
9477
9116
  async function getProviderModelRecords(providerConfig, requestHeaders) {
9478
- if (providerConfig.name === "opencode-go") return getOpencodeGoModelRecords();
9479
- if (providerConfig.name === "xai" && providerConfig.authType === "oauth2") return getBuiltinProviderModelRecords("xai");
9117
+ const localModels = getLocalProviderModelRecords(providerConfig.name, providerConfig);
9118
+ if (localModels !== void 0) return localModels;
9480
9119
  try {
9481
9120
  const response = await forwardProviderModels(providerConfig, requestHeaders);
9482
9121
  if (!response.ok) return getFallbackProviderModelRecords(providerConfig.name, "non_ok", { statusCode: response.status });
9483
9122
  const body = await response.json();
9484
9123
  if (!isRecord(body) || !Array.isArray(body.data)) return getFallbackProviderModelRecords(providerConfig.name, "invalid_body");
9485
- return body.data.filter(isRecord);
9124
+ return body.data.filter(isRecord).map(normalizeModelCapabilities);
9486
9125
  } catch (error) {
9487
9126
  return getFallbackProviderModelRecords(providerConfig.name, "error", { error });
9488
9127
  }
@@ -9510,8 +9149,8 @@ async function getProviderModels(provider, requestHeaders, selectModels) {
9510
9149
  try {
9511
9150
  const providerConfig = await resolveProviderConfig(provider);
9512
9151
  if (!providerConfig) return [];
9513
- const models = providerConfig.name === "codex" ? getModels().data : await getProviderModelRecords(providerConfig, requestHeaders);
9514
- return normalizeProviderModels(providerConfig.name, selectModels?.(providerConfig, models) ?? models);
9152
+ const models = providerConfig.name === "codex" ? getModels().data.map(normalizeModelCapabilities) : await getProviderModelRecords(providerConfig, requestHeaders);
9153
+ return normalizeProviderModels(providerConfig.name, selectModels?.(providerConfig, models) ?? models, providerConfig);
9515
9154
  } catch (error) {
9516
9155
  if (provider === "codex") {
9517
9156
  logger$9.warn("models.provider.skip_error", {
@@ -9521,7 +9160,8 @@ async function getProviderModels(provider, requestHeaders, selectModels) {
9521
9160
  return [];
9522
9161
  }
9523
9162
  const fallbackModels = getFallbackProviderModelRecords(provider, "error", { error });
9524
- return normalizeProviderModels(provider, selectModels?.(getRawProviderConfig(provider), fallbackModels) ?? fallbackModels);
9163
+ const providerConfig = getRawProviderConfig(provider);
9164
+ return normalizeProviderModels(provider, selectModels?.(providerConfig, fallbackModels) ?? fallbackModels, providerConfig);
9525
9165
  }
9526
9166
  }
9527
9167
  async function getAggregatedModels(requestHeaders, selectors = {}) {
@@ -9629,6 +9269,53 @@ function serializeCodexModelCatalog(response, options) {
9629
9269
  });
9630
9270
  }
9631
9271
  //#endregion
9272
+ //#region src/routes/models/model-metadata.ts
9273
+ function normalizeMetadata(fields) {
9274
+ const contextWindow = firstPositiveInteger(fields?.contextWindow);
9275
+ const maxOutputTokens = firstPositiveInteger(fields?.maxOutputTokens);
9276
+ const inputModalities = getStringList(fields?.inputModalities);
9277
+ const reasoningEfforts = getStringList(fields?.reasoningEfforts);
9278
+ return {
9279
+ ...contextWindow && { contextWindow },
9280
+ ...maxOutputTokens && { maxOutputTokens },
9281
+ ...inputModalities && { inputModalities },
9282
+ ...reasoningEfforts && { reasoningEfforts },
9283
+ ...fields?.defaultReasoningEffort && { defaultReasoningEffort: fields.defaultReasoningEffort }
9284
+ };
9285
+ }
9286
+ function getModelMetadata(provider, modelId, model, config) {
9287
+ const clientId = getStringField(model, "id") ?? modelId;
9288
+ const modelConfig = config?.models?.[modelId] ?? config?.models?.[clientId];
9289
+ const catalogProvider = resolveProviderModelsDevId(provider, config);
9290
+ const catalog = getModelsDevModel(catalogProvider, modelId) ?? getModelsDevModel(catalogProvider, clientId);
9291
+ const defaults = getProviderModelConfig(provider, modelId, config) ?? getProviderModelConfig(provider, clientId, config);
9292
+ const capabilities = getRecordField(model, "capabilities");
9293
+ const supports = getRecordField(capabilities, "supports");
9294
+ const limits = getRecordField(capabilities, "limits");
9295
+ const metadata = {
9296
+ ...defaults,
9297
+ ...normalizeMetadata({
9298
+ contextWindow: model.context_window,
9299
+ maxOutputTokens: model.max_output_tokens,
9300
+ inputModalities: model.input_modalities,
9301
+ reasoningEfforts: model.reasoning_efforts
9302
+ }),
9303
+ ...normalizeMetadata(modelConfig)
9304
+ };
9305
+ return {
9306
+ modelConfig,
9307
+ catalog,
9308
+ defaults,
9309
+ capabilities,
9310
+ supports,
9311
+ limits,
9312
+ ...metadata,
9313
+ inputLimit: firstPositiveInteger(model.input_limit, catalog?.limit?.input),
9314
+ inputModalities: metadata.inputModalities ?? ["text"],
9315
+ reasoningEfforts: metadata.reasoningEfforts ?? []
9316
+ };
9317
+ }
9318
+ //#endregion
9632
9319
  //#region src/routes/models/codex-model-candidates.ts
9633
9320
  const logger$8 = createHandlerLogger("models-handler");
9634
9321
  const RESPONSES_ENDPOINTS = /* @__PURE__ */ new Set(["/responses", "ws:/responses"]);
@@ -9690,14 +9377,14 @@ async function getProviderCodexCandidates(provider, requestHeaders) {
9690
9377
  try {
9691
9378
  const providerConfig = await resolveProviderConfig(provider);
9692
9379
  if (!providerConfig || providerConfig.name === "codex") return [];
9693
- const remoteById = getModelsById(await getProviderModelRecords(providerConfig, requestHeaders));
9694
- const modelIds = /* @__PURE__ */ new Set([...remoteById.keys(), ...providerConfig.name === "xai" && providerConfig.authType === "oauth2" ? [] : Object.keys(providerConfig.models ?? {})]);
9380
+ const modelsById = getModelsById(await getProviderModelRecords(providerConfig, requestHeaders));
9381
+ const modelIds = /* @__PURE__ */ new Set([...modelsById.keys(), ...Object.keys(providerConfig.models ?? {})]);
9695
9382
  const candidates = [];
9696
9383
  for (const modelId of modelIds) {
9384
+ if (!isProviderModelVisible(provider, modelId, providerConfig)) continue;
9697
9385
  const effectiveType = resolveEffectiveProviderType(providerConfig, modelId);
9698
9386
  if (!isMessagesFallbackProviderType(effectiveType) && effectiveType !== "openai-responses") continue;
9699
- const modelConfig = providerConfig.models?.[modelId];
9700
- candidates.push(createProviderCodexCandidate(providerConfig, modelId, remoteById.get(modelId), modelConfig, effectiveType));
9387
+ candidates.push(createProviderCodexCandidate(providerConfig, modelId, modelsById.get(modelId), effectiveType));
9701
9388
  }
9702
9389
  return candidates;
9703
9390
  } catch (error) {
@@ -9716,15 +9403,9 @@ function describeProviderAdapter(type) {
9716
9403
  if (type === "openai-responses") return "Messages-to-Responses";
9717
9404
  return "Messages-to-Chat";
9718
9405
  }
9719
- function createProviderCodexCandidate(providerConfig, modelId, remoteModel, modelConfig, effectiveType) {
9720
- const builtinModelConfig = builtinProviderModelRegistry.getModelConfig(providerConfig.name, modelId);
9721
- const configuredReasoningEfforts = normalizeReasoningEfforts(modelConfig?.reasoningEfforts);
9722
- const remoteReasoningEfforts = normalizeRemoteReasoningEfforts(remoteModel);
9723
- const builtinReasoningEfforts = normalizeReasoningEfforts(builtinModelConfig?.reasoningEfforts);
9724
- const reasoningEfforts = configuredReasoningEfforts.length > 0 ? configuredReasoningEfforts : remoteReasoningEfforts.length > 0 ? remoteReasoningEfforts : builtinReasoningEfforts;
9725
- const configuredModalities = normalizeInputModalities(modelConfig?.inputModalities);
9726
- const remoteModalities = normalizeInputModalities(remoteModel?.input_modalities ?? remoteModel?.modalities ?? getRecordField(remoteModel, "architecture")?.input_modalities);
9727
- const builtinModalities = normalizeInputModalities(builtinModelConfig?.inputModalities);
9406
+ function createProviderCodexCandidate(providerConfig, modelId, remoteModel, effectiveType) {
9407
+ const metadata = getModelMetadata(providerConfig.name, modelId, remoteModel ?? {}, providerConfig);
9408
+ const reasoningEfforts = normalizeReasoningEfforts(metadata.reasoningEfforts);
9728
9409
  const displayName = getStringField(remoteModel ?? {}, "display_name") ?? getStringField(remoteModel ?? {}, "name") ?? modelId;
9729
9410
  const adapterName = describeProviderAdapter(effectiveType);
9730
9411
  const requiresCatalogMatch = effectiveType === "openai-responses" && modelId.startsWith("gpt");
@@ -9735,41 +9416,20 @@ function createProviderCodexCandidate(providerConfig, modelId, remoteModel, mode
9735
9416
  providerName: providerConfig.name,
9736
9417
  displayName: `${displayName} (${providerConfig.name})`,
9737
9418
  description: `${displayName} through the ${providerConfig.name} ${adapterName} adapter.`,
9738
- contextWindow: positiveNumber(modelConfig?.contextWindow ?? getFirstPositiveNumber(remoteModel, [
9739
- "context_window",
9740
- "context_length",
9741
- "max_context_length",
9742
- "max_model_len"
9743
- ]) ?? builtinModelConfig?.contextWindow, 256e3),
9744
- maxOutputTokens: positiveNumber(modelConfig?.maxOutputTokens ?? getFirstPositiveNumber(remoteModel, ["max_output_tokens"]) ?? getModelsDevModelMaxOutputTokens(providerConfig.modelsDevProviderId || providerConfig.name, modelId) ?? builtinModelConfig?.maxOutputTokens, 32e3),
9745
- inputModalities: resolveInputModalities(providerConfig.name, configuredModalities, remoteModalities, builtinModalities),
9419
+ contextWindow: metadata.contextWindow ?? 256e3,
9420
+ maxOutputTokens: metadata.maxOutputTokens ?? 32e3,
9421
+ inputModalities: normalizeInputModalities(metadata.inputModalities),
9746
9422
  reasoningEfforts,
9747
- defaultReasoningEffort: selectDefaultReasoningEffort(reasoningEfforts, modelConfig?.defaultReasoningEffort ?? builtinModelConfig?.defaultReasoningEffort)
9423
+ defaultReasoningEffort: selectDefaultReasoningEffort(reasoningEfforts, metadata.defaultReasoningEffort)
9748
9424
  };
9749
9425
  }
9750
- function normalizeRemoteReasoningEfforts(model) {
9751
- if (!model) return [];
9752
- const value = model.reasoning_efforts ?? model.supported_reasoning_levels;
9753
- if (!Array.isArray(value)) return [];
9754
- return normalizeReasoningEfforts(value.map((entry) => isRecord(entry) && typeof entry.effort === "string" ? entry.effort : entry));
9755
- }
9756
9426
  function normalizeReasoningEfforts(value) {
9757
9427
  if (!Array.isArray(value)) return [];
9758
9428
  return [...new Set(value.filter((effort) => typeof effort === "string" && CODEX_REASONING_EFFORTS.has(effort)))];
9759
9429
  }
9760
9430
  function normalizeInputModalities(value) {
9761
- if (!Array.isArray(value)) return [];
9762
- return [...new Set(value.filter((modality) => modality === "text" || modality === "image"))];
9763
- }
9764
- function fallbackModalities(remoteModalities, builtinModalities) {
9765
- if (remoteModalities.length > 0) return remoteModalities;
9766
- return builtinModalities.length > 0 ? builtinModalities : ["text"];
9767
- }
9768
- function resolveInputModalities(providerName, configuredModalities, remoteModalities, builtinModalities) {
9769
- if (configuredModalities.length > 0) return configuredModalities;
9770
- const modalities = fallbackModalities(remoteModalities, builtinModalities);
9771
- if (providerName === "kimi") return [.../* @__PURE__ */ new Set([...modalities, "image"])];
9772
- return modalities;
9431
+ const modalities = [...new Set(value.filter((modality) => modality === "text" || modality === "image"))];
9432
+ return modalities.length > 0 ? modalities : ["text"];
9773
9433
  }
9774
9434
  function selectDefaultReasoningEffort(efforts, configured) {
9775
9435
  if (configured && efforts.includes(configured)) return configured;
@@ -11609,15 +11269,6 @@ function mapConfiguredCost(pricing, rate) {
11609
11269
  size: (tiers[index - 1].maxInputTokens ?? 0) + 1
11610
11270
  } : void 0));
11611
11271
  }
11612
- function positiveInteger(...values) {
11613
- const value = values.find((value) => typeof value === "number" && Number.isFinite(value) && value >= 1);
11614
- return Math.floor(value ?? 0);
11615
- }
11616
- function stringList(value) {
11617
- if (!Array.isArray(value)) return void 0;
11618
- const strings = [...new Set(value.filter((item) => typeof item === "string"))];
11619
- return strings.length > 0 ? strings : void 0;
11620
- }
11621
11272
  const RESPONSES_EFFORTS = /* @__PURE__ */ new Set([
11622
11273
  "none",
11623
11274
  "minimal",
@@ -11631,45 +11282,28 @@ function normalizeEffortValues(values) {
11631
11282
  const efforts = (values ?? []).filter((value) => RESPONSES_EFFORTS.has(value));
11632
11283
  return [...new Set(efforts)];
11633
11284
  }
11634
- function catalogEffortValues(catalog) {
11635
- const options = catalog?.reasoning_options;
11636
- if (!Array.isArray(options)) return void 0;
11637
- const values = [];
11638
- for (const option of options) {
11639
- if (!isRecord(option) || option.type !== "effort") continue;
11640
- const optionValues = option.values;
11641
- if (!Array.isArray(optionValues)) continue;
11642
- for (const value of optionValues) if (typeof value === "string") values.push(value);
11643
- }
11644
- return stringList(values);
11645
- }
11646
11285
  function toOpencodeModel(model, contextWindow) {
11647
11286
  const separator = model.id.indexOf("/");
11648
11287
  const provider = separator < 0 ? GITHUB_COPILOT_PROVIDER : model.id.slice(0, separator);
11649
11288
  const rawId = separator < 0 ? findEndpointModel(model.id)?.id ?? model.id : model.id.slice(separator + 1);
11650
11289
  const config = getRawProviderConfig(provider);
11651
- const modelConfig = config?.models?.[rawId] ?? config?.models?.[model.id];
11652
- const builtin = builtinProviderModelRegistry.getModelConfig(provider, rawId);
11653
- const catalogProvider = config?.modelsDevProviderId || provider;
11654
- const catalog = getModelsDevModel(catalogProvider, rawId) ?? getModelsDevModel(catalogProvider, model.id);
11655
- const capabilities = getRecordField(model, "capabilities");
11656
- const supports = getRecordField(capabilities, "supports");
11657
- const limits = getRecordField(capabilities, "limits");
11658
- const context = positiveInteger(modelConfig?.contextWindow, getFirstPositiveNumber(limits, ["max_context_window_tokens", "max_prompt_tokens"]), getFirstPositiveNumber(model, [
11659
- "context_window",
11660
- "context_length",
11661
- "max_context_length",
11662
- "max_model_len"
11663
- ]), catalog?.limit?.context, builtin?.contextWindow, 2e5);
11664
- const inputLimit = positiveInteger(getFirstPositiveNumber(limits, ["max_prompt_tokens"]), catalog?.limit?.input);
11665
- const supportedMediaTypes = stringList(getRecordField(limits, "vision")?.supported_media_types);
11666
- const supportPdf = modelConfig?.supportPdf ?? (provider === "codex" || provider === "xai" || provider === "github-copilot" && supportedMediaTypes?.includes("application/pdf") === true || stringList(catalog?.modalities?.input)?.includes("pdf") === true);
11667
- const input = [...stringList(modelConfig?.inputModalities) ?? stringList(model.input_modalities ?? getRecordField(model, "modalities")?.input ?? model.modalities ?? getRecordField(model, "architecture")?.input_modalities) ?? (typeof supports?.vision === "boolean" ? ["text", ...supports.vision ? ["image"] : []] : void 0) ?? catalog?.modalities?.input ?? builtin?.inputModalities ?? ["text"]].filter((modality) => modality !== "pdf" || supportPdf);
11290
+ const metadata = getModelMetadata(provider, rawId, model, config);
11291
+ const { modelConfig, defaults, catalog, capabilities, supports, limits } = metadata;
11292
+ const context = metadata.contextWindow ?? 256e3;
11293
+ const inputLimit = metadata.inputLimit ?? 0;
11294
+ const supportedMediaTypes = getStringList(getRecordField(limits, "vision")?.supported_media_types);
11295
+ const supportPdf = resolveModelPdfSupport(provider, {
11296
+ supportPdf: modelConfig?.supportPdf,
11297
+ supportedMediaTypes,
11298
+ catalogInputModalities: catalog?.modalities?.input,
11299
+ builtinSupportPdf: defaults?.supportPdf ?? builtinProviderModelRegistry.getProviderDefaults(provider)?.supportPdf
11300
+ });
11301
+ const input = metadata.inputModalities.filter((modality) => modality !== "pdf" || supportPdf);
11668
11302
  if (supportPdf && !input.includes("pdf")) input.push("pdf");
11669
- const efforts = normalizeEffortValues(stringList(modelConfig?.reasoningEfforts ?? model.reasoning_efforts ?? supports?.reasoning_effort) ?? catalogEffortValues(catalog) ?? builtin?.reasoningEfforts);
11303
+ const efforts = normalizeEffortValues(metadata.reasoningEfforts);
11670
11304
  const configuredRate = resolveUsdRate(resolveProviderCurrency(provider, config?.pricingCurrency));
11671
11305
  const builtinRate = resolveUsdRate(resolveProviderCurrency(provider, void 0));
11672
- const cost = modelConfig?.pricing && configuredRate !== void 0 ? mapConfiguredCost(modelConfig.pricing, configuredRate) : catalog?.cost ? mapCatalogCost(catalog.cost) : builtin?.pricing && builtinRate !== void 0 ? mapConfiguredCost(builtin.pricing, builtinRate) : [];
11306
+ const cost = modelConfig?.pricing && configuredRate !== void 0 ? mapConfiguredCost(modelConfig.pricing, configuredRate) : catalog?.cost ? mapCatalogCost(catalog.cost) : defaults?.pricing && builtinRate !== void 0 ? mapConfiguredCost(defaults.pricing, builtinRate) : [];
11673
11307
  const released = Date.parse(catalog?.release_date ?? "");
11674
11308
  return {
11675
11309
  id: model.id,
@@ -11694,7 +11328,7 @@ function toOpencodeModel(model, contextWindow) {
11694
11328
  limit: {
11695
11329
  context: Math.min(context, contextWindow),
11696
11330
  ...inputLimit > 0 && { input: Math.min(inputLimit, context, contextWindow) },
11697
- output: Math.min(context, positiveInteger(modelConfig?.maxOutputTokens, getFirstPositiveNumber(limits, ["max_output_tokens"]), getFirstPositiveNumber(model, ["max_output_tokens"]), catalog?.limit?.output, builtin?.maxOutputTokens, 32e3))
11331
+ output: Math.min(context, metadata.maxOutputTokens ?? 32e3)
11698
11332
  }
11699
11333
  };
11700
11334
  }
@@ -11822,23 +11456,18 @@ providerModelRoutes.get("/", async (c) => {
11822
11456
  has_more: false
11823
11457
  });
11824
11458
  }
11825
- if (providerConfig.name === "opencode-go") {
11826
- const models = getOpencodeGoModelRecords();
11827
- if (models.length === 0) return c.json({ error: {
11828
- message: "OpenCode Go model catalog is unavailable",
11459
+ const localModels = getLocalProviderModelRecords(providerConfig.name, providerConfig);
11460
+ if (localModels !== void 0) {
11461
+ if (localModels.length === 0) return c.json({ error: {
11462
+ message: `${providerConfig.name} model catalog is unavailable`,
11829
11463
  type: "service_unavailable"
11830
11464
  } }, 503);
11831
11465
  return c.json({
11832
11466
  object: "list",
11833
- data: models.map((model) => withModelDisplayName(model, providerConfig.name)),
11467
+ data: localModels.map((model) => withModelDisplayName(model, providerConfig.name)),
11834
11468
  has_more: false
11835
11469
  });
11836
11470
  }
11837
- if (providerConfig.name === "xai" && providerConfig.authType === "oauth2") return c.json({
11838
- object: "list",
11839
- data: getBuiltinProviderModelRecords("xai").map((model) => withModelDisplayName(model, providerConfig.name)),
11840
- has_more: false
11841
- });
11842
11471
  const upstreamResponse = await forwardProviderModels(providerConfig, c.req.raw.headers);
11843
11472
  logger$4.debug("provider.models.response", {
11844
11473
  provider,
@@ -13096,6 +12725,8 @@ const handleResponses = async (c) => {
13096
12725
  fallbackSessionId,
13097
12726
  model: payload.model
13098
12727
  });
12728
+ const normalizedAgentMessageCount = normalizeGuardianAgentMessages(payload);
12729
+ if (normalizedAgentMessageCount > 0) logger$1.debug(`Translated ${normalizedAgentMessageCount} Guardian agent message(s) to user messages before forwarding to Copilot Responses`);
13099
12730
  const sanitizedUnsupportedFieldCount = sanitizeUnsupportedInputFields(payload);
13100
12731
  if (sanitizedUnsupportedFieldCount > 0) logger$1.debug(`Removed ${sanitizedUnsupportedFieldCount} unsupported input field(s) before forwarding to Copilot Responses`);
13101
12732
  const normalizedImageDetailCount = normalizeInputImageDetails(payload);
@@ -13372,4 +13003,4 @@ createServer();
13372
13003
  //#endregion
13373
13004
  export { createServer };
13374
13005
 
13375
- //# sourceMappingURL=server-1fLM5e0J.js.map
13006
+ //# sourceMappingURL=server-DBfAMzVE.js.map