Show OpenCode agent colors in modes
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import type { AgentMode } from "./agent-sdk-types.js";
|
import type { AgentMode } from "./agent-sdk-types.js";
|
||||||
|
|
||||||
export type AgentModeColorTier = "safe" | "moderate" | "dangerous" | "planning";
|
export type AgentModeColorTier = "safe" | "moderate" | "dangerous" | "planning" | `#${string}`;
|
||||||
export type AgentModeIcon = "ShieldCheck" | "ShieldAlert" | "ShieldOff" | "ShieldQuestionMark";
|
export type AgentModeIcon = "ShieldCheck" | "ShieldAlert" | "ShieldOff" | "ShieldQuestionMark";
|
||||||
|
|
||||||
export interface AgentModeVisuals {
|
export interface AgentModeVisuals {
|
||||||
|
|||||||
@@ -582,6 +582,35 @@ describe("OpenCode adapter context-window normalization", () => {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("carries only hex OpenCode agent colors as mode color tiers", () => {
|
||||||
|
expect(
|
||||||
|
__openCodeInternals.mapOpenCodeAgentToMode({
|
||||||
|
name: "review",
|
||||||
|
description: "Review code",
|
||||||
|
color: "#ff6b6b",
|
||||||
|
}),
|
||||||
|
).toMatchObject({
|
||||||
|
id: "review",
|
||||||
|
label: "Review",
|
||||||
|
description: "Review code",
|
||||||
|
colorTier: "#ff6b6b",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
__openCodeInternals.mapOpenCodeAgentToMode({
|
||||||
|
name: "creative",
|
||||||
|
color: "accent",
|
||||||
|
}),
|
||||||
|
).not.toHaveProperty("colorTier");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
__openCodeInternals.mapOpenCodeAgentToMode({
|
||||||
|
name: "debug",
|
||||||
|
color: "#fff",
|
||||||
|
}),
|
||||||
|
).not.toHaveProperty("colorTier");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("OpenCode adapter startTurn error handling", () => {
|
describe("OpenCode adapter startTurn error handling", () => {
|
||||||
|
|||||||
@@ -445,6 +445,31 @@ function isSelectableOpenCodeAgent(agent: { mode?: string; hidden?: boolean }):
|
|||||||
return (agent.mode === "primary" || agent.mode === "all") && agent.hidden !== true;
|
return (agent.mode === "primary" || agent.mode === "all") && agent.hidden !== true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const OPENCODE_AGENT_HEX_COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;
|
||||||
|
|
||||||
|
function readOpenCodeAgentHexColor(agent: { color?: unknown }): string | undefined {
|
||||||
|
return typeof agent.color === "string" && OPENCODE_AGENT_HEX_COLOR_PATTERN.test(agent.color)
|
||||||
|
? agent.color
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapOpenCodeAgentToMode(agent: {
|
||||||
|
name: string;
|
||||||
|
description?: unknown;
|
||||||
|
color?: unknown;
|
||||||
|
}): AgentMode {
|
||||||
|
const colorTier = readOpenCodeAgentHexColor(agent);
|
||||||
|
return {
|
||||||
|
id: agent.name,
|
||||||
|
label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1),
|
||||||
|
description:
|
||||||
|
typeof agent.description === "string" && agent.description.trim().length > 0
|
||||||
|
? agent.description.trim()
|
||||||
|
: DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description,
|
||||||
|
...(colorTier ? { colorTier } : {}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function mergeOpenCodeModes(discoveredModes: AgentMode[]): AgentMode[] {
|
function mergeOpenCodeModes(discoveredModes: AgentMode[]): AgentMode[] {
|
||||||
const modesById = new Map(DEFAULT_MODES.map((mode) => [mode.id, mode]));
|
const modesById = new Map(DEFAULT_MODES.map((mode) => [mode.id, mode]));
|
||||||
for (const mode of discoveredModes) {
|
for (const mode of discoveredModes) {
|
||||||
@@ -1042,6 +1067,7 @@ export const __openCodeInternals = {
|
|||||||
resolveOpenCodeModelLookupKeyFromAssistantMessage,
|
resolveOpenCodeModelLookupKeyFromAssistantMessage,
|
||||||
resolveOpenCodeSelectedModelContextWindow,
|
resolveOpenCodeSelectedModelContextWindow,
|
||||||
isSelectableOpenCodeAgent,
|
isSelectableOpenCodeAgent,
|
||||||
|
mapOpenCodeAgentToMode,
|
||||||
get OpenCodeAgentSession() {
|
get OpenCodeAgentSession() {
|
||||||
return OpenCodeAgentSession;
|
return OpenCodeAgentSession;
|
||||||
},
|
},
|
||||||
@@ -1277,14 +1303,9 @@ export class OpenCodeAgentClient implements AgentClient {
|
|||||||
return DEFAULT_MODES;
|
return DEFAULT_MODES;
|
||||||
}
|
}
|
||||||
|
|
||||||
const discovered = response.data.filter(isSelectableOpenCodeAgent).map((agent) => ({
|
const discovered = response.data
|
||||||
id: agent.name,
|
.filter(isSelectableOpenCodeAgent)
|
||||||
label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1),
|
.map(mapOpenCodeAgentToMode);
|
||||||
description:
|
|
||||||
typeof agent.description === "string" && agent.description.trim().length > 0
|
|
||||||
? agent.description.trim()
|
|
||||||
: DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return mergeOpenCodeModes(discovered);
|
return mergeOpenCodeModes(discovered);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -3202,14 +3223,7 @@ class OpenCodeAgentSession implements AgentSession {
|
|||||||
});
|
});
|
||||||
const agents = response.error || !response.data ? [] : response.data;
|
const agents = response.error || !response.data ? [] : response.data;
|
||||||
|
|
||||||
const discoveredModes = agents.filter(isSelectableOpenCodeAgent).map((agent) => ({
|
const discoveredModes = agents.filter(isSelectableOpenCodeAgent).map(mapOpenCodeAgentToMode);
|
||||||
id: agent.name,
|
|
||||||
label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1),
|
|
||||||
description:
|
|
||||||
typeof agent.description === "string" && agent.description.trim().length > 0
|
|
||||||
? agent.description.trim()
|
|
||||||
: DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description,
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.availableModesCache = mergeOpenCodeModes(discoveredModes);
|
this.availableModesCache = mergeOpenCodeModes(discoveredModes);
|
||||||
return this.availableModesCache;
|
return this.availableModesCache;
|
||||||
|
|||||||
Reference in New Issue
Block a user