feat: add scratchpad chat model controls

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-22 10:20:17 +01:00
co-authored by Copilot
parent 1b41cbd1e0
commit fd0256d62f
12 changed files with 541 additions and 153 deletions
+1
View File
@@ -6,6 +6,7 @@ export const ipcChannels = {
deletePattern: 'patterns:delete',
createSession: 'sessions:create',
sendSessionMessage: 'sessions:send-message',
updateScratchpadSessionConfig: 'sessions:update-scratchpad-config',
selectProject: 'selection:project',
selectPattern: 'selection:pattern',
selectSession: 'selection:session',
+8 -1
View File
@@ -1,4 +1,4 @@
import type { PatternDefinition } from '@shared/domain/pattern';
import type { PatternDefinition, ReasoningEffort } from '@shared/domain/pattern';
import type { ProjectRecord } from '@shared/domain/project';
import type { SessionEventRecord } from '@shared/domain/event';
import type { WorkspaceState } from '@shared/domain/workspace';
@@ -17,6 +17,12 @@ export interface SendSessionMessageInput {
content: string;
}
export interface UpdateScratchpadSessionConfigInput {
sessionId: string;
model: string;
reasoningEffort: ReasoningEffort;
}
export interface ElectronApi {
loadWorkspace(): Promise<WorkspaceState>;
addProject(): Promise<WorkspaceState>;
@@ -25,6 +31,7 @@ export interface ElectronApi {
deletePattern(patternId: string): Promise<WorkspaceState>;
createSession(input: CreateSessionInput): Promise<WorkspaceState>;
sendSessionMessage(input: SendSessionMessageInput): Promise<void>;
updateScratchpadSessionConfig(input: UpdateScratchpadSessionConfigInput): Promise<WorkspaceState>;
selectProject(projectId?: string): Promise<WorkspaceState>;
selectPattern(patternId?: string): Promise<WorkspaceState>;
selectSession(sessionId?: string): Promise<WorkspaceState>;
+13
View File
@@ -11,6 +11,13 @@ export type OrchestrationMode =
export type PatternAvailability = 'available' | 'preview' | 'unavailable';
export type ReasoningEffort = 'low' | 'medium' | 'high' | 'xhigh';
export const reasoningEffortOptions: ReadonlyArray<{ value: ReasoningEffort; label: string }> = [
{ value: 'low', label: 'Low' },
{ value: 'medium', label: 'Medium' },
{ value: 'high', label: 'High' },
{ value: 'xhigh', label: 'Maximum' },
];
export interface PatternAgentDefinition {
id: string;
name: string;
@@ -45,6 +52,12 @@ const defaultModels = {
gpt53: 'gpt-5.3-codex',
} as const;
const reasoningEffortSet = new Set<ReasoningEffort>(reasoningEffortOptions.map((option) => option.value));
export function isReasoningEffort(value: string | undefined): value is ReasoningEffort {
return value !== undefined && reasoningEffortSet.has(value as ReasoningEffort);
}
export function createBuiltinPatterns(timestamp: string): PatternDefinition[] {
return [
{
+61
View File
@@ -1,6 +1,13 @@
import type { PatternDefinition, ReasoningEffort } from '@shared/domain/pattern';
export type ChatRole = 'system' | 'user' | 'assistant';
export type SessionStatus = 'idle' | 'running' | 'error';
export interface ScratchpadSessionConfig {
model: string;
reasoningEffort?: ReasoningEffort;
}
export interface ChatMessageRecord {
id: string;
role: ChatRole;
@@ -20,4 +27,58 @@ export interface SessionRecord {
status: SessionStatus;
messages: ChatMessageRecord[];
lastError?: string;
scratchpadConfig?: ScratchpadSessionConfig;
}
export function createScratchpadSessionConfig(
pattern: PatternDefinition,
): ScratchpadSessionConfig | undefined {
const primaryAgent = pattern.agents[0];
if (!primaryAgent) {
return undefined;
}
return {
model: primaryAgent.model,
reasoningEffort: primaryAgent.reasoningEffort,
};
}
export function resolveScratchpadSessionConfig(
session: SessionRecord,
pattern: PatternDefinition,
): ScratchpadSessionConfig | undefined {
const defaults = createScratchpadSessionConfig(pattern);
if (!defaults) {
return undefined;
}
const overrideModel = session.scratchpadConfig?.model.trim();
return {
model: overrideModel || defaults.model,
reasoningEffort: session.scratchpadConfig?.reasoningEffort ?? defaults.reasoningEffort,
};
}
export function applyScratchpadSessionConfig(
pattern: PatternDefinition,
session: SessionRecord,
): PatternDefinition {
const config = resolveScratchpadSessionConfig(session, pattern);
const primaryAgent = pattern.agents[0];
if (!config || !primaryAgent) {
return pattern;
}
return {
...pattern,
agents: [
{
...primaryAgent,
model: config.model,
reasoningEffort: config.reasoningEffort,
},
...pattern.agents.slice(1),
],
};
}