refactor(context): completely purge legacy worker terminology and reorganize file layout

This commit serves as the final polish for the context architecture unification.

Key Changes:
- **Lexical Cleansing:** Swept the entire `context` module (including tests, documentation, and snapshot configurations) to replace all legacy terms ('worker', 'ContextWorker', 'StateSnapshotWorker') with their modern unified equivalents ('async pipeline', 'AsyncContextProcessor', 'StateSnapshotAsyncProcessor').
- **Registry Cleanup:** Stripped `registry.ts` of `ContextWorkerDef` maps, unifying around a single, clean processor definition registry.
- **File Reorganization:** Dismantled the monolithic `sidecar/` directory (which initially housed both engine machinery and configuration loaders).
  - `pipeline/`: Now houses the core execution engine (`orchestrator`, `inbox`, `contextWorkingBuffer`, `environment`).
  - `config/`: Now exclusively contains the dynamic JSON configuration logic (`SidecarLoader`, `profiles`, `schema`, `registry`).
This commit is contained in:
Your Name
2026-04-10 15:28:39 +00:00
parent a52ded7357
commit ae899acad5
34 changed files with 75 additions and 90 deletions
@@ -4,9 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type { SidecarConfig, PipelineDef } from './types.js';
import type { ContextEnvironment } from './environment.js';
import type { AsyncPipelineDef } from './types.js';
import type { AsyncPipelineDef, SidecarConfig, PipelineDef } from './types.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
// Import factories
import { createToolMaskingProcessor } from '../processors/toolMaskingProcessor.js';
@@ -9,44 +9,30 @@ export interface ContextProcessorDef {
readonly schema: object;
}
export interface ContextWorkerDef {
readonly id: string;
readonly schema: object;
}
/**
* Registry for validating declarative sidecar configuration schemas.
* (Dynamic instantiation has been replaced by static ContextProfiles)
*/
export class SidecarRegistry {
private processors = new Map<string, ContextProcessorDef>();
private workers = new Map<string, ContextWorkerDef>();
registerProcessor(def: ContextProcessorDef) {
this.processors.set(def.id, def);
}
registerWorker(def: ContextWorkerDef) {
this.workers.set(def.id, def);
}
getSchema(id: string): object | undefined {
return this.processors.get(id)?.schema || this.workers.get(id)?.schema;
return this.processors.get(id)?.schema;
}
getSchemaDefs(): { id: string; schema: object }[] {
const defs: { id: string; schema: object }[] = [];
getSchemaDefs(): Array<{ id: string; schema: object }> {
const defs: Array<{ id: string; schema: object }> = [];
for (const def of this.processors.values()) {
if (def.schema) defs.push({ id: def.id, schema: def.schema });
}
for (const def of this.workers.values()) {
if (def.schema) defs.push({ id: def.id, schema: def.schema });
}
return defs;
}
clear() {
this.processors.clear();
this.workers.clear();
}
}
@@ -55,7 +55,7 @@ export function getSidecarConfigSchema(registry?: SidecarRegistry) {
},
processorOptions: {
type: 'object',
description: 'Named hyperparameter configurations for ContextProcessors and Workers.',
description: 'Named hyperparameter configurations for ContextProcessors and AsyncProcessors.',
additionalProperties: processorOptionsMapping
}
},
@@ -36,7 +36,7 @@ export interface SidecarConfig {
maxTokens: number;
};
/**
* Dynamic hyperparameter overrides for individual ContextProcessors and Workers.
* Dynamic hyperparameter overrides for individual ContextProcessors and AsyncProcessors.
* Keys are named identifiers (e.g. "gentleTruncation").
*/
processorOptions?: Record<string, { type: string; options: unknown }>;
@@ -70,20 +70,20 @@ all mutations through a synchronous, blocking pipeline of pure functions, we
guarantee that the context is always modified in a sane, predictable, and
mathematically sound sequence.
### The "Open" Extensions: Processors, Workers, and Inboxes (The Actor Model)
### The "Open" Extensions: Processors, AsyncProcessors, and Inboxes (The Actor Model)
To extend the system, developers author two types of plugins:
1. **Context Processors:** Pure, fast, synchronous functions that take an input
graph and return an immutable mutated graph. They run inside Pipelines.
2. **Context Workers:** Inspired by the **Actor Model**, these are
2. **Context AsyncProcessors:** Inspired by the **Actor Model**, these are
event-triggered background jobs designed for isolated, long-running async
computations (e.g., asking an LLM to distill 50 turns of history).
3. **Inboxes:** Because the graph can only be mutated synchronously, Workers
3. **Inboxes:** Because the graph can only be mutated synchronously, AsyncProcessors
cannot touch the graph directly (preventing race conditions). Instead, they
drop their results via message-passing into point-in-time snapshots called
_Inboxes_. Processors later read from these Inboxes during a synchronous
pipeline run to safely apply the worker's findings.
pipeline run to safely apply the async processor's findings.
## 4. Proofs of Construction
@@ -119,7 +119,7 @@ class ToolMaskingProcessor implements ContextProcessor {
}
```
### Example B: Long-Running Summarization (Worker + Inbox + Processor)
### Example B: Long-Running Summarization (async pipeline + Inbox + Processor)
_Scenario: The user has exceeded their token budget. We need to use an LLM to
summarize the oldest 20 turns of conversation, but we cannot block the user from
@@ -127,10 +127,10 @@ continuing to chat while the LLM generates the summary._
This requires our async-to-sync bridge.
**Step 1: The Worker (Async Analysis)**
**Step 1: The async pipeline (Async Analysis)**
```typescript
class StateSnapshotWorker implements ContextWorker {
class StateSnapshotasync pipeline implements Contextasync pipeline {
// Triggers automatically in the background when the budget is exceeded
async onBudgetExceeded(event: BudgetEvent, inbox: Inbox) {
const agedOutNodes = event.getAgedOutNodes();
@@ -138,7 +138,7 @@ class StateSnapshotWorker implements ContextWorker {
// Slow, async LLM call
const summaryText = await llm.summarize(agedOutNodes);
// The worker CANNOT mutate the graph. It leaves a message in the Inbox.
// The async pipeline CANNOT mutate the graph. It leaves a message in the Inbox.
inbox.deliver('SUMMARY_READY', {
targetNodes: agedOutNodes,
summary: summaryText,
@@ -153,7 +153,7 @@ class StateSnapshotWorker implements ContextWorker {
class StateSnapshotProcessor implements ContextProcessor {
// Runs fast and synchronously during the next Pipeline execution
apply(graph: ContextGraph, inbox: InboxSnapshot): ContextGraph {
// Check if the background worker finished its job
// Check if the async background pipeline finished its job
const messages = inbox.read('SUMMARY_READY');
if (messages.isEmpty()) return graph;
@@ -227,7 +227,7 @@ class MemoryExtractionProcessor implements ContextProcessor {
By treating the Context Graph as an immutable ledger updated only via functional
Pipelines, we have eliminated race conditions and untraceable graph corruption.
By utilizing Workers and Inboxes, we have safely bridged the gap between slow
By utilizing AsyncProcessors and Inboxes, we have safely bridged the gap between slow
LLM analysis and fast, synchronous terminal UI updates.
We recognize this is not the final form—future iterations may require strict
+5 -5
View File
@@ -9,12 +9,12 @@ import type { AgentChatHistory } from '../core/agentChatHistory.js';
import type { ConcreteNode } from './ir/types.js';
import type { ContextEventBus } from './eventBus.js';
import type { ContextTracer } from './tracer.js';
import type { ContextEnvironment } from './sidecar/environment.js';
import type { ContextProfile } from './sidecar/profiles.js';
import type { PipelineOrchestrator } from './sidecar/orchestrator.js';
import type { ContextEnvironment } from './pipeline/environment.js';
import type { ContextProfile } from './config/profiles.js';
import type { PipelineOrchestrator } from './pipeline/orchestrator.js';
import { HistoryObserver } from './historyObserver.js';
import { IrProjector } from './ir/projector.js';
import { ContextWorkingBufferImpl } from './sidecar/contextWorkingBuffer.js';
import { ContextWorkingBufferImpl } from './pipeline/contextWorkingBuffer.js';
export class ContextManager {
// The master state containing the pristine graph and current active graph.
@@ -62,7 +62,7 @@ export class ContextManager {
}
/**
* Safely stops background workers and clears event listeners.
* Safely stops background async pipelines and clears event listeners.
*/
shutdown() {
this.orchestrator.shutdown();
+3 -3
View File
@@ -10,9 +10,9 @@ import { debugLogger } from '../../utils/debugLogger.js';
import type {
ContextEnvironment,
ContextTracer,
} from '../sidecar/environment.js';
import type { PipelineOrchestrator } from '../sidecar/orchestrator.js';
import type { ContextProfile } from '../sidecar/profiles.js';
} from '../pipeline/environment.js';
import type { PipelineOrchestrator } from '../pipeline/orchestrator.js';
import type { ContextProfile } from '../config/profiles.js';
export class IrProjector {
/**
@@ -47,7 +47,7 @@ export class InboxSnapshotImpl implements InboxSnapshot {
* completely erases generic type information (<T>) at runtime, the central array
* can only hold `unknown` payloads. To enforce strict type safety without a central
* registry (which would break decoupling) or heavy runtime validation (Zod schemas),
* we must assert the type boundary here. The contract relies on the Worker and Processor
* we must assert the type boundary here. The contract relies on the async pipeline and Processor
* agreeing on the payload structure associated with the configured topic string.
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
@@ -17,7 +17,7 @@ import type {
AsyncContextProcessor,
ProcessArgs,
} from '../pipeline.js';
import type { PipelineDef, AsyncPipelineDef } from './types.js';
import type { PipelineDef, AsyncPipelineDef } from '../config/types.js';
import type { ContextEventBus } from '../eventBus.js';
import type { ConcreteNode, UserPrompt } from '../ir/types.js';
@@ -180,10 +180,10 @@ describe('PipelineOrchestrator (Component)', () => {
});
});
describe('Asynchronous Worker Events', () => {
describe('Asynchronous async pipeline Events', () => {
it('routes emitChunkReceived to async pipelines with nodes_added trigger', async () => {
const executeSpy = vi.fn();
const asyncProcessor = createMockAsyncProcessor('MyWorker', executeSpy);
const asyncProcessor = createMockAsyncProcessor('MyAsyncProcessor', executeSpy);
setupOrchestrator([], [{
name: 'TestAsync',
@@ -204,7 +204,7 @@ describe('PipelineOrchestrator (Component)', () => {
expect(executeSpy).toHaveBeenCalledTimes(1);
const callArgs = executeSpy.mock.calls[0][0];
expect(callArgs.targets).toEqual([node2]); // Workers only get the target nodes
expect(callArgs.targets).toEqual([node2]); // AsyncProcessors only get the target nodes
});
});
});
@@ -5,7 +5,7 @@
*/
import type { ConcreteNode } from '../ir/types.js';
import type { AsyncPipelineDef, PipelineDef, PipelineTrigger } from './types.js';
import type { AsyncPipelineDef, PipelineDef, PipelineTrigger } from '../config/types.js';
import type {
ContextEnvironment,
ContextEventBus,
@@ -5,7 +5,7 @@
*/
import type { ProcessArgs, ContextProcessor } from '../pipeline.js';
import type { ConcreteNode, UserPrompt } from '../ir/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import { sanitizeFilenamePart } from '../../utils/fileUtils.js';
export function createBlobDegradationProcessor(
@@ -10,7 +10,7 @@ import type {
ProcessArgs,
} from '../pipeline.js';
import type { ConcreteNode } from '../ir/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
export type HistoryTruncationProcessorOptions = BackstopTargetOptions;
@@ -5,7 +5,7 @@
*/
import type { ContextProcessor, ProcessArgs } from '../pipeline.js';
import type { ConcreteNode } from '../ir/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import { debugLogger } from '../../utils/debugLogger.js';
import { getResponseText } from '../../utils/partUtils.js';
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type { ContextProcessor, ProcessArgs } from '../pipeline.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import { truncateProportionally } from '../truncation.js';
import type { ConcreteNode } from '../ir/types.js';
@@ -8,7 +8,7 @@ import type {
ProcessArgs,
BackstopTargetOptions,
} from '../pipeline.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import type { ConcreteNode, RollingSummary } from '../ir/types.js';
import { SnapshotGenerator } from '../utils/snapshotGenerator.js';
import { debugLogger } from '../../utils/debugLogger.js';
@@ -11,15 +11,15 @@ import {
createMockProcessArgs,
} from '../testing/contextTestUtils.js';
import type { InboxMessage } from '../pipeline.js';
import type { InboxSnapshotImpl } from '../sidecar/inbox.js';
import type { InboxSnapshotImpl } from '../pipeline/inbox.js';
describe('StateSnapshotWorker', () => {
describe('StateSnapshotAsyncProcessor', () => {
it('should generate a snapshot and publish it to the inbox', async () => {
const env = createMockEnvironment();
// Spy on the publish method
const publishSpy = vi.spyOn(env.inbox, 'publish');
const worker = createStateSnapshotAsyncProcessor('StateSnapshotWorker', env, { type: 'point-in-time' });
const worker = createStateSnapshotAsyncProcessor('StateSnapshotAsyncProcessor', env, { type: 'point-in-time' });
const nodeA = createDummyNode('ep1', 'USER_PROMPT', 50, {}, 'node-A');
const nodeB = createDummyNode('ep1', 'AGENT_THOUGHT', 60, {}, 'node-B');
@@ -47,7 +47,7 @@ describe('StateSnapshotWorker', () => {
const publishSpy = vi.spyOn(env.inbox, 'publish');
const drainSpy = vi.spyOn(env.inbox, 'drainConsumed');
const worker = createStateSnapshotAsyncProcessor('StateSnapshotWorker', env, { type: 'accumulate' });
const worker = createStateSnapshotAsyncProcessor('StateSnapshotAsyncProcessor', env, { type: 'accumulate' });
const nodeC = createDummyNode('ep2', 'USER_PROMPT', 50, {}, 'node-C');
const targets = [nodeC];
@@ -103,7 +103,7 @@ describe('StateSnapshotWorker', () => {
it('should ignore empty targets', async () => {
const env = createMockEnvironment();
const publishSpy = vi.spyOn(env.inbox, 'publish');
const worker = createStateSnapshotAsyncProcessor('StateSnapshotWorker', env, { type: 'accumulate' });
const worker = createStateSnapshotAsyncProcessor('StateSnapshotAsyncProcessor', env, { type: 'accumulate' });
await worker.process(createMockProcessArgs([], [], []));
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type { AsyncContextProcessor, ProcessArgs } from '../pipeline.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import type { ConcreteNode } from '../ir/types.js';
import { SnapshotGenerator } from '../utils/snapshotGenerator.js';
import { debugLogger } from '../../utils/debugLogger.js';
@@ -30,9 +30,9 @@ export function createStateSnapshotAsyncProcessor(
try {
let nodesToSummarize = [...targets];
let previousConsumedIds: string[] = [];
const workerType = options.type ?? 'point-in-time';
const processorType = options.type ?? 'point-in-time';
if (workerType === 'accumulate') {
if (processorType === 'accumulate') {
// Look for the most recent unconsumed accumulate snapshot in the inbox
const proposedSnapshots = inbox.getMessages<{
newText: string;
@@ -80,13 +80,13 @@ export function createStateSnapshotAsyncProcessor(
...targets.map((t) => t.id),
];
// In V2, workers communicate their work to the inbox, and the processor picks it up.
// In V2, async pipelines communicate their work to the inbox, and the processor picks it up.
env.inbox.publish(
'PROPOSED_SNAPSHOT',
{
newText: snapshotText,
consumedIds: newConsumedIds,
type: workerType,
type: processorType,
},
env.idGenerator,
);
@@ -10,7 +10,7 @@ import {
createDummyNode,
createMockProcessArgs,
} from '../testing/contextTestUtils.js';
import type { InboxSnapshotImpl } from '../sidecar/inbox.js';
import type { InboxSnapshotImpl } from '../pipeline/inbox.js';
describe('StateSnapshotProcessor', () => {
it('should ignore if budget is satisfied', async () => {
@@ -35,7 +35,7 @@ describe('StateSnapshotProcessor', () => {
const targets = [nodeA, nodeB, nodeC];
// The background worker created a snapshot of A and B
// The async background pipeline created a snapshot of A and B
const messages = [
{
id: 'msg-1',
@@ -8,7 +8,7 @@ import type {
ProcessArgs,
BackstopTargetOptions,
} from '../pipeline.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import type { ConcreteNode, Snapshot } from '../ir/types.js';
import { SnapshotGenerator } from '../utils/snapshotGenerator.js';
import { debugLogger } from '../../utils/debugLogger.js';
@@ -5,7 +5,7 @@
*/
import type { ContextProcessor, ProcessArgs } from '../pipeline.js';
import type { ConcreteNode, ToolExecution } from '../ir/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import { sanitizeFilenamePart } from '../../utils/fileUtils.js';
import {
ACTIVATE_SKILL_TOOL_NAME,
@@ -7,11 +7,11 @@
import { ContextManager } from '../contextManager.js';
import { AgentChatHistory } from '../../core/agentChatHistory.js';
import type { Content } from '@google/genai';
import type { ContextProfile } from '../sidecar/profiles.js';
import { ContextEnvironmentImpl } from '../sidecar/environmentImpl.js';
import type { ContextProfile } from '../config/profiles.js';
import { ContextEnvironmentImpl } from '../pipeline/environmentImpl.js';
import { ContextTracer } from '../tracer.js';
import { ContextEventBus } from '../eventBus.js';
import { PipelineOrchestrator } from '../sidecar/orchestrator.js';
import { PipelineOrchestrator } from '../pipeline/orchestrator.js';
import { debugLogger } from '../../utils/debugLogger.js';
import { DeterministicIdGenerator } from '../system/DeterministicIdGenerator.js';
import { InMemoryFileSystem } from '../system/InMemoryFileSystem.js';
@@ -218,7 +218,7 @@ exports[`System Lifecycle Golden Tests > Scenario 2: Under Budget (No Modificati
}
`;
exports[`System Lifecycle Golden Tests > Scenario 3: Worker-Driven Background GC 1`] = `
exports[`System Lifecycle Golden Tests > Scenario 3: Async-Driven Background GC 1`] = `
{
"finalProjection": [
{
@@ -7,7 +7,7 @@
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
import { SimulationHarness } from './SimulationHarness.js';
import { createMockLlmClient } from '../testing/contextTestUtils.js';
import type { ContextProfile } from '../sidecar/profiles.js';
import type { ContextProfile } from '../config/profiles.js';
import { createToolMaskingProcessor } from '../processors/toolMaskingProcessor.js';
import { createBlobDegradationProcessor } from '../processors/blobDegradationProcessor.js';
import { createStateSnapshotProcessor } from '../processors/stateSnapshotProcessor.js';
@@ -61,7 +61,7 @@ describe('System Lifecycle Golden Tests', () => {
buildAsyncPipelines: (env) => [{
name: 'Async',
triggers: ['nodes_aged_out'],
processors: [createStateSnapshotAsyncProcessor('StateSnapshotWorker', env, {})]
processors: [createStateSnapshotAsyncProcessor('StateSnapshotAsyncProcessor', env, {})]
}],
});
@@ -180,7 +180,7 @@ describe('System Lifecycle Golden Tests', () => {
expect(goldenState).toMatchSnapshot();
});
it('Scenario 3: Worker-Driven Background GC', async () => {
it('Scenario 3: Async-Driven Background GC', async () => {
const gcConfig: ContextProfile = {
config: {
budget: { maxTokens: 200, retainedTokens: 100 },
@@ -189,7 +189,7 @@ describe('System Lifecycle Golden Tests', () => {
buildAsyncPipelines: (env) => [{
name: 'Async',
triggers: ['nodes_aged_out'],
processors: [createStateSnapshotAsyncProcessor('StateSnapshotWorker', env, {})]
processors: [createStateSnapshotAsyncProcessor('StateSnapshotAsyncProcessor', env, {})]
}],
};
@@ -201,13 +201,13 @@ describe('System Lifecycle Golden Tests', () => {
{ role: 'model', parts: [{ text: 'B'.repeat(50) }] },
]);
// Turn 1 (Should trigger StateSnapshotWorker because we exceed 100 retainedTokens)
// Turn 1 (Should trigger StateSnapshotasync pipeline because we exceed 100 retainedTokens)
await harness.simulateTurn([
{ role: 'user', parts: [{ text: 'C'.repeat(50) }] },
{ role: 'model', parts: [{ text: 'D'.repeat(50) }] },
]);
// Give the background worker an extra beat to complete its async execution and emit variants
// Give the async background pipeline an extra beat to complete its async execution and emit variants
await new Promise((resolve) => setTimeout(resolve, 50));
// Turn 2
@@ -218,7 +218,7 @@ describe('System Lifecycle Golden Tests', () => {
const goldenState = await harness.getGoldenState();
// We should see ROLLING_SUMMARY nodes injected into the graph, proving the worker ran in the background
// We should see ROLLING_SUMMARY nodes injected into the graph, proving the async pipeline ran in the background
expect(goldenState).toMatchSnapshot();
});
});
@@ -11,19 +11,19 @@ import { InMemoryFileSystem } from '../system/InMemoryFileSystem.js';
import { DeterministicIdGenerator } from '../system/DeterministicIdGenerator.js';
import { randomUUID } from 'node:crypto';
import { ContextTracer } from '../tracer.js';
import { ContextEnvironmentImpl } from '../sidecar/environmentImpl.js';
import { SidecarLoader } from '../sidecar/SidecarLoader.js';
import { SidecarRegistry } from '../sidecar/registry.js';
import { ContextEnvironmentImpl } from '../pipeline/environmentImpl.js';
import { SidecarLoader } from '../config/SidecarLoader.js';
import { SidecarRegistry } from '../config/registry.js';
import { ContextEventBus } from '../eventBus.js';
import { PipelineOrchestrator } from '../sidecar/orchestrator.js';
import { PipelineOrchestrator } from '../pipeline/orchestrator.js';
import type { ConcreteNode, ToolExecution } from '../ir/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import type { Config } from '../../config/config.js';
import type { BaseLlmClient } from '../../core/baseLlmClient.js';
import type { Content, GenerateContentResponse } from '@google/genai';
import { InboxSnapshotImpl } from '../sidecar/inbox.js';
import { InboxSnapshotImpl } from '../pipeline/inbox.js';
import type { InboxMessage, ProcessArgs } from '../pipeline.js';
import type { ContextProfile } from '../sidecar/profiles.js';
import type { ContextProfile } from '../config/profiles.js';
/**
* Creates a valid mock GenerateContentResponse with the provided text.
@@ -172,7 +172,7 @@ export function createMockEnvironment(
* Creates a block of synthetic conversation history designed to consume a specific number of tokens.
* Assumes roughly 4 characters per token for standard English text.
*/
import { ContextWorkingBufferImpl } from '../sidecar/contextWorkingBuffer.js';
import { ContextWorkingBufferImpl } from '../pipeline/contextWorkingBuffer.js';
export function createMockProcessArgs(
targets: ConcreteNode[],
@@ -239,7 +239,7 @@ export function createMockContextConfig(
}
/**
* Wires up a full ContextManager component with an AgentChatHistory and active background workers.
* Wires up a full ContextManager component with an AgentChatHistory and active background async pipelines.
*/
export function setupContextComponentTest(
@@ -281,6 +281,6 @@ export function setupContextComponentTest(
chatHistory,
);
// The async worker is now internally managed by ContextManager
// The async async pipeline is now internally managed by ContextManager
return { chatHistory, contextManager };
}
@@ -3,9 +3,9 @@
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type { ContextProfile } from '../sidecar/profiles.js';
import type { PipelineDef } from '../sidecar/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextProfile } from '../config/profiles.js';
import type { PipelineDef } from '../config/types.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import { createHistoryTruncationProcessor } from '../processors/historyTruncationProcessor.js';
export const testTruncateProfile: ContextProfile = {
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type { ConcreteNode } from '../ir/types.js';
import type { ContextEnvironment } from '../sidecar/environment.js';
import type { ContextEnvironment } from '../pipeline/environment.js';
import { LlmRole } from '../../telemetry/llmRole.js';
export class SnapshotGenerator {