Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/FORK_OWNED_FILES
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,9 @@ scripts/check-no-comments.mjs :: check

# --- Fork-owned deps (root package.json has http-proxy-agent@^9 which
# upstream removed; this is what the pnpm-lockfile guard is for) ---
package.json :: http-proxy-agent
package.json :: http-proxy-agent

# --- squeeze-model fork modules (refactor: isolated from upstream hotspots) ---
packages/agent-core-v2/src/agent/fullCompaction/squeezeForkOps.ts :: SqueezeModelDecided
packages/agent-core-v2/src/agent/fullCompaction/squeezeCascade.ts :: resolveSqueezeModelAliasWithCascade
packages/agent-core-v2/src/app/telemetry/forkEvents.ts :: forkTelemetryEventDefinitions
1 change: 1 addition & 0 deletions apps/kimi-code/test/tui/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ auto_install = false
disablePasteBurst: false,
cacheExpiryHint: true,
disableFeedbackSurvey: false,
editorCommand: 'code --wait',
favoriteModels: [],
notifications: { enabled: false, condition: 'always' },
upgrade: { autoInstall: false },
Expand Down
2 changes: 2 additions & 0 deletions apps/vis/server/src/lib/agent-record-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import type {
import type { PermissionSetMode } from '@moonshot-ai/agent-core-v2/agent/permissionMode/permissionModeOps';
import type { PermissionRecordApprovalResult } from '@moonshot-ai/agent-core-v2/agent/permissionRules/permissionRulesOps';
import type { RuntimeSetBinding } from '@moonshot-ai/agent-core-v2/agent/runtimeBinding/runtimeBindingOps';
import type { SqueezeModelDecided } from '@moonshot-ai/agent-core-v2/agent/fullCompaction/squeezeForkOps';
import type { SwarmModeEnter, SwarmModeExit } from '@moonshot-ai/agent-core-v2/features/swarm/swarmOps';
import type { TowerModeEnter, TowerModeExit } from '@moonshot-ai/agent-core-v2/features/tower/towerOps';
import type { ToolsUpdateStore } from '@moonshot-ai/agent-core-v2/features/todo/todoOps';
Expand Down Expand Up @@ -186,6 +187,7 @@ export type AgentRecord =
| WireRecordOf<'prompt.completed', PromptCompleted>
| WireRecordOf<'prompt.steered', PromptSteered>
| WireRecordOf<'runtime.set_binding', RuntimeSetBinding>
| WireRecordOf<'squeeze_model.decided', SqueezeModelDecided>
| WireRecordOf<'swarm_mode.enter', SwarmModeEnter>
| WireRecordOf<'swarm_mode.exit', SwarmModeExit>
| WireRecordOf<'task.started', TaskStarted>
Expand Down
1 change: 1 addition & 0 deletions apps/vis/server/src/lib/context-projector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ export function projectContext(
case 'plan.revision':
case 'plugin.session_start':
case 'runtime.set_binding':
case 'squeeze_model.decided':
case 'staleGuard.recorded':
case 'staleGuard.cleared':
case 'interruptionReminder.recorded':
Expand Down
13 changes: 13 additions & 0 deletions apps/vis/web/src/components/wire/renderers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,19 @@ export const WIRE_RENDERERS: RendererMap = {
}),
},

'squeeze_model.decided': {
tone: 'compaction',
label: 'squeeze',
headline: (r) => ({
main: (
<span className="flex items-center gap-2 min-w-0">
<Mono>{r.model}</Mono>
{r.modelDisplay ? <Dim className="truncate">{r.modelDisplay}</Dim> : null}
</span>
),
}),
},

'staleGuard.recorded': {
tone: 'meta',
label: 'stale',
Expand Down
23 changes: 22 additions & 1 deletion packages/agent-core-v2/docs/state-manifest.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
// references become '(circular)', and class instances collapse to a '(ClassName)'
// marker — the wire shape of an entry is the JSON projection of the type here.
//
// Index (App: 0 keys · Workspace: 6 keys · Session: 9 keys · Agent: 83 keys)
// Index (App: 0 keys · Workspace: 6 keys · Session: 9 keys · Agent: 86 keys)
// App
// Workspace
// workspaceDirs.ephemeralDirs src/workspace/workspaceDirs/workspaceDirsService.ts
Expand Down Expand Up @@ -59,6 +59,7 @@
// contextMemory src/agent/contextMemory/contextOps.ts
// contextProjector.lastRepairSignature src/agent/contextProjector/contextProjectorService.ts
// externalHooks.stopHookContinuationUsed src/features/externalHooks/agent/agentExternalHooksService.ts
// fallbackModel.active src/session/fallback/state.ts
// fileHistory src/features/fileHistory/fileHistoryOps.ts
// fullCompaction src/agent/fullCompaction/compactionOps.ts
// fullCompaction.activeTurnId src/agent/fullCompaction/fullCompactionService.ts
Expand Down Expand Up @@ -102,8 +103,10 @@
// runtime.binding src/agent/runtimeBinding/runtimeBindingService.ts
// runtimeBinding src/agent/runtimeBinding/runtimeBindingOps.ts
// shellCommand.tasks src/agent/shellCommand/shellCommandService.ts
// squeezeModel src/agent/fullCompaction/squeezeForkOps.ts
// stepRetry.failedAttempts src/agent/stepRetry/stepRetryService.ts
// stepRetry.lastFailedDriverId src/agent/stepRetry/stepRetryService.ts
// substituteModel.active src/session/substitute/state.ts
// swarm src/features/swarm/swarmOps.ts
// task src/agent/task/taskOps.ts
// task.activeTaskReminderPending src/agent/task/taskService.ts
Expand Down Expand Up @@ -1188,6 +1191,12 @@ export interface AgentStateSnapshot {
'fullCompaction.consecutiveOverflowCompactions': number;
'fullCompaction.lastCompactedTokenCount': number | null;
'fullCompaction.observedMaxContextTokensByModel': Map<string, number>;
// src/agent/fullCompaction/squeezeForkOps.ts
// replayable · durable — folds: SqueezeModelDecided
'squeezeModel': /* SqueezeModelState — packages/agent-core-v2/src/agent/fullCompaction/squeezeForkOps.ts */ {
readonly model: string;
readonly modelDisplay?: string;
};
// src/agent/interruptionReminder/interruptionReminderOps.ts
// replayable · durable — folds: InterruptionReminderRecorded
'interruptionReminder': null;
Expand Down Expand Up @@ -1221,6 +1230,7 @@ export interface AgentStateSnapshot {
readonly thinkingLevel: /* ThinkingEffort — packages/agent-core-v2/src/kosong/contract/provider.ts */ 'off' | 'on' | (string & {});
readonly reservedContextSize: number | undefined;
readonly compactionTriggerRatio: number | undefined;
readonly compactionTokenBudget: number | undefined;
};
readonly params: /* ModelRequestParams — packages/agent-core-v2/src/kosong/model/modelRequester.ts */ {
readonly cacheKey?: string;
Expand Down Expand Up @@ -1534,6 +1544,17 @@ export interface AgentStateSnapshot {
'tower.base': string | null;
// replayable · durable — folds: TowerModeEnter, TowerModeExit
'tower.owner': string | undefined;
// src/session/fallback/state.ts
'fallbackModel.active': /* ActiveFallbackModel — packages/agent-core-v2/src/session/fallback/state.ts */ {
readonly alias: string;
readonly tier: 'primary' | 'secondary';
} | undefined;
// src/session/substitute/state.ts
'substituteModel.active': /* ActiveSubstituteModel — packages/agent-core-v2/src/session/substitute/state.ts */ {
readonly alias: string;
readonly primaryAlias: string;
readonly until: number;
} | undefined;
}

export type AgentStateKey = keyof AgentStateSnapshot;
17 changes: 16 additions & 1 deletion packages/agent-core-v2/docs/wire-manifest.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// cross-reducers), blobs (the folding states whose blob codec offloads inline
// media to blob storage), owner (the source file declaring the class).

// Index (60 record types)
// Index (61 record types)
// config.update profile src/agent/profile/profileOps.ts
// context.append_loop_event contextMemory, turn src/agent/contextMemory/contextEvents.ts
// context.append_message contextMemory, plan, task.notificationDelivery src/agent/contextMemory/contextEvents.ts
Expand Down Expand Up @@ -62,6 +62,7 @@
// prompt.completed promptResolution src/agent/prompt/promptService.ts
// prompt.steered promptResolution src/agent/prompt/promptService.ts
// runtime.set_binding runtimeBinding src/agent/runtimeBinding/runtimeBindingOps.ts
// squeeze_model.decided (none) src/agent/fullCompaction/squeezeForkOps.ts
// swarm_mode.enter swarm src/features/swarm/swarmOps.ts
// swarm_mode.exit contextMemory, swarm src/features/swarm/swarmOps.ts
// task.started task src/agent/task/taskOps.ts
Expand Down Expand Up @@ -268,6 +269,8 @@ interface FullCompactionBeginPayload {
instruction?: string;
/** CompactionSource */
source: 'manual' | 'auto';
model?: string;
modelDisplay?: string;
}

/**
Expand Down Expand Up @@ -596,6 +599,17 @@ interface RuntimeSetBindingPayload {
runtimeId: string;
}

/**
* states: (none)
* owner: src/agent/fullCompaction/squeezeForkOps.ts
*/
interface SqueezeModelDecidedPayload {
_name: 'squeeze_model.decided';
agentId: string;
model: string;
modelDisplay?: string;
}

/**
* states: swarm
* owner: src/features/swarm/swarmOps.ts
Expand Down Expand Up @@ -953,6 +967,7 @@ interface WirePayloadMap {
"prompt.completed": PromptCompletedPayload;
"prompt.steered": PromptSteeredPayload;
"runtime.set_binding": RuntimeSetBindingPayload;
"squeeze_model.decided": SqueezeModelDecidedPayload;
"swarm_mode.enter": SwarmModeEnterPayload;
"swarm_mode.exit": SwarmModeExitPayload;
"task.started": TaskStartedPayload;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ import {
FullCompactionCancel,
FullCompactionComplete,
} from './compactionOps';
import { resolveSqueezeModelAliasWithCascade } from './squeezeCascade';
import { SqueezeModelDecided, squeezeModelKey } from './squeezeForkOps';
import {
type CompactionBeginData,
type CompactionResult,
Expand Down Expand Up @@ -182,6 +184,7 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom
this.states.contributeState(fullCompactionLastCompactedTokenCountKey);
this.states.contributeState(fullCompactionConsecutiveOverflowCompactionsKey);
this.states.contributeState(fullCompactionActiveTurnIdKey);
this.states.contributeState(squeezeModelKey);
this.strategy = new RuntimeCompactionStrategy(
() => this.resolveModelContextWithEffectiveMax(),
(message) => this.tokenCounting.estimateMessage(message),
Expand Down Expand Up @@ -351,47 +354,11 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom
this.observedMaxContextTokensByModel.set(modelAlias, observed);
}

private resolveSqueezeModelAliasWithCascade(currentModelAlias: string): string {
const overrides = this.profile.getAllSessionModelOverrides();
const binding = compactionModelBindingFor(this.configService, this.flags, {
modelAlias: currentModelAlias,
thinkingLevel: this.profile.data().thinkingLevel,
}, { compactionAlias: overrides.compaction });
const primaryAlias = binding.model;
if (primaryAlias !== currentModelAlias) {
try {
this.profile.resolveModelContextFor(primaryAlias);
return primaryAlias;
} catch {
}
}
const secondaryAlias = resolveCompactionSecondaryModel(this.configService, this.flags, {
compactionSecondaryAlias: overrides.compactionSecondary,
});
if (
secondaryAlias !== undefined &&
secondaryAlias !== currentModelAlias &&
secondaryAlias !== primaryAlias
) {
try {
this.profile.resolveModelContextFor(secondaryAlias);
return secondaryAlias;
} catch {
}
}
return currentModelAlias;
}

begin(input: FullCompactionInput): boolean {
if (this._compacting) return false;
const data: CompactionBeginData = { source: input.source, instruction: input.instruction };
const profileData = this.profile.data();
const currentModelAlias = profileData.modelAlias;
if (currentModelAlias !== undefined) {
const squeezeAlias = this.resolveSqueezeModelAliasWithCascade(currentModelAlias);
data.model = squeezeAlias;
data.modelDisplay = compactionDisplayModel(this.configService, squeezeAlias);
}
if (!this.reserveCompactionSlot(data.source)) return false;

const tokenCount = this.validateCompactionStart(data.source);
Expand All @@ -409,6 +376,22 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom
new FullCompactionBegin({ ...data, agentId: this.agent.agentId }),
);

if (currentModelAlias !== undefined) {
const squeezeResult = resolveSqueezeModelAliasWithCascade({
currentModelAlias,
profile: this.profile,
configService: this.configService,
flags: this.flags,
});
void this.dispatcher.dispatch(
new SqueezeModelDecided({
agentId: this.agent.agentId,
model: squeezeResult.alias,
modelDisplay: compactionDisplayModel(this.configService, squeezeResult.alias),
}),
);
}

const active = this.createActiveCompaction(
data.source,
tokenCount,
Expand Down
53 changes: 53 additions & 0 deletions packages/agent-core-v2/src/agent/fullCompaction/squeezeCascade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { IConfigService } from '#/app/config/config';
import type { IFlagService } from '#/app/flag/flag';
import {
compactionModelBindingFor,
resolveCompactionSecondaryModel,
} from '#/session/compaction/configSection';
import type { IAgentProfileService } from '#/agent/profile/profile';

export interface SqueezeCascadeInput {
readonly currentModelAlias: string;
readonly profile: IAgentProfileService;
readonly configService: IConfigService;
readonly flags: IFlagService;
}

export interface SqueezeCascadeResult {
readonly alias: string;
readonly isSqueezed: boolean;
}

export function resolveSqueezeModelAliasWithCascade(
input: SqueezeCascadeInput,
): SqueezeCascadeResult {
const { currentModelAlias, profile, configService, flags } = input;
const overrides = profile.getAllSessionModelOverrides();
const binding = compactionModelBindingFor(configService, flags, {
modelAlias: currentModelAlias,
thinkingLevel: profile.data().thinkingLevel,
}, { compactionAlias: overrides.compaction });
const primaryAlias = binding.model;
if (primaryAlias !== currentModelAlias) {
try {
profile.resolveModelContextFor(primaryAlias);
return { alias: primaryAlias, isSqueezed: true };
} catch {
}
}
const secondaryAlias = resolveCompactionSecondaryModel(configService, flags, {
compactionSecondaryAlias: overrides.compactionSecondary,
});
if (
secondaryAlias !== undefined &&
secondaryAlias !== currentModelAlias &&
secondaryAlias !== primaryAlias
) {
try {
profile.resolveModelContextFor(secondaryAlias);
return { alias: secondaryAlias, isSqueezed: true };
} catch {
}
}
return { alias: currentModelAlias, isSqueezed: false };
}
44 changes: 44 additions & 0 deletions packages/agent-core-v2/src/agent/fullCompaction/squeezeForkOps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */
import { z } from 'zod';

import { AgentEvent2 } from '#/app/event/event2';
import { defineState } from '#/state/state';

export interface SqueezeModelDecision {
readonly agentId: string;
readonly model: string;
readonly modelDisplay?: string;
}

const squeezeModelDecidedSchema = z.object({
agentId: z.string(),
model: z.string(),
modelDisplay: z.string().optional(),
});

export class SqueezeModelDecided extends AgentEvent2<
z.infer<typeof squeezeModelDecidedSchema>
> {
static override readonly type = 'squeeze_model.decided';
static override readonly durable = true;
static override readonly schema = squeezeModelDecidedSchema;
}
export interface SqueezeModelDecided {
readonly agentId: string;
readonly model: string;
readonly modelDisplay?: string;
}

export interface SqueezeModelState {
readonly model: string;
readonly modelDisplay?: string;
}

export const squeezeModelKey = defineState<SqueezeModelState>(
'squeezeModel',
() => ({ model: '' }),
).replayable({ schema: z.custom<SqueezeModelState>() })
.on(SqueezeModelDecided, (s, e) => {
s.model = e.model;
s.modelDisplay = e.modelDisplay;
});
Loading
Loading