summaryrefslogtreecommitdiffhomepage
path: root/src/features/concurrency/logic
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/concurrency/logic')
-rw-r--r--src/features/concurrency/logic/view-model.test.ts28
-rw-r--r--src/features/concurrency/logic/view-model.ts12
2 files changed, 35 insertions, 5 deletions
diff --git a/src/features/concurrency/logic/view-model.test.ts b/src/features/concurrency/logic/view-model.test.ts
index 6e6b770..9c557f5 100644
--- a/src/features/concurrency/logic/view-model.test.ts
+++ b/src/features/concurrency/logic/view-model.test.ts
@@ -13,6 +13,7 @@ import {
parseLimitInput,
pauseLabel,
providerFromModel,
+ providerLabel,
providerOptions,
statusLabel,
summarizeLimits,
@@ -95,7 +96,7 @@ describe("cooldownLabel", () => {
describe("providerFromModel", () => {
it("takes the part before the first slash", () => {
expect(providerFromModel("openai/gpt-4o")).toBe("openai");
- expect(providerFromModel("openai-compat/gpt-4o-mini")).toBe("openai-compat");
+ expect(providerFromModel("opencode-1/gpt-4o-mini")).toBe("opencode-1");
});
it("returns the whole string when there is no slash", () => {
expect(providerFromModel("umans")).toBe("umans");
@@ -127,6 +128,23 @@ describe("providerOptions", () => {
});
});
+describe("providerLabel", () => {
+ it("labels a numbered OpenCode provider as OpenCode #N", () => {
+ expect(providerLabel("opencode-2")).toBe("OpenCode #2");
+ expect(providerLabel("opencode-10")).toBe("OpenCode #10");
+ });
+
+ it("leaves non-OpenCode provider ids unchanged", () => {
+ expect(providerLabel("umans")).toBe("umans");
+ expect(providerLabel("anthropic")).toBe("anthropic");
+ });
+
+ it("rejects noncanonical numbered ids (label passthrough)", () => {
+ expect(providerLabel("opencode")).toBe("opencode");
+ expect(providerLabel("opencode-0")).toBe("opencode-0");
+ });
+});
+
// ── pauseLabel + formatPauseDuration ───────────────────────────────────────────
describe("formatPauseDuration", () => {
@@ -450,12 +468,12 @@ describe("normalizeConcurrencyLimits", () => {
const limits = normalizeConcurrencyLimits({
limits: [
{ providerId: "umans", limit: 4 },
- { providerId: "openai-compat", limit: 5 },
+ { providerId: "opencode-1", limit: 5 },
],
});
expect(limits).toEqual([
{ providerId: "umans", limit: 4 },
- { providerId: "openai-compat", limit: 5 },
+ { providerId: "opencode-1", limit: 5 },
]);
});
@@ -510,7 +528,7 @@ describe("normalizeConcurrencyStatus", () => {
providers: [
{ providerId: "umans", limit: 4, inFlight: 2, queued: 1, paused: false },
{
- providerId: "openai-compat",
+ providerId: "opencode-1",
limit: 5,
inFlight: 5,
queued: 3,
@@ -532,7 +550,7 @@ describe("normalizeConcurrencyStatus", () => {
});
expect(first !== undefined && !("pausedUntil" in first)).toBe(true);
expect(second).toEqual({
- providerId: "openai-compat",
+ providerId: "opencode-1",
limit: 5,
inFlight: 5,
queued: 3,
diff --git a/src/features/concurrency/logic/view-model.ts b/src/features/concurrency/logic/view-model.ts
index 8a37198..80c155c 100644
--- a/src/features/concurrency/logic/view-model.ts
+++ b/src/features/concurrency/logic/view-model.ts
@@ -170,6 +170,18 @@ export function providerOptions(
return out;
}
+/**
+ * Friendly display label for a concurrency provider id. A numbered OpenCode
+ * provider (`opencode-<n>`) renders as "OpenCode #<n>" (so "opencode-2" reads
+ * as a coherent credential identity, matching the model picker); any other id is
+ * shown unchanged. The RAW id is still what is sent to / displayed-with the
+ * backend — this only affects presentation.
+ */
+export function providerLabel(providerId: string): string {
+ const m = /^opencode-([1-9][0-9]*)$/.exec(providerId);
+ return m === null ? providerId : `OpenCode #${m[1]}`;
+}
+
// ── Status → display view ──────────────────────────────────────────────────────
const NO_LIMITS = "No limits configured";