diff --git a/src/components/settings/acp-agent-settings.tsx b/src/components/settings/acp-agent-settings.tsx index b8f26df..8a080bb 100644 --- a/src/components/settings/acp-agent-settings.tsx +++ b/src/components/settings/acp-agent-settings.tsx @@ -118,6 +118,7 @@ interface AgentDraft { codexProviderOptions: string[] codexReasoningEffort: CodexReasoningEffort codexSupportsWebsockets: boolean + codexSkills: boolean claudeMainModel: string claudeReasoningModel: string claudeDefaultHaikuModel: string @@ -1142,6 +1143,7 @@ interface CodexTomlImportantValues { providerBaseUrls: Record providerSupportsWebsockets: Record featureResponsesWebsocketsV2: boolean + featureSkills: boolean } interface CodexImportantValues { @@ -1152,6 +1154,7 @@ interface CodexImportantValues { reasoningEffort: CodexReasoningEffort providerOptions: string[] supportsWebsockets: boolean + skills: boolean } const CODEX_DEFAULT_MODEL_PROVIDER = "codeg" @@ -1312,6 +1315,7 @@ function extractCodexTomlImportantValues( let modelReasoningEffort: CodexReasoningEffort = CODEX_DEFAULT_REASONING_EFFORT let featureResponsesWebsocketsV2 = false + let featureSkills = false let currentProviderSection: string | null = null let inFeaturesSection = false @@ -1377,6 +1381,10 @@ function extractCodexTomlImportantValues( featureResponsesWebsocketsV2 = boolAssignment.value continue } + if (inFeaturesSection && boolAssignment.key === "skills") { + featureSkills = boolAssignment.value + continue + } const dottedProviderWebsocketMatch = boolAssignment.key.match( /^model_providers\.([A-Za-z0-9_-]+)\.supports_websockets$/ ) @@ -1390,6 +1398,10 @@ function extractCodexTomlImportantValues( featureResponsesWebsocketsV2 = boolAssignment.value continue } + if (boolAssignment.key === "features.skills") { + featureSkills = boolAssignment.value + continue + } } if (!assignment) continue @@ -1436,6 +1448,7 @@ function extractCodexTomlImportantValues( providerBaseUrls, providerSupportsWebsockets, featureResponsesWebsocketsV2, + featureSkills, } } @@ -1530,6 +1543,7 @@ function extractCodexImportantValues( toml.providerNames ), supportsWebsockets: providerSupportsWebsockets, + skills: toml.featureSkills, } } @@ -1701,7 +1715,14 @@ function upsertTomlSectionBooleanKey( if (assignmentIndex >= 0) { lines[assignmentIndex] = lineText } else { - lines.splice(section.end, 0, lineText) + let insertAt = section.end + for (let i = section.end - 1; i > section.start; i -= 1) { + if (lines[i].trim() !== "") { + insertAt = i + 1 + break + } + } + lines.splice(insertAt, 0, lineText) } return lines.join("\n").trim() } @@ -1927,6 +1948,7 @@ function patchCodexConfigTomlText( modelProvider?: string modelReasoningEffort?: string supportsWebsockets?: boolean + skills?: boolean } ): string { let nextTomlText = configTomlText @@ -2019,6 +2041,14 @@ function patchCodexConfigTomlText( "responses_websockets_v2", shouldEnableFeature ? true : null ) + if (typeof patch.skills === "boolean") { + nextTomlText = upsertTomlSectionBooleanKey( + nextTomlText, + "features", + "skills", + patch.skills ? true : null + ) + } nextTomlText = updateTomlRootBooleanKey( nextTomlText, "disable_response_storage", @@ -2252,6 +2282,7 @@ function buildAgentDraft(agent: AcpAgentInfo): AgentDraft { codexProviderOptions: codexImportant.providerOptions, codexReasoningEffort: codexImportant.reasoningEffort, codexSupportsWebsockets: codexImportant.supportsWebsockets, + codexSkills: codexImportant.skills, claudeMainModel: important.claudeMainModel, claudeReasoningModel: important.claudeReasoningModel, claudeDefaultHaikuModel: important.claudeDefaultHaikuModel, @@ -4432,6 +4463,7 @@ export function AcpAgentSettings() { codexProviderOptions: important.providerOptions, codexReasoningEffort: important.reasoningEffort, codexSupportsWebsockets: important.supportsWebsockets, + codexSkills: important.skills, })) }, [selectedAgent, selectedDraft, updateSelectedDraft] @@ -4454,6 +4486,7 @@ export function AcpAgentSettings() { codexProviderOptions: important.providerOptions, codexReasoningEffort: important.reasoningEffort, codexSupportsWebsockets: important.supportsWebsockets, + codexSkills: important.skills, })) }, [selectedAgent, selectedDraft, updateSelectedDraft] @@ -4505,6 +4538,7 @@ export function AcpAgentSettings() { codexProviderOptions: synced.providerOptions, codexReasoningEffort: synced.reasoningEffort, codexSupportsWebsockets: synced.supportsWebsockets, + codexSkills: synced.skills, })) return } @@ -4537,6 +4571,7 @@ export function AcpAgentSettings() { codexProviderOptions: synced.providerOptions, codexReasoningEffort: synced.reasoningEffort, codexSupportsWebsockets: synced.supportsWebsockets, + codexSkills: synced.skills, })) }, [selectedAgent, selectedDraft, updateSelectedDraft] @@ -4602,6 +4637,7 @@ export function AcpAgentSettings() { codexProviderOptions: synced.providerOptions, codexReasoningEffort: synced.reasoningEffort, codexSupportsWebsockets: synced.supportsWebsockets, + codexSkills: synced.skills, codexAuthJsonText: nextAuth.authJsonText, codexConfigTomlText: nextToml, })) @@ -4637,6 +4673,39 @@ export function AcpAgentSettings() { codexProviderOptions: synced.providerOptions, codexReasoningEffort: synced.reasoningEffort, codexSupportsWebsockets: synced.supportsWebsockets, + codexSkills: synced.skills, + codexConfigTomlText: nextToml, + })) + }, + [selectedAgent, selectedDraft, updateSelectedDraft] + ) + + const handleCodexSkillsChange = useCallback( + (enabled: boolean) => { + if ( + !selectedAgent || + !selectedDraft || + selectedAgent.agent_type !== "codex" + ) + return + const nextToml = patchCodexConfigTomlText( + selectedDraft.codexConfigTomlText, + { skills: enabled } + ) + const synced = extractCodexImportantValues( + selectedDraft.codexAuthJsonText, + nextToml + ) + updateSelectedDraft((current) => ({ + ...current, + apiBaseUrl: synced.apiBaseUrl, + apiKey: synced.apiKey ?? current.apiKey, + model: synced.model, + codexModelProvider: synced.modelProvider, + codexProviderOptions: synced.providerOptions, + codexReasoningEffort: synced.reasoningEffort, + codexSupportsWebsockets: synced.supportsWebsockets, + codexSkills: synced.skills, codexConfigTomlText: nextToml, })) }, @@ -5196,6 +5265,19 @@ export function AcpAgentSettings() { +
+
+ + +
+
+