lint burn down

This commit is contained in:
Your Name
2026-04-07 02:25:21 +00:00
parent 54e901bf42
commit 61dacecacf
11 changed files with 58 additions and 32 deletions
@@ -30,7 +30,7 @@ describe('ContextManager Barrier Tests', () => {
}
// Set history directly to avoid event races
await chatHistory.set(tinyHistory);
chatHistory.set(tinyHistory);
// 3. Pre-verify baseline length.
const baseline = await contextManager.projectCompressedHistory();
@@ -99,7 +99,7 @@ describe('ContextManager Barrier Tests', () => {
{ role: 'user', parts: [{ text: 'U1' }] },
{ role: 'model', parts: [{ text: 'M1_LARGE!!' }] },
];
await chatHistory.set(history);
chatHistory.set(history);
const projection = await contextManager.projectCompressedHistory();
+2 -2
View File
@@ -8,7 +8,7 @@ import { describe, it, expect } from 'vitest';
import { IrMapper } from './mapper.js';
import { ContextTokenCalculator } from '../utils/contextTokenCalculator.js';
import type { Content } from '@google/genai';
import type { UserPrompt, ToolExecution } from './types.js';
import type { UserPrompt, ToolExecution, AgentThought } from './types.js';
describe('IrMapper', () => {
it('should correctly map a complex conversation into Episodes and back', () => {
@@ -196,7 +196,7 @@ describe('IrMapper', () => {
expect(ep.steps).toHaveLength(3);
expect(ep.steps[0].type).toBe('AGENT_THOUGHT');
expect((ep.steps[0] as any).text).toBe('I will call them concurrently.');
expect((ep.steps[0] as AgentThought).text).toBe('I will call them concurrently.');
expect(ep.steps[1].type).toBe('TOOL_EXECUTION');
expect((ep.steps[1] as ToolExecution).toolName).toBe('tool_one');
@@ -15,7 +15,7 @@ export class BlobDegradationProcessor implements ContextProcessor {
readonly name = 'BlobDegradation';
private env: ContextEnvironment;
constructor(env: ContextEnvironment, options: Record<string, unknown> = {}) {
constructor(env: ContextEnvironment, _options: Record<string, unknown> = {}) {
this.env = env;
}
@@ -10,7 +10,7 @@ import type { ContextEnvironment } from '../sidecar/environment.js';
import type { EpisodeEditor } from '../ir/episodeEditor.js';
export interface EmergencyTruncationProcessorOptions {}
export type EmergencyTruncationProcessorOptions = Record<string, never>;
export class EmergencyTruncationProcessor implements ContextProcessor {
static create(env: ContextEnvironment, options: EmergencyTruncationProcessorOptions): EmergencyTruncationProcessor {
@@ -4,7 +4,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type { IrMetadata } from '../ir/types.js';
import type { ContextAccountingState, ContextProcessor } from '../pipeline.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import { debugLogger } from '../../utils/debugLogger.js';
@@ -125,7 +124,7 @@ export class SemanticCompressionProcessor implements ContextProcessor {
} else {
try {
stringifiedObs = JSON.stringify(rawObs);
} catch (_e) {
} catch {
stringifiedObs = String(rawObs);
}
}
@@ -166,7 +165,7 @@ export class SemanticCompressionProcessor implements ContextProcessor {
observation: newObsObject,
tokens: { intent: intentTokens, observation: newObsTokens },
};
if (!draftStep.metadata) { draftStep.metadata = { transformations: [], currentTokens: 0, originalTokens: 0 } as unknown as IrMetadata };
if (!draftStep.metadata) { draftStep.metadata = { transformations: [], currentTokens: 0, originalTokens: 0 } };
if (!draftStep.metadata.transformations) { draftStep.metadata.transformations = [] };
draftStep.metadata.transformations.push({
processorName: this.name,
@@ -202,8 +201,8 @@ export class SemanticCompressionProcessor implements ContextProcessor {
});
const text = getResponseText(response) ?? '';
return `[Semantic Summary of old ${contentType}]\n${text.trim()}`;
} catch (_e) {
debugLogger.warn('Semantic compression LLM call failed: ' + String(_e));
} catch (e) {
debugLogger.warn(`Semantic compression LLM call failed: ${e}`);
// If we fail to summarize, we just return the original truncated by 50% as a fail-safe, or the original.
// Returning original is safer to prevent data loss on API failure.
return content;
@@ -5,7 +5,7 @@
*/
import type { ContextProcessor, ContextAccountingState } from '../pipeline.js';
import type { Episode, ToolExecution } from '../ir/types.js';
import type { Episode } from '../ir/types.js';
import type { ContextEnvironment, ContextEventBus } from '../sidecar/environment.js';
import { v4 as uuidv4 } from 'uuid';
@@ -33,7 +33,7 @@ export class StateSnapshotProcessor implements ContextProcessor {
constructor(
env: ContextEnvironment,
options: StateSnapshotProcessorOptions,
eventBus: ContextEventBus,
_eventBus: ContextEventBus,
) {
this.env = env;
this.options = options;
@@ -51,8 +51,15 @@ export class StateSnapshotProcessor implements ContextProcessor {
for (let i = 1; i < editor.episodes.length - 1; i++) {
const ep = editor.episodes[i];
selectedEpisodes.push(ep);
let triggerText = '';
if (ep.trigger?.type === 'USER_PROMPT') {
const firstPart = ep.trigger.semanticParts?.[0];
if (firstPart) {
triggerText = firstPart.type === 'text' ? firstPart.text : (firstPart.presentation?.text ?? '');
}
}
deficitAccumulator += this.env.tokenCalculator.estimateTokensForParts([
{ text: (ep.trigger as any)?.semanticParts?.[0]?.text ?? '' },
{ text: triggerText },
{ text: ep.yield?.text ?? '' },
]);
if (deficitAccumulator >= targetDeficit) break;
@@ -82,12 +89,19 @@ Output ONLY the raw factual snapshot, formatted compactly. Do not include markdo
let userPromptText = 'TRANSCRIPT TO SNAPSHOT:\n\n';
for (const ep of episodes) {
if (ep.trigger) {
userPromptText += `USER: ${(ep.trigger as any).semanticParts?.map((p: any) => p.text).join('')}\n`;
if (ep.trigger?.type === 'USER_PROMPT') {
const partsText = ep.trigger.semanticParts.map(p => {
if (p.type === 'text') return p.text;
if (p.presentation) return p.presentation.text;
return '';
}).join('');
userPromptText += `USER: ${partsText}\n`;
} else if (ep.trigger?.type === 'SYSTEM_EVENT') {
userPromptText += `[SYSTEM EVENT: ${ep.trigger.name}]\n`;
}
for (const step of ep.steps) {
if (step.type === 'TOOL_EXECUTION') {
userPromptText += `[Tool Called: ${(step).toolName}]\n`;
userPromptText += `[Tool Called: ${step.toolName}]\n`;
}
}
if (ep.yield) {
@@ -7,6 +7,7 @@ import { describe, it, expect, beforeEach } from 'vitest';
import { SidecarLoader } from './SidecarLoader.js';
import { defaultSidecarProfile } from './profiles.js';
import { InMemoryFileSystem } from '../system/InMemoryFileSystem.js';
import type { Config } from 'src/config/config.js';
describe('SidecarLoader (Fake FS)', () => {
let fileSystem: InMemoryFileSystem;
@@ -17,7 +18,7 @@ describe('SidecarLoader (Fake FS)', () => {
const mockConfig = {
getExperimentalContextSidecarConfig: () => '/path/to/sidecar.json'
} as any;
} as unknown as Config;
it('returns default profile if file does not exist', () => {
const result = SidecarLoader.fromConfig(mockConfig, fileSystem);
@@ -39,7 +39,7 @@ export class PipelineOrchestrator {
}
// The Orchestrator injects standard dependencies required by processors
// If a processor needs the eventBus (like Snapshot), it expects it via constructor.
const instance = processorClass.create(this.env, procDef.options) as unknown as ContextProcessor;
const instance = processorClass.create(this.env, procDef.options);
this.instantiatedProcessors.set(procDef.processorId, instance);
}
}
@@ -69,7 +69,7 @@ export class PipelineOrchestrator {
deficitTokens: event.targetDeficit,
protectedEpisodeIds: new Set()
};
this.executePipelineAsync(pipeline, event.episodes, state);
void this.executePipelineAsync(pipeline, event.episodes, state);
});
}
}
@@ -154,18 +154,30 @@ export class PipelineOrchestrator {
else if (procDef.processorId.includes('Semantic')) vType = 'summary';
const ep = mutation.episode!;
let fallbackText = '';
if (ep.yield?.text) fallbackText = ep.yield.text;
else if (ep.trigger?.type === 'USER_PROMPT') {
const firstPart = ep.trigger.semanticParts?.[0];
if (firstPart) {
fallbackText = firstPart.type === 'text' ? (firstPart.presentation?.text || firstPart.text) : '';
}
}
this.eventBus.emitVariantReady({
targetId: mutation.type === 'replaced' ? mutation.originalIds![0] : ep.id,
variantId,
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
variant: {
variant: (vType === 'snapshot' ? {
status: 'ready',
type: vType,
episode: vType === 'snapshot' ? ep : undefined,
text: vType !== 'snapshot' ? (ep.yield?.text || (ep.trigger as any)?.semanticParts?.[0]?.presentation?.text || '') : undefined,
type: 'snapshot',
episode: ep,
recoveredTokens: ep.yield?.metadata?.currentTokens || 10,
replacedEpisodeIds: mutation.originalIds,
} as any
} : {
status: 'ready',
type: vType,
text: fallbackText,
recoveredTokens: ep.yield?.metadata?.currentTokens || 10,
})
});
}
}
@@ -9,7 +9,7 @@ import type { ContextEnvironment } from './environment.js';
export interface ContextProcessorDef<
TOptions extends Record<string, unknown> = any,
TOptions extends Record<string, unknown> = Record<string, unknown>,
> {
readonly id: string;
readonly schema?: object;
@@ -44,24 +44,24 @@ export class InMemoryFileSystem implements IFileSystem {
return content;
}
writeFileSync(p: string, data: string | Buffer, encoding?: 'utf-8'): void {
writeFileSync(p: string, data: string | Buffer, _encoding?: 'utf-8'): void {
this.files.set(this.normalize(p), data);
}
appendFileSync(p: string, data: string, encoding: 'utf-8'): void {
appendFileSync(p: string, data: string, _encoding: 'utf-8'): void {
const norm = this.normalize(p);
const existing = this.files.get(norm) || '';
const existingStr = Buffer.isBuffer(existing) ? existing.toString('utf8') : existing;
this.files.set(norm, existingStr + data);
}
mkdirSync(p: string, options?: { recursive?: boolean }): void {}
mkdirSync(_p: string, _options?: { recursive?: boolean }): void {}
async writeFile(p: string, data: string | Buffer): Promise<void> {
this.writeFileSync(p, data);
}
async mkdir(p: string, options?: { recursive?: boolean }): Promise<void> {}
async mkdir(_p: string, _options?: { recursive?: boolean }): Promise<void> {}
join(...paths: string[]): string {
return this.normalize(paths.join('/'));
+1 -1
View File
@@ -81,7 +81,7 @@ export class ContextTracer {
'utf-8',
);
} catch (e) {
// fail silently in trace
debugLogger.warn(`Tracing failed: ${e}`);
}
}