Understanding the Agent Scope in agent-core-v2: Isolation and Lifecycle Management in MoonshotAI
The Agent Scope in agent-core-v2 represents the fourth and innermost tier of MoonshotAI's dependency injection kernel, isolating per-agent services, tools, and telemetry state for individual LLM processes while maintaining hierarchical access to parent container resources.
The agent-core-v2 package within the MoonshotAI/kimi-code repository implements a sophisticated four-level DI (Dependency Injection) topology. The Agent Scope sits at the innermost level, encapsulating everything that must live for the duration of a single logical "agent"—from model bindings and system prompts to active tool registries and profile configurations.
The Four-Tier DI Hierarchy
MoonshotAI's architecture organizes dependency containers into a strict parent-child hierarchy. The Agent Scope is declared in packages/agent-core-v2/src/app/scopes.ts and registered with the DI kernel via setScopeTopology to establish this inheritance chain:
| Tier | Parent Relationship | Typical Lifetime | Key Responsibilities |
|---|---|---|---|
| App | Root | Process lifetime | Global services, feature registry |
| Workspace | App → Workspace |
Workspace on disk | Workspace-wide state, tool-policy |
| Session | Workspace → Session |
Terminal/REPL session | Session-level state, model binding |
| Agent | Session → Agent |
Single LLM process | Per-agent services, tool registry, profile, telemetry, state |
When the kernel creates isolated child containers, it uses host.child(LifecycleScope.Agent, …) to instantiate this innermost tier, ensuring each agent receives a fresh service container.
Core Responsibilities of the Agent Scope
Isolation of Per-Agent Services
Each agent receives independent instances of services registered with LifecycleScope.Agent. This prevents state leakage between concurrent agents. In packages/agent-core-v2/src/agent/profile/profileService.ts, the service registration explicitly targets this scope:
registerScopedService(
LifecycleScope.Agent,
IAgentProfileService,
AgentProfileService,
ScopeActivation.OnScopeCreated,
'profile',
);
As noted in the extensive comment block at the top of profileService.ts, agent profiles are "Bound at Agent scope," meaning model configurations and system prompts remain frozen for the agent's entire lifetime.
Feature Contribution Venue
Features can contribute services, tools, or recipes specifically to the Agent scope. The test suite in packages/agent-core-v2/test/features/feature.test.ts (lines 96-100) demonstrates this isolation by registering an IGreeter service and verifying that separate agents receive distinct instances:
this.contributeAgentService(IGreeter, GreeterService);
// Later verification:
expect(agentOne.accessor.get(IGreeter)).not.toBe(agentTwo.accessor.get(IGreeter));
Lifetime-Bounded Resources
Resources such as active tool sets, telemetry contexts (IAgentTelemetryContextService), and state overlays (IAgentStateService) are stored at the Agent level. When an agent shuts down, these resources are automatically released, preventing memory leaks across sessions.
Hierarchical Lookup with Override Capability
If a requested service is not found in the Agent scope, the DI kernel walks up the hierarchy (Session → Workspace → App). This allows agents to inherit higher-level defaults while maintaining the ability to override them with agent-specific implementations.
Working with the Agent Scope: Practical Examples
Registering Agent-Scoped Services
Services must be explicitly registered to the Agent scope to receive per-agent instantiation:
// From packages/agent-core-v2/src/app/scopes.ts
enum LifecycleScope {
App = 'app',
Workspace = 'workspace',
Session = 'session',
Agent = 'agent',
}
// Custom service registration
registerScopedService(
LifecycleScope.Agent,
ICustomAgentLogger,
CustomAgentLogger,
ScopeActivation.OnScopeCreated,
'agentLogger',
);
Creating Agent Containers
Runtime instantiation follows the hierarchical pattern:
const host = createScopedTestHost();
const session = host.child(LifecycleScope.Session, 's1');
const agent = session.createChild(LifecycleScope.Agent, 'agent-1');
// Resolve per-agent profile service
const profileService = agent.accessor.get(IAgentProfileService);
await profileService.bind({ profile: 'default', model: 'gpt-4' });
Contributing Tools to Individual Agents
Features use the Feature API to inject capabilities specific to the Agent scope:
class MyFeature extends Feature {
static override readonly name = 'my-feature';
constructor() {
super();
// Tool available only to agents created after this feature loads
this.contributeTool(ITestTool, TestTool, { name: 'TestTool' });
}
}
Accessing Per-Agent State
Retrieve frozen state values such as active tool configurations:
const activeTools = agent.accessor
.get(IAgentStateService)
.get(profileActiveToolNamesOverlayKey);
console.log('Active tools for this agent:', activeTools);
Key Implementation Files
packages/agent-core-v2/src/app/scopes.ts– Declares theLifecycleScopeenum and registers the topology withsetScopeTopologyto establish parent-child relationships.packages/agent-core-v2/src/agent/profile/profileService.ts– ImplementsAgentProfileService; lines 51-57 contain the scope registration that binds profiles at the Agent level.packages/agent-core-v2/src/features/feature.ts– Core API (lines 84-92) exposingcontributeAgentService()andcontributeTool()for scope-specific feature injection.packages/agent-core-v2/test/features/feature.test.ts– Demonstrates isolation guarantees between agents (lines 90-124), verifying that scoped services are not shared across agent instances.packages/agent-core-v2/test/_base/di/scoped-test-container.test.ts– Validates container creation and disposal behavior for Agent-scoped resources.
Summary
- The Agent Scope is the fourth and innermost tier of the DI hierarchy (App → Workspace → Session → Agent), declared in
packages/agent-core-v2/src/app/scopes.ts. - It guarantees strict isolation of services like
IAgentProfileServiceandIAgentStateService, ensuring each LLM process receives independent instances. - Features contribute tools and services specifically to this scope using
contributeAgentService()andcontributeTool(), with automatic instance separation between agents. - Resources bound at this scope are automatically disposed when the agent shuts down, preventing cross-session memory leaks.
- The scope supports hierarchical resolution, allowing agents to access parent scope resources while maintaining override capabilities for agent-specific configurations.
Frequently Asked Questions
What distinguishes the Agent Scope from the Session Scope in agent-core-v2?
The Session Scope manages terminal or REPL session-level state and model bindings, while the Agent Scope sits one level deeper as the fourth tier, isolating resources for a single LLM process. According to the source code in packages/agent-core-v2/src/app/scopes.ts, the Session acts as the parent container, meaning multiple Agent scopes can exist within a single session, each with independent service instances.
How does the Agent Scope handle service disposal?
When an agent is disposed, the DI kernel automatically disposes all services registered in the Agent scope, ensuring deterministic cleanup of resources like telemetry contexts and active tool registries. This prevents memory leaks and state pollution across different agent instances, as demonstrated in the scoped container tests at packages/agent-core-v2/test/_base/di/scoped-test-container.test.ts.
Can services registered in parent scopes be accessed from within an Agent?
Yes. If a service is not found in the Agent scope, the DI kernel performs hierarchical lookup walking up through Session, Workspace, and App scopes. This allows agents to inherit global defaults while maintaining the ability to override them with agent-specific implementations, providing flexibility while preserving isolation boundaries.
How do features contribute tools exclusively to individual agents?
Features use the contributeAgentService() or contributeTool() methods available in the Feature API, specifying that the contribution targets the Agent scope. As shown in packages/agent-core-v2/test/features/feature.test.ts, this ensures that each agent receives its own instance of the service, such as the IGreeter example where agentOne and agentTwo receive distinct GreeterService instances.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →