refactor: update context handling in team provisioning and UI components
- Replaced references to extended context with limit context in TeamProvisioningService and related components, ensuring consistent terminology. - Updated LaunchTeamDialog and CreateTeamDialog to reflect the new limit context functionality, enhancing user clarity. - Removed the deprecated ExtendedContextCheckbox component and integrated its functionality into the new LimitContextCheckbox. - Adjusted teamSlice to accommodate changes in launch parameters, streamlining the context management process.
This commit is contained in:
parent
da4d98ec2b
commit
1073a51039
7 changed files with 126 additions and 40 deletions
|
|
@ -145,8 +145,17 @@ export class TeamMemberLogsFinder {
|
||||||
since?: string;
|
since?: string;
|
||||||
}
|
}
|
||||||
): Promise<MemberLogSummary[]> {
|
): Promise<MemberLogSummary[]> {
|
||||||
|
const t0 = performance.now();
|
||||||
|
|
||||||
const discovery = await this.discoverProjectSessions(teamName);
|
const discovery = await this.discoverProjectSessions(teamName);
|
||||||
if (!discovery) return [];
|
const tDiscovery = performance.now();
|
||||||
|
|
||||||
|
if (!discovery) {
|
||||||
|
logger.info(
|
||||||
|
`[perf] findLogsForTask(${taskId}) discovery=null ${(tDiscovery - t0).toFixed(0)}ms`
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const sinceMs = this.deriveSinceMs(options);
|
const sinceMs = this.deriveSinceMs(options);
|
||||||
const { projectDir, projectId, config, sessionIds, knownMembers } = discovery;
|
const { projectDir, projectId, config, sessionIds, knownMembers } = discovery;
|
||||||
|
|
@ -171,6 +180,12 @@ export class TeamMemberLogsFinder {
|
||||||
// file missing or unreadable
|
// file missing or unreadable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const tLead = performance.now();
|
||||||
|
|
||||||
|
let totalFiles = 0;
|
||||||
|
let mentionHits = 0;
|
||||||
|
let cacheHits = 0;
|
||||||
|
const cacheSnapshotBefore = this.fileMentionsCache.size;
|
||||||
|
|
||||||
for (const sessionId of sessionIds) {
|
for (const sessionId of sessionIds) {
|
||||||
const subagentsDir = path.join(projectDir, sessionId, 'subagents');
|
const subagentsDir = path.join(projectDir, sessionId, 'subagents');
|
||||||
|
|
@ -183,9 +198,15 @@ export class TeamMemberLogsFinder {
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
if (!file.startsWith('agent-') || !file.endsWith('.jsonl')) continue;
|
if (!file.startsWith('agent-') || !file.endsWith('.jsonl')) continue;
|
||||||
if (file.startsWith('agent-acompact')) continue;
|
if (file.startsWith('agent-acompact')) continue;
|
||||||
|
totalFiles++;
|
||||||
const filePath = path.join(subagentsDir, file);
|
const filePath = path.join(subagentsDir, file);
|
||||||
if (!(await this.fileMentionsTaskIdCached(filePath, teamName, taskId, false, sinceMs)))
|
const cacheSizeBefore = this.fileMentionsCache.size;
|
||||||
|
if (!(await this.fileMentionsTaskIdCached(filePath, teamName, taskId, false, sinceMs))) {
|
||||||
|
if (this.fileMentionsCache.size === cacheSizeBefore) cacheHits++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (this.fileMentionsCache.size === cacheSizeBefore) cacheHits++;
|
||||||
|
mentionHits++;
|
||||||
const attribution = await this.attributeSubagent(filePath, knownMembers);
|
const attribution = await this.attributeSubagent(filePath, knownMembers);
|
||||||
if (!attribution) continue;
|
if (!attribution) continue;
|
||||||
const summary = await this.parseSubagentSummary(
|
const summary = await this.parseSubagentSummary(
|
||||||
|
|
@ -199,6 +220,7 @@ export class TeamMemberLogsFinder {
|
||||||
if (summary) results.push(summary);
|
if (summary) results.push(summary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const tScan = performance.now();
|
||||||
|
|
||||||
const normalizedOwner =
|
const normalizedOwner =
|
||||||
typeof options?.owner === 'string' ? options.owner.trim() : options?.owner;
|
typeof options?.owner === 'string' ? options.owner.trim() : options?.owner;
|
||||||
|
|
@ -281,10 +303,25 @@ export class TeamMemberLogsFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const tOwner = performance.now();
|
||||||
|
|
||||||
return results.sort(
|
const sorted = results.sort(
|
||||||
(a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime()
|
(a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime()
|
||||||
);
|
);
|
||||||
|
const tTotal = performance.now();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
`[perf] findLogsForTask(${taskId}@${teamName}) ` +
|
||||||
|
`total=${(tTotal - t0).toFixed(0)}ms | ` +
|
||||||
|
`discovery=${(tDiscovery - t0).toFixed(0)}ms | ` +
|
||||||
|
`lead=${(tLead - tDiscovery).toFixed(0)}ms | ` +
|
||||||
|
`scan=${(tScan - tLead).toFixed(0)}ms (${totalFiles} files, ${mentionHits} hits, ${cacheHits} cache) | ` +
|
||||||
|
`owner=${(tOwner - tScan).toFixed(0)}ms | ` +
|
||||||
|
`sessions=${sessionIds.length} | cache=${cacheSnapshotBefore}→${this.fileMentionsCache.size} | ` +
|
||||||
|
`results=${sorted.length}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return sorted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -301,8 +338,17 @@ export class TeamMemberLogsFinder {
|
||||||
since?: string;
|
since?: string;
|
||||||
}
|
}
|
||||||
): Promise<{ filePath: string; memberName: string }[]> {
|
): Promise<{ filePath: string; memberName: string }[]> {
|
||||||
|
const t0 = performance.now();
|
||||||
|
|
||||||
const discovery = await this.discoverProjectSessions(teamName);
|
const discovery = await this.discoverProjectSessions(teamName);
|
||||||
if (!discovery) return [];
|
const tDiscovery = performance.now();
|
||||||
|
|
||||||
|
if (!discovery) {
|
||||||
|
logger.info(
|
||||||
|
`[perf] findLogFileRefsForTask(${taskId}) discovery=null ${(tDiscovery - t0).toFixed(0)}ms`
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const sinceMs = this.deriveSinceMs(options);
|
const sinceMs = this.deriveSinceMs(options);
|
||||||
const { projectDir, config, sessionIds, knownMembers } = discovery;
|
const { projectDir, config, sessionIds, knownMembers } = discovery;
|
||||||
|
|
@ -330,6 +376,10 @@ export class TeamMemberLogsFinder {
|
||||||
// file missing or unreadable
|
// file missing or unreadable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const tLead = performance.now();
|
||||||
|
|
||||||
|
let totalFiles = 0;
|
||||||
|
let mentionHits = 0;
|
||||||
|
|
||||||
for (const sessionId of sessionIds) {
|
for (const sessionId of sessionIds) {
|
||||||
const subagentsDir = path.join(projectDir, sessionId, 'subagents');
|
const subagentsDir = path.join(projectDir, sessionId, 'subagents');
|
||||||
|
|
@ -342,11 +392,13 @@ export class TeamMemberLogsFinder {
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
if (!file.startsWith('agent-') || !file.endsWith('.jsonl')) continue;
|
if (!file.startsWith('agent-') || !file.endsWith('.jsonl')) continue;
|
||||||
if (file.startsWith('agent-acompact')) continue;
|
if (file.startsWith('agent-acompact')) continue;
|
||||||
|
totalFiles++;
|
||||||
|
|
||||||
const filePath = path.join(subagentsDir, file);
|
const filePath = path.join(subagentsDir, file);
|
||||||
if (!(await this.fileMentionsTaskIdCached(filePath, teamName, taskId, false, sinceMs))) {
|
if (!(await this.fileMentionsTaskIdCached(filePath, teamName, taskId, false, sinceMs))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
mentionHits++;
|
||||||
|
|
||||||
const attribution = await this.attributeSubagent(filePath, knownMembers);
|
const attribution = await this.attributeSubagent(filePath, knownMembers);
|
||||||
if (!attribution) continue;
|
if (!attribution) continue;
|
||||||
|
|
@ -357,6 +409,7 @@ export class TeamMemberLogsFinder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const tScan = performance.now();
|
||||||
|
|
||||||
const normalizedOwner =
|
const normalizedOwner =
|
||||||
typeof options?.owner === 'string' ? options.owner.trim() : options?.owner;
|
typeof options?.owner === 'string' ? options.owner.trim() : options?.owner;
|
||||||
|
|
@ -432,8 +485,21 @@ export class TeamMemberLogsFinder {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const tOwner = performance.now();
|
||||||
|
|
||||||
const sortedRefs = [...refs].sort((a, b) => b.sortTime - a.sortTime);
|
const sortedRefs = [...refs].sort((a, b) => b.sortTime - a.sortTime);
|
||||||
|
const tTotal = performance.now();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
`[perf] findLogFileRefsForTask(${taskId}@${teamName}) ` +
|
||||||
|
`total=${(tTotal - t0).toFixed(0)}ms | ` +
|
||||||
|
`discovery=${(tDiscovery - t0).toFixed(0)}ms | ` +
|
||||||
|
`lead=${(tLead - tDiscovery).toFixed(0)}ms | ` +
|
||||||
|
`scan=${(tScan - tLead).toFixed(0)}ms (${totalFiles} files, ${mentionHits} hits) | ` +
|
||||||
|
`owner=${(tOwner - tScan).toFixed(0)}ms | ` +
|
||||||
|
`sessions=${sessionIds.length} | results=${sortedRefs.length}`
|
||||||
|
);
|
||||||
|
|
||||||
return sortedRefs.map(({ filePath, memberName }) => ({ filePath, memberName }));
|
return sortedRefs.map(({ filePath, memberName }) => ({ filePath, memberName }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1067,6 +1133,16 @@ export class TeamMemberLogsFinder {
|
||||||
} catch {
|
} catch {
|
||||||
// Skip malformed lines
|
// Skip malformed lines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Early exit: reliable signal found and description extracted — no need to scan further.
|
||||||
|
// Only process_team and routing_sender trigger this; teammate_id is unreliable (identifies
|
||||||
|
// the message sender, not the agent) so we keep scanning for better signals.
|
||||||
|
if (
|
||||||
|
description &&
|
||||||
|
signals.some((s) => s.source === 'process_team' || s.source === 'routing_sender')
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signals.length === 0) return null;
|
if (signals.length === 0) return null;
|
||||||
|
|
|
||||||
|
|
@ -2779,7 +2779,10 @@ export class TeamProvisioningService {
|
||||||
try {
|
try {
|
||||||
child = spawnCli(claudePath, spawnArgs, {
|
child = spawnCli(claudePath, spawnArgs, {
|
||||||
cwd: request.cwd,
|
cwd: request.cwd,
|
||||||
env: { ...shellEnv },
|
env: {
|
||||||
|
...shellEnv,
|
||||||
|
...(request.limitContext ? { CLAUDE_CODE_DISABLE_1M_CONTEXT: '1' } : {}),
|
||||||
|
},
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -2797,7 +2800,10 @@ export class TeamProvisioningService {
|
||||||
claudePath,
|
claudePath,
|
||||||
args: spawnArgs,
|
args: spawnArgs,
|
||||||
cwd: request.cwd,
|
cwd: request.cwd,
|
||||||
env: { ...shellEnv },
|
env: {
|
||||||
|
...shellEnv,
|
||||||
|
...(request.limitContext ? { CLAUDE_CODE_DISABLE_1M_CONTEXT: '1' } : {}),
|
||||||
|
},
|
||||||
prompt,
|
prompt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3182,6 +3188,7 @@ export class TeamProvisioningService {
|
||||||
cwd: request.cwd,
|
cwd: request.cwd,
|
||||||
env: {
|
env: {
|
||||||
...shellEnv,
|
...shellEnv,
|
||||||
|
...(request.limitContext ? { CLAUDE_CODE_DISABLE_1M_CONTEXT: '1' } : {}),
|
||||||
},
|
},
|
||||||
stdio: ['pipe', 'pipe', 'pipe'],
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
});
|
});
|
||||||
|
|
@ -3202,7 +3209,10 @@ export class TeamProvisioningService {
|
||||||
claudePath,
|
claudePath,
|
||||||
args: launchArgs,
|
args: launchArgs,
|
||||||
cwd: request.cwd,
|
cwd: request.cwd,
|
||||||
env: { ...shellEnv },
|
env: {
|
||||||
|
...shellEnv,
|
||||||
|
...(request.limitContext ? { CLAUDE_CODE_DISABLE_1M_CONTEXT: '1' } : {}),
|
||||||
|
},
|
||||||
prompt,
|
prompt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1175,8 +1175,8 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele
|
||||||
const effortLabel = launchParams.effort
|
const effortLabel = launchParams.effort
|
||||||
? launchParams.effort.charAt(0).toUpperCase() + launchParams.effort.slice(1)
|
? launchParams.effort.charAt(0).toUpperCase() + launchParams.effort.slice(1)
|
||||||
: '';
|
: '';
|
||||||
const extLabel = launchParams.extendedContext ? '1M' : '';
|
const limitLabel = launchParams.limitContext ? '200K' : '';
|
||||||
const parts = [modelLabel, effortLabel, extLabel].filter(Boolean).join(' ');
|
const parts = [modelLabel, effortLabel, limitLabel].filter(Boolean).join(' ');
|
||||||
return (
|
return (
|
||||||
<span className="inline-flex items-center gap-1 rounded-full bg-[var(--color-surface-raised)] px-1.5 py-0.5 text-[10px] font-medium text-[var(--color-text-secondary)]">
|
<span className="inline-flex items-center gap-1 rounded-full bg-[var(--color-surface-raised)] px-1.5 py-0.5 text-[10px] font-medium text-[var(--color-text-secondary)]">
|
||||||
{parts}
|
{parts}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';
|
||||||
|
|
||||||
import { AdvancedCliSection } from './AdvancedCliSection';
|
import { AdvancedCliSection } from './AdvancedCliSection';
|
||||||
import { EffortLevelSelector } from './EffortLevelSelector';
|
import { EffortLevelSelector } from './EffortLevelSelector';
|
||||||
import { LimitContextCheckbox } from './ExtendedContextCheckbox';
|
import { LimitContextCheckbox } from './LimitContextCheckbox';
|
||||||
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
import { OptionalSettingsSection } from './OptionalSettingsSection';
|
||||||
import { ProjectPathSelector } from './ProjectPathSelector';
|
import { ProjectPathSelector } from './ProjectPathSelector';
|
||||||
import { SkipPermissionsCheckbox } from './SkipPermissionsCheckbox';
|
import { SkipPermissionsCheckbox } from './SkipPermissionsCheckbox';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { api } from '@renderer/api';
|
import { api } from '@renderer/api';
|
||||||
import { ExtendedContextCheckbox } from '@renderer/components/team/dialogs/ExtendedContextCheckbox';
|
import { LimitContextCheckbox } from '@renderer/components/team/dialogs/LimitContextCheckbox';
|
||||||
import { SkipPermissionsCheckbox } from '@renderer/components/team/dialogs/SkipPermissionsCheckbox';
|
import { SkipPermissionsCheckbox } from '@renderer/components/team/dialogs/SkipPermissionsCheckbox';
|
||||||
import { Button } from '@renderer/components/ui/button';
|
import { Button } from '@renderer/components/ui/button';
|
||||||
import { Checkbox } from '@renderer/components/ui/checkbox';
|
import { Checkbox } from '@renderer/components/ui/checkbox';
|
||||||
|
|
@ -170,8 +170,8 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
// Launch-only state
|
// Launch-only state
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const [extendedContext, setExtendedContextRaw] = useState(
|
const [limitContext, setLimitContextRaw] = useState(
|
||||||
() => localStorage.getItem('team:lastExtendedContext') === 'true'
|
() => localStorage.getItem('team:lastLimitContext') === 'true'
|
||||||
);
|
);
|
||||||
const [clearContext, setClearContext] = useState(false);
|
const [clearContext, setClearContext] = useState(false);
|
||||||
const [conflictDismissed, setConflictDismissed] = useState(false);
|
const [conflictDismissed, setConflictDismissed] = useState(false);
|
||||||
|
|
@ -235,9 +235,9 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
localStorage.setItem('team:lastSelectedModel', value);
|
localStorage.setItem('team:lastSelectedModel', value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setExtendedContext = (value: boolean): void => {
|
const setLimitContext = (value: boolean): void => {
|
||||||
setExtendedContextRaw(value);
|
setLimitContextRaw(value);
|
||||||
localStorage.setItem('team:lastExtendedContext', String(value));
|
localStorage.setItem('team:lastLimitContext', String(value));
|
||||||
};
|
};
|
||||||
|
|
||||||
const setSkipPermissions = (value: boolean): void => {
|
const setSkipPermissions = (value: boolean): void => {
|
||||||
|
|
@ -512,12 +512,12 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
args.push('--verbose', '--setting-sources', 'user,project,local');
|
args.push('--verbose', '--setting-sources', 'user,project,local');
|
||||||
args.push('--mcp-config', '<auto>', '--disallowedTools', 'TeamDelete,TodoWrite');
|
args.push('--mcp-config', '<auto>', '--disallowedTools', 'TeamDelete,TodoWrite');
|
||||||
if (skipPermissions) args.push('--dangerously-skip-permissions');
|
if (skipPermissions) args.push('--dangerously-skip-permissions');
|
||||||
const model = computeEffectiveTeamModel(selectedModel, extendedContext);
|
const model = computeEffectiveTeamModel(selectedModel);
|
||||||
if (model) args.push('--model', model);
|
if (model) args.push('--model', model);
|
||||||
if (selectedEffort) args.push('--effort', selectedEffort);
|
if (selectedEffort) args.push('--effort', selectedEffort);
|
||||||
if (!clearContext) args.push('--resume', '<previous>');
|
if (!clearContext) args.push('--resume', '<previous>');
|
||||||
return args;
|
return args;
|
||||||
}, [isLaunch, skipPermissions, selectedModel, extendedContext, selectedEffort, clearContext]);
|
}, [isLaunch, skipPermissions, selectedModel, selectedEffort, clearContext]);
|
||||||
|
|
||||||
const launchOptionalSummary = useMemo(() => {
|
const launchOptionalSummary = useMemo(() => {
|
||||||
if (!isLaunch) return [];
|
if (!isLaunch) return [];
|
||||||
|
|
@ -526,7 +526,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
if (promptDraft.value.trim()) summary.push('Lead prompt');
|
if (promptDraft.value.trim()) summary.push('Lead prompt');
|
||||||
if (selectedModel) summary.push(`Model: ${selectedModel}`);
|
if (selectedModel) summary.push(`Model: ${selectedModel}`);
|
||||||
if (selectedEffort) summary.push(`Effort: ${selectedEffort}`);
|
if (selectedEffort) summary.push(`Effort: ${selectedEffort}`);
|
||||||
if (extendedContext) summary.push('Extended context');
|
if (limitContext) summary.push('Limited to 200K context');
|
||||||
if (skipPermissions) summary.push('Auto-approve tools');
|
if (skipPermissions) summary.push('Auto-approve tools');
|
||||||
if (clearContext) summary.push('Fresh session');
|
if (clearContext) summary.push('Fresh session');
|
||||||
if (worktreeEnabled && worktreeName.trim()) summary.push(`Worktree: ${worktreeName.trim()}`);
|
if (worktreeEnabled && worktreeName.trim()) summary.push(`Worktree: ${worktreeName.trim()}`);
|
||||||
|
|
@ -537,7 +537,7 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
promptDraft.value,
|
promptDraft.value,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
selectedEffort,
|
selectedEffort,
|
||||||
extendedContext,
|
limitContext,
|
||||||
skipPermissions,
|
skipPermissions,
|
||||||
clearContext,
|
clearContext,
|
||||||
worktreeEnabled,
|
worktreeEnabled,
|
||||||
|
|
@ -590,9 +590,10 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
teamName: effectiveTeamName,
|
teamName: effectiveTeamName,
|
||||||
cwd: effectiveCwd,
|
cwd: effectiveCwd,
|
||||||
prompt: promptDraft.value.trim() || undefined,
|
prompt: promptDraft.value.trim() || undefined,
|
||||||
model: computeEffectiveTeamModel(selectedModel, extendedContext),
|
model: computeEffectiveTeamModel(selectedModel),
|
||||||
effort: (selectedEffort as EffortLevel) || undefined,
|
effort: (selectedEffort as EffortLevel) || undefined,
|
||||||
clearContext: clearContext || undefined,
|
clearContext: clearContext || undefined,
|
||||||
|
limitContext: limitContext || undefined,
|
||||||
skipPermissions,
|
skipPermissions,
|
||||||
worktree: worktreeEnabled && worktreeName.trim() ? worktreeName.trim() : undefined,
|
worktree: worktreeEnabled && worktreeName.trim() ? worktreeName.trim() : undefined,
|
||||||
extraCliArgs: customArgs.trim() || undefined,
|
extraCliArgs: customArgs.trim() || undefined,
|
||||||
|
|
@ -953,11 +954,10 @@ export const LaunchTeamDialog = (props: LaunchTeamDialogProps): React.JSX.Elemen
|
||||||
onValueChange={setSelectedEffort}
|
onValueChange={setSelectedEffort}
|
||||||
id="dialog-effort"
|
id="dialog-effort"
|
||||||
/>
|
/>
|
||||||
<ExtendedContextCheckbox
|
<LimitContextCheckbox
|
||||||
id="launch-extended-context"
|
id="launch-limit-context"
|
||||||
checked={extendedContext}
|
checked={limitContext}
|
||||||
onCheckedChange={setExtendedContext}
|
onCheckedChange={setLimitContext}
|
||||||
disabled={selectedModel === 'haiku'}
|
|
||||||
/>
|
/>
|
||||||
<SkipPermissionsCheckbox
|
<SkipPermissionsCheckbox
|
||||||
id="dialog-skip-permissions"
|
id="dialog-skip-permissions"
|
||||||
|
|
|
||||||
|
|
@ -310,7 +310,7 @@ export interface GlobalTaskDetailState {
|
||||||
export interface TeamLaunchParams {
|
export interface TeamLaunchParams {
|
||||||
model?: string; // 'opus' | 'sonnet' | 'haiku'
|
model?: string; // 'opus' | 'sonnet' | 'haiku'
|
||||||
effort?: EffortLevel;
|
effort?: EffortLevel;
|
||||||
extendedContext?: boolean;
|
limitContext?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TeamSlice {
|
export interface TeamSlice {
|
||||||
|
|
@ -542,15 +542,15 @@ function saveLaunchParams(teamName: string, params: TeamLaunchParams): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse raw model string from TeamLaunchRequest back into base model + extended context flag.
|
* Parse raw model string — simply returns the base model name.
|
||||||
* E.g. 'opus[1m]' → { model: 'opus', extendedContext: true }
|
* The [1m] suffix is no longer used; context limiting is handled via env var.
|
||||||
* 'sonnet' → { model: 'sonnet', extendedContext: false }
|
|
||||||
*/
|
*/
|
||||||
function parseModelString(raw?: string): { model?: string; extendedContext: boolean } {
|
function parseModelString(raw?: string): { model?: string } {
|
||||||
if (!raw) return { extendedContext: false };
|
if (!raw) return {};
|
||||||
|
// Strip legacy [1m] suffix if present in saved data
|
||||||
const match = raw.match(/^(\w+)\[1m\]$/);
|
const match = raw.match(/^(\w+)\[1m\]$/);
|
||||||
if (match) return { model: match[1], extendedContext: true };
|
if (match) return { model: match[1] };
|
||||||
return { model: raw, extendedContext: false };
|
return { model: raw };
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadToolApprovalSettings(): ToolApprovalSettings {
|
function loadToolApprovalSettings(): ToolApprovalSettings {
|
||||||
|
|
@ -1421,12 +1421,12 @@ export const createTeamSlice: StateCreator<AppState, [], [], TeamSlice> = (set,
|
||||||
}
|
}
|
||||||
const response = await unwrapIpc('team:create', () => api.teams.createTeam(request));
|
const response = await unwrapIpc('team:create', () => api.teams.createTeam(request));
|
||||||
|
|
||||||
// Persist per-team launch params (model, effort, extended context)
|
// Persist per-team launch params (model, effort, limit context)
|
||||||
const { model: baseModel, extendedContext } = parseModelString(request.model);
|
const { model: baseModel } = parseModelString(request.model);
|
||||||
const params: TeamLaunchParams = {
|
const params: TeamLaunchParams = {
|
||||||
model: baseModel || 'default',
|
model: baseModel || 'default',
|
||||||
effort: request.effort,
|
effort: request.effort,
|
||||||
extendedContext,
|
limitContext: request.limitContext,
|
||||||
};
|
};
|
||||||
saveLaunchParams(request.teamName, params);
|
saveLaunchParams(request.teamName, params);
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
|
|
@ -1558,12 +1558,12 @@ export const createTeamSlice: StateCreator<AppState, [], [], TeamSlice> = (set,
|
||||||
try {
|
try {
|
||||||
const response = await unwrapIpc('team:launch', () => api.teams.launchTeam(request));
|
const response = await unwrapIpc('team:launch', () => api.teams.launchTeam(request));
|
||||||
|
|
||||||
// Persist per-team launch params (model, effort, extended context)
|
// Persist per-team launch params (model, effort, limit context)
|
||||||
const { model: baseModel, extendedContext } = parseModelString(request.model);
|
const { model: baseModel } = parseModelString(request.model);
|
||||||
const params: TeamLaunchParams = {
|
const params: TeamLaunchParams = {
|
||||||
model: baseModel || 'default',
|
model: baseModel || 'default',
|
||||||
effort: request.effort,
|
effort: request.effort,
|
||||||
extendedContext,
|
limitContext: request.limitContext,
|
||||||
};
|
};
|
||||||
saveLaunchParams(request.teamName, params);
|
saveLaunchParams(request.teamName, params);
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue