replicas-engine 0.1.874 → 0.1.876

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.
@@ -5,11 +5,11 @@ import {
5
5
  getCodexAspHost,
6
6
  restartCodexAspHost,
7
7
  restartCodexAspHostIfRunning
8
- } from "./chunk-3NTL5GI6.js";
9
- import "./chunk-CZLOYOGI.js";
10
- import "./chunk-UO4OL7D2.js";
8
+ } from "./chunk-QUDJR3YI.js";
9
+ import "./chunk-VONPE7H2.js";
10
+ import "./chunk-LDEEMUMD.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-OJTGCTIK.js";
12
+ import "./chunk-DFV4EYJI.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
  export {
15
15
  getCodexAspHost,
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  monolithRequest
6
- } from "./chunk-CZLOYOGI.js";
6
+ } from "./chunk-VONPE7H2.js";
7
7
  import {
8
8
  extractCommandProtectionCommandText,
9
9
  findGitCommitSignals,
10
10
  findPrMergeSignals
11
- } from "./chunk-OJTGCTIK.js";
11
+ } from "./chunk-DFV4EYJI.js";
12
12
 
13
13
  // src/services/command-protection-service.ts
14
14
  var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
@@ -277,6 +277,8 @@ var FALLBACK_AGENT_MODEL = {
277
277
  relay: DEFAULT_CLAUDE_MODEL
278
278
  };
279
279
  function getDefaultAgentModel(provider, overrides) {
280
+ const catalogDefault = overrides?.defaultModels?.[provider];
281
+ if (catalogDefault !== void 0) return catalogDefault ?? "";
280
282
  const fallback = FALLBACK_AGENT_MODEL[provider];
281
283
  const options = getAgentModelOptions(provider, overrides);
282
284
  return options.includes(fallback) ? fallback : options[0];
@@ -544,124 +546,6 @@ function paginateEngineLogContent(input) {
544
546
  // ../shared/src/analytics/types.ts
545
547
  import { z as z2 } from "zod";
546
548
 
547
- // ../shared/src/credentials/types.ts
548
- var CREDENTIAL_SCOPE = {
549
- USER: "user",
550
- ORG: "org"
551
- };
552
- var CREDENTIAL_SCOPES = Object.values(CREDENTIAL_SCOPE);
553
- var CREDENTIAL_SCOPE_PRIORITY = [CREDENTIAL_SCOPE.USER, CREDENTIAL_SCOPE.ORG];
554
-
555
- // ../shared/src/credentials/agents.ts
556
- var CREDENTIAL_METHOD = {
557
- OAUTH: "oauth",
558
- API_KEY: "api_key",
559
- OPENAI_COMPATIBLE: "openai-compatible",
560
- FOUNDRY: "foundry",
561
- BEDROCK: "bedrock",
562
- OPENCODE_GO: "opencode-go",
563
- ASTER: "aster",
564
- OPENROUTER: "openrouter",
565
- AI_GATEWAY: "ai-gateway",
566
- MUSE_OAUTH: "muse-oauth"
567
- };
568
- var CREDENTIAL_TYPE = {
569
- CLAUDE_OAUTH: "claude",
570
- ANTHROPIC_API_KEY: "claude_anthropic_api_key",
571
- CLAUDE_FOUNDRY: "claude_foundry",
572
- CLAUDE_BEDROCK: "claude_bedrock",
573
- CODEX_OAUTH: "codex",
574
- OPENAI_API_KEY: "openai_api_key",
575
- OPENAI_COMPATIBLE: "openai_compatible",
576
- CODEX_FOUNDRY: "codex_foundry",
577
- CURSOR_API_KEY: "cursor_api_key",
578
- OPENCODE_GO_API_KEY: "opencode_go_api_key",
579
- ASTER_API_KEY: "aster_api_key",
580
- OPENROUTER_API_KEY: "openrouter_api_key",
581
- AI_GATEWAY_API_KEY: "ai_gateway_api_key",
582
- GEMINI_API_KEY: "gemini_api_key",
583
- MUSE_OAUTH: "muse_oauth",
584
- MUSE_API_KEY: "muse_api_key"
585
- };
586
- var INFERENCE_PROVIDER_LABELS = {
587
- [CREDENTIAL_METHOD.OPENCODE_GO]: "OpenCode Go",
588
- [CREDENTIAL_METHOD.ASTER]: "Aster",
589
- [CREDENTIAL_METHOD.OPENROUTER]: "OpenRouter"
590
- };
591
- var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
592
- [AGENT.CLAUDE]: [
593
- { method: CREDENTIAL_METHOD.OAUTH, credentialType: CREDENTIAL_TYPE.CLAUDE_OAUTH },
594
- { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.ANTHROPIC_API_KEY },
595
- { method: CREDENTIAL_METHOD.FOUNDRY, credentialType: CREDENTIAL_TYPE.CLAUDE_FOUNDRY },
596
- { method: CREDENTIAL_METHOD.BEDROCK, credentialType: CREDENTIAL_TYPE.CLAUDE_BEDROCK }
597
- ],
598
- [AGENT.CODEX]: [
599
- { method: CREDENTIAL_METHOD.OAUTH, credentialType: CREDENTIAL_TYPE.CODEX_OAUTH },
600
- { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.OPENAI_API_KEY },
601
- { method: CREDENTIAL_METHOD.OPENAI_COMPATIBLE, credentialType: CREDENTIAL_TYPE.OPENAI_COMPATIBLE },
602
- { method: CREDENTIAL_METHOD.FOUNDRY, credentialType: CREDENTIAL_TYPE.CODEX_FOUNDRY }
603
- ],
604
- [AGENT.CURSOR]: [
605
- { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.CURSOR_API_KEY }
606
- ],
607
- [AGENT.DEEPSEEK]: [
608
- { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY }
609
- ],
610
- [AGENT.FX]: [
611
- { method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY }
612
- ],
613
- [AGENT.GEMINI]: [
614
- { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.GEMINI_API_KEY }
615
- ],
616
- [AGENT.KIMI]: [
617
- { method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY }
618
- ],
619
- [AGENT.MUSE]: [
620
- { method: CREDENTIAL_METHOD.MUSE_OAUTH, credentialType: CREDENTIAL_TYPE.MUSE_OAUTH },
621
- { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.MUSE_API_KEY }
622
- ],
623
- [AGENT.OPENCODE]: [
624
- { method: CREDENTIAL_METHOD.OPENCODE_GO, credentialType: CREDENTIAL_TYPE.OPENCODE_GO_API_KEY },
625
- { method: CREDENTIAL_METHOD.ASTER, credentialType: CREDENTIAL_TYPE.ASTER_API_KEY },
626
- { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY }
627
- ],
628
- [AGENT.PI]: [
629
- { method: CREDENTIAL_METHOD.OPENCODE_GO, credentialType: CREDENTIAL_TYPE.OPENCODE_GO_API_KEY },
630
- { method: CREDENTIAL_METHOD.ASTER, credentialType: CREDENTIAL_TYPE.ASTER_API_KEY },
631
- { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY }
632
- ]
633
- };
634
- function agentCredentialMethods(agent) {
635
- return AGENT_CREDENTIAL_METHODS_IN_ORDER[agent].map((entry) => entry.method);
636
- }
637
- function getCredentialMethodLabel(agent, method) {
638
- switch (method) {
639
- case CREDENTIAL_METHOD.OAUTH:
640
- if (agent === AGENT.CODEX) return "ChatGPT account";
641
- return "Claude account";
642
- case CREDENTIAL_METHOD.API_KEY:
643
- if (agent === AGENT.CODEX) return "OpenAI API key";
644
- if (agent === AGENT.CURSOR) return "Cursor API key";
645
- if (agent === AGENT.GEMINI) return "Gemini API key";
646
- if (agent === AGENT.MUSE) return "Muse API key";
647
- return "Anthropic API key";
648
- case CREDENTIAL_METHOD.OPENAI_COMPATIBLE:
649
- return "OpenAI-compatible endpoint";
650
- case CREDENTIAL_METHOD.FOUNDRY:
651
- return "Microsoft Foundry";
652
- case CREDENTIAL_METHOD.BEDROCK:
653
- return "AWS Bedrock";
654
- case CREDENTIAL_METHOD.OPENCODE_GO:
655
- case CREDENTIAL_METHOD.ASTER:
656
- case CREDENTIAL_METHOD.OPENROUTER:
657
- return INFERENCE_PROVIDER_LABELS[method];
658
- case CREDENTIAL_METHOD.AI_GATEWAY:
659
- return "Vercel AI Gateway";
660
- case CREDENTIAL_METHOD.MUSE_OAUTH:
661
- return "Muse account";
662
- }
663
- }
664
-
665
549
  // ../shared/src/result.ts
666
550
  function createSuccessResult(data) {
667
551
  return { ok: true, data };
@@ -798,6 +682,209 @@ function resolveOpenAICompatibleModelsUrl(values) {
798
682
  return values.modelsUrl || `${values.baseUrl}/models`;
799
683
  }
800
684
 
685
+ // ../shared/src/credentials/ollama.ts
686
+ var OLLAMA_AGENTS = ["claude", "codex", "deepseek", "kimi", "opencode", "pi"];
687
+ function ollamaAuthEnvKeys(agent) {
688
+ return ["API_KEY", "BASE_URL"].map((key) => `REPLICAS_${agent.toUpperCase()}_OLLAMA_${key}`);
689
+ }
690
+ function ollamaAuthEnv(agent, credential) {
691
+ const [key, url] = ollamaAuthEnvKeys(agent);
692
+ return { [key]: credential.apiKey, [url]: credential.baseUrl };
693
+ }
694
+ function readOllamaAuthEnv(agent, env) {
695
+ const [key, url] = ollamaAuthEnvKeys(agent);
696
+ const apiKey = env[key];
697
+ const baseUrl = env[url];
698
+ return apiKey && baseUrl ? { apiKey, baseUrl } : null;
699
+ }
700
+
701
+ // ../shared/src/credentials/ollama-models.ts
702
+ var DEFAULT_OLLAMA_MODEL = "gpt-oss:20b";
703
+ var catalogs = /* @__PURE__ */ new Map();
704
+ function getDefaultOllamaModel(models) {
705
+ return models.find((model) => model.id === DEFAULT_OLLAMA_MODEL && model.capabilities?.includes("tools") && (model.contextWindow ?? 0) >= 64e3)?.id ?? null;
706
+ }
707
+ function parseOllamaModelDetails(model, payload) {
708
+ if (!isRecord(payload)) return model;
709
+ const capabilities = Array.isArray(payload.capabilities) ? payload.capabilities.filter((value) => typeof value === "string") : void 0;
710
+ const info = isRecord(payload.model_info) ? payload.model_info : {};
711
+ const context = Object.entries(info).find(([key]) => key.endsWith(".context_length"))?.[1];
712
+ const configured = typeof payload.parameters === "string" ? /(?:^|\n)\s*num_ctx\s+(\d+)/.exec(payload.parameters)?.[1] : void 0;
713
+ const contextWindow = configured ? Number(configured) : context;
714
+ return {
715
+ ...model,
716
+ ...capabilities ? { capabilities } : {},
717
+ ...typeof contextWindow === "number" && Number.isSafeInteger(contextWindow) && contextWindow > 0 ? { contextWindow } : {}
718
+ };
719
+ }
720
+ function listOllamaModels(credential) {
721
+ const key = JSON.stringify([credential.baseUrl, credential.apiKey]);
722
+ const cached = catalogs.get(key);
723
+ if (cached && cached.expiresAt > Date.now()) return cached.models;
724
+ const models = loadOllamaModels(credential).catch((error) => {
725
+ if (catalogs.get(key)?.models === models) catalogs.delete(key);
726
+ throw error;
727
+ });
728
+ catalogs.set(key, { expiresAt: Date.now() + 6e4, models });
729
+ return models;
730
+ }
731
+ async function loadOllamaModels(credential) {
732
+ const models = await listOpenAICompatibleModels({ apiKey: credential.apiKey, baseUrl: `${credential.baseUrl}/v1` });
733
+ const url = `${credential.baseUrl}/api/show`;
734
+ validateExternalApiHost(url, "Ollama model details");
735
+ const detailed = [];
736
+ const signal = AbortSignal.timeout(1e4);
737
+ for (let offset = 0; offset < models.length; offset += 10) {
738
+ if (signal.aborted) {
739
+ detailed.push(...models.slice(offset));
740
+ break;
741
+ }
742
+ detailed.push(...await Promise.all(models.slice(offset, offset + 10).map(async (model) => {
743
+ try {
744
+ const response = await fetch(url, {
745
+ method: "POST",
746
+ redirect: "error",
747
+ signal,
748
+ headers: { Authorization: `Bearer ${credential.apiKey}`, "Content-Type": "application/json" },
749
+ body: JSON.stringify({ model: model.id })
750
+ });
751
+ return response.ok ? parseOllamaModelDetails(model, await response.json()) : model;
752
+ } catch {
753
+ return model;
754
+ }
755
+ })));
756
+ }
757
+ return detailed.sort((left, right) => left.id.localeCompare(right.id));
758
+ }
759
+
760
+ // ../shared/src/credentials/types.ts
761
+ var CREDENTIAL_SCOPE = {
762
+ USER: "user",
763
+ ORG: "org"
764
+ };
765
+ var CREDENTIAL_SCOPES = Object.values(CREDENTIAL_SCOPE);
766
+ var CREDENTIAL_SCOPE_PRIORITY = [CREDENTIAL_SCOPE.USER, CREDENTIAL_SCOPE.ORG];
767
+
768
+ // ../shared/src/credentials/agents.ts
769
+ var CREDENTIAL_METHOD = {
770
+ OAUTH: "oauth",
771
+ API_KEY: "api_key",
772
+ OPENAI_COMPATIBLE: "openai-compatible",
773
+ OLLAMA: "ollama",
774
+ FOUNDRY: "foundry",
775
+ BEDROCK: "bedrock",
776
+ OPENCODE_GO: "opencode-go",
777
+ ASTER: "aster",
778
+ OPENROUTER: "openrouter",
779
+ AI_GATEWAY: "ai-gateway",
780
+ MUSE_OAUTH: "muse-oauth"
781
+ };
782
+ var CREDENTIAL_TYPE = {
783
+ CLAUDE_OAUTH: "claude",
784
+ ANTHROPIC_API_KEY: "claude_anthropic_api_key",
785
+ CLAUDE_FOUNDRY: "claude_foundry",
786
+ CLAUDE_BEDROCK: "claude_bedrock",
787
+ CODEX_OAUTH: "codex",
788
+ OPENAI_API_KEY: "openai_api_key",
789
+ OPENAI_COMPATIBLE: "openai_compatible",
790
+ OLLAMA: "ollama",
791
+ CODEX_FOUNDRY: "codex_foundry",
792
+ CURSOR_API_KEY: "cursor_api_key",
793
+ OPENCODE_GO_API_KEY: "opencode_go_api_key",
794
+ ASTER_API_KEY: "aster_api_key",
795
+ OPENROUTER_API_KEY: "openrouter_api_key",
796
+ AI_GATEWAY_API_KEY: "ai_gateway_api_key",
797
+ GEMINI_API_KEY: "gemini_api_key",
798
+ MUSE_OAUTH: "muse_oauth",
799
+ MUSE_API_KEY: "muse_api_key"
800
+ };
801
+ var INFERENCE_PROVIDER_LABELS = {
802
+ [CREDENTIAL_METHOD.OLLAMA]: "Ollama",
803
+ [CREDENTIAL_METHOD.OPENCODE_GO]: "OpenCode Go",
804
+ [CREDENTIAL_METHOD.ASTER]: "Aster",
805
+ [CREDENTIAL_METHOD.OPENROUTER]: "OpenRouter"
806
+ };
807
+ var AGENT_CREDENTIAL_METHODS_IN_ORDER = {
808
+ [AGENT.CLAUDE]: [
809
+ { method: CREDENTIAL_METHOD.OAUTH, credentialType: CREDENTIAL_TYPE.CLAUDE_OAUTH },
810
+ { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.ANTHROPIC_API_KEY },
811
+ { method: CREDENTIAL_METHOD.FOUNDRY, credentialType: CREDENTIAL_TYPE.CLAUDE_FOUNDRY },
812
+ { method: CREDENTIAL_METHOD.BEDROCK, credentialType: CREDENTIAL_TYPE.CLAUDE_BEDROCK },
813
+ { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
814
+ ],
815
+ [AGENT.CODEX]: [
816
+ { method: CREDENTIAL_METHOD.OAUTH, credentialType: CREDENTIAL_TYPE.CODEX_OAUTH },
817
+ { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.OPENAI_API_KEY },
818
+ { method: CREDENTIAL_METHOD.OPENAI_COMPATIBLE, credentialType: CREDENTIAL_TYPE.OPENAI_COMPATIBLE },
819
+ { method: CREDENTIAL_METHOD.FOUNDRY, credentialType: CREDENTIAL_TYPE.CODEX_FOUNDRY },
820
+ { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
821
+ ],
822
+ [AGENT.CURSOR]: [
823
+ { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.CURSOR_API_KEY }
824
+ ],
825
+ [AGENT.DEEPSEEK]: [
826
+ { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY },
827
+ { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
828
+ ],
829
+ [AGENT.FX]: [
830
+ { method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY }
831
+ ],
832
+ [AGENT.GEMINI]: [
833
+ { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.GEMINI_API_KEY }
834
+ ],
835
+ [AGENT.KIMI]: [
836
+ { method: CREDENTIAL_METHOD.AI_GATEWAY, credentialType: CREDENTIAL_TYPE.AI_GATEWAY_API_KEY },
837
+ { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
838
+ ],
839
+ [AGENT.MUSE]: [
840
+ { method: CREDENTIAL_METHOD.MUSE_OAUTH, credentialType: CREDENTIAL_TYPE.MUSE_OAUTH },
841
+ { method: CREDENTIAL_METHOD.API_KEY, credentialType: CREDENTIAL_TYPE.MUSE_API_KEY }
842
+ ],
843
+ [AGENT.OPENCODE]: [
844
+ { method: CREDENTIAL_METHOD.OPENCODE_GO, credentialType: CREDENTIAL_TYPE.OPENCODE_GO_API_KEY },
845
+ { method: CREDENTIAL_METHOD.ASTER, credentialType: CREDENTIAL_TYPE.ASTER_API_KEY },
846
+ { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY },
847
+ { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
848
+ ],
849
+ [AGENT.PI]: [
850
+ { method: CREDENTIAL_METHOD.OPENCODE_GO, credentialType: CREDENTIAL_TYPE.OPENCODE_GO_API_KEY },
851
+ { method: CREDENTIAL_METHOD.ASTER, credentialType: CREDENTIAL_TYPE.ASTER_API_KEY },
852
+ { method: CREDENTIAL_METHOD.OPENROUTER, credentialType: CREDENTIAL_TYPE.OPENROUTER_API_KEY },
853
+ { method: CREDENTIAL_METHOD.OLLAMA, credentialType: CREDENTIAL_TYPE.OLLAMA }
854
+ ]
855
+ };
856
+ function agentCredentialMethods(agent) {
857
+ return AGENT_CREDENTIAL_METHODS_IN_ORDER[agent].map((entry) => entry.method);
858
+ }
859
+ function getCredentialMethodLabel(agent, method) {
860
+ switch (method) {
861
+ case CREDENTIAL_METHOD.OAUTH:
862
+ if (agent === AGENT.CODEX) return "ChatGPT account";
863
+ return "Claude account";
864
+ case CREDENTIAL_METHOD.API_KEY:
865
+ if (agent === AGENT.CODEX) return "OpenAI API key";
866
+ if (agent === AGENT.CURSOR) return "Cursor API key";
867
+ if (agent === AGENT.GEMINI) return "Gemini API key";
868
+ if (agent === AGENT.MUSE) return "Muse API key";
869
+ return "Anthropic API key";
870
+ case CREDENTIAL_METHOD.OPENAI_COMPATIBLE:
871
+ return "OpenAI-compatible endpoint";
872
+ case CREDENTIAL_METHOD.FOUNDRY:
873
+ return "Microsoft Foundry";
874
+ case CREDENTIAL_METHOD.BEDROCK:
875
+ return "AWS Bedrock";
876
+ case CREDENTIAL_METHOD.OLLAMA:
877
+ case CREDENTIAL_METHOD.OPENCODE_GO:
878
+ case CREDENTIAL_METHOD.ASTER:
879
+ case CREDENTIAL_METHOD.OPENROUTER:
880
+ return INFERENCE_PROVIDER_LABELS[method];
881
+ case CREDENTIAL_METHOD.AI_GATEWAY:
882
+ return "Vercel AI Gateway";
883
+ case CREDENTIAL_METHOD.MUSE_OAUTH:
884
+ return "Muse account";
885
+ }
886
+ }
887
+
801
888
  // ../shared/src/pricing.ts
802
889
  var WORKSPACE_SOURCES = ["api", "dashboard", "slack", "linear", "github", "gitlab", "automation", "mothership"];
803
890
  var CLIENT_MESSAGE_SOURCES = ["web", "desktop", "mobile", "tui"];
@@ -6948,6 +7035,8 @@ function hasChatStarted(chat) {
6948
7035
 
6949
7036
  // ../shared/src/routes/codex.ts
6950
7037
  var CODEX_AUTH_ENV_KEYS = [
7038
+ "REPLICAS_CODEX_OLLAMA_API_KEY",
7039
+ "REPLICAS_CODEX_OLLAMA_BASE_URL",
6951
7040
  "OPENAI_API_KEY",
6952
7041
  "CODEX_OPENAI_BASE_URL",
6953
7042
  "CODEX_OPENAI_MODELS_URL",
@@ -6968,6 +7057,12 @@ function codexOpenAICompatibleAuthEnv(response) {
6968
7057
  }
6969
7058
  function codexAuthEnvFromResponse(response) {
6970
7059
  switch (response.type) {
7060
+ case "ollama":
7061
+ return {
7062
+ ...codexOpenAICompatibleAuthEnv({ apiKey: response.apiKey, baseUrl: `${response.baseUrl}/v1` }),
7063
+ ...ollamaAuthEnv("codex", response),
7064
+ REPLICAS_CODEX_AUTH_METHOD: "ollama"
7065
+ };
6971
7066
  case "oauth":
6972
7067
  return { REPLICAS_CODEX_AUTH_METHOD: "oauth" };
6973
7068
  case "api_key":
@@ -7003,6 +7098,7 @@ var CODEX_AUTH_ENV_KEYS_BY_METHOD = {
7003
7098
  "CODEX_OPENAI_AUTHORIZATION_HEADER",
7004
7099
  "REPLICAS_CODEX_AUTH_METHOD"
7005
7100
  ],
7101
+ ollama: ["OPENAI_API_KEY", "CODEX_OPENAI_BASE_URL", "REPLICAS_CODEX_AUTH_METHOD", "REPLICAS_CODEX_OLLAMA_API_KEY", "REPLICAS_CODEX_OLLAMA_BASE_URL"],
7006
7102
  bedrock: [],
7007
7103
  foundry: ["AZURE_OPENAI_API_KEY", "CODEX_FOUNDRY_BASE_URL", "CODEX_FOUNDRY_MODEL", "REPLICAS_CODEX_AUTH_METHOD"]
7008
7104
  };
@@ -7010,6 +7106,8 @@ var CODEX_AUTH_ENV_KEYS_BY_METHOD = {
7010
7106
  // ../shared/src/routes/claude.ts
7011
7107
  var CLAUDE_AUTH_ENV_KEYS = [
7012
7108
  "ANTHROPIC_API_KEY",
7109
+ "ANTHROPIC_AUTH_TOKEN",
7110
+ "ANTHROPIC_BASE_URL",
7013
7111
  "CLAUDE_CODE_USE_BEDROCK",
7014
7112
  "AWS_ACCESS_KEY_ID",
7015
7113
  "AWS_SECRET_ACCESS_KEY",
@@ -7025,6 +7123,13 @@ var CLAUDE_AUTH_ENV_KEYS = [
7025
7123
  ];
7026
7124
  function claudeAuthEnvFromResponse(response) {
7027
7125
  switch (response.type) {
7126
+ case "ollama":
7127
+ return {
7128
+ ANTHROPIC_API_KEY: "",
7129
+ ANTHROPIC_AUTH_TOKEN: response.apiKey,
7130
+ ANTHROPIC_BASE_URL: response.baseUrl,
7131
+ REPLICAS_CLAUDE_AUTH_METHOD: "ollama"
7132
+ };
7028
7133
  case "oauth":
7029
7134
  return { REPLICAS_CLAUDE_AUTH_METHOD: "oauth" };
7030
7135
  case "api_key":
@@ -7055,6 +7160,7 @@ var CLAUDE_AUTH_ENV_KEYS_BY_METHOD = {
7055
7160
  oauth: ["REPLICAS_CLAUDE_AUTH_METHOD"],
7056
7161
  api_key: ["ANTHROPIC_API_KEY", "REPLICAS_CLAUDE_AUTH_METHOD"],
7057
7162
  "openai-compatible": [],
7163
+ ollama: ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL", "REPLICAS_CLAUDE_AUTH_METHOD"],
7058
7164
  bedrock: [
7059
7165
  "CLAUDE_CODE_USE_BEDROCK",
7060
7166
  "AWS_ACCESS_KEY_ID",
@@ -7926,10 +8032,15 @@ export {
7926
8032
  codexReasoningEffortForThinkingLevel,
7927
8033
  getProviderDisplayName,
7928
8034
  detectAgentQuotaLimit,
7929
- CREDENTIAL_METHOD,
7930
- AGENT_CREDENTIAL_METHODS_IN_ORDER,
7931
8035
  listOpenAICompatibleModels,
7932
8036
  resolveOpenAICompatibleModelsUrl,
8037
+ OLLAMA_AGENTS,
8038
+ readOllamaAuthEnv,
8039
+ DEFAULT_OLLAMA_MODEL,
8040
+ getDefaultOllamaModel,
8041
+ listOllamaModels,
8042
+ CREDENTIAL_METHOD,
8043
+ AGENT_CREDENTIAL_METHODS_IN_ORDER,
7933
8044
  agentCredentialSnapshotSchema,
7934
8045
  isAgentChatTurnActivityRecord,
7935
8046
  isAgentChatSkillActivityRecord,
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  HOOK_EXEC_MAX_BUFFER_BYTES,
6
6
  isVersionBelow
7
- } from "./chunk-OJTGCTIK.js";
7
+ } from "./chunk-DFV4EYJI.js";
8
8
 
9
9
  // src/utils/codex-agent-env.ts
10
10
  function buildCodexAgentEnv(source = process.env) {
@@ -241,7 +241,11 @@ var DEFAULT_CODEX_ARGS = [
241
241
  var MIN_CODEX_CLI_VERSION = "0.153.3";
242
242
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
243
243
  var codexCliVersionEnsured = null;
244
- var ENGINE_PACKAGE_VERSION = "0.1.874";
244
+ function getCodexModelProvider(method) {
245
+ if (method === "foundry") return "azure";
246
+ return method === "ollama" || method === "openai-compatible" ? "replicas_openai_compatible" : "openai";
247
+ }
248
+ var ENGINE_PACKAGE_VERSION = "0.1.876";
245
249
  var INITIALIZE_METHOD = "initialize";
246
250
  var INITIALIZED_NOTIFICATION = "initialized";
247
251
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -266,7 +270,7 @@ var AppServerProcess = class {
266
270
  "-c",
267
271
  `model=${JSON.stringify(options.env.CODEX_FOUNDRY_MODEL)}`,
268
272
  "-c",
269
- 'model_provider="azure"',
273
+ `model_provider=${JSON.stringify(getCodexModelProvider(options.env.REPLICAS_CODEX_AUTH_METHOD))}`,
270
274
  "-c",
271
275
  'model_providers.azure.name="Azure OpenAI"',
272
276
  "-c",
@@ -276,11 +280,15 @@ var AppServerProcess = class {
276
280
  "-c",
277
281
  'model_providers.azure.wire_api="responses"'
278
282
  ];
279
- } else if (!options.args && options.env.REPLICAS_CODEX_AUTH_METHOD === "openai-compatible") {
283
+ } else if (!options.args && (options.env.REPLICAS_CODEX_AUTH_METHOD === "openai-compatible" || options.env.REPLICAS_CODEX_AUTH_METHOD === "ollama")) {
280
284
  baseArgs = [
281
285
  ...DEFAULT_CODEX_ARGS,
286
+ ...options.env.REPLICAS_CODEX_AUTH_METHOD === "ollama" ? [
287
+ "-c",
288
+ 'web_search="disabled"'
289
+ ] : [],
282
290
  "-c",
283
- 'model_provider="replicas_openai_compatible"',
291
+ `model_provider=${JSON.stringify(getCodexModelProvider(options.env.REPLICAS_CODEX_AUTH_METHOD))}`,
284
292
  "-c",
285
293
  'model_providers.replicas_openai_compatible.name="OpenAI Compatible"',
286
294
  "-c",
@@ -480,5 +488,6 @@ export {
480
488
  execAsync,
481
489
  execFileAsync,
482
490
  SUBPROCESS_MAX_BUFFER,
491
+ getCodexModelProvider,
483
492
  AppServerProcess
484
493
  };
@@ -5,13 +5,13 @@ import {
5
5
  ENGINE_ENV,
6
6
  monolithRequest,
7
7
  setAgentCredentialSnapshot
8
- } from "./chunk-CZLOYOGI.js";
8
+ } from "./chunk-VONPE7H2.js";
9
9
  import {
10
10
  AppServerProcess,
11
11
  SUBPROCESS_MAX_BUFFER,
12
12
  buildCodexAgentEnv,
13
13
  execFileAsync
14
- } from "./chunk-UO4OL7D2.js";
14
+ } from "./chunk-LDEEMUMD.js";
15
15
  import {
16
16
  isRecord
17
17
  } from "./chunk-UZSNFLDQ.js";
@@ -21,9 +21,11 @@ import {
21
21
  codexAuthEnvFromResponse,
22
22
  createErrorResult,
23
23
  createSuccessResult,
24
+ listOllamaModels,
24
25
  listOpenAICompatibleModels,
26
+ readOllamaAuthEnv,
25
27
  resolveOpenAICompatibleModelsUrl
26
- } from "./chunk-OJTGCTIK.js";
28
+ } from "./chunk-DFV4EYJI.js";
27
29
 
28
30
  // src/managers/codex-token-manager.ts
29
31
  import { promises as fs } from "fs";
@@ -244,7 +246,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
244
246
  await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
245
247
  await this.applyCredentialsResponse(data);
246
248
  if (data.scope) setAgentCredentialSnapshot("codex", { method: data.type, scope: data.scope, revision: data.revision });
247
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-PHP7SXBO.js");
249
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-7QXMUTSZ.js");
248
250
  await restartCodexAspHostIfRunning2();
249
251
  });
250
252
  await this.start(true);
@@ -264,7 +266,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
264
266
  await this.applyCredentialUpdate(generation, async () => {
265
267
  await this.applyCredentialsResponse(data);
266
268
  if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
267
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-PHP7SXBO.js");
269
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-7QXMUTSZ.js");
268
270
  await restartCodexAspHostIfRunning2();
269
271
  }
270
272
  if (data.scope) {
@@ -326,14 +328,14 @@ var CodexTokenManager = class extends BaseRefreshManager {
326
328
  }
327
329
  }
328
330
  async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex, allowedMethods) {
329
- const failedMethod = failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "openai-compatible" || failedCredential?.method === "foundry" ? failedCredential.method : ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD;
331
+ const failedMethod = failedCredential?.method === "ollama" || failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "openai-compatible" || failedCredential?.method === "foundry" ? failedCredential.method : ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD;
330
332
  return this.swapCredentials({
331
333
  provider: "codex",
332
334
  failureKind,
333
335
  allowedMethods,
334
336
  refresh: async (exclusions) => {
335
337
  await this.refreshWithRequest(
336
- failedMethod === "oauth" || failedMethod === "api_key" || failedMethod === "openai-compatible" || failedMethod === "foundry" ? {
338
+ failedMethod === "ollama" || failedMethod === "oauth" || failedMethod === "api_key" || failedMethod === "openai-compatible" || failedMethod === "foundry" ? {
337
339
  failedMethod,
338
340
  ...failedCredential?.method === failedMethod ? { failedCredential } : {},
339
341
  failureReason,
@@ -393,8 +395,9 @@ var CATALOG_TTL_MS = 6e4;
393
395
  var CODEX_MODEL_CATALOG_PATH = join(tmpdir(), "replicas-openai-compatible-model-catalog.json");
394
396
  var cachedCatalog = null;
395
397
  async function writeCodexModelCatalog(modelsUrl) {
398
+ const ollama = ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD === "ollama" ? readOllamaAuthEnv("codex", process.env) : null;
396
399
  const [models, { stdout }] = await Promise.all([
397
- listOpenAICompatibleModels({
400
+ ollama ? listOllamaModels(ollama) : listOpenAICompatibleModels({
398
401
  apiKey: ENGINE_ENV.OPENAI_API_KEY,
399
402
  authorizationHeader: ENGINE_ENV.CODEX_OPENAI_AUTHORIZATION_HEADER,
400
403
  baseUrl: ENGINE_ENV.CODEX_OPENAI_BASE_URL ?? "",
@@ -408,6 +411,7 @@ async function writeCodexModelCatalog(modelsUrl) {
408
411
  await writeFile(CODEX_MODEL_CATALOG_PATH, JSON.stringify({
409
412
  models: models.flatMap((model) => model.contextWindow ? [{
410
413
  ...template,
414
+ ...ollama ? { apply_patch_tool_type: null, support_verbosity: false, supports_search_tool: false, input_modalities: ["text"] } : {},
411
415
  slug: model.id,
412
416
  display_name: model.displayName,
413
417
  description: model.description ?? model.displayName,
@@ -423,7 +427,7 @@ async function writeCodexModelCatalog(modelsUrl) {
423
427
  ];
424
428
  }
425
429
  async function getOpenAICompatibleCodexModelCatalogConfig() {
426
- if (ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD !== "openai-compatible" || !ENGINE_ENV.CODEX_OPENAI_BASE_URL) return [];
430
+ if (ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD !== "openai-compatible" && ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD !== "ollama" || !ENGINE_ENV.CODEX_OPENAI_BASE_URL) return [];
427
431
  const modelsUrl = resolveOpenAICompatibleModelsUrl({
428
432
  baseUrl: ENGINE_ENV.CODEX_OPENAI_BASE_URL,
429
433
  modelsUrl: ENGINE_ENV.CODEX_OPENAI_MODELS_URL ?? ""
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  shouldRefreshPullRequests
6
- } from "./chunk-OJTGCTIK.js";
6
+ } from "./chunk-DFV4EYJI.js";
7
7
 
8
8
  // src/services/post-tool-pr-notifier.ts
9
9
  async function notifyPostToolUse(toolName, toolInput) {
@@ -15,7 +15,7 @@ import {
15
15
  isValidRelayBaseProvider,
16
16
  parsePosixEnvFile,
17
17
  readReplicasRuntimeEnv
18
- } from "./chunk-OJTGCTIK.js";
18
+ } from "./chunk-DFV4EYJI.js";
19
19
 
20
20
  // src/engine-env.ts
21
21
  import { readFileSync as readFileSync2 } from "fs";
@@ -78,13 +78,13 @@ function requireValidURL(value, name) {
78
78
  }
79
79
  }
80
80
  function parseClaudeAuthMethod(value) {
81
- if (value === "oauth" || value === "api_key" || value === "bedrock" || value === "foundry") {
81
+ if (value === "ollama" || value === "oauth" || value === "api_key" || value === "bedrock" || value === "foundry") {
82
82
  return value;
83
83
  }
84
84
  return void 0;
85
85
  }
86
86
  function parseCodexAuthMethod(value) {
87
- if (value === "oauth" || value === "api_key" || value === "openai-compatible" || value === "foundry") {
87
+ if (value === "ollama" || value === "oauth" || value === "api_key" || value === "openai-compatible" || value === "foundry") {
88
88
  return value;
89
89
  }
90
90
  return void 0;
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-M4NXJJHV.js";
7
- import "./chunk-CZLOYOGI.js";
6
+ } from "./chunk-7S5PY3WN.js";
7
+ import "./chunk-VONPE7H2.js";
8
8
  import {
9
9
  isRecord
10
10
  } from "./chunk-UZSNFLDQ.js";
11
- import "./chunk-OJTGCTIK.js";
11
+ import "./chunk-DFV4EYJI.js";
12
12
  import "./chunk-VEQXQN22.js";
13
13
 
14
14
  // src/command-protection-hook.ts
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-M4NXJJHV.js";
6
+ } from "./chunk-7S5PY3WN.js";
7
7
  import {
8
8
  notifyPostToolUse
9
- } from "./chunk-2QTX7QUN.js";
10
- import "./chunk-CZLOYOGI.js";
9
+ } from "./chunk-UCOIF2JZ.js";
10
+ import "./chunk-VONPE7H2.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-OJTGCTIK.js";
12
+ import "./chunk-DFV4EYJI.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/deepseek-command-protection-plugin.ts