Files
Netcatty/application/state/useCodexConfigModel.ts
T
Netcatty-Botandnetcatty-bot 078353dc87 fix(ai): allow custom model ids in composer picker and persist manual picks (#3535)
* fix(#3534): automated AI fix

* fix: address Codex review on PR #3535

* fix: address Codex review on PR #3535

* fix: address Codex review on PR #3535

* fix: address Codex review on PR #3535

---------

Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com>
2026-09-27 14:57:10 +08:00

40 lines
1.7 KiB
TypeScript

import { useEffect, useMemo, useState } from 'react';
import { getNetcattyBridge } from '../../infrastructure/ai/aiChatStreamingSupport';
import { getManualAgentCommand, matchesManagedAgentConfig } from '../../infrastructure/ai/managedAgents';
import type { ExternalAgentConfig } from '../../infrastructure/ai/types';
/** Share the config probe between the picker and sends, scoped to this agent. */
export function useCodexConfigModel(agent: ExternalAgentConfig | undefined, isVisible: boolean) {
const loadModel = useMemo(() => {
let pending: Promise<string | null> | undefined;
return () => {
pending ??= Promise.resolve().then(async () => {
if (!isVisible || !agent || !matchesManagedAgentConfig(agent, 'codex')) return null;
const info = await getNetcattyBridge()?.aiCodexGetIntegration?.({
codexPath: getManualAgentCommand(agent),
agentEnv: agent.env,
});
return info?.customConfig?.model || null;
}).catch(() => null);
return pending;
};
// Reopening the panel refreshes config changed outside Netcatty.
}, [agent, isVisible]);
const [result, setResult] = useState<{ loadModel: typeof loadModel; model: string | null }>();
useEffect(() => {
if (!isVisible) return;
let cancelled = false;
void loadModel().then(model => {
if (!cancelled) setResult({ loadModel, model });
});
return () => { cancelled = true; };
}, [isVisible, loadModel]);
return {
model: result?.loadModel === loadModel ? result.model : null,
loadModel,
// `model` is null both while the probe is pending and when no locked model
// exists; this flag lets consumers distinguish the unresolved state.
isPending: result?.loadModel !== loadModel,
};
}