docs: effort 级别描述去掉模型名限制

This commit is contained in:
claude-code-best 2026-05-22 20:11:12 +08:00 committed by James Feng
parent 9ae258f917
commit af7af8cc9d
3 changed files with 82 additions and 80 deletions

View File

@ -1,11 +1,11 @@
import * as React from 'react' import * as React from 'react';
import { useMainLoopModel } from '../../hooks/useMainLoopModel.js' import { useMainLoopModel } from '../../hooks/useMainLoopModel.js';
import { import {
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
logEvent, logEvent,
} from '../../services/analytics/index.js' } from '../../services/analytics/index.js';
import { useAppState, useSetAppState } from '../../state/AppState.js' import { useAppState, useSetAppState } from '../../state/AppState.js';
import type { LocalJSXCommandOnDone } from '../../types/command.js' import type { LocalJSXCommandOnDone } from '../../types/command.js';
import { import {
type EffortValue, type EffortValue,
getDisplayedEffortLevel, getDisplayedEffortLevel,
@ -13,171 +13,157 @@ import {
getEffortValueDescription, getEffortValueDescription,
isEffortLevel, isEffortLevel,
toPersistableEffort, toPersistableEffort,
} from '../../utils/effort.js' } from '../../utils/effort.js';
import { updateSettingsForSource } from '../../utils/settings/settings.js' import { updateSettingsForSource } from '../../utils/settings/settings.js';
const COMMON_HELP_ARGS = ['help', '-h', '--help'] const COMMON_HELP_ARGS = ['help', '-h', '--help'];
type EffortCommandResult = { type EffortCommandResult = {
message: string message: string;
effortUpdate?: { value: EffortValue | undefined } effortUpdate?: { value: EffortValue | undefined };
} };
function setEffortValue(effortValue: EffortValue): EffortCommandResult { function setEffortValue(effortValue: EffortValue): EffortCommandResult {
const persistable = toPersistableEffort(effortValue) const persistable = toPersistableEffort(effortValue);
if (persistable !== undefined) { if (persistable !== undefined) {
const result = updateSettingsForSource('userSettings', { const result = updateSettingsForSource('userSettings', {
effortLevel: persistable, effortLevel: persistable,
}) });
if (result.error) { if (result.error) {
return { return {
message: `Failed to set effort level: ${result.error.message}`, message: `Failed to set effort level: ${result.error.message}`,
} };
} }
} }
logEvent('tengu_effort_command', { logEvent('tengu_effort_command', {
effort: effort: effortValue as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
effortValue as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, });
})
// Env var wins at resolveAppliedEffort time. Only flag it when it actually // Env var wins at resolveAppliedEffort time. Only flag it when it actually
// conflicts — if env matches what the user just asked for, the outcome is // conflicts — if env matches what the user just asked for, the outcome is
// the same, so "Set effort to X" is true and the note is noise. // the same, so "Set effort to X" is true and the note is noise.
const envOverride = getEffortEnvOverride() const envOverride = getEffortEnvOverride();
if (envOverride !== undefined && envOverride !== effortValue) { if (envOverride !== undefined && envOverride !== effortValue) {
const envRaw = process.env.CLAUDE_CODE_EFFORT_LEVEL const envRaw = process.env.CLAUDE_CODE_EFFORT_LEVEL;
if (persistable === undefined) { if (persistable === undefined) {
return { return {
message: `Not applied: CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides effort this session, and ${effortValue} is session-only (nothing saved)`, message: `Not applied: CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides effort this session, and ${effortValue} is session-only (nothing saved)`,
effortUpdate: { value: effortValue }, effortUpdate: { value: effortValue },
} };
} }
return { return {
message: `CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides this session — clear it and ${effortValue} takes over`, message: `CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides this session — clear it and ${effortValue} takes over`,
effortUpdate: { value: effortValue }, effortUpdate: { value: effortValue },
} };
} }
const description = getEffortValueDescription(effortValue) const description = getEffortValueDescription(effortValue);
const suffix = persistable !== undefined ? '' : ' (this session only)' const suffix = persistable !== undefined ? '' : ' (this session only)';
return { return {
message: `Set effort level to ${effortValue}${suffix}: ${description}`, message: `Set effort level to ${effortValue}${suffix}: ${description}`,
effortUpdate: { value: effortValue }, effortUpdate: { value: effortValue },
} };
} }
export function showCurrentEffort( export function showCurrentEffort(appStateEffort: EffortValue | undefined, model: string): EffortCommandResult {
appStateEffort: EffortValue | undefined, const envOverride = getEffortEnvOverride();
model: string, const effectiveValue = envOverride === null ? undefined : (envOverride ?? appStateEffort);
): EffortCommandResult {
const envOverride = getEffortEnvOverride()
const effectiveValue =
envOverride === null ? undefined : (envOverride ?? appStateEffort)
if (effectiveValue === undefined) { if (effectiveValue === undefined) {
const level = getDisplayedEffortLevel(model, appStateEffort) const level = getDisplayedEffortLevel(model, appStateEffort);
return { message: `Effort level: auto (currently ${level})` } return { message: `Effort level: auto (currently ${level})` };
} }
const description = getEffortValueDescription(effectiveValue) const description = getEffortValueDescription(effectiveValue);
return { return {
message: `Current effort level: ${effectiveValue} (${description})`, message: `Current effort level: ${effectiveValue} (${description})`,
} };
} }
function unsetEffortLevel(): EffortCommandResult { function unsetEffortLevel(): EffortCommandResult {
const result = updateSettingsForSource('userSettings', { const result = updateSettingsForSource('userSettings', {
effortLevel: undefined, effortLevel: undefined,
}) });
if (result.error) { if (result.error) {
return { return {
message: `Failed to set effort level: ${result.error.message}`, message: `Failed to set effort level: ${result.error.message}`,
} };
} }
logEvent('tengu_effort_command', { logEvent('tengu_effort_command', {
effort: effort: 'auto' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
'auto' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, });
})
// env=auto/unset (null) matches what /effort auto asks for, so only warn // env=auto/unset (null) matches what /effort auto asks for, so only warn
// when env is pinning a specific level that will keep overriding. // when env is pinning a specific level that will keep overriding.
const envOverride = getEffortEnvOverride() const envOverride = getEffortEnvOverride();
if (envOverride !== undefined && envOverride !== null) { if (envOverride !== undefined && envOverride !== null) {
const envRaw = process.env.CLAUDE_CODE_EFFORT_LEVEL const envRaw = process.env.CLAUDE_CODE_EFFORT_LEVEL;
return { return {
message: `Cleared effort from settings, but CLAUDE_CODE_EFFORT_LEVEL=${envRaw} still controls this session`, message: `Cleared effort from settings, but CLAUDE_CODE_EFFORT_LEVEL=${envRaw} still controls this session`,
effortUpdate: { value: undefined }, effortUpdate: { value: undefined },
} };
} }
return { return {
message: 'Effort level set to auto', message: 'Effort level set to auto',
effortUpdate: { value: undefined }, effortUpdate: { value: undefined },
} };
} }
export function executeEffort(args: string): EffortCommandResult { export function executeEffort(args: string): EffortCommandResult {
const normalized = args.toLowerCase() const normalized = args.toLowerCase();
if (normalized === 'auto' || normalized === 'unset') { if (normalized === 'auto' || normalized === 'unset') {
return unsetEffortLevel() return unsetEffortLevel();
} }
if (!isEffortLevel(normalized)) { if (!isEffortLevel(normalized)) {
return { return {
message: `Invalid argument: ${args}. Valid options are: low, medium, high, max, auto`, message: `Invalid argument: ${args}. Valid options are: low, medium, high, max, auto`,
} };
} }
return setEffortValue(normalized) return setEffortValue(normalized);
} }
function ShowCurrentEffort({ function ShowCurrentEffort({ onDone }: { onDone: (result: string) => void }): React.ReactNode {
onDone, const effortValue = useAppState(s => s.effortValue);
}: { const model = useMainLoopModel();
onDone: (result: string) => void const { message } = showCurrentEffort(effortValue, model);
}): React.ReactNode { onDone(message);
const effortValue = useAppState(s => s.effortValue) return null;
const model = useMainLoopModel()
const { message } = showCurrentEffort(effortValue, model)
onDone(message)
return null
} }
function ApplyEffortAndClose({ function ApplyEffortAndClose({
result, result,
onDone, onDone,
}: { }: {
result: EffortCommandResult result: EffortCommandResult;
onDone: (result: string) => void onDone: (result: string) => void;
}): React.ReactNode { }): React.ReactNode {
const setAppState = useSetAppState() const setAppState = useSetAppState();
const { effortUpdate, message } = result const { effortUpdate, message } = result;
React.useEffect(() => { React.useEffect(() => {
if (effortUpdate) { if (effortUpdate) {
setAppState(prev => ({ setAppState(prev => ({
...prev, ...prev,
effortValue: effortUpdate.value, effortValue: effortUpdate.value,
})) }));
} }
onDone(message) onDone(message);
}, [setAppState, effortUpdate, message, onDone]) }, [setAppState, effortUpdate, message, onDone]);
return null return null;
} }
export async function call( export async function call(onDone: LocalJSXCommandOnDone, _context: unknown, args?: string): Promise<React.ReactNode> {
onDone: LocalJSXCommandOnDone, args = args?.trim() || '';
_context: unknown,
args?: string,
): Promise<React.ReactNode> {
args = args?.trim() || ''
if (COMMON_HELP_ARGS.includes(args)) { if (COMMON_HELP_ARGS.includes(args)) {
onDone( onDone(
'Usage: /effort [low|medium|high|max|xhigh|auto]\\n\\nEffort levels:\\n- low: Quick, straightforward implementation\\n- medium: Balanced approach with standard testing\\n- high: Comprehensive implementation with extensive testing\\n- xhigh: Extended reasoning beyond high\\n- max: Maximum capability with deepest reasoning\\n- auto: Use the default effort level for your model', 'Usage: /effort [low|medium|high|xhigh|max|auto]\n\nEffort levels:\n- low: Quick, straightforward implementation\n- medium: Balanced approach with standard testing\n- high: Comprehensive implementation with extensive testing\n- xhigh: Extended reasoning beyond high\n- max: Maximum capability with deepest reasoning\n- auto: Use the default effort level for your model',
) );
return return;
} }
if (!args || args === 'current' || args === 'status') { if (!args || args === 'current' || args === 'status') {
return <ShowCurrentEffort onDone={onDone} /> return <ShowCurrentEffort onDone={onDone} />;
} }
const result = executeEffort(args) const result = executeEffort(args);
return <ApplyEffortAndClose result={result} onDone={onDone} /> return <ApplyEffortAndClose result={result} onDone={onDone} />;
} }

View File

@ -224,6 +224,22 @@ describe('getEffortLevelDescription', () => {
const desc = getEffortLevelDescription('max') const desc = getEffortLevelDescription('max')
expect(desc).toContain('Maximum') expect(desc).toContain('Maximum')
}) })
test('max description does not contain model names', () => {
const desc = getEffortLevelDescription('max')
expect(desc).not.toContain('Opus')
expect(desc).not.toContain('DeepSeek')
})
test("returns description for 'xhigh'", () => {
const desc = getEffortLevelDescription('xhigh')
expect(desc).toContain('Extended reasoning')
})
test('xhigh description does not contain model names', () => {
const desc = getEffortLevelDescription('xhigh')
expect(desc).not.toContain('Opus')
})
}) })
// ─── resolvePickerEffortPersistence ──────────────────────────────────── // ─── resolvePickerEffortPersistence ────────────────────────────────────

View File

@ -262,9 +262,9 @@ export function getEffortLevelDescription(level: EffortLevel): string {
case 'high': case 'high':
return 'Comprehensive implementation with extensive testing and documentation' return 'Comprehensive implementation with extensive testing and documentation'
case 'xhigh': case 'xhigh':
return 'Extended reasoning beyond high, short of max (Opus 4.7 only)' return 'Extended reasoning beyond high, short of max'
case 'max': case 'max':
return 'Maximum capability with deepest reasoning (Opus 4.6/4.7/DeepSeek V4 Pro)' return 'Maximum capability with deepest reasoning'
} }
} }