@khalilgharbaoui/opencode-claude-code-plugin 0.13.2 → 0.14.0
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/README.md +31 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +314 -212
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -731,6 +731,251 @@ Now continuing with the current message:
|
|
|
731
731
|
});
|
|
732
732
|
}
|
|
733
733
|
|
|
734
|
+
// src/models.ts
|
|
735
|
+
var PROVIDER_ID = "claude-code";
|
|
736
|
+
var NPM = "@khalilgharbaoui/opencode-claude-code-plugin";
|
|
737
|
+
var reasoningVariants = {
|
|
738
|
+
low: { reasoningEffort: "low" },
|
|
739
|
+
medium: { reasoningEffort: "medium" },
|
|
740
|
+
high: { reasoningEffort: "high" },
|
|
741
|
+
xhigh: { reasoningEffort: "xhigh" },
|
|
742
|
+
max: { reasoningEffort: "max" }
|
|
743
|
+
};
|
|
744
|
+
var baseCapabilities = {
|
|
745
|
+
temperature: false,
|
|
746
|
+
attachment: true,
|
|
747
|
+
toolcall: true,
|
|
748
|
+
input: { text: true, audio: false, image: true, video: false, pdf: false },
|
|
749
|
+
output: { text: true, audio: false, image: false, video: false, pdf: false },
|
|
750
|
+
interleaved: false
|
|
751
|
+
};
|
|
752
|
+
function defineModel(opts) {
|
|
753
|
+
return {
|
|
754
|
+
id: opts.id,
|
|
755
|
+
providerID: PROVIDER_ID,
|
|
756
|
+
api: { id: opts.id, url: "", npm: NPM },
|
|
757
|
+
name: `${opts.name} (${opts.multiplier}\xD7)`,
|
|
758
|
+
family: opts.family,
|
|
759
|
+
capabilities: { ...baseCapabilities, reasoning: opts.reasoning },
|
|
760
|
+
cost: {
|
|
761
|
+
input: opts.cost.input,
|
|
762
|
+
output: opts.cost.output,
|
|
763
|
+
cache: { read: opts.cost.cacheRead, write: opts.cost.cacheWrite }
|
|
764
|
+
},
|
|
765
|
+
limit: { context: opts.context, output: opts.output },
|
|
766
|
+
status: opts.status ?? "active",
|
|
767
|
+
options: {},
|
|
768
|
+
headers: {},
|
|
769
|
+
release_date: opts.releaseDate,
|
|
770
|
+
variants: opts.reasoning ? reasoningVariants : void 0
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
var haikuCost = { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 };
|
|
774
|
+
var sonnetCost = { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 };
|
|
775
|
+
var sonnet5Cost = { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 };
|
|
776
|
+
var opusCost = { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 };
|
|
777
|
+
var fableCost = { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 };
|
|
778
|
+
var opusFastCost = { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 };
|
|
779
|
+
function toConfigModel(model) {
|
|
780
|
+
const inputMods = [];
|
|
781
|
+
const outputMods = [];
|
|
782
|
+
for (const [k, v] of Object.entries(model.capabilities.input)) {
|
|
783
|
+
if (v) inputMods.push(k);
|
|
784
|
+
}
|
|
785
|
+
for (const [k, v] of Object.entries(model.capabilities.output)) {
|
|
786
|
+
if (v) outputMods.push(k);
|
|
787
|
+
}
|
|
788
|
+
return {
|
|
789
|
+
id: model.api.id,
|
|
790
|
+
name: model.name,
|
|
791
|
+
status: model.status,
|
|
792
|
+
family: model.family ?? "",
|
|
793
|
+
release_date: model.release_date,
|
|
794
|
+
temperature: model.capabilities.temperature,
|
|
795
|
+
reasoning: model.capabilities.reasoning,
|
|
796
|
+
attachment: model.capabilities.attachment,
|
|
797
|
+
tool_call: model.capabilities.toolcall,
|
|
798
|
+
modalities: { input: inputMods, output: outputMods },
|
|
799
|
+
cost: {
|
|
800
|
+
input: model.cost.input,
|
|
801
|
+
output: model.cost.output,
|
|
802
|
+
cache_read: model.cost.cache.read,
|
|
803
|
+
cache_write: model.cost.cache.write
|
|
804
|
+
},
|
|
805
|
+
limit: model.limit,
|
|
806
|
+
options: model.options,
|
|
807
|
+
headers: model.headers,
|
|
808
|
+
variants: model.variants
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
var defaultModels = {
|
|
812
|
+
"claude-haiku-4-5": defineModel({
|
|
813
|
+
id: "claude-haiku-4-5",
|
|
814
|
+
name: "Claude Haiku 4.5",
|
|
815
|
+
family: "haiku",
|
|
816
|
+
reasoning: false,
|
|
817
|
+
context: 2e5,
|
|
818
|
+
output: 64e3,
|
|
819
|
+
cost: haikuCost,
|
|
820
|
+
multiplier: 1,
|
|
821
|
+
releaseDate: "2025-10-01"
|
|
822
|
+
}),
|
|
823
|
+
"claude-sonnet-4-5": defineModel({
|
|
824
|
+
id: "claude-sonnet-4-5",
|
|
825
|
+
name: "Claude Sonnet 4.5",
|
|
826
|
+
family: "sonnet",
|
|
827
|
+
reasoning: true,
|
|
828
|
+
context: 2e5,
|
|
829
|
+
output: 64e3,
|
|
830
|
+
cost: sonnetCost,
|
|
831
|
+
multiplier: 3,
|
|
832
|
+
releaseDate: "2025-09-29"
|
|
833
|
+
}),
|
|
834
|
+
"claude-sonnet-4-6": defineModel({
|
|
835
|
+
id: "claude-sonnet-4-6",
|
|
836
|
+
name: "Claude Sonnet 4.6",
|
|
837
|
+
family: "sonnet",
|
|
838
|
+
reasoning: true,
|
|
839
|
+
context: 1e6,
|
|
840
|
+
output: 128e3,
|
|
841
|
+
cost: sonnetCost,
|
|
842
|
+
multiplier: 3,
|
|
843
|
+
releaseDate: "2025-06-19"
|
|
844
|
+
}),
|
|
845
|
+
"claude-sonnet-5": defineModel({
|
|
846
|
+
id: "claude-sonnet-5",
|
|
847
|
+
name: "Claude Sonnet 5",
|
|
848
|
+
family: "sonnet",
|
|
849
|
+
reasoning: true,
|
|
850
|
+
context: 1e6,
|
|
851
|
+
output: 128e3,
|
|
852
|
+
cost: sonnet5Cost,
|
|
853
|
+
multiplier: 2,
|
|
854
|
+
releaseDate: "2026-06-30"
|
|
855
|
+
}),
|
|
856
|
+
"claude-opus-4-5": defineModel({
|
|
857
|
+
id: "claude-opus-4-5",
|
|
858
|
+
name: "Claude Opus 4.5",
|
|
859
|
+
family: "opus",
|
|
860
|
+
reasoning: true,
|
|
861
|
+
context: 2e5,
|
|
862
|
+
output: 64e3,
|
|
863
|
+
cost: opusCost,
|
|
864
|
+
multiplier: 5,
|
|
865
|
+
releaseDate: "2025-11-01"
|
|
866
|
+
}),
|
|
867
|
+
"claude-opus-4-6": defineModel({
|
|
868
|
+
id: "claude-opus-4-6",
|
|
869
|
+
name: "Claude Opus 4.6",
|
|
870
|
+
family: "opus",
|
|
871
|
+
reasoning: true,
|
|
872
|
+
context: 1e6,
|
|
873
|
+
output: 128e3,
|
|
874
|
+
cost: opusCost,
|
|
875
|
+
multiplier: 5,
|
|
876
|
+
releaseDate: "2025-06-19"
|
|
877
|
+
}),
|
|
878
|
+
"claude-opus-4-7": defineModel({
|
|
879
|
+
id: "claude-opus-4-7",
|
|
880
|
+
name: "Claude Opus 4.7",
|
|
881
|
+
family: "opus",
|
|
882
|
+
reasoning: true,
|
|
883
|
+
context: 1e6,
|
|
884
|
+
output: 128e3,
|
|
885
|
+
cost: opusCost,
|
|
886
|
+
multiplier: 5,
|
|
887
|
+
releaseDate: "2025-07-16"
|
|
888
|
+
}),
|
|
889
|
+
"claude-opus-4-8": defineModel({
|
|
890
|
+
id: "claude-opus-4-8",
|
|
891
|
+
name: "Claude Opus 4.8",
|
|
892
|
+
family: "opus",
|
|
893
|
+
reasoning: true,
|
|
894
|
+
context: 1e6,
|
|
895
|
+
output: 128e3,
|
|
896
|
+
cost: opusCost,
|
|
897
|
+
multiplier: 5,
|
|
898
|
+
releaseDate: "2026-05-28"
|
|
899
|
+
}),
|
|
900
|
+
// Fast mode. The `-fast` suffix is OUR marker, not a model name Anthropic
|
|
901
|
+
// serves: `parseModelId` strips it before `--model` and turns it into
|
|
902
|
+
// `--settings {"fastMode":true}` on the spawn. Retired `-fast` model strings
|
|
903
|
+
// (`claude-opus-4-6-fast`) are a different thing and are not registered here.
|
|
904
|
+
//
|
|
905
|
+
// Only Opus 4.8 and Opus 5 qualify: the CLI gates fast mode on the resolved
|
|
906
|
+
// model name containing `opus-4-8` or `opus-5`, so registering a fast entry
|
|
907
|
+
// for any other model would produce a picker option that silently runs at
|
|
908
|
+
// standard speed while displaying the 10x price.
|
|
909
|
+
"claude-opus-4-8-fast": defineModel({
|
|
910
|
+
id: "claude-opus-4-8-fast",
|
|
911
|
+
name: "Claude Opus 4.8 Fast",
|
|
912
|
+
family: "opus",
|
|
913
|
+
reasoning: true,
|
|
914
|
+
context: 1e6,
|
|
915
|
+
output: 128e3,
|
|
916
|
+
cost: opusFastCost,
|
|
917
|
+
multiplier: 10,
|
|
918
|
+
releaseDate: "2026-05-28"
|
|
919
|
+
}),
|
|
920
|
+
"claude-opus-5": defineModel({
|
|
921
|
+
id: "claude-opus-5",
|
|
922
|
+
name: "Claude Opus 5",
|
|
923
|
+
family: "opus",
|
|
924
|
+
reasoning: true,
|
|
925
|
+
context: 1e6,
|
|
926
|
+
output: 128e3,
|
|
927
|
+
cost: opusCost,
|
|
928
|
+
multiplier: 5,
|
|
929
|
+
releaseDate: "2026-07-24"
|
|
930
|
+
}),
|
|
931
|
+
"claude-opus-5-fast": defineModel({
|
|
932
|
+
id: "claude-opus-5-fast",
|
|
933
|
+
name: "Claude Opus 5 Fast",
|
|
934
|
+
family: "opus",
|
|
935
|
+
reasoning: true,
|
|
936
|
+
context: 1e6,
|
|
937
|
+
output: 128e3,
|
|
938
|
+
cost: opusFastCost,
|
|
939
|
+
multiplier: 10,
|
|
940
|
+
releaseDate: "2026-07-24"
|
|
941
|
+
}),
|
|
942
|
+
"claude-fable-5": defineModel({
|
|
943
|
+
id: "claude-fable-5",
|
|
944
|
+
name: "Claude Fable 5",
|
|
945
|
+
family: "fable",
|
|
946
|
+
reasoning: true,
|
|
947
|
+
context: 1e6,
|
|
948
|
+
output: 128e3,
|
|
949
|
+
cost: fableCost,
|
|
950
|
+
multiplier: 10,
|
|
951
|
+
releaseDate: "2026-06-09"
|
|
952
|
+
}),
|
|
953
|
+
// Mythos 5 shares Fable 5's capabilities and pricing without the safety
|
|
954
|
+
// classifiers; limited availability via Project Glasswing. `claude --model
|
|
955
|
+
// claude-mythos-5` simply errors for accounts without access, so it's safe to
|
|
956
|
+
// register unconditionally.
|
|
957
|
+
"claude-mythos-5": defineModel({
|
|
958
|
+
id: "claude-mythos-5",
|
|
959
|
+
name: "Claude Mythos 5",
|
|
960
|
+
family: "mythos",
|
|
961
|
+
reasoning: true,
|
|
962
|
+
context: 1e6,
|
|
963
|
+
output: 128e3,
|
|
964
|
+
cost: fableCost,
|
|
965
|
+
multiplier: 10,
|
|
966
|
+
releaseDate: "2026-06-09"
|
|
967
|
+
})
|
|
968
|
+
};
|
|
969
|
+
var FAST_SUFFIX = "-fast";
|
|
970
|
+
function parseModelId(modelId) {
|
|
971
|
+
const at = modelId.indexOf("@");
|
|
972
|
+
const base = at === -1 ? modelId : modelId.slice(0, at);
|
|
973
|
+
const account = at === -1 ? "" : modelId.slice(at);
|
|
974
|
+
if (!base.endsWith(FAST_SUFFIX)) return { model: modelId, fast: false };
|
|
975
|
+
if (!Object.hasOwn(defaultModels, base)) return { model: modelId, fast: false };
|
|
976
|
+
return { model: base.slice(0, -FAST_SUFFIX.length) + account, fast: true };
|
|
977
|
+
}
|
|
978
|
+
|
|
734
979
|
// src/plan-mode-question.ts
|
|
735
980
|
var QUESTION_TOOL_NAME = "question";
|
|
736
981
|
var APPROVED_EXIT_PLAN_MODE_MESSAGE = "User has approved your plan. You can now start coding. Start with updating your todo list if applicable.";
|
|
@@ -1386,6 +1631,10 @@ function cliSupportsThinkingDisplay(v) {
|
|
|
1386
1631
|
if (!v) return false;
|
|
1387
1632
|
return gte(v, { major: 2, minor: 1, patch: 142 });
|
|
1388
1633
|
}
|
|
1634
|
+
function cliSupportsFastMode(v) {
|
|
1635
|
+
if (!v) return false;
|
|
1636
|
+
return gte(v, { major: 2, minor: 1, patch: 220 });
|
|
1637
|
+
}
|
|
1389
1638
|
function cliSupportsThinking(v) {
|
|
1390
1639
|
if (!v) return false;
|
|
1391
1640
|
return gte(v, { major: 2, minor: 0, patch: 0 });
|
|
@@ -1609,6 +1858,7 @@ function buildCliArgs(opts) {
|
|
|
1609
1858
|
appendSystemPromptFile,
|
|
1610
1859
|
thinking,
|
|
1611
1860
|
thinkingDisplay,
|
|
1861
|
+
fastMode,
|
|
1612
1862
|
cliVersion
|
|
1613
1863
|
} = opts;
|
|
1614
1864
|
const args = [
|
|
@@ -1654,6 +1904,9 @@ function buildCliArgs(opts) {
|
|
|
1654
1904
|
if (appendSystemPromptFile) {
|
|
1655
1905
|
args.push("--append-system-prompt-file", appendSystemPromptFile);
|
|
1656
1906
|
}
|
|
1907
|
+
if (fastMode && cliSupportsFastMode(cliVersion ?? null)) {
|
|
1908
|
+
args.push("--settings", JSON.stringify({ fastMode: true }));
|
|
1909
|
+
}
|
|
1657
1910
|
if (skipPermissions) {
|
|
1658
1911
|
args.push("--dangerously-skip-permissions");
|
|
1659
1912
|
}
|
|
@@ -2081,11 +2334,15 @@ function spawnInteractiveProcess(opts) {
|
|
|
2081
2334
|
"--strict-mcp-config"
|
|
2082
2335
|
);
|
|
2083
2336
|
}
|
|
2337
|
+
const flagSettings = {};
|
|
2084
2338
|
if (opts.permissionsAllow && opts.permissionsAllow.length > 0) {
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2339
|
+
flagSettings.permissions = { allow: opts.permissionsAllow };
|
|
2340
|
+
}
|
|
2341
|
+
if (opts.fastMode) {
|
|
2342
|
+
flagSettings.fastMode = true;
|
|
2343
|
+
}
|
|
2344
|
+
if (Object.keys(flagSettings).length > 0) {
|
|
2345
|
+
extraArgs.push("--settings", JSON.stringify(flagSettings));
|
|
2089
2346
|
}
|
|
2090
2347
|
if (opts.permissionMode === "bypassPermissions") {
|
|
2091
2348
|
log.warn(
|
|
@@ -3336,6 +3593,47 @@ ${options.compressionSummary.trim()}`
|
|
|
3336
3593
|
return void 0;
|
|
3337
3594
|
}
|
|
3338
3595
|
}
|
|
3596
|
+
var FAST_MODE_REASONS = {
|
|
3597
|
+
sdk_opt_in_required: "the CLI did not receive the headless opt-in (--settings). This is a plugin bug, please report it",
|
|
3598
|
+
extra_usage_disabled: "your account has usage credits turned off. Run /usage-credits in an interactive `claude` session to enable them",
|
|
3599
|
+
free: "fast mode requires a paid subscription or purchased credits",
|
|
3600
|
+
preference: "fast mode is turned off for your organization",
|
|
3601
|
+
model_not_allowed: "this model is not in your organization's allowed models",
|
|
3602
|
+
not_first_party: "fast mode only works against the Anthropic API directly, not Bedrock / Vertex / Foundry",
|
|
3603
|
+
network_error: "the CLI could not reach Anthropic to check availability",
|
|
3604
|
+
disabled_by_env: "CLAUDE_CODE_DISABLE_FAST_MODE is set in the environment",
|
|
3605
|
+
pending: "the CLI is still checking availability"
|
|
3606
|
+
};
|
|
3607
|
+
var warnedFastModeReasons = /* @__PURE__ */ new Set();
|
|
3608
|
+
function reportFastModeState(msg, requested) {
|
|
3609
|
+
const state = msg.fast_mode_state;
|
|
3610
|
+
if (!state) return;
|
|
3611
|
+
if (!requested) {
|
|
3612
|
+
log.debug("fast mode state", { state });
|
|
3613
|
+
return;
|
|
3614
|
+
}
|
|
3615
|
+
if (state === "on") {
|
|
3616
|
+
log.info("fast mode active", { state });
|
|
3617
|
+
return;
|
|
3618
|
+
}
|
|
3619
|
+
const reason = msg.fast_mode_disabled_reason;
|
|
3620
|
+
if (state === "cooldown") {
|
|
3621
|
+
log.notice(
|
|
3622
|
+
"fast mode is in cooldown after a rate limit; this turn runs at standard speed and is billed at standard Opus rates, not the 10x shown in the model picker.",
|
|
3623
|
+
{ state, reason: reason ?? null }
|
|
3624
|
+
);
|
|
3625
|
+
return;
|
|
3626
|
+
}
|
|
3627
|
+
const key = reason ?? "unknown";
|
|
3628
|
+
const explanation = reason ? FAST_MODE_REASONS[reason] : void 0;
|
|
3629
|
+
const message = `fast mode was requested but is off${explanation ? `: ${explanation}` : reason ? ` (${reason})` : ""}. Turns run at standard speed and are billed at standard Opus rates, not the 10x shown in the model picker. Switch to the non-fast model id to make the picker's price accurate.`;
|
|
3630
|
+
if (warnedFastModeReasons.has(key)) {
|
|
3631
|
+
log.debug(message, { state, reason: reason ?? null });
|
|
3632
|
+
return;
|
|
3633
|
+
}
|
|
3634
|
+
warnedFastModeReasons.add(key);
|
|
3635
|
+
log.warn(message, { state, reason: reason ?? null });
|
|
3636
|
+
}
|
|
3339
3637
|
var ClaudeCodeLanguageModel = class {
|
|
3340
3638
|
specificationVersion = "v3";
|
|
3341
3639
|
modelId;
|
|
@@ -3945,17 +4243,19 @@ var ClaudeCodeLanguageModel = class {
|
|
|
3945
4243
|
// An existing summary still carries: it is this key's prior context.
|
|
3946
4244
|
{ compressEnabled: false, compressionSummary: getCompressionSummary(sk) }
|
|
3947
4245
|
);
|
|
4246
|
+
const { model: spawnModelId, fast: fastMode } = parseModelId(this.modelId);
|
|
3948
4247
|
const cliArgs = buildCliArgs({
|
|
3949
4248
|
sessionKey: sk,
|
|
3950
4249
|
skipPermissions: this.config.skipPermissions !== false,
|
|
3951
4250
|
includeSessionId: false,
|
|
3952
|
-
model:
|
|
4251
|
+
model: spawnModelId,
|
|
3953
4252
|
permissionMode: this.config.permissionMode,
|
|
3954
4253
|
mcpConfig: this.effectiveMcpConfig(cwd, void 0, runtimeStatus).paths,
|
|
3955
4254
|
strictMcpConfig: this.config.strictMcpConfig,
|
|
3956
4255
|
disallowedTools: this.config.webSearch === "disabled" ? ["WebSearch"] : void 0,
|
|
3957
4256
|
appendSystemPromptFile: systemPromptFile,
|
|
3958
4257
|
...this.thinkingCliOptions(),
|
|
4258
|
+
fastMode,
|
|
3959
4259
|
cliVersion
|
|
3960
4260
|
});
|
|
3961
4261
|
log.info("doGenerate starting", {
|
|
@@ -4009,6 +4309,7 @@ var ClaudeCodeLanguageModel = class {
|
|
|
4009
4309
|
if (msg.session_id) {
|
|
4010
4310
|
setClaudeSessionId(sk, msg.session_id);
|
|
4011
4311
|
}
|
|
4312
|
+
reportFastModeState(msg, fastMode);
|
|
4012
4313
|
}
|
|
4013
4314
|
if (msg.type === "assistant" && msg.message?.content && !gotPartialEvents) {
|
|
4014
4315
|
for (const block of msg.message.content) {
|
|
@@ -4246,6 +4547,7 @@ ${plan}
|
|
|
4246
4547
|
const affinity = this.sessionAffinity(options);
|
|
4247
4548
|
const compactionMode = this.isCompactionCall(options);
|
|
4248
4549
|
const effectiveModelId = compactionMode ? this.resolveCompactionModel() : this.modelId;
|
|
4550
|
+
const { model: spawnModelId, fast: fastMode } = parseModelId(effectiveModelId);
|
|
4249
4551
|
const sk = compactionMode ? sessionKey(cwd, `${effectiveModelId}::compaction::${affinity}`) : sessionKey(cwd, `${this.modelId}::${scope}::${affinity}`);
|
|
4250
4552
|
const toUsage = this.toUsage.bind(this);
|
|
4251
4553
|
const toFinishReason = this.toFinishReason.bind(this);
|
|
@@ -4441,7 +4743,8 @@ ${plan}
|
|
|
4441
4743
|
cwd,
|
|
4442
4744
|
cliPath,
|
|
4443
4745
|
configDir: self.config.configDir,
|
|
4444
|
-
model:
|
|
4746
|
+
model: spawnModelId,
|
|
4747
|
+
fastMode,
|
|
4445
4748
|
mcpConfigPaths: mcp.paths,
|
|
4446
4749
|
permissionsAllow: allow,
|
|
4447
4750
|
systemPromptFile,
|
|
@@ -4468,8 +4771,9 @@ ${plan}
|
|
|
4468
4771
|
sessionKey: sk,
|
|
4469
4772
|
skipPermissions,
|
|
4470
4773
|
includeSessionId: false,
|
|
4471
|
-
model:
|
|
4774
|
+
model: spawnModelId,
|
|
4472
4775
|
permissionMode: self.config.permissionMode,
|
|
4776
|
+
fastMode,
|
|
4473
4777
|
cliVersion
|
|
4474
4778
|
});
|
|
4475
4779
|
} else {
|
|
@@ -4556,13 +4860,14 @@ ${plan}
|
|
|
4556
4860
|
cliArgs = buildCliArgs({
|
|
4557
4861
|
sessionKey: sk,
|
|
4558
4862
|
skipPermissions,
|
|
4559
|
-
model:
|
|
4863
|
+
model: spawnModelId,
|
|
4560
4864
|
permissionMode: self.config.permissionMode,
|
|
4561
4865
|
mcpConfig: mcp.paths,
|
|
4562
4866
|
strictMcpConfig: self.config.strictMcpConfig,
|
|
4563
4867
|
disallowedTools: allDisallowed.length > 0 ? allDisallowed : void 0,
|
|
4564
4868
|
appendSystemPromptFile: systemPromptFile,
|
|
4565
4869
|
...self.thinkingCliOptions(),
|
|
4870
|
+
fastMode,
|
|
4566
4871
|
cliVersion
|
|
4567
4872
|
});
|
|
4568
4873
|
spawnSystemPromptFile = systemPromptFile;
|
|
@@ -4994,6 +5299,7 @@ ${plan}
|
|
|
4994
5299
|
claudeSessionId: msg.session_id
|
|
4995
5300
|
});
|
|
4996
5301
|
}
|
|
5302
|
+
reportFastModeState(msg, fastMode);
|
|
4997
5303
|
}
|
|
4998
5304
|
if (msg.type === "content_block_start" && msg.content_block && msg.index !== void 0) {
|
|
4999
5305
|
const block = msg.content_block;
|
|
@@ -5745,210 +6051,6 @@ ${plan}
|
|
|
5745
6051
|
}
|
|
5746
6052
|
};
|
|
5747
6053
|
|
|
5748
|
-
// src/models.ts
|
|
5749
|
-
var PROVIDER_ID = "claude-code";
|
|
5750
|
-
var NPM = "@khalilgharbaoui/opencode-claude-code-plugin";
|
|
5751
|
-
var reasoningVariants = {
|
|
5752
|
-
low: { reasoningEffort: "low" },
|
|
5753
|
-
medium: { reasoningEffort: "medium" },
|
|
5754
|
-
high: { reasoningEffort: "high" },
|
|
5755
|
-
xhigh: { reasoningEffort: "xhigh" },
|
|
5756
|
-
max: { reasoningEffort: "max" }
|
|
5757
|
-
};
|
|
5758
|
-
var baseCapabilities = {
|
|
5759
|
-
temperature: false,
|
|
5760
|
-
attachment: true,
|
|
5761
|
-
toolcall: true,
|
|
5762
|
-
input: { text: true, audio: false, image: true, video: false, pdf: false },
|
|
5763
|
-
output: { text: true, audio: false, image: false, video: false, pdf: false },
|
|
5764
|
-
interleaved: false
|
|
5765
|
-
};
|
|
5766
|
-
function defineModel(opts) {
|
|
5767
|
-
return {
|
|
5768
|
-
id: opts.id,
|
|
5769
|
-
providerID: PROVIDER_ID,
|
|
5770
|
-
api: { id: opts.id, url: "", npm: NPM },
|
|
5771
|
-
name: `${opts.name} (${opts.multiplier}\xD7)`,
|
|
5772
|
-
family: opts.family,
|
|
5773
|
-
capabilities: { ...baseCapabilities, reasoning: opts.reasoning },
|
|
5774
|
-
cost: {
|
|
5775
|
-
input: opts.cost.input,
|
|
5776
|
-
output: opts.cost.output,
|
|
5777
|
-
cache: { read: opts.cost.cacheRead, write: opts.cost.cacheWrite }
|
|
5778
|
-
},
|
|
5779
|
-
limit: { context: opts.context, output: opts.output },
|
|
5780
|
-
status: opts.status ?? "active",
|
|
5781
|
-
options: {},
|
|
5782
|
-
headers: {},
|
|
5783
|
-
release_date: opts.releaseDate,
|
|
5784
|
-
variants: opts.reasoning ? reasoningVariants : void 0
|
|
5785
|
-
};
|
|
5786
|
-
}
|
|
5787
|
-
var haikuCost = { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 };
|
|
5788
|
-
var sonnetCost = { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 };
|
|
5789
|
-
var sonnet5Cost = { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 };
|
|
5790
|
-
var opusCost = { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 };
|
|
5791
|
-
var fableCost = { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 };
|
|
5792
|
-
function toConfigModel(model) {
|
|
5793
|
-
const inputMods = [];
|
|
5794
|
-
const outputMods = [];
|
|
5795
|
-
for (const [k, v] of Object.entries(model.capabilities.input)) {
|
|
5796
|
-
if (v) inputMods.push(k);
|
|
5797
|
-
}
|
|
5798
|
-
for (const [k, v] of Object.entries(model.capabilities.output)) {
|
|
5799
|
-
if (v) outputMods.push(k);
|
|
5800
|
-
}
|
|
5801
|
-
return {
|
|
5802
|
-
id: model.api.id,
|
|
5803
|
-
name: model.name,
|
|
5804
|
-
status: model.status,
|
|
5805
|
-
family: model.family ?? "",
|
|
5806
|
-
release_date: model.release_date,
|
|
5807
|
-
temperature: model.capabilities.temperature,
|
|
5808
|
-
reasoning: model.capabilities.reasoning,
|
|
5809
|
-
attachment: model.capabilities.attachment,
|
|
5810
|
-
tool_call: model.capabilities.toolcall,
|
|
5811
|
-
modalities: { input: inputMods, output: outputMods },
|
|
5812
|
-
cost: {
|
|
5813
|
-
input: model.cost.input,
|
|
5814
|
-
output: model.cost.output,
|
|
5815
|
-
cache_read: model.cost.cache.read,
|
|
5816
|
-
cache_write: model.cost.cache.write
|
|
5817
|
-
},
|
|
5818
|
-
limit: model.limit,
|
|
5819
|
-
options: model.options,
|
|
5820
|
-
headers: model.headers,
|
|
5821
|
-
variants: model.variants
|
|
5822
|
-
};
|
|
5823
|
-
}
|
|
5824
|
-
var defaultModels = {
|
|
5825
|
-
"claude-haiku-4-5": defineModel({
|
|
5826
|
-
id: "claude-haiku-4-5",
|
|
5827
|
-
name: "Claude Haiku 4.5",
|
|
5828
|
-
family: "haiku",
|
|
5829
|
-
reasoning: false,
|
|
5830
|
-
context: 2e5,
|
|
5831
|
-
output: 64e3,
|
|
5832
|
-
cost: haikuCost,
|
|
5833
|
-
multiplier: 1,
|
|
5834
|
-
releaseDate: "2025-10-01"
|
|
5835
|
-
}),
|
|
5836
|
-
"claude-sonnet-4-5": defineModel({
|
|
5837
|
-
id: "claude-sonnet-4-5",
|
|
5838
|
-
name: "Claude Sonnet 4.5",
|
|
5839
|
-
family: "sonnet",
|
|
5840
|
-
reasoning: true,
|
|
5841
|
-
context: 2e5,
|
|
5842
|
-
output: 64e3,
|
|
5843
|
-
cost: sonnetCost,
|
|
5844
|
-
multiplier: 3,
|
|
5845
|
-
releaseDate: "2025-09-29"
|
|
5846
|
-
}),
|
|
5847
|
-
"claude-sonnet-4-6": defineModel({
|
|
5848
|
-
id: "claude-sonnet-4-6",
|
|
5849
|
-
name: "Claude Sonnet 4.6",
|
|
5850
|
-
family: "sonnet",
|
|
5851
|
-
reasoning: true,
|
|
5852
|
-
context: 1e6,
|
|
5853
|
-
output: 128e3,
|
|
5854
|
-
cost: sonnetCost,
|
|
5855
|
-
multiplier: 3,
|
|
5856
|
-
releaseDate: "2025-06-19"
|
|
5857
|
-
}),
|
|
5858
|
-
"claude-sonnet-5": defineModel({
|
|
5859
|
-
id: "claude-sonnet-5",
|
|
5860
|
-
name: "Claude Sonnet 5",
|
|
5861
|
-
family: "sonnet",
|
|
5862
|
-
reasoning: true,
|
|
5863
|
-
context: 1e6,
|
|
5864
|
-
output: 128e3,
|
|
5865
|
-
cost: sonnet5Cost,
|
|
5866
|
-
multiplier: 2,
|
|
5867
|
-
releaseDate: "2026-06-30"
|
|
5868
|
-
}),
|
|
5869
|
-
"claude-opus-4-5": defineModel({
|
|
5870
|
-
id: "claude-opus-4-5",
|
|
5871
|
-
name: "Claude Opus 4.5",
|
|
5872
|
-
family: "opus",
|
|
5873
|
-
reasoning: true,
|
|
5874
|
-
context: 2e5,
|
|
5875
|
-
output: 64e3,
|
|
5876
|
-
cost: opusCost,
|
|
5877
|
-
multiplier: 5,
|
|
5878
|
-
releaseDate: "2025-11-01"
|
|
5879
|
-
}),
|
|
5880
|
-
"claude-opus-4-6": defineModel({
|
|
5881
|
-
id: "claude-opus-4-6",
|
|
5882
|
-
name: "Claude Opus 4.6",
|
|
5883
|
-
family: "opus",
|
|
5884
|
-
reasoning: true,
|
|
5885
|
-
context: 1e6,
|
|
5886
|
-
output: 128e3,
|
|
5887
|
-
cost: opusCost,
|
|
5888
|
-
multiplier: 5,
|
|
5889
|
-
releaseDate: "2025-06-19"
|
|
5890
|
-
}),
|
|
5891
|
-
"claude-opus-4-7": defineModel({
|
|
5892
|
-
id: "claude-opus-4-7",
|
|
5893
|
-
name: "Claude Opus 4.7",
|
|
5894
|
-
family: "opus",
|
|
5895
|
-
reasoning: true,
|
|
5896
|
-
context: 1e6,
|
|
5897
|
-
output: 128e3,
|
|
5898
|
-
cost: opusCost,
|
|
5899
|
-
multiplier: 5,
|
|
5900
|
-
releaseDate: "2025-07-16"
|
|
5901
|
-
}),
|
|
5902
|
-
"claude-opus-4-8": defineModel({
|
|
5903
|
-
id: "claude-opus-4-8",
|
|
5904
|
-
name: "Claude Opus 4.8",
|
|
5905
|
-
family: "opus",
|
|
5906
|
-
reasoning: true,
|
|
5907
|
-
context: 1e6,
|
|
5908
|
-
output: 128e3,
|
|
5909
|
-
cost: opusCost,
|
|
5910
|
-
multiplier: 5,
|
|
5911
|
-
releaseDate: "2026-05-28"
|
|
5912
|
-
}),
|
|
5913
|
-
"claude-opus-5": defineModel({
|
|
5914
|
-
id: "claude-opus-5",
|
|
5915
|
-
name: "Claude Opus 5",
|
|
5916
|
-
family: "opus",
|
|
5917
|
-
reasoning: true,
|
|
5918
|
-
context: 1e6,
|
|
5919
|
-
output: 128e3,
|
|
5920
|
-
cost: opusCost,
|
|
5921
|
-
multiplier: 5,
|
|
5922
|
-
releaseDate: "2026-07-24"
|
|
5923
|
-
}),
|
|
5924
|
-
"claude-fable-5": defineModel({
|
|
5925
|
-
id: "claude-fable-5",
|
|
5926
|
-
name: "Claude Fable 5",
|
|
5927
|
-
family: "fable",
|
|
5928
|
-
reasoning: true,
|
|
5929
|
-
context: 1e6,
|
|
5930
|
-
output: 128e3,
|
|
5931
|
-
cost: fableCost,
|
|
5932
|
-
multiplier: 10,
|
|
5933
|
-
releaseDate: "2026-06-09"
|
|
5934
|
-
}),
|
|
5935
|
-
// Mythos 5 shares Fable 5's capabilities and pricing without the safety
|
|
5936
|
-
// classifiers; limited availability via Project Glasswing. `claude --model
|
|
5937
|
-
// claude-mythos-5` simply errors for accounts without access, so it's safe to
|
|
5938
|
-
// register unconditionally.
|
|
5939
|
-
"claude-mythos-5": defineModel({
|
|
5940
|
-
id: "claude-mythos-5",
|
|
5941
|
-
name: "Claude Mythos 5",
|
|
5942
|
-
family: "mythos",
|
|
5943
|
-
reasoning: true,
|
|
5944
|
-
context: 1e6,
|
|
5945
|
-
output: 128e3,
|
|
5946
|
-
cost: fableCost,
|
|
5947
|
-
multiplier: 10,
|
|
5948
|
-
releaseDate: "2026-06-09"
|
|
5949
|
-
})
|
|
5950
|
-
};
|
|
5951
|
-
|
|
5952
6054
|
// src/accounts.ts
|
|
5953
6055
|
import { chmod, lstat, mkdir, readlink, symlink, writeFile } from "fs/promises";
|
|
5954
6056
|
import path5 from "path";
|