feat(web): per-thread/per-spoon runtime picker and Anthropic OAuth provider profile
This commit is contained in:
1 parent
6ec2e51312
commit
702e53a4ba
4 files changed
+190
-36
No files matched your search
@@ -24,9 +24,17 @@ import {
|
||||
} from '@spoon/ui';
|
||||
|
||||
const efforts = ['minimal', 'low', 'medium', 'high', 'xhigh'] as const;
|
||||
type RuntimeName = 'codex' | 'opencode' | 'claude';
|
||||
|
||||
const runtimeLabels: Record<RuntimeName, string> = {
|
||||
codex: 'Codex',
|
||||
opencode: 'OpenCode',
|
||||
claude: 'Claude',
|
||||
};
|
||||
|
||||
type AgentSettings = {
|
||||
enabled: boolean;
|
||||
runtime?: 'opencode' | 'openai_direct';
|
||||
runtime?: RuntimeName | 'openai_direct';
|
||||
defaultBaseBranch?: string;
|
||||
branchPrefix: string;
|
||||
installCommand?: string;
|
||||
@@ -91,6 +99,7 @@ export const SpoonAgentSettingsForm = ({
|
||||
const [aiProviderProfileId, setAiProviderProfileId] = useState(
|
||||
settings?.aiProviderProfileId ?? '__default',
|
||||
);
|
||||
const [runtime, setRuntime] = useState<RuntimeName | undefined>();
|
||||
const selectedProfile = profiles.find(
|
||||
(profile) =>
|
||||
profile._id ===
|
||||
@@ -118,6 +127,19 @@ export const SpoonAgentSettingsForm = ({
|
||||
: settings.reasoningEffort,
|
||||
);
|
||||
|
||||
const supportedRuntimes = (selectedProfile?.supportedRuntimes ??
|
||||
[]) as RuntimeName[];
|
||||
const settingsRuntime = settings?.runtime as RuntimeName | undefined;
|
||||
const effectiveRuntime =
|
||||
runtime && supportedRuntimes.includes(runtime)
|
||||
? runtime
|
||||
: settingsRuntime && supportedRuntimes.includes(settingsRuntime)
|
||||
? settingsRuntime
|
||||
: supportedRuntimes[0];
|
||||
const runtimeValid = Boolean(
|
||||
effectiveRuntime && supportedRuntimes.includes(effectiveRuntime),
|
||||
);
|
||||
|
||||
const selectableModels = selectedModelProfile?.configured
|
||||
? selectedModelProfile.models
|
||||
: [];
|
||||
@@ -135,7 +157,7 @@ export const SpoonAgentSettingsForm = ({
|
||||
await update({
|
||||
spoonId: spoon._id,
|
||||
enabled,
|
||||
runtime: 'opencode',
|
||||
runtime: effectiveRuntime,
|
||||
defaultBaseBranch,
|
||||
branchPrefix,
|
||||
installCommand: installCommand || undefined,
|
||||
@@ -186,7 +208,25 @@ export const SpoonAgentSettingsForm = ({
|
||||
<div className='grid gap-3 md:grid-cols-2'>
|
||||
<div className='grid gap-2'>
|
||||
<Label>Runtime</Label>
|
||||
<Input value='OpenCode workspace' disabled />
|
||||
<Select
|
||||
value={effectiveRuntime ?? ''}
|
||||
onValueChange={(value) => setRuntime(value as RuntimeName)}
|
||||
disabled={!supportedRuntimes.length}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder='Select a provider profile first' />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{supportedRuntimes.map((name) => (
|
||||
<SelectItem key={name} value={name}>
|
||||
{runtimeLabels[name]}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className='text-muted-foreground text-xs'>
|
||||
Runtimes available for the selected provider profile.
|
||||
</p>
|
||||
</div>
|
||||
<div className='grid gap-2'>
|
||||
<Label>AI provider profile</Label>
|
||||
@@ -400,6 +440,7 @@ export const SpoonAgentSettingsForm = ({
|
||||
onClick={save}
|
||||
disabled={
|
||||
!selectedProfile?.configured ||
|
||||
!runtimeValid ||
|
||||
!selectableModels.some((model) => model.id === selectedAgentModel)
|
||||
}
|
||||
>
|
||||
|
||||
Reference in new issue
Block a user