fix: preserve exploration tool history and cap context budget
This commit is contained in:
1 parent
ee256ad7ce
commit
621f30e437
17 files changed
+211
-23
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
contextPercent,
|
||||
runMode,
|
||||
formatCompactTokens,
|
||||
formatElapsed,
|
||||
parseRunTuning,
|
||||
@@ -35,13 +36,14 @@ describe('run-info.util', () => {
|
||||
|
||||
describe('contextPercent', () => {
|
||||
it('reports one-decimal share of the window and clamps at 100', () => {
|
||||
expect(contextPercent(150_000, 1_000_000)).toBe(15);
|
||||
expect(contextPercent(123_456, 1_000_000)).toBe(12.3);
|
||||
expect(contextPercent(150_000, 300_000)).toBe(50);
|
||||
expect(contextPercent(123_456, 300_000)).toBe(41.2);
|
||||
expect(contextPercent(2_000_000, 1_000_000)).toBe(100);
|
||||
});
|
||||
|
||||
it('falls back to the 1M window and is null when usage is unknown', () => {
|
||||
expect(contextPercent(250_000, undefined)).toBe(25);
|
||||
it('falls back to the 300k window and is null when usage is unknown', () => {
|
||||
expect(contextPercent(150_000, undefined)).toBe(50);
|
||||
expect(contextPercent(150_000, 1_000_000)).toBe(50);
|
||||
expect(contextPercent(null, 1_000_000)).toBeNull();
|
||||
expect(contextPercent(undefined, 1_000_000)).toBeNull();
|
||||
});
|
||||
@@ -90,3 +92,23 @@ describe('run-info.util', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('runMode', () => {
|
||||
const model = { name: 'mimo-v2.6-pro', id: 'mimo-v2.6-pro', provider: 'openai', architecture: 'flash' };
|
||||
it('uses recorded execution mode, never the API model name', () => {
|
||||
expect(runMode({ profile: 'pro' }, model)).toBe('pro');
|
||||
expect(runMode(null, model)).toBe('flash');
|
||||
expect(runMode(null, { ...model, name: 'mimo-v2.6-pro', architecture: undefined })).toBe('unknown');
|
||||
});
|
||||
it('distinguishes exploration from a Flash or Pro validation rerun', () => {
|
||||
expect(runMode({ profile: 'pro', exploration_kind: 'exploration' }, model)).toBe('explore');
|
||||
expect(runMode({ profile: 'pro', exploration_kind: 'validation' }, model)).toBe('pro');
|
||||
expect(runMode({ profile: 'flash', exploration_kind: 'validation' }, model)).toBe('flash');
|
||||
});
|
||||
it('supports older saved mode names without defaulting missing data to Flash', () => {
|
||||
expect(runMode(null, { ...model, name: 'ARTEMIS Pro', architecture: undefined })).toBe('pro');
|
||||
expect(runMode(null, { ...model, name: '探索', architecture: undefined })).toBe('explore');
|
||||
expect(runMode(null, null)).toBe('unknown');
|
||||
});
|
||||
});
|
||||
@@ -27,10 +27,24 @@ import {
|
||||
DEFAULT_EXPLORER_MODE,
|
||||
DEFAULT_VERIFICATION_LEVEL
|
||||
} from '../core/models/pro-tuning.model';
|
||||
import { SessionRunTuning } from '../core/models/session.model';
|
||||
import { ModelInfo, Session, SessionRunTuning } from '../core/models/session.model';
|
||||
|
||||
/** Denominator for "context used" when the backend does not report one. */
|
||||
export const OPERATOR_CONTEXT_WINDOW_TOKENS = 1_000_000;
|
||||
export const OPERATOR_CONTEXT_WINDOW_TOKENS = 300_000;
|
||||
|
||||
/** Execution mode is independent of the API model name (e.g. MiMo Pro). */
|
||||
export function runMode(session?: Partial<Session> | null, model?: ModelInfo | null): 'flash' | 'pro' | 'explore' | 'unknown' {
|
||||
if (session?.exploration_kind === 'exploration') return 'explore';
|
||||
const recorded = session?.profile || session?.model_info?.architecture || model?.architecture;
|
||||
const mode = (recorded || session?.model_info?.name || model?.name || '').toLowerCase().replace(/^artemis\s+/, '');
|
||||
if (mode === '探索' || mode === 'explore') return 'explore';
|
||||
return mode === 'flash' || mode === 'pro' ? mode : 'unknown';
|
||||
}
|
||||
|
||||
export function contextWindow(windowTokens?: number | null): number {
|
||||
const value = Number(windowTokens);
|
||||
return value > 0 && Number.isFinite(value) ? Math.min(value, OPERATOR_CONTEXT_WINDOW_TOKENS) : OPERATOR_CONTEXT_WINDOW_TOKENS;
|
||||
}
|
||||
|
||||
/** `42s`, `12m 05s`, `1h 02m 05s`. Negative or invalid input reads as `0s`. */
|
||||
export function formatElapsed(totalSeconds: number | null | undefined): string {
|
||||
@@ -58,7 +72,7 @@ export function contextPercent(
|
||||
windowTokens: number | null | undefined
|
||||
): number | null {
|
||||
const used = Number(usedTokens);
|
||||
const window = Number(windowTokens) || OPERATOR_CONTEXT_WINDOW_TOKENS;
|
||||
const window = contextWindow(windowTokens);
|
||||
if (!Number.isFinite(used) || used < 0 || usedTokens === null || usedTokens === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user