import { SystemMessage } from '@langchain/core/messages'; import type { UsageMetadata, BaseMessage } from '@langchain/core/messages'; import type { RunnableConfig, Runnable } from '@langchain/core/runnables'; import type * as t from '@/types'; import type { createPruneMessages } from '@/messages'; import { ContentTypes, Providers } from '@/common'; /** * Encapsulates agent-specific state that can vary between agents in a multi-agent system */ export declare class AgentContext { /** * Create an AgentContext from configuration with token accounting initialization */ static fromConfig(agentConfig: t.AgentInputs, tokenCounter?: t.TokenCounter, indexTokenCountMap?: Record): AgentContext; /** Agent identifier */ agentId: string; /** Human-readable name for this agent (used in handoff context). Falls back to agentId if not provided. */ name?: string; /** Description of what this agent does (used to enrich handoff tool descriptions). */ description?: string; /** Provider for this specific agent */ provider: Providers; /** Client options for this agent */ clientOptions?: t.ClientOptions; /** Token count map indexed by message position */ indexTokenCountMap: Record; /** Canonical pre-run token map used to restore token accounting on reset */ baseIndexTokenCountMap: Record; /** Maximum context tokens for this agent */ maxContextTokens?: number; /** Current usage metadata for this agent */ currentUsage?: Partial; /** Prune messages function configured for this agent */ pruneMessages?: ReturnType; /** Token counter function for this agent */ tokenCounter?: t.TokenCounter; /** Instructions/system message token count */ instructionTokens: number; /** The amount of time that should pass before another consecutive API call */ streamBuffer?: number; /** Last stream call timestamp for rate limiting */ lastStreamCall?: number; /** Tools available to this agent */ tools?: t.GraphTools; /** Graph-managed tools (e.g., handoff tools created by MultiAgentGraph) that bypass event-driven dispatch */ graphTools?: t.GraphTools; /** Tool map for this agent */ toolMap?: t.ToolMap; /** * Tool definitions registry (includes deferred and programmatic tool metadata). * Used for tool search and programmatic tool calling. */ toolRegistry?: t.LCToolRegistry; /** * Serializable tool definitions for event-driven execution. * When provided, ToolNode operates in event-driven mode. */ toolDefinitions?: t.LCTool[]; /** Set of tool names discovered via tool search (to be loaded) */ discoveredToolNames: Set; /** Instructions for this agent */ instructions?: string; /** Additional instructions for this agent */ additionalInstructions?: string; /** * Dynamic context that changes per-request (e.g., current time, user info). * This is NOT included in the system message to preserve cache. * Instead, it's injected as a user message at the start of the conversation. */ dynamicContext?: string; /** Reasoning key for this agent */ reasoningKey: 'reasoning_content' | 'reasoning'; /** Last token for reasoning detection */ lastToken?: string; /** Token type switch state */ tokenTypeSwitch?: 'reasoning' | 'content'; /** Tracks how many reasoning→text transitions have occurred (ensures unique post-reasoning step keys) */ reasoningTransitionCount: number; /** Current token type being processed */ currentTokenType: ContentTypes.TEXT | ContentTypes.THINK | 'think_and_text'; /** Whether tools should end the workflow */ toolEnd: boolean; /** Cached system runnable (created lazily) */ private cachedSystemRunnable?; /** Whether system runnable needs rebuild (set when discovered tools change) */ private systemRunnableStale; /** Cached system message token count (separate from tool tokens) */ private systemMessageTokens; /** Promise for token calculation initialization */ tokenCalculationPromise?: Promise; /** Format content blocks as strings (for legacy compatibility) */ useLegacyContent: boolean; /** Detailed per-tool token breakdown for admin tracking */ private toolsDetail; /** Total tool tokens (sum of all toolsDetail) */ private toolTokensTotal; /** Per-prompt token breakdown for detailed admin reporting */ private promptBreakdown; /** * Handoff context when this agent receives control via handoff. * Contains source and parallel execution info for system message context. */ handoffContext?: { /** Source agent that transferred control */ sourceAgentName: string; /** Names of sibling agents executing in parallel (empty if sequential) */ parallelSiblings: string[]; }; /** * Structured output configuration. * When set, the agent will return a validated JSON response * instead of streaming text. */ structuredOutput?: t.StructuredOutputConfig; /** Optional callback to summarize discarded messages during context pruning */ summarizeCallback?: (messages: BaseMessage[]) => Promise; /** Pre-existing summary loaded from persistent storage, injected into context on new turns */ persistedSummary?: string; /** Summarization configuration controlling trigger strategy, reserve ratio, and EMA calibration */ summarizationConfig?: t.SummarizationConfig; /** Lightweight file manifest for file-aware compaction (IDs and names only, no content) */ fileManifest?: t.FileManifestEntry[]; /** * Workspace-shared system-message tiers. When set, each entry becomes a * separate text block in the SystemMessage with its own cachePoint / * cache_control marker, BEFORE the per-agent `instructions` block. * See {@link t.AgentInputs.system_cache_blocks} for full semantics. */ systemCacheBlocks?: Array<{ text: string; ttl?: '5m' | '1h'; }>; /** TTL hint for the per-agent instructions cache marker. Defaults to '5m'. */ instructionsCacheTtl?: '5m' | '1h'; /** Original AgentInputs used to create this context — used for self-spawn subagent resolution. */ _sourceInputs?: t.AgentInputs; /** Subagent configurations for hierarchical delegation. */ subagentConfigs?: t.SubagentConfig[]; /** Maximum subagent nesting depth. */ maxSubagentDepth?: number; constructor({ agentId, name, description, provider, clientOptions, maxContextTokens, streamBuffer, tokenCounter, tools, toolMap, toolRegistry, toolDefinitions, instructions, additionalInstructions, dynamicContext, reasoningKey, toolEnd, instructionTokens, useLegacyContent, structuredOutput, discoveredTools, summarizeCallback, persistedSummary, summarizationConfig, fileManifest, systemCacheBlocks, instructionsCacheTtl, }: { agentId: string; name?: string; description?: string; provider: Providers; clientOptions?: t.ClientOptions; maxContextTokens?: number; streamBuffer?: number; tokenCounter?: t.TokenCounter; tools?: t.GraphTools; toolMap?: t.ToolMap; toolRegistry?: t.LCToolRegistry; toolDefinitions?: t.LCTool[]; instructions?: string; additionalInstructions?: string; dynamicContext?: string; reasoningKey?: 'reasoning_content' | 'reasoning'; toolEnd?: boolean; instructionTokens?: number; useLegacyContent?: boolean; structuredOutput?: t.StructuredOutputConfig; discoveredTools?: string[]; summarizeCallback?: (messages: BaseMessage[]) => Promise; persistedSummary?: string; summarizationConfig?: t.SummarizationConfig; fileManifest?: t.FileManifestEntry[]; systemCacheBlocks?: Array<{ text: string; ttl?: '5m' | '1h'; }>; instructionsCacheTtl?: '5m' | '1h'; }); /** * Checks if structured output mode is enabled for this agent. * When enabled, the agent will use model.invoke() instead of streaming * and return a validated JSON response. */ get isStructuredOutputMode(): boolean; /** * Gets the structured output schema with normalized defaults. * Returns undefined if structured output is not configured. */ getStructuredOutputSchema(): Record | undefined; /** * Resolves the structured output mode to a concrete method based on provider capabilities. * * Resolution logic: * - 'native' or 'auto' + supported provider → native constrained decoding * - 'native' + unsupported provider → fallback to 'functionCalling' with warning * - 'provider' → LangChain's jsonMode (existing behavior) * - 'tool' → function calling trick (existing behavior) * - 'auto' + unsupported provider → 'functionCalling' * * @returns The resolved method for withStructuredOutput, or 'native' for direct API usage */ resolveStructuredOutputMode(): { method: t.ResolvedStructuredOutputMethod; warnings: string[]; }; /** * Builds instructions text for tools that are ONLY callable via programmatic code execution. * These tools cannot be called directly by the LLM but are available through the * run_tools_with_code tool. * * Includes: * - Code_execution-only tools that are NOT deferred * - Code_execution-only tools that ARE deferred but have been discovered via tool search */ private buildProgrammaticOnlyToolsInstructions; /** * Gets the system runnable, creating it lazily if needed. * Includes instructions, additional instructions, and programmatic-only tools documentation. * Only rebuilds when marked stale (via markToolsAsDiscovered). */ get systemRunnable(): Runnable>> | undefined; /** * Explicitly initializes the system runnable. * Call this before async token calculation to ensure system message tokens are counted first. */ initializeSystemRunnable(): void; /** * Builds the raw instructions string (without creating SystemMessage). * Includes agent identity preamble and handoff context when available. */ private buildInstructionsString; /** * Builds the agent identity preamble including handoff context if present. * This helps the agent understand its role in the multi-agent workflow. */ private buildIdentityPreamble; /** * Build system runnable from pre-built instructions string. * Only called when content has actually changed. */ private buildSystemRunnable; /** * Reset context for a new run */ reset(): void; /** * Update the token count map with instruction tokens */ updateTokenMapWithInstructions(baseTokenMap: Record): void; /** * Calculate tool tokens and add to instruction tokens * Note: System message tokens are calculated during systemRunnable creation * Also tracks per-tool token breakdown for admin reporting */ calculateInstructionTokens(tokenCounter: t.TokenCounter): Promise; /** * Set the per-prompt token breakdown for detailed admin tracking. * Called by the client after assembling all prompt components. * @param breakdown - Object with token counts per prompt component */ setPromptBreakdown(breakdown: { branding?: number; toolRouting?: number; agentInstructions?: number; mcpInstructions?: number; artifacts?: number; memory?: number; }): void; /** * Get a detailed breakdown of context tokens for admin reporting. * This provides visibility into what's consuming the input token budget. * @returns ContextBreakdown object with per-component token counts */ getContextBreakdown(): { instructions: number; artifacts: number; tools: number; toolCount: number; toolContext: number; total: number; toolsDetail: Array<{ name: string; tokens: number; }>; toolContextDetail: Array<{ name: string; tokens: number; }>; prompts?: { branding: number; toolRouting: number; agentInstructions: number; mcpInstructions: number; artifacts: number; memory: number; }; }; /** * Gets the tool registry for deferred tools (for tool search). * @param onlyDeferred If true, only returns tools with defer_loading=true * @returns LCToolRegistry with tool definitions */ getDeferredToolRegistry(onlyDeferred?: boolean): t.LCToolRegistry; /** * Sets the handoff context for this agent. * Call this when the agent receives control via handoff from another agent. * Marks system runnable as stale to include handoff context in system message. * @param sourceAgentName - Name of the agent that transferred control * @param parallelSiblings - Names of other agents executing in parallel with this one */ setHandoffContext(sourceAgentName: string, parallelSiblings: string[]): void; /** * Clears any handoff context. * Call this when resetting the agent or when handoff context is no longer relevant. */ clearHandoffContext(): void; /** * Marks tools as discovered via tool search. * Discovered tools will be included in the next model binding. * Only marks system runnable stale if NEW tools were actually added. * @param toolNames - Array of discovered tool names * @returns true if any new tools were discovered */ markToolsAsDiscovered(toolNames: string[]): boolean; /** * Gets tools that should be bound to the LLM. * In event-driven mode (toolDefinitions present, tools empty), creates schema-only tools. * Otherwise filters tool instances based on: * 1. Non-deferred tools with allowed_callers: ['direct'] * 2. Discovered tools (from tool search) * @returns Array of tools to bind to model */ getToolsForBinding(): t.GraphTools | undefined; /** Creates schema-only tools from toolDefinitions for event-driven mode, merged with native tools */ private getEventDrivenToolsForBinding; /** Filters tool instances for binding based on registry config */ private filterToolsForBinding; }