@robota-sdk/agent-core 3.0.0-beta.63 → 3.0.0-beta.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ID_RADIX","executeStreamFn","processEventHelper","ID_RADIX","validateAgentConfig","ID_RADIX","ID_RANDOM_LENGTH","DEFAULT_TIMEOUT_SECONDS"],"sources":["../../src/interfaces/types.ts","../../src/interfaces/provider-capabilities.ts","../../src/interfaces/provider-definition.ts","../../src/interfaces/media-provider.ts","../../src/interfaces/progress-reporting.ts","../../src/abstracts/abstract-agent.ts","../../src/abstracts/abstract-manager.ts","../../src/interfaces/messages.ts","../../src/utils/logger.ts","../../src/abstracts/ai-provider-helpers.ts","../../src/abstracts/abstract-ai-provider.ts","../../src/agents/constants.ts","../../src/utils/errors.ts","../../src/services/tool-execution-batch.ts","../../src/services/tool-execution-service.ts","../../src/services/execution-constants.ts","../../src/event-service/event-service.ts","../../src/event-service/task-events.ts","../../src/event-service/user-events.ts","../../src/services/execution-event-helpers.ts","../../src/services/execution-types.ts","../../src/services/execution-event-emitter-high-level.ts","../../src/services/execution-event-emitter.ts","../../src/services/plugin-hook-dispatcher.ts","../../src/services/execution-stream-tools.ts","../../src/services/execution-stream.ts","../../src/services/execution-service-helpers.ts","../../src/services/execution-round-provider.ts","../../src/context/models.ts","../../src/context/token-usage.ts","../../src/context/estimation.ts","../../src/services/execution-round-tool-results.ts","../../src/services/execution-round-tools.ts","../../src/services/execution-usage.ts","../../src/services/execution-round-context.ts","../../src/services/execution-round-streaming.ts","../../src/services/execution-round.ts","../../src/services/execution-pipeline.ts","../../src/services/execution-service.ts","../../src/plugins/event-emitter/types.ts","../../src/abstracts/abstract-plugin-types.ts","../../src/abstracts/abstract-plugin.ts","../../src/abstracts/abstract-executor.ts","../../src/abstracts/abstract-tool.ts","../../src/utils/message-converter.ts","../../src/utils/validation.ts","../../src/utils/periodic-task.ts","../../src/managers/conversation-message-factory.ts","../../src/managers/conversation-store-history.ts","../../src/managers/conversation-store.ts","../../src/managers/conversation-history-manager.ts","../../src/executors/local-executor.ts","../../src/utils/env-ref.ts","../../src/plugins/event-emitter/metrics.ts","../../src/plugins/event-emitter-helpers.ts","../../src/plugins/event-emitter-plugin.ts","../../src/managers/module-type-registry-helpers.ts","../../src/managers/module-type-registry.ts","../../src/managers/module-registry-validation.ts","../../src/managers/module-registry.ts","../../src/managers/ai-provider-manager.ts","../../src/tool-registry/tool-registry.ts","../../src/tool-registry/function-tool.ts","../../src/managers/tool-manager.ts","../../src/managers/agent-templates.ts","../../src/managers/agent-factory-helpers.ts","../../src/managers/agent-factory.ts","../../src/core/robota-config-manager.ts","../../src/core/robota-module-manager.ts","../../src/core/robota-plugin-manager.ts","../../src/core/robota-delegate-factory.ts","../../src/services/cache/cache-key-builder.ts","../../src/services/cache/memory-cache-storage.ts","../../src/services/cache/execution-cache-service.ts","../../src/core/robota-initializer.ts","../../src/core/robota-execution.ts","../../src/core/robota-lifecycle.ts","../../src/core/robota-history.ts","../../src/core/robota-events.ts","../../src/core/robota-base.ts","../../src/core/robota.ts","../../src/services/history-module.ts","../../src/utils/execution-proxy-types.ts","../../src/utils/execution-proxy.ts","../../src/permissions/types.ts","../../src/permissions/permission-mode.ts","../../src/permissions/permission-gate.ts","../../src/hooks/executors/command-executor.ts","../../src/hooks/executors/http-executor.ts","../../src/hooks/hook-runner.ts"],"sourcesContent":["/**\n * Agent-specific type definitions\n * Local types for agent functionality - not forced to use base types unless needed for cross-connections\n */\n\nimport type { TUniversalMessage } from './messages';\n\n/**\n * Primitive value types - foundation for all other types\n * Extended to include null/undefined for agent contexts\n */\nexport type TPrimitiveValue = string | number | boolean | null | undefined;\n\n/**\n * Universal value type axis (recursive, JSON-like + Date).\n *\n * IMPORTANT:\n * - This axis is the single source of truth for payload/context/result values.\n * - It must support nested objects/arrays without `any`/`unknown`.\n */\nexport type TUniversalValue = TPrimitiveValue | Date | TUniversalArrayValue | IUniversalObjectValue;\n\nexport type TUniversalArrayValue = TUniversalValue[];\n\nexport interface IUniversalObjectValue {\n [key: string]: TUniversalValue;\n}\n\n/**\n * Metadata type - consistent across agent components\n */\nexport type TMetadataValue = TPrimitiveValue | TUniversalArrayValue | Date;\nexport type TMetadata = Record<string, TMetadataValue>;\n\n/**\n * Context data type - for execution contexts\n */\nexport type TContextData = Record<string, TUniversalValue>;\n\n/**\n * Logger data type - for logging contexts\n */\nexport type TLoggerData = Record<string, TUniversalValue | Date | Error>;\n\n/**\n * Configuration types - for agent configuration\n */\nexport type TComplexConfigValue = Record<\n string,\n TPrimitiveValue | TUniversalArrayValue | IUniversalObjectValue\n>;\nexport type TConfigValue =\n | TPrimitiveValue\n | TUniversalArrayValue\n | IUniversalObjectValue\n | Array<TComplexConfigValue>\n | Array<Record<string, TPrimitiveValue | TUniversalArrayValue | IUniversalObjectValue>>\n | Array<TComplexConfigValue>\n | TComplexConfigValue;\nexport type TConfigData = Record<string, TConfigValue>;\n\n/**\n * Tool parameter value type - specific for tool parameters\n */\nexport type TToolParameters = Record<string, TUniversalValue>;\n\n/**\n * Tool result data type - for tool execution results\n */\n// NOTE:\n// Tool result values are represented by the canonical TUniversalValue axis.\n\n// NOTE:\n// Provider config value types are owned by the provider axis (`interfaces/provider.ts`).\n// Avoid defining provider config interfaces in this value axis module.\n// Do not introduce duplicate provider config value types here.\n\n/**\n * Plugin context type - for plugin execution contexts\n */\nexport interface IPluginContext {\n input?: string;\n response?: string;\n messages?: TUniversalMessage[];\n responseMessage?: TUniversalMessage;\n metadata?: TMetadata;\n error?: Error;\n executionContext?: TContextData;\n}\n\n/**\n * Type utility functions for safe type checking and validation\n * @internal\n */\nexport const TypeUtils = {\n isPrimitive: (value: TUniversalValue): value is TPrimitiveValue => {\n return (\n value === null ||\n value === undefined ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n );\n },\n\n isArray: (value: TUniversalValue): value is TUniversalArrayValue => {\n return Array.isArray(value) && value.every((item) => TypeUtils.isUniversalValue(item));\n },\n\n isObject: (value: TUniversalValue): value is IUniversalObjectValue => {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n Object.values(value).every((val) => TypeUtils.isUniversalValue(val))\n );\n },\n\n isUniversalValue: (value: TUniversalValue): value is TUniversalValue => {\n if (value instanceof Date) return true;\n return TypeUtils.isPrimitive(value) || TypeUtils.isArray(value) || TypeUtils.isObject(value);\n },\n};\n","import type { IAIProvider } from './provider';\n\nexport interface IProviderFunctionCallingCapability {\n supported: boolean;\n reason?: string;\n}\n\nexport interface IProviderNativeWebToolCapability {\n supported: boolean;\n enabled: boolean;\n source?: string;\n reason?: string;\n}\n\nexport interface IProviderNativeWebToolCapabilities {\n webSearch: IProviderNativeWebToolCapability;\n webFetch: IProviderNativeWebToolCapability;\n}\n\nexport interface IProviderCapabilities {\n functionCalling: IProviderFunctionCallingCapability;\n nativeWebTools: IProviderNativeWebToolCapabilities;\n}\n\nexport interface IProviderNativeWebToolRequest {\n webSearch?: boolean;\n webFetch?: boolean;\n}\n\nconst DEFAULT_NATIVE_WEB_SEARCH_REASON = 'Provider does not declare native web search support.';\nconst DEFAULT_NATIVE_WEB_FETCH_REASON = 'Provider does not declare native web fetch support.';\n\nexport function createDefaultProviderCapabilities(\n functionCallingSupported: boolean,\n): IProviderCapabilities {\n return {\n functionCalling: { supported: functionCallingSupported },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n reason: DEFAULT_NATIVE_WEB_SEARCH_REASON,\n },\n webFetch: {\n supported: false,\n enabled: false,\n reason: DEFAULT_NATIVE_WEB_FETCH_REASON,\n },\n },\n };\n}\n\nexport function getProviderCapabilities(provider: IAIProvider): IProviderCapabilities {\n const supportsTools =\n typeof provider.supportsTools === 'function' ? provider.supportsTools() : false;\n return provider.getCapabilities?.() ?? createDefaultProviderCapabilities(supportsTools);\n}\n\nexport function assertProviderNativeWebToolsAvailable(\n providerName: string,\n capabilities: IProviderCapabilities,\n request: IProviderNativeWebToolRequest | undefined,\n): void {\n if (request?.webSearch === true) {\n assertNativeWebToolAvailable(providerName, 'web search', capabilities.nativeWebTools.webSearch);\n }\n if (request?.webFetch === true) {\n assertNativeWebToolAvailable(providerName, 'web fetch', capabilities.nativeWebTools.webFetch);\n }\n}\n\nfunction assertNativeWebToolAvailable(\n providerName: string,\n label: string,\n capability: IProviderNativeWebToolCapability,\n): void {\n if (!capability.supported) {\n throw new Error(\n `Provider ${providerName} does not support native ${label}.${formatCapabilityReason(capability.reason)}`,\n );\n }\n if (!capability.enabled) {\n throw new Error(\n `Provider ${providerName} supports native ${label} but it is not enabled.${formatCapabilityReason(capability.reason)}`,\n );\n }\n}\n\nfunction formatCapabilityReason(reason: string | undefined): string {\n return reason ? ` ${reason}` : '';\n}\n","import type { IAIProvider } from './provider';\nimport type { TUniversalValue } from './types';\n\nexport interface IProviderConfig {\n name: string;\n model: string;\n apiKey?: string;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n}\n\nexport interface IProviderProfileDefaults {\n model?: string;\n apiKey?: string;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n}\n\nexport interface IProviderProfileConfig {\n type?: string;\n model?: string;\n apiKey?: string;\n baseURL?: string;\n timeout?: number;\n options?: Record<string, TUniversalValue>;\n}\n\nexport interface IProviderProbeResult {\n ok: boolean;\n message: string;\n models?: string[];\n}\n\nexport type TProviderCredentialField = 'apiKey';\nexport type TProviderSetupField = 'baseURL' | 'model' | TProviderCredentialField;\nexport type TProviderSetupHelpLinkKind = 'api-key' | 'console' | 'official';\n\nexport interface IProviderCredentialRequirement {\n anyOf: readonly TProviderCredentialField[];\n}\n\nexport interface IProviderSetupHelpLink {\n kind: TProviderSetupHelpLinkKind;\n label: string;\n url: string;\n sourceUrl?: string;\n lastVerifiedAt?: string;\n}\n\nexport type TProviderModelCatalogStatus = 'live' | 'generated' | 'fallback' | 'unavailable';\nexport type TProviderModelLifecycle = 'active' | 'preview' | 'deprecated' | 'unavailable';\nexport type TProviderModelCapability =\n | 'tools'\n | 'vision'\n | 'json_schema'\n | 'reasoning'\n | 'native_web'\n | 'streaming';\n\nexport interface IProviderModelCatalogEntry {\n id: string;\n displayName: string;\n aliases?: readonly string[];\n contextWindow?: number;\n capabilities?: readonly TProviderModelCapability[];\n lifecycle?: TProviderModelLifecycle;\n lastVerifiedAt?: string;\n sourceUrl?: string;\n}\n\nexport interface IProviderModelCatalog {\n status: TProviderModelCatalogStatus;\n entries?: readonly IProviderModelCatalogEntry[];\n lastVerifiedAt?: string;\n sourceUrl?: string;\n message?: string;\n}\n\nexport interface IProviderModelCatalogRefreshOptions {\n profile: IProviderProfileConfig;\n}\n\nexport type TProviderModelCatalogRefresh = (\n options: IProviderModelCatalogRefreshOptions,\n) => Promise<IProviderModelCatalog>;\n\nexport interface IProviderSetupStepDefinition {\n key: TProviderSetupField;\n title: string;\n defaultValue?: string;\n required?: boolean;\n masked?: boolean;\n}\n\nexport interface IProviderDefinition {\n type: string;\n aliases?: readonly string[];\n displayName?: string;\n description?: string;\n defaults?: IProviderProfileDefaults;\n modelCatalog?: IProviderModelCatalog;\n refreshModelCatalog?: TProviderModelCatalogRefresh;\n /** Maximum age in seconds before the model catalog is considered stale and auto-refreshed. */\n modelCatalogCacheTtlSeconds?: number;\n setupHelpLinks?: readonly IProviderSetupHelpLink[];\n setupSteps?: readonly IProviderSetupStepDefinition[];\n credentialRequirement?: IProviderCredentialRequirement;\n requiresApiKey?: boolean;\n createProvider: (config: IProviderConfig) => IAIProvider;\n probeProfile?: (profile: IProviderProfileConfig) => Promise<IProviderProbeResult>;\n}\n\nexport function findProviderDefinition(\n definitions: readonly IProviderDefinition[],\n type: string,\n): IProviderDefinition | undefined {\n return definitions.find(\n (definition) => definition.type === type || definition.aliases?.includes(type) === true,\n );\n}\n\nexport function formatSupportedProviderTypes(definitions: readonly IProviderDefinition[]): string {\n return definitions\n .map((definition) => {\n if (!definition.aliases || definition.aliases.length === 0) {\n return definition.type;\n }\n const aliasLabel = definition.aliases.length === 1 ? 'alias' : 'aliases';\n return `${definition.type} (${aliasLabel}: ${definition.aliases.join(', ')})`;\n })\n .join(', ');\n}\n\nexport function getProviderCredentialRequirement(\n definition: IProviderDefinition | undefined,\n): IProviderCredentialRequirement | undefined {\n if (definition?.credentialRequirement !== undefined) {\n return definition.credentialRequirement;\n }\n if (definition?.requiresApiKey === true) {\n return { anyOf: ['apiKey'] };\n }\n return undefined;\n}\n","import type { TUniversalValue } from './types';\n\n/**\n * Provider-agnostic media output reference.\n * Providers must not return raw binary payloads in this contract.\n */\nexport interface IMediaOutputRef {\n kind: 'asset' | 'uri';\n assetId?: string;\n uri?: string;\n mimeType?: string;\n bytes?: number;\n}\n\nexport interface IProviderMediaError {\n code:\n | 'PROVIDER_AUTH_ERROR'\n | 'PROVIDER_RATE_LIMITED'\n | 'PROVIDER_TIMEOUT'\n | 'PROVIDER_INVALID_REQUEST'\n | 'PROVIDER_UPSTREAM_ERROR'\n | 'PROVIDER_JOB_NOT_FOUND'\n | 'PROVIDER_JOB_NOT_CANCELLABLE';\n message: string;\n details?: Record<string, TUniversalValue>;\n}\n\nexport type TProviderMediaResult<TValue> =\n | { ok: true; value: TValue }\n | { ok: false; error: IProviderMediaError };\n\nexport interface IInlineImageInputSource {\n kind: 'inline';\n mimeType: string;\n data: string;\n}\n\nexport interface IUriImageInputSource {\n kind: 'uri';\n uri: string;\n mimeType?: string;\n}\n\nexport type TImageInputSource = IInlineImageInputSource | IUriImageInputSource;\n\nexport interface IImageGenerationRequest {\n prompt: string;\n model: string;\n}\n\nexport interface IImageEditRequest {\n image: TImageInputSource;\n prompt: string;\n model: string;\n}\n\nexport interface IImageComposeRequest {\n images: TImageInputSource[];\n prompt: string;\n model: string;\n}\n\nexport interface IImageGenerationResult {\n outputs: IMediaOutputRef[];\n model: string;\n}\n\nexport interface IImageGenerationProvider {\n generateImage(\n request: IImageGenerationRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>>;\n editImage?(request: IImageEditRequest): Promise<TProviderMediaResult<IImageGenerationResult>>;\n composeImage?(\n request: IImageComposeRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>>;\n}\n\nexport interface IVideoGenerationRequest {\n prompt: string;\n model: string;\n durationSeconds?: number;\n aspectRatio?: string;\n seed?: number;\n inputImages?: TImageInputSource[];\n}\n\nexport interface IVideoJobAccepted {\n jobId: string;\n status: 'queued' | 'running';\n createdAt: string;\n}\n\nexport interface IVideoJobSnapshot {\n jobId: string;\n status: 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';\n output?: IMediaOutputRef;\n error?: IProviderMediaError;\n updatedAt: string;\n}\n\nexport interface IVideoGenerationProvider {\n createVideo(request: IVideoGenerationRequest): Promise<TProviderMediaResult<IVideoJobAccepted>>;\n getVideoJob(jobId: string): Promise<TProviderMediaResult<IVideoJobSnapshot>>;\n cancelVideoJob(jobId: string): Promise<TProviderMediaResult<IVideoJobSnapshot>>;\n}\n\nexport function isImageGenerationProvider(provider: object): provider is IImageGenerationProvider {\n return (\n 'generateImage' in provider &&\n typeof (\n provider as {\n generateImage?: (...args: never[]) => Promise<TProviderMediaResult<IImageGenerationResult>>;\n }\n ).generateImage === 'function'\n );\n}\n\nexport function isVideoGenerationProvider(provider: object): provider is IVideoGenerationProvider {\n return (\n 'createVideo' in provider &&\n 'getVideoJob' in provider &&\n 'cancelVideoJob' in provider &&\n typeof (\n provider as {\n createVideo?: (...args: never[]) => Promise<TProviderMediaResult<IVideoJobAccepted>>;\n }\n ).createVideo === 'function' &&\n typeof (\n provider as {\n getVideoJob?: (...args: never[]) => Promise<TProviderMediaResult<IVideoJobSnapshot>>;\n }\n ).getVideoJob === 'function' &&\n typeof (\n provider as {\n cancelVideoJob?: (...args: never[]) => Promise<TProviderMediaResult<IVideoJobSnapshot>>;\n }\n ).cancelVideoJob === 'function'\n );\n}\n","import type { ITool, TToolParameters } from './tool';\n\n/**\n * Execution step definition for tools that support step-by-step progress reporting\n */\nexport interface IToolExecutionStep {\n /** Unique identifier for this step */\n id: string;\n\n /** Human-readable name of the step */\n name: string;\n\n /** Tool-provided estimated duration for this step in milliseconds */\n estimatedDuration: number;\n\n /** Optional description of what this step does */\n description?: string;\n}\n\n/**\n * Progress callback function type for real-time progress updates\n */\nexport type TToolProgressCallback = (step: string, progress: number) => void;\n\n/**\n * 🆕 IProgressReportingTool - Optional interface for tools that can provide their own progress information\n *\n * This interface extends the standard ITool to allow tools to optionally provide:\n * - Estimated execution duration\n * - Step-by-step execution plans\n * - Real-time progress callbacks\n *\n * Benefits:\n * - Tools can provide accurate progress information based on their internal knowledge\n * - No simulation or fake progress - only real tool-provided estimates\n * - Completely optional - existing tools work unchanged\n * - Tools can self-report progress for better user experience\n */\nexport interface IProgressReportingTool extends ITool {\n /**\n * Get estimated execution duration for given parameters (optional)\n *\n * Tools can implement this to provide accurate time estimates based on:\n * - Parameter complexity (e.g., search query length, file size)\n * - Historical execution data\n * - Internal optimization knowledge\n *\n * @param parameters - The parameters that will be passed to execute()\n * @returns Estimated duration in milliseconds, or undefined if not available\n */\n getEstimatedDuration?(parameters: TToolParameters): number;\n\n /**\n * Get execution steps for given parameters (optional)\n *\n * Tools can implement this to provide step-by-step execution plans:\n * - webSearch: [query processing, API call, result parsing, filtering]\n * - fileSearch: [file scanning, content reading, pattern matching, result formatting]\n * - github-mcp: [authentication, API request, response processing, data transformation]\n *\n * @param parameters - The parameters that will be passed to execute()\n * @returns Array of execution steps, or undefined if not available\n */\n getExecutionSteps?(parameters: TToolParameters): IToolExecutionStep[];\n\n /**\n * Set progress callback for real-time updates (optional)\n *\n * Tools can implement this to provide real-time progress updates during execution:\n * - Called when each step starts/completes\n * - Progress value between 0-100 representing completion percentage\n * - Step name helps users understand what's currently happening\n *\n * @param callback - Function to call with progress updates\n */\n setProgressCallback?(callback: TToolProgressCallback): void;\n}\n\n/**\n * Type guard to check if a tool implements progress reporting\n */\nexport function isProgressReportingTool(tool: ITool): tool is IProgressReportingTool {\n return (\n 'getEstimatedDuration' in tool || 'getExecutionSteps' in tool || 'setProgressCallback' in tool\n );\n}\n\n/**\n * Helper function to safely get estimated duration from any tool\n */\nexport function getToolEstimatedDuration(\n tool: ITool,\n parameters: TToolParameters,\n): number | undefined {\n if (isProgressReportingTool(tool) && tool.getEstimatedDuration) {\n return tool.getEstimatedDuration(parameters);\n }\n return undefined;\n}\n\n/**\n * Helper function to safely get execution steps from any tool\n */\nexport function getToolExecutionSteps(\n tool: ITool,\n parameters: TToolParameters,\n): IToolExecutionStep[] | undefined {\n if (isProgressReportingTool(tool) && tool.getExecutionSteps) {\n return tool.getExecutionSteps(parameters);\n }\n return undefined;\n}\n\n/**\n * Helper function to safely set progress callback on any tool\n */\nexport function setToolProgressCallback(tool: ITool, callback: TToolProgressCallback): boolean {\n if (isProgressReportingTool(tool) && tool.setProgressCallback) {\n tool.setProgressCallback(callback);\n return true;\n }\n return false;\n}\n","/**\n * @fileoverview Abstract Agent Base Class\n *\n * 🎯 ABSTRACT CLASS - DO NOT DEPEND ON CONCRETE IMPLEMENTATIONS\n *\n * This class defines the foundational lifecycle for agent implementations.\n * Subclasses provide provider/tool-specific behavior while inheriting the\n * shared guarantees around initialization, history, and disposal.\n */\nimport type { IAgent, IAgentConfig, TUniversalMessage, IRunOptions } from '../interfaces/agent';\n\nexport abstract class AbstractAgent<\n TConfig = IAgentConfig,\n TContext = IRunOptions,\n TMessage = TUniversalMessage,\n> implements IAgent<TConfig, TContext, TMessage>\n{\n protected history: TMessage[] = [];\n protected isInitialized = false;\n protected config?: TConfig;\n\n /**\n * Initialize the agent (subclass responsibility)\n */\n protected abstract initialize(): Promise<void>;\n\n /**\n * Configure the agent with type-safe configuration\n */\n async configure(config: TConfig): Promise<void> {\n this.config = config;\n await this.ensureInitialized();\n }\n\n /**\n * Run agent with user input and type-safe context\n */\n abstract run(input: string, context?: TContext): Promise<string>;\n\n /**\n * Run agent with streaming response and type-safe context\n */\n abstract runStream(input: string, context?: TContext): AsyncGenerator<string, void, never>;\n\n /**\n * Get conversation history with type-safe messages\n */\n getHistory(): TMessage[] {\n return [...this.history];\n }\n\n /**\n * Clear conversation history\n */\n clearHistory(): void {\n this.history = [];\n }\n\n /**\n * Add message to history\n */\n protected addMessage(message: TMessage): void {\n this.history.push(message);\n }\n\n /**\n * Validate user input\n */\n protected validateInput(input: string): void {\n if (!input || typeof input !== 'string') {\n throw new Error('Input must be a non-empty string');\n }\n }\n\n /**\n * Ensure agent is initialized before running\n */\n protected async ensureInitialized(): Promise<void> {\n if (!this.isInitialized) {\n await this.initialize();\n this.isInitialized = true;\n }\n }\n\n /**\n * Cleanup resources\n */\n async dispose(): Promise<void> {\n this.clearHistory();\n this.isInitialized = false;\n }\n}\n","/**\n * @fileoverview Abstract Manager Base Class\n *\n * 🎯 ABSTRACT CLASS - DO NOT IMPORT CONCRETE IMPLEMENTATIONS\n *\n * This class defines the common lifecycle contract for all manager implementations.\n * It enforces explicit initialization/disposal semantics so that subclasses can\n * provide their own resource management logic while sharing guard rails.\n *\n * Architectural rules:\n * - Depends only on abstractions (no concrete manager implementations)\n * - Provides finalize hooks (`doInitialize`, `doDispose`) for subclasses\n * - Guards public APIs via `ensureInitialized`\n */\nexport abstract class AbstractManager {\n protected initialized = false;\n\n /**\n * Initialize the manager (idempotent)\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n await this.doInitialize();\n this.initialized = true;\n }\n\n /**\n * Subclass-specific initialization logic\n */\n protected abstract doInitialize(): Promise<void>;\n\n /**\n * Dispose manager resources (idempotent)\n */\n async dispose(): Promise<void> {\n await this.doDispose();\n this.initialized = false;\n }\n\n /**\n * Subclass-specific disposal logic\n */\n protected abstract doDispose(): Promise<void>;\n\n /**\n * Whether the manager completed initialization\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * Ensure manager is initialized before performing operations\n */\n protected ensureInitialized(): void {\n if (!this.initialized) {\n throw new Error(`${this.constructor.name} is not initialized`);\n }\n }\n}\n","/**\n * Message Contracts (Single Source of Truth)\n *\n * IMPORTANT:\n * - This module is owned by the `interfaces` layer.\n * - All message types used across the SDK must be defined here to avoid drift.\n * - Runtime values (variables/classes/objects) and compile-time types can share the same name in TypeScript.\n * Prefixing type aliases (`T*`) and interfaces (`I*`) reduces value/type name collision risk and review overhead.\n */\n\n/**\n * Universal message role type - provider-independent neutral role.\n */\nexport type TUniversalMessageRole = 'user' | 'assistant' | 'system' | 'tool';\n\n/**\n * Message metadata used across conversation history and provider adapters.\n */\nexport type TUniversalMessageMetadata = Record<\n string,\n string | number | boolean | Date | string[] | number[] | Record<string, number>\n>;\n\n/**\n * Universal multimodal message part contracts.\n */\nexport interface ITextMessagePart {\n type: 'text';\n text: string;\n}\n\nexport interface IInlineImageMessagePart {\n type: 'image_inline';\n mimeType: string;\n data: string;\n}\n\nexport interface IUriImageMessagePart {\n type: 'image_uri';\n uri: string;\n mimeType?: string;\n}\n\nexport type TUniversalMessagePart =\n | ITextMessagePart\n | IInlineImageMessagePart\n | IUriImageMessagePart;\n\n/**\n * Tool call (OpenAI tool calling format).\n */\nexport interface IToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/** State of a message in conversation history */\nexport type TMessageState = 'complete' | 'interrupted';\n\n/**\n * Base message contract shared by all message variants.\n */\nexport interface IBaseMessage {\n /** Unique message identifier */\n id: string;\n /** Message creation timestamp */\n timestamp: Date;\n /** Whether this message is complete or was interrupted */\n state: TMessageState;\n /** Additional metadata */\n metadata?: TUniversalMessageMetadata;\n}\n\nexport interface IUserMessage extends IBaseMessage {\n role: 'user';\n content: string;\n parts?: TUniversalMessagePart[];\n name?: string;\n}\n\nexport interface IAssistantMessage extends IBaseMessage {\n role: 'assistant';\n /** Assistant response content (can be null when making tool calls) */\n content: string | null;\n parts?: TUniversalMessagePart[];\n toolCalls?: IToolCall[];\n}\n\nexport interface ISystemMessage extends IBaseMessage {\n role: 'system';\n content: string;\n parts?: TUniversalMessagePart[];\n name?: string;\n}\n\nexport interface IToolMessage extends IBaseMessage {\n role: 'tool';\n content: string;\n parts?: TUniversalMessagePart[];\n toolCallId: string;\n name?: string;\n}\n\n/**\n * Universal message union used across the SDK as the canonical contract.\n * Used for AI provider communication. Extracted from IHistoryEntry[] via filtering.\n */\nexport type TUniversalMessage = IUserMessage | IAssistantMessage | ISystemMessage | IToolMessage;\n\n/**\n * Universal history entry — the base type for all records in conversation history.\n *\n * History is a universal timeline that records everything: AI chat messages,\n * system events, skill invocations, permission decisions, etc.\n * AI provider receives only chat entries (filtered and converted to TUniversalMessage).\n * TUI can render any range of entries.\n *\n * - append-only, read-only\n * - category + type for classification (free-form strings, no pre-defined enum)\n * - data holds type-specific structured content\n */\nexport interface IHistoryEntry<T = unknown> {\n /** Unique entry identifier */\n id: string;\n /** Entry creation timestamp */\n timestamp: Date;\n /** Top-level classification: 'chat', 'event', etc. */\n category: string;\n /** Sub-classification within category. Free-form, not pre-defined. */\n type: string;\n /** Type-specific structured data */\n data?: T;\n}\n\n/** Check if a history entry is a chat message (for AI provider filtering). */\nexport function isChatEntry(entry: IHistoryEntry): boolean {\n return entry.category === 'chat';\n}\n\n/**\n * Convert a chat history entry to TUniversalMessage for AI provider consumption.\n * Only call on entries where isChatEntry() returns true.\n */\nexport function chatEntryToMessage(entry: IHistoryEntry): TUniversalMessage {\n // data contains the full original message — just restore id/timestamp from entry\n const data = entry.data as Record<string, unknown>;\n if (!data) {\n throw new Error(`Chat entry ${entry.id} has no data`);\n }\n return {\n ...data,\n id: entry.id,\n timestamp: entry.timestamp,\n } as TUniversalMessage;\n}\n\n/**\n * Convert a TUniversalMessage to an IHistoryEntry for storage.\n */\nexport function messageToHistoryEntry(message: TUniversalMessage): IHistoryEntry {\n return {\n id: message.id,\n timestamp: message.timestamp,\n category: 'chat',\n type: message.role,\n data: { ...message },\n };\n}\n\n/**\n * Filter history entries and convert chat entries to TUniversalMessage[].\n * Used when passing conversation to AI provider.\n */\nexport function getMessagesForAPI(history: IHistoryEntry[]): TUniversalMessage[] {\n return history.filter(isChatEntry).map(chatEntryToMessage);\n}\n\n/**\n * Type guards for the canonical TUniversalMessage union.\n *\n * NOTE:\n * - These guards are owned by the `interfaces` layer and must not depend on managers/services.\n * - Call sites should use these guards instead of importing from manager layers.\n */\nexport function isUserMessage(message: TUniversalMessage): message is IUserMessage {\n return message.role === 'user';\n}\n\nexport function isAssistantMessage(message: TUniversalMessage): message is IAssistantMessage {\n return message.role === 'assistant';\n}\n\nexport function isSystemMessage(message: TUniversalMessage): message is ISystemMessage {\n return message.role === 'system';\n}\n\nexport function isToolMessage(message: TUniversalMessage): message is IToolMessage {\n return message.role === 'tool';\n}\n","import type { TLoggerData, TUniversalValue } from '../interfaces/types';\n\n/**\n * Reusable type definitions for logger utility\n */\n\n/**\n * Log levels for the logger\n */\nexport type TUtilLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';\n\n/**\n * Log entry structure\n */\nexport interface IUtilLogEntry {\n timestamp: string;\n level: TUtilLogLevel;\n message: string;\n context?: TLoggerData;\n packageName?: string;\n}\n\n/**\n * Logger interface\n */\nexport interface ILogger {\n debug(...args: Array<TUniversalValue | TLoggerData | Error>): void;\n info(...args: Array<TUniversalValue | TLoggerData | Error>): void;\n warn(...args: Array<TUniversalValue | TLoggerData | Error>): void;\n error(...args: Array<TUniversalValue | TLoggerData | Error>): void;\n log(...args: Array<TUniversalValue | TLoggerData | Error>): void;\n group?(label?: string): void;\n groupEnd?(): void;\n}\n\n/**\n * Silent logger that does nothing (Null Object Pattern)\n *\n * IMPORTANT:\n * - This library must not write to stdio by default.\n * - Inject a real logger explicitly if you want output.\n */\nexport const SilentLogger: ILogger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n log: () => {},\n group: () => {},\n groupEnd: () => {},\n};\n\n/**\n * Global logger configuration\n */\nclass LoggerConfig {\n private static instance: LoggerConfig;\n private globalLevel: TUtilLogLevel;\n\n private constructor() {\n // Set default level (environment variables no longer used for browser compatibility)\n this.globalLevel = 'warn';\n }\n\n static getInstance(): LoggerConfig {\n if (!LoggerConfig.instance) {\n LoggerConfig.instance = new LoggerConfig();\n }\n return LoggerConfig.instance;\n }\n\n getGlobalLevel(): TUtilLogLevel {\n return this.globalLevel;\n }\n\n setGlobalLevel(level: TUtilLogLevel): void {\n this.globalLevel = level;\n }\n}\n\n/**\n * Console logger implementation\n * @internal\n */\nexport class ConsoleLogger implements ILogger {\n private level?: TUtilLogLevel; // undefined means use global level\n private packageName: string;\n private sinkLogger: ILogger;\n\n constructor(packageName: string, logger?: ILogger) {\n this.packageName = packageName;\n this.sinkLogger = logger || SilentLogger;\n }\n\n debug(...args: Array<TUniversalValue | TLoggerData | Error>): void {\n if (this.shouldLog('debug')) {\n const [message, context] = args;\n this.forward('debug', String(message ?? ''), isLoggerContext(context) ? context : undefined);\n }\n }\n\n info(...args: Array<TUniversalValue | TLoggerData | Error>): void {\n if (this.shouldLog('info')) {\n const [message, context] = args;\n this.forward('info', String(message ?? ''), isLoggerContext(context) ? context : undefined);\n }\n }\n\n warn(...args: Array<TUniversalValue | TLoggerData | Error>): void {\n if (this.shouldLog('warn')) {\n const [message, context] = args;\n this.forward('warn', String(message ?? ''), isLoggerContext(context) ? context : undefined);\n }\n }\n\n error(...args: Array<TUniversalValue | TLoggerData | Error>): void {\n if (this.shouldLog('error')) {\n const [message, context] = args;\n this.forward('error', String(message ?? ''), isLoggerContext(context) ? context : undefined);\n }\n }\n\n log(...args: Array<TUniversalValue | TLoggerData | Error>): void {\n // Alias for info-level output (when enabled).\n this.info(...args);\n }\n\n private getLevel(): TUtilLogLevel {\n return this.level || LoggerConfig.getInstance().getGlobalLevel();\n }\n\n private shouldLog(level: TUtilLogLevel): boolean {\n const currentLevel = this.getLevel();\n if (currentLevel === 'silent') return false;\n\n const levels: TUtilLogLevel[] = ['debug', 'info', 'warn', 'error', 'silent'];\n return levels.indexOf(level) >= levels.indexOf(currentLevel);\n }\n\n private forward(level: TUtilLogLevel, message: string, context?: TLoggerData): void {\n const entry: IUtilLogEntry = {\n timestamp: new Date().toISOString(),\n level,\n message,\n ...(context && { context }),\n packageName: this.packageName,\n };\n\n const formattedMessage = `[${entry.timestamp}] [${entry.level.toUpperCase()}] [${entry.packageName}] ${entry.message}`;\n switch (level) {\n case 'debug':\n this.sinkLogger.debug(formattedMessage, context ?? {});\n return;\n case 'info':\n this.sinkLogger.info(formattedMessage, context ?? {});\n return;\n case 'warn':\n this.sinkLogger.warn(formattedMessage, context ?? {});\n return;\n case 'error':\n this.sinkLogger.error(formattedMessage, context ?? {});\n return;\n case 'silent':\n return;\n }\n }\n}\n\nfunction isLoggerContext(value: unknown): value is TLoggerData {\n return (\n typeof value === 'object' &&\n value !== null &&\n !(value instanceof Error) &&\n !(value instanceof Date) &&\n !Array.isArray(value)\n );\n}\n\n/**\n * Create a named logger instance for a package or module.\n * Use this to create loggers with a specific name prefix for easy log filtering.\n */\nexport function createLogger(packageName: string, logger?: ILogger): ILogger {\n return new ConsoleLogger(packageName, logger);\n}\n\n/**\n * Set global log level for all loggers\n */\nexport function setGlobalLogLevel(level: TUtilLogLevel): void {\n LoggerConfig.getInstance().setGlobalLevel(level);\n}\n\n/**\n * Get global log level\n */\nexport function getGlobalLogLevel(): TUtilLogLevel {\n return LoggerConfig.getInstance().getGlobalLevel();\n}\n\n/**\n * Default logger for the agents package\n */\nexport const logger = createLogger('agents');\n","/**\n * Helper functions for AbstractAIProvider.\n *\n * Extracted from abstracts/abstract-ai-provider.ts to keep that file under 300 lines.\n * Contains message/tool validation and executor delegation utilities.\n */\nimport type { IToolSchema, IChatOptions } from '../interfaces/provider';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { IExecutor } from '../interfaces/executor';\n\n/**\n * Validate that messages is a non-empty array of messages with valid roles.\n * Throws if validation fails.\n */\nexport function validateProviderMessages(messages: TUniversalMessage[]): void {\n if (!Array.isArray(messages)) {\n throw new Error('Messages must be an array');\n }\n if (messages.length === 0) {\n throw new Error('Messages array cannot be empty');\n }\n for (const message of messages) {\n if (!message.role || !['user', 'assistant', 'system', 'tool'].includes(message.role)) {\n throw new Error(`Invalid message role: ${message.role}`);\n }\n }\n}\n\n/**\n * Validate that tools is an array of tool schemas with name, description, and parameters.\n * No-ops if tools is undefined.\n */\nexport function validateProviderTools(tools?: IToolSchema[]): void {\n if (!tools) return;\n if (!Array.isArray(tools)) {\n throw new Error('Tools must be an array');\n }\n for (const tool of tools) {\n if (!tool.name || typeof tool.name !== 'string') {\n throw new Error('Tool must have a valid name');\n }\n if (!tool.description || typeof tool.description !== 'string') {\n throw new Error('Tool must have a valid description');\n }\n if (\n !tool.parameters ||\n typeof tool.parameters !== 'object' ||\n tool.parameters === null ||\n Array.isArray(tool.parameters)\n ) {\n throw new Error('Tool must have valid parameters');\n }\n }\n}\n\n/**\n * Execute a chat request via an injected executor (non-streaming).\n * Throws if executor or model is missing.\n */\nexport async function executeChatViaExecutor(\n executor: IExecutor | undefined,\n providerName: string,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n): Promise<TUniversalMessage> {\n if (!executor) {\n throw new Error(\n `Executor is required for ${providerName} provider. Configure an executor or use direct execution path.`,\n );\n }\n if (!options?.model) {\n throw new Error(`Model is required for executor execution in ${providerName} provider.`);\n }\n return executor.executeChat({\n messages,\n options,\n provider: providerName,\n model: options.model,\n ...(options.tools && { tools: options.tools }),\n });\n}\n\n/**\n * Execute a streaming chat request via an injected executor.\n * Throws if executor or model is missing.\n */\nexport async function* executeChatStreamViaExecutor(\n executor: IExecutor | undefined,\n providerName: string,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n): AsyncIterable<TUniversalMessage> {\n if (!executor || !executor.executeChatStream) {\n throw new Error(`Streaming executor is required for ${providerName} provider.`);\n }\n if (!options?.model) {\n throw new Error(`Model is required for executor streaming in ${providerName} provider.`);\n }\n const stream = executor.executeChatStream({\n messages,\n options,\n provider: providerName,\n model: options.model,\n stream: true,\n ...(options.tools && { tools: options.tools }),\n });\n for await (const chunk of stream) {\n yield chunk;\n }\n}\n","/**\n * @fileoverview Abstract AI Provider Base Class\n *\n * 🎯 ABSTRACT CLASS - DO NOT DEPEND ON CONCRETE IMPLEMENTATIONS\n *\n * Defines the shared contract and helper utilities for all AI provider implementations.\n * Concrete providers should extend this class and inject their own dependencies.\n */\nimport type {\n IAIProvider,\n IToolSchema,\n IChatOptions,\n IProviderRequest,\n IRawProviderResponse,\n} from '../interfaces/provider';\nimport type {\n IProviderCapabilities,\n IProviderNativeWebToolRequest,\n} from '../interfaces/provider-capabilities';\nimport {\n assertProviderNativeWebToolsAvailable,\n createDefaultProviderCapabilities,\n} from '../interfaces/provider-capabilities';\nimport type { IExecutor } from '../interfaces/executor';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport { isAssistantMessage } from '../interfaces/messages';\nimport type { ILogger } from '../utils/logger';\nimport { SilentLogger } from '../utils/logger';\nimport {\n validateProviderMessages,\n validateProviderTools,\n executeChatViaExecutor,\n executeChatStreamViaExecutor,\n} from './ai-provider-helpers';\n\n/**\n * Provider logging data type\n * Used for storing logging information in provider operations\n */\nexport type TProviderLoggingData = Record<string, string | number | boolean | Date | string[]>;\n\n/**\n * Provider configuration base interface\n */\nexport interface IProviderConfig {\n apiKey?: string;\n baseUrl?: string;\n timeout?: number;\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Enhanced provider configuration that supports executor injection\n */\nexport interface IExecutorAwareProviderConfig {\n apiKey?: string;\n baseUrl?: string;\n timeout?: number;\n /**\n * Optional executor for handling AI requests\n * When provided, the provider will delegate all chat operations to this executor\n * instead of making direct API calls. This enables remote execution capabilities.\n */\n executor?: IExecutor;\n [key: string]: string | number | boolean | IExecutor | undefined;\n}\n\n/**\n * Base AI provider implementation with proper type constraints.\n * All AI providers should extend this class.\n *\n * Subclasses MUST: extend this class, use override keyword, call super() in constructor,\n * not redefine types that exist in agent-core, handle null message content correctly.\n *\n * @template TConfig - Provider configuration type\n */\nexport abstract class AbstractAIProvider<TConfig = IProviderConfig> implements IAIProvider {\n abstract readonly name: string;\n abstract readonly version: string;\n protected config?: TConfig;\n protected executor?: IExecutor;\n protected readonly logger: ILogger;\n\n constructor(logger: ILogger = SilentLogger) {\n this.logger = logger;\n }\n\n /**\n * Configure the provider with type-safe configuration\n */\n async configure(config: TConfig): Promise<void> {\n this.config = config;\n\n // Check if config includes executor and set it\n if (this.hasExecutor(config) && config.executor) {\n this.executor = config.executor;\n }\n\n // Subclasses can override for additional setup\n }\n\n private hasExecutor(config: TConfig): config is TConfig & { executor?: IExecutor } {\n return typeof config === 'object' && config !== null && 'executor' in config;\n }\n\n /**\n * Each provider must implement chat using their own native SDK types internally\n * @param messages - Array of messages from conversation history\n * @param options - Chat options including tools, model settings, etc.\n * @returns Promise resolving to a response\n */\n abstract chat(messages: TUniversalMessage[], options?: IChatOptions): Promise<TUniversalMessage>;\n\n /**\n * Wrap an async iterable to yield to the macrotask queue periodically.\n * Providers MUST use this when iterating over streaming events to ensure\n * the main thread event loop stays responsive (ESC abort, Ctrl+C, etc.).\n *\n * Usage in provider:\n * for await (const event of this.streamWithAbort(stream, signal)) { ... }\n */\n protected async *streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n ): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done) break;\n await yieldToMacrotask(signal);\n if (signal?.aborted) break;\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n }\n\n /**\n * Each provider must implement streaming chat using their own native SDK types internally\n * @param messages - Array of messages from conversation history\n * @param options - Chat options including tools, model settings, etc.\n * @returns AsyncIterable of response chunks\n */\n chatStream?(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage>;\n\n /**\n * Provider-agnostic raw response API.\n *\n * This is the canonical \"raw payload\" entrypoint required by the AIProvider contract.\n * The default implementation delegates to `chat()` and adapts the result into a\n * RawProviderResponse shape.\n */\n async generateResponse(payload: IProviderRequest): Promise<IRawProviderResponse> {\n const response = await this.chat(payload.messages, {\n ...(payload.model !== undefined && { model: payload.model }),\n ...(payload.temperature !== undefined && { temperature: payload.temperature }),\n ...(payload.maxTokens !== undefined && { maxTokens: payload.maxTokens }),\n ...(payload.tools !== undefined && { tools: payload.tools }),\n });\n\n return {\n content: response.content ?? null,\n toolCalls: isAssistantMessage(response) ? response.toolCalls : undefined,\n model: payload.model,\n metadata: payload.metadata,\n };\n }\n\n /**\n * Provider-agnostic raw streaming API.\n *\n * If a provider does not implement chatStream, it does not support streaming.\n */\n async *generateStreamingResponse(payload: IProviderRequest): AsyncIterable<IRawProviderResponse> {\n if (!this.chatStream) {\n throw new Error(`[AI-PROVIDER] Streaming is not supported by provider \"${this.name}\"`);\n }\n\n for await (const chunk of this.chatStream(payload.messages, {\n ...(payload.model !== undefined && { model: payload.model }),\n ...(payload.temperature !== undefined && { temperature: payload.temperature }),\n ...(payload.maxTokens !== undefined && { maxTokens: payload.maxTokens }),\n ...(payload.tools !== undefined && { tools: payload.tools }),\n })) {\n yield {\n content: chunk.content ?? null,\n toolCalls: isAssistantMessage(chunk) ? chunk.toolCalls : undefined,\n model: payload.model,\n metadata: payload.metadata,\n };\n }\n }\n\n /**\n * Default implementation - most modern providers support tools\n * @returns true if tool calling is supported\n */\n supportsTools(): boolean {\n return true;\n }\n\n getCapabilities(): IProviderCapabilities {\n return createDefaultProviderCapabilities(this.supportsTools());\n }\n\n /**\n * Default implementation - providers can override for specific validation\n * @returns true if configuration is valid\n */\n validateConfig(): boolean {\n return true;\n }\n\n /** Validate that messages is a non-empty array with valid roles. */\n protected validateMessages(messages: TUniversalMessage[]): void {\n validateProviderMessages(messages);\n }\n\n /** Validate tool schemas. No-ops if tools is undefined. */\n protected validateTools(tools?: IToolSchema[]): void {\n validateProviderTools(tools);\n }\n\n protected validateNativeWebTools(request?: IProviderNativeWebToolRequest): void {\n assertProviderNativeWebToolsAvailable(this.name, this.getCapabilities(), request);\n }\n\n /**\n * Execute chat via executor.\n * Subclasses should call this only when an executor is configured.\n */\n protected async executeViaExecutorOrDirect(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n return executeChatViaExecutor(this.executor, this.name, messages, options);\n }\n\n /**\n * Execute streaming chat via executor.\n * Subclasses should call this only when an executor is configured.\n */\n protected async *executeStreamViaExecutorOrDirect(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.logger.debug?.(\n '🔍 [TOOL-FLOW] AbstractAIProvider.executeStreamViaExecutorOrDirect() - Executor request',\n {\n provider: this.name,\n model: options?.model,\n hasTools: !!options?.tools,\n toolsCount: options?.tools?.length || 0,\n toolNames: options?.tools?.map((t: IToolSchema) => t.name) || [],\n },\n );\n yield* executeChatStreamViaExecutor(this.executor, this.name, messages, options);\n }\n\n /**\n * Clean up resources when provider is no longer needed\n * Override this method in subclasses for additional cleanup\n */\n async dispose(): Promise<void> {\n // Clean up executor if present\n if (this.executor?.dispose) {\n await this.executor.dispose();\n }\n\n // Subclasses can override for additional cleanup\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) return iterator.next();\n if (signal.aborted) return { done: true, value: undefined as T };\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) signal.removeEventListener('abort', abortListener);\n }\n}\n\nasync function yieldToMacrotask(signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) return;\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n}\n","/**\n * Agent event constants\n *\n * Events emitted by Agent instances themselves.\n * Event names are local (no dots) and must be used via constants (no string literals).\n */\nexport const AGENT_EVENTS = {\n /** Agent instance has been created and initialized */\n CREATED: 'created',\n /** Agent execution lifecycle - start */\n EXECUTION_START: 'execution_start',\n /** Agent execution lifecycle - complete */\n EXECUTION_COMPLETE: 'execution_complete',\n /** Agent execution lifecycle - error */\n EXECUTION_ERROR: 'execution_error',\n /** Agent aggregation process completed */\n AGGREGATION_COMPLETE: 'aggregation_complete',\n /** Agent configuration (e.g., tools) has been updated by the agent */\n CONFIG_UPDATED: 'config_updated',\n} as const;\n\nexport const AGENT_EVENT_PREFIX = 'agent' as const;\n\nexport type TAgentEvent = (typeof AGENT_EVENTS)[keyof typeof AGENT_EVENTS];\n","/**\n * Reusable type definitions for error utilities\n */\n\n/**\n * Error context data type\n * Used for storing contextual information in error instances\n */\nexport type TErrorContextData = Record<\n string,\n string | number | boolean | Date | Error | string[] | undefined\n>;\n\n/**\n * Error external input type\n * Used for handling external errors from unknown sources\n */\nexport type TErrorExternalInput =\n | Error\n | string\n | Record<string, string | number | boolean>\n | null\n | undefined;\n\n/**\n * Base error class for all Robota errors\n */\nexport abstract class RobotaError extends Error {\n abstract readonly code: string;\n abstract readonly category: 'user' | 'system' | 'provider';\n abstract readonly recoverable: boolean;\n\n constructor(\n message: string,\n public readonly context?: TErrorContextData,\n ) {\n super(message);\n this.name = this.constructor.name;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Configuration related errors\n */\nexport class ConfigurationError extends RobotaError {\n readonly code = 'CONFIGURATION_ERROR';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(message: string, context?: TErrorContextData) {\n super(`Configuration Error: ${message}`, context);\n }\n}\n\n/**\n * Input validation errors\n */\nexport class ValidationError extends RobotaError {\n readonly code = 'VALIDATION_ERROR';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly field?: string,\n context?: TErrorContextData,\n ) {\n super(`Validation Error: ${message}`, context);\n }\n}\n\n/**\n * Provider related errors\n */\nexport class ProviderError extends RobotaError {\n readonly code = 'PROVIDER_ERROR';\n readonly category = 'provider' as const;\n readonly recoverable = true;\n\n constructor(\n message: string,\n public readonly provider: string,\n public readonly originalError?: Error,\n context?: TErrorContextData,\n ) {\n super(`Provider Error (${provider}): ${message}`, context);\n }\n}\n\n/**\n * Authentication errors\n */\nexport class AuthenticationError extends RobotaError {\n readonly code = 'AUTHENTICATION_ERROR';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly provider?: string,\n context?: TErrorContextData,\n ) {\n super(`Authentication Error: ${message}`, context);\n }\n}\n\n/**\n * Rate limit errors\n */\nexport class RateLimitError extends RobotaError {\n readonly code = 'RATE_LIMIT_ERROR';\n readonly category = 'provider' as const;\n readonly recoverable = true;\n\n constructor(\n message: string,\n public readonly retryAfter?: number,\n public readonly provider?: string,\n context?: TErrorContextData,\n ) {\n super(`Rate Limit Error: ${message}`, context);\n }\n}\n\n/**\n * Network/connectivity errors\n */\nexport class NetworkError extends RobotaError {\n readonly code = 'NETWORK_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(\n message: string,\n public readonly originalError?: Error,\n context?: TErrorContextData,\n ) {\n super(`Network Error: ${message}`, context);\n }\n}\n\n/**\n * Tool execution errors\n */\nexport class ToolExecutionError extends RobotaError {\n readonly code = 'TOOL_EXECUTION_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly toolName: string,\n public readonly originalError?: Error,\n context?: TErrorContextData,\n ) {\n super(`Tool Execution Error (${toolName}): ${message}`, context);\n }\n}\n\n/**\n * Model not available errors\n */\nexport class ModelNotAvailableError extends RobotaError {\n readonly code = 'MODEL_NOT_AVAILABLE';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(\n model: string,\n provider: string,\n public readonly availableModels?: string[],\n context?: TErrorContextData,\n ) {\n super(`Model \"${model}\" is not available for provider \"${provider}\"`, context);\n }\n}\n\n/**\n * Circuit breaker open error\n */\nexport class CircuitBreakerOpenError extends RobotaError {\n readonly code = 'CIRCUIT_BREAKER_OPEN';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(message: string = 'Circuit breaker is open', context?: TErrorContextData) {\n super(message, context);\n }\n}\n\n/**\n * Plugin errors\n */\nexport class PluginError extends RobotaError {\n readonly code = 'PLUGIN_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly pluginName: string,\n context?: TErrorContextData,\n ) {\n super(`Plugin Error (${pluginName}): ${message}`, context);\n }\n}\n\n/**\n * Storage related errors\n */\nexport class StorageError extends RobotaError {\n readonly code = 'STORAGE_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(message: string, context?: TErrorContextData) {\n super(`Storage Error: ${message}`, context);\n }\n}\n\n/**\n * Cache integrity validation errors\n */\nexport class CacheIntegrityError extends RobotaError {\n readonly code = 'CACHE_INTEGRITY_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = false;\n\n constructor(message: string, context?: TErrorContextData) {\n super(`Cache Integrity Error: ${message}`, context);\n }\n}\n\n/**\n * Error utility functions\n */\nexport class ErrorUtils {\n /**\n * Check if error is recoverable\n */\n static isRecoverable(error: Error): boolean {\n if (error instanceof RobotaError) {\n return error.recoverable;\n }\n return false;\n }\n\n /**\n * Extract error code from any error\n */\n static getErrorCode(error: Error): string {\n if (error instanceof RobotaError) {\n return error.code;\n }\n return 'UNKNOWN_ERROR';\n }\n\n /**\n * Create error from unknown value\n */\n static fromUnknown(\n error: TErrorExternalInput,\n defaultMessage = 'An unknown error occurred',\n ): RobotaError {\n if (error instanceof RobotaError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new ConfigurationError(error.message || defaultMessage);\n }\n\n const message = typeof error === 'string' ? error : defaultMessage;\n return new ConfigurationError(message);\n }\n\n /**\n * Wrap external errors\n */\n static wrapProviderError(\n error: TErrorExternalInput,\n provider: string,\n operation: string,\n ): ProviderError {\n const originalError = error instanceof Error ? error : new Error(String(error));\n return new ProviderError(`Failed to ${operation}`, provider, originalError, { operation });\n }\n}\n","import type {\n IToolExecutionResult,\n IToolExecutionContext,\n TToolParameters,\n} from '../interfaces/tool';\nimport type { ILogger } from '../utils/logger';\nimport { ValidationError } from '../utils/errors';\nimport type { IToolExecutionBatchContext } from './tool-execution-service';\nimport type { IToolExecutionRequest } from '../interfaces/service';\n\nconst MIN_PARALLEL_CONCURRENCY = 1;\n\n/**\n * Shared interface for the minimal ToolExecutionService surface needed by batch helpers.\n */\nexport interface IToolExecutor {\n executeTool(\n toolName: string,\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<IToolExecutionResult>;\n}\n\ninterface IParallelExecutionState {\n resultsByIndex: Array<IToolExecutionResult | undefined>;\n errorsByIndex: Array<Error | undefined>;\n nextRequestIndex: number;\n}\n\nfunction requireExecutionRequestFields(request: {\n executionId?: string;\n ownerType?: string;\n ownerId?: string;\n}): { executionId: string; ownerType: string; ownerId: string } {\n if (!request.executionId) {\n throw new ValidationError(\n '[STRICT-POLICY][EMITTER-CONTRACT] Tool execution request missing executionId',\n );\n }\n if (!request.ownerType) {\n throw new ValidationError(\n `[STRICT-POLICY][EMITTER-CONTRACT] Tool execution request missing ownerType: executionId=${request.executionId}`,\n );\n }\n if (!request.ownerId) {\n throw new ValidationError(\n `[STRICT-POLICY][EMITTER-CONTRACT] Tool execution request missing ownerId: executionId=${request.executionId}`,\n );\n }\n return {\n executionId: request.executionId,\n ownerType: request.ownerType,\n ownerId: request.ownerId,\n };\n}\n\nfunction createExecutionContext(request: IToolExecutionRequest): IToolExecutionContext {\n const required = requireExecutionRequestFields(request);\n return {\n toolName: request.toolName,\n parameters: request.parameters,\n executionId: required.executionId,\n ownerType: required.ownerType,\n ownerId: required.ownerId,\n ownerPath: request.ownerPath,\n metadata: request.metadata,\n eventService: request.eventService,\n baseEventService: request.baseEventService,\n };\n}\n\nfunction createInterruptedResult(request: IToolExecutionRequest): IToolExecutionResult {\n return {\n toolName: request.toolName,\n executionId: request.executionId ?? '',\n success: false,\n error: 'Execution interrupted by user',\n result: null,\n };\n}\n\nfunction createErrorResult(request: IToolExecutionRequest, error: Error): IToolExecutionResult {\n return {\n toolName: request.toolName,\n result: null,\n success: false,\n error: error.message,\n executionId: request.executionId,\n };\n}\n\nfunction createToolFailureError(result: IToolExecutionResult): Error {\n return new Error(\n `Tool execution failed: toolName=${String(result.toolName)} executionId=${String(result.executionId)} error=${String(result.error || 'Unknown error')}`,\n );\n}\n\nfunction isDefinedResult(result: IToolExecutionResult | undefined): result is IToolExecutionResult {\n return result !== undefined;\n}\n\nfunction isDefinedError(error: Error | undefined): error is Error {\n return error !== undefined;\n}\n\nfunction resolveMaxConcurrency(requestCount: number, maxConcurrency?: number): number {\n if (requestCount === 0) {\n return 0;\n }\n if (maxConcurrency === undefined || !Number.isFinite(maxConcurrency)) {\n return requestCount;\n }\n\n const normalized = Math.floor(maxConcurrency);\n if (normalized < MIN_PARALLEL_CONCURRENCY) {\n return MIN_PARALLEL_CONCURRENCY;\n }\n\n return Math.min(normalized, requestCount);\n}\n\nasync function executeParallelRequest(\n batchContext: IToolExecutionBatchContext,\n executor: IToolExecutor,\n state: IParallelExecutionState,\n index: number,\n): Promise<void> {\n const request = batchContext.requests[index];\n if (!request) {\n return;\n }\n\n try {\n const result = batchContext.signal?.aborted\n ? createInterruptedResult(request)\n : await executor.executeTool(\n request.toolName,\n request.parameters,\n createExecutionContext(request),\n );\n state.resultsByIndex[index] = result;\n if (!result.success) {\n state.errorsByIndex[index] = createToolFailureError(result);\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n state.errorsByIndex[index] = err;\n state.resultsByIndex[index] = createErrorResult(request, err);\n }\n}\n\nasync function runParallelWorker(\n batchContext: IToolExecutionBatchContext,\n executor: IToolExecutor,\n state: IParallelExecutionState,\n): Promise<void> {\n while (state.nextRequestIndex < batchContext.requests.length) {\n const currentIndex = state.nextRequestIndex;\n state.nextRequestIndex += 1;\n await executeParallelRequest(batchContext, executor, state, currentIndex);\n }\n}\n\n/**\n * Execute tool requests in parallel with a bounded worker pool.\n * Preserves a result entry for every request (SSOT for toolCallId → result mapping).\n */\nasync function executeParallel(\n batchContext: IToolExecutionBatchContext,\n executor: IToolExecutor,\n): Promise<{ results: IToolExecutionResult[]; errors: Error[] }> {\n const state: IParallelExecutionState = {\n resultsByIndex: new Array(batchContext.requests.length),\n errorsByIndex: new Array(batchContext.requests.length),\n nextRequestIndex: 0,\n };\n const concurrency = resolveMaxConcurrency(\n batchContext.requests.length,\n batchContext.maxConcurrency,\n );\n\n const workers = Array.from({ length: concurrency }, () =>\n runParallelWorker(batchContext, executor, state),\n );\n await Promise.all(workers);\n\n const results = state.resultsByIndex.filter(isDefinedResult);\n const errors = state.errorsByIndex.filter(isDefinedError);\n\n if (errors.length > 0 && !batchContext.continueOnError) {\n throw errors[0];\n }\n\n return { results, errors };\n}\n\n/**\n * Execute tool requests sequentially, stopping on first error unless continueOnError is set.\n */\nasync function executeSequential(\n batchContext: IToolExecutionBatchContext,\n executor: IToolExecutor,\n): Promise<{ results: IToolExecutionResult[]; errors: Error[] }> {\n const results: IToolExecutionResult[] = [];\n const errors: Error[] = [];\n\n for (const request of batchContext.requests) {\n try {\n const result = await executor.executeTool(\n request.toolName,\n request.parameters,\n createExecutionContext(request),\n );\n results.push(result);\n if (!result.success) {\n errors.push(createToolFailureError(result));\n }\n if (!result.success && !batchContext.continueOnError) {\n break;\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n errors.push(err);\n if (!batchContext.continueOnError) {\n break;\n }\n }\n }\n\n return { results, errors };\n}\n\n/**\n * Execute a batch of tool requests, dispatching to parallel or sequential strategy.\n */\nexport async function executeBatch(\n batchContext: IToolExecutionBatchContext,\n executor: IToolExecutor,\n logger: ILogger,\n): Promise<{ results: IToolExecutionResult[]; errors: Error[] }> {\n logger.debug(`Executing ${batchContext.requests.length} tools in ${batchContext.mode} mode`);\n\n if (batchContext.mode === 'parallel') {\n return executeParallel(batchContext, executor);\n }\n return executeSequential(batchContext, executor);\n}\n","import type { IToolManager } from '../interfaces/manager';\nimport type {\n IToolExecutionContext,\n IToolExecutionResult,\n TToolParameters,\n TToolMetadata,\n} from '../interfaces/tool';\nimport type { IOwnerPathSegment, IToolEventData } from '../interfaces/event-service';\nimport type { IToolExecutionRequest } from '../interfaces/service';\nimport { SilentLogger, type ILogger } from '../utils/logger';\nimport { ValidationError } from '../utils/errors';\nimport { executeBatch } from './tool-execution-batch';\n\n/**\n * ToolExecutionService owned events\n * Local event names only (no dots). Full names are composed at emit time.\n */\nexport const TOOL_EVENTS = {\n CALL_START: 'call_start',\n CALL_COMPLETE: 'call_complete',\n CALL_ERROR: 'call_error',\n CALL_RESPONSE_READY: 'call_response_ready',\n} as const;\n\nexport const TOOL_EVENT_PREFIX = 'tool' as const;\n\nexport const UNKNOWN_TOOL_ERROR_CODE = 'unknown_tool' as const;\n\nexport interface IToolExecutionBatchContext {\n requests: IToolExecutionRequest[];\n mode: 'parallel' | 'sequential';\n timeout?: number;\n continueOnError?: boolean;\n maxConcurrency?: number;\n parentContext?: IToolExecutionContext;\n /** AbortSignal — queued tools are skipped when aborted */\n signal?: AbortSignal;\n}\n\n/**\n * Simplified ToolExecutionService\n * Focuses only on core tool execution without complex hierarchy tracking\n */\nexport class ToolExecutionService {\n private tools: IToolManager;\n private logger: ILogger;\n\n constructor(tools: IToolManager, logger: ILogger = SilentLogger) {\n this.tools = tools;\n this.logger = logger;\n }\n\n /**\n * Execute a single tool\n * @param toolName - Name of the tool to execute\n * @param parameters - Tool parameters\n * @param context - Optional execution context\n * @returns Promise resolving to tool execution result\n */\n async executeTool(\n toolName: string,\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<IToolExecutionResult> {\n this.logger.debug(`Executing tool: ${toolName}`);\n\n try {\n if (!context?.executionId) {\n throw new ValidationError(\n 'ToolExecutionService requires executionId (toolCallId) in ToolExecutionContext',\n );\n }\n\n if (!this.tools.hasTool(toolName)) {\n const availableTools = this.tools\n .getTools()\n .map((tool) => tool.name)\n .sort();\n const error = formatUnknownToolError(toolName, availableTools);\n const eventService = context.eventService;\n if (eventService) {\n const errorEvent: IToolEventData = {\n timestamp: new Date(),\n toolName,\n error,\n };\n eventService.emit(TOOL_EVENTS.CALL_ERROR, errorEvent);\n }\n this.logger.warn('Tool call skipped because requested tool is not registered', {\n toolName,\n availableTools,\n });\n return {\n success: false,\n error,\n toolName,\n executionId: context.executionId,\n metadata: {\n errorCode: UNKNOWN_TOOL_ERROR_CODE,\n requestedTool: toolName,\n availableTools,\n },\n };\n }\n\n const eventService = context.eventService;\n if (eventService) {\n const startEvent: IToolEventData = {\n timestamp: new Date(),\n toolName,\n parameters,\n };\n eventService.emit(TOOL_EVENTS.CALL_START, startEvent);\n }\n\n // Normalize execution context without duplicating keys from the spread.\n const { toolName: _toolName, parameters: _parameters, ...restContext } = context;\n void _toolName;\n void _parameters;\n\n const executionContext: IToolExecutionContext = {\n ...restContext,\n toolName,\n parameters,\n executionId: context.executionId,\n };\n\n // Execute the tool with full context\n // Context already contains all necessary information including tool call ID\n const result = await this.tools.executeTool(toolName, parameters, executionContext);\n\n this.logger.debug(`Tool execution completed: ${toolName}`);\n\n if (eventService) {\n const completeEvent: IToolEventData = {\n timestamp: new Date(),\n toolName,\n result: result,\n };\n eventService.emit(TOOL_EVENTS.CALL_COMPLETE, completeEvent);\n eventService.emit(TOOL_EVENTS.CALL_RESPONSE_READY, completeEvent);\n }\n\n return {\n success: true,\n result: result,\n toolName,\n executionId: executionContext.executionId!,\n };\n } catch (error) {\n this.logger.error(`Tool execution failed: ${toolName}`);\n\n const toolError = error instanceof Error ? error : new Error(String(error));\n\n const eventService = context?.eventService;\n if (eventService && context?.executionId) {\n const errorEvent: IToolEventData = {\n timestamp: new Date(),\n toolName,\n error: toolError.message,\n };\n eventService.emit(TOOL_EVENTS.CALL_ERROR, errorEvent);\n }\n\n return {\n success: false,\n error: toolError.message,\n toolName,\n executionId: context?.executionId,\n };\n }\n }\n\n /**\n * Create execution requests with context (for ExecutionService compatibility)\n * @param toolCalls - Array of tool calls from AI provider\n * @param context - Execution context\n * @returns Array of tool execution requests\n */\n createExecutionRequestsWithContext(\n toolCalls: Array<{ id: string; function: { name: string; arguments: string } }>,\n context: {\n ownerPathBase: IOwnerPathSegment[];\n metadataFactory?: (toolCall: {\n id: string;\n function: { name: string; arguments: string };\n }) => TToolMetadata | undefined;\n },\n ): IToolExecutionRequest[] {\n return toolCalls.map((toolCall) => {\n let parsedParameters: TToolParameters;\n try {\n parsedParameters = JSON.parse(toolCall.function.arguments) as TToolParameters;\n } catch {\n throw new ValidationError(\n `Failed to parse arguments for tool \"${toolCall.function.name}\" (call ${toolCall.id}): invalid JSON`,\n );\n }\n return {\n toolName: toolCall.function.name,\n parameters: parsedParameters,\n executionId: toolCall.id,\n ownerType: 'tool',\n ownerId: toolCall.id,\n ownerPath: [...context.ownerPathBase, { type: 'tool', id: toolCall.id }],\n metadata: context.metadataFactory ? context.metadataFactory(toolCall) : undefined,\n };\n });\n }\n\n /**\n * Execute tools from batch context (for ExecutionService compatibility)\n * @param batchContext - Batch execution context\n * @returns Promise resolving to tool execution summary\n */\n async executeTools(\n batchContext: IToolExecutionBatchContext,\n ): Promise<{ results: IToolExecutionResult[]; errors: Error[] }> {\n return executeBatch(batchContext, this, this.logger);\n }\n}\n\nfunction formatUnknownToolError(toolName: string, availableTools: string[]): string {\n const available =\n availableTools.length > 0 ? availableTools.join(', ') : 'no registered tools are available';\n return `Tool \"${toolName}\" is not registered, so the tool call was not executed. Available tools: ${available}.`;\n}\n","/**\n * ExecutionService owned events.\n * Local event names only (no dots). Full names are composed at emit time.\n */\nexport const EXECUTION_EVENTS = {\n START: 'start',\n COMPLETE: 'complete',\n ERROR: 'error',\n ASSISTANT_MESSAGE_START: 'assistant_message_start',\n ASSISTANT_MESSAGE_COMPLETE: 'assistant_message_complete',\n USER_MESSAGE: 'user_message',\n TOOL_RESULTS_TO_LLM: 'tool_results_to_llm',\n TOOL_RESULTS_READY: 'tool_results_ready',\n} as const;\n\nexport const EXECUTION_EVENT_PREFIX = 'execution' as const;\n","export type {\n IAgentEventData,\n IBaseEventData,\n IExecutionEventData,\n IEventContext,\n IEventService,\n IEventServiceOwnerBinding,\n IOwnerPathSegment,\n IToolEventData,\n TEventListener,\n} from './interfaces';\n\nimport type {\n IBaseEventData,\n IEventContext,\n IEventService,\n IEventServiceOwnerBinding,\n TEventListener,\n} from './interfaces';\n\n/**\n * Abstract base for event services.\n * Concrete implementations decide how events are delivered.\n */\nexport abstract class AbstractEventService implements IEventService {\n private listeners = new Set<TEventListener>();\n\n abstract emit(eventType: string, data: IBaseEventData, context?: IEventContext): void;\n\n subscribe(listener: TEventListener): void {\n this.listeners.add(listener);\n }\n\n unsubscribe(listener: TEventListener): void {\n this.listeners.delete(listener);\n }\n\n protected notifyListeners(\n eventType: string,\n data: IBaseEventData,\n context?: IEventContext,\n ): void {\n for (const listener of this.listeners) {\n listener(eventType, data, context);\n }\n }\n}\n\n/**\n * Default no-op event service (production-safe).\n * When injected, emit() intentionally does nothing.\n */\nexport class DefaultEventService extends AbstractEventService {\n emit(_eventType: string, _data: IBaseEventData, _context?: IEventContext): void {\n // Intentionally empty: no-op event service.\n }\n}\n\n/**\n * Singleton default event service instance.\n */\nexport const DEFAULT_ABSTRACT_EVENT_SERVICE: IEventService = new DefaultEventService();\n\n/**\n * Check if a given service is the default no-op implementation.\n */\nexport function isDefaultEventService(service: IEventService): boolean {\n return service === DEFAULT_ABSTRACT_EVENT_SERVICE || service instanceof DefaultEventService;\n}\n\n/**\n * Compose a full event name from owner prefix and local name.\n * Local names must not contain dots.\n */\nexport function composeEventName(ownerType: string, localName: string): string {\n if (!ownerType || ownerType.trim().length === 0) {\n throw new Error('[EVENTS] ownerType is required to compose event names.');\n }\n if (ownerType.includes('.')) {\n throw new Error(`[EVENTS] ownerType must not contain '.': \"${ownerType}\"`);\n }\n if (!localName || localName.trim().length === 0) {\n throw new Error('[EVENTS] local event name is required.');\n }\n if (localName.includes('.')) {\n throw new Error(`[EVENTS] Local event name must not contain '.': \"${localName}\"`);\n }\n return `${ownerType}.${localName}`;\n}\n\nconst ID_RADIX = 36;\nconst SPAN_ID_SUBSTR_END = 10;\n\n/**\n * Generate a unique span ID for distributed tracing correlation.\n */\nfunction generateSpanId(): string {\n return `span_${Date.now().toString(ID_RADIX)}_${Math.random().toString(ID_RADIX).slice(2, SPAN_ID_SUBSTR_END)}`;\n}\n\n/**\n * A scoped event service that always emits with an owner binding applied.\n */\nexport class StructuredEventService extends AbstractEventService {\n private readonly base: IEventService;\n private readonly binding: IEventServiceOwnerBinding;\n\n constructor(base: IEventService, binding: IEventServiceOwnerBinding) {\n super();\n this.base = base;\n this.binding = binding;\n }\n\n emit(eventType: string, data: IBaseEventData, context?: IEventContext): void {\n if (eventType.includes('.')) {\n throw new Error(`[EVENTS] Local event name must not contain '.': \"${eventType}\"`);\n }\n const merged: IEventContext = {\n ...context,\n ownerType: this.binding.ownerType,\n ownerId: this.binding.ownerId,\n ownerPath: this.binding.ownerPath,\n depth: this.binding.ownerPath.length,\n spanId: context?.spanId ?? generateSpanId(),\n };\n const fullEventName = composeEventName(this.binding.ownerType, eventType);\n this.base.emit(fullEventName, data, merged);\n }\n\n override subscribe(listener: TEventListener): void {\n this.base.subscribe(listener);\n }\n\n override unsubscribe(listener: TEventListener): void {\n this.base.unsubscribe(listener);\n }\n}\n\n/**\n * Bind an EventService to an explicit owner path.\n * This is the standard entry point for scoped emission (path-only architecture).\n */\nexport function bindWithOwnerPath(\n base: IEventService,\n binding: IEventServiceOwnerBinding,\n): IEventService {\n return new StructuredEventService(base, binding);\n}\n\n/**\n * Alias for bindWithOwnerPath for historical call sites.\n * Intentionally forwards to the single authoritative implementation.\n */\nexport function bindEventServiceOwner(\n base: IEventService,\n binding: IEventServiceOwnerBinding,\n): IEventService {\n return bindWithOwnerPath(base, binding);\n}\n\n/**\n * Observable EventService that notifies subscribed listeners.\n */\nexport class ObservableEventService extends AbstractEventService {\n emit(eventType: string, data: IBaseEventData, context?: IEventContext): void {\n this.notifyListeners(eventType, data, context);\n }\n}\n","export const TASK_EVENTS = {\n ASSIGNED: 'assigned',\n COMPLETED: 'completed',\n} as const;\n\nexport const TASK_EVENT_PREFIX = 'task' as const;\n","export const USER_EVENTS = {\n MESSAGE: 'message',\n INPUT: 'input',\n} as const;\n\nexport const USER_EVENT_PREFIX = 'user' as const;\n\nexport type TUserEvent = (typeof USER_EVENTS)[keyof typeof USER_EVENTS];\n","import type { IEventContext, IOwnerPathSegment } from '../interfaces/event-service';\nimport { TOOL_EVENT_PREFIX } from './tool-execution-service';\nimport { EXECUTION_EVENT_PREFIX } from './execution-constants';\n\n/**\n * Build the owner path from an optional IExecutionContextInjection.\n */\nexport function buildBaseOwnerPath(executionContext?: {\n ownerPath?: IOwnerPathSegment[];\n}): IOwnerPathSegment[] {\n if (!executionContext?.ownerPath?.length) {\n return [];\n }\n return executionContext.ownerPath.map((segment) => ({ ...segment }));\n}\n\n/**\n * Build the IEventContext for an execution-level event.\n */\nexport function buildExecutionOwnerContext(\n agentOwnerPathBase: IOwnerPathSegment[],\n ownerPathBase: IOwnerPathSegment[],\n rootId: string,\n executionId: string,\n): IEventContext {\n if (!rootId || rootId.length === 0) {\n throw new Error('[EXECUTION] Missing rootId for execution owner context');\n }\n if (!executionId || executionId.length === 0) {\n throw new Error('[EXECUTION] Missing executionId for execution owner context');\n }\n const basePath = agentOwnerPathBase.length ? agentOwnerPathBase : ownerPathBase;\n const path: IOwnerPathSegment[] = [...basePath];\n if (rootId && !path.some((segment) => segment.type === 'agent' && segment.id === rootId)) {\n path.push({ type: 'agent', id: rootId });\n }\n path.push({ type: 'execution', id: executionId });\n return {\n ownerType: EXECUTION_EVENT_PREFIX,\n ownerId: executionId,\n ownerPath: path,\n };\n}\n\n/**\n * Build the IEventContext for a thinking-level event.\n */\nexport function buildThinkingOwnerContext(\n agentOwnerPathBase: IOwnerPathSegment[],\n ownerPathBase: IOwnerPathSegment[],\n rootId: string,\n executionId: string,\n thinkingNodeId: string,\n previousThinkingNodeId?: string,\n): IEventContext {\n if (!thinkingNodeId || thinkingNodeId.length === 0) {\n throw new Error('[EXECUTION] Missing thinkingNodeId for thinking owner context');\n }\n const base = buildExecutionOwnerContext(\n agentOwnerPathBase,\n ownerPathBase,\n rootId,\n executionId,\n ).ownerPath;\n const path: IOwnerPathSegment[] = [...base];\n if (previousThinkingNodeId) {\n path.push({ type: 'thinking', id: previousThinkingNodeId });\n path.push({\n type: 'tool_result',\n id: `tool_result_${previousThinkingNodeId}`,\n });\n }\n path.push({ type: 'thinking', id: thinkingNodeId });\n return {\n ownerType: EXECUTION_EVENT_PREFIX,\n ownerId: executionId,\n ownerPath: path,\n };\n}\n\n/**\n * Build the IEventContext for a tool-level event.\n */\nexport function buildToolOwnerContext(\n agentOwnerPathBase: IOwnerPathSegment[],\n ownerPathBase: IOwnerPathSegment[],\n rootId: string,\n executionId: string,\n toolCallId: string,\n): IEventContext {\n if (!toolCallId || toolCallId.length === 0) {\n throw new Error('[EXECUTION] Missing toolCallId for tool owner context');\n }\n const base = buildExecutionOwnerContext(\n agentOwnerPathBase,\n ownerPathBase,\n rootId,\n executionId,\n ).ownerPath;\n const path = [...base, { type: 'tool', id: toolCallId }];\n return {\n ownerType: TOOL_EVENT_PREFIX,\n ownerId: toolCallId,\n ownerPath: path,\n };\n}\n\n/**\n * Build the IEventContext for a response-level event.\n */\nexport function buildResponseOwnerContext(\n agentOwnerPathBase: IOwnerPathSegment[],\n ownerPathBase: IOwnerPathSegment[],\n rootId: string,\n executionId: string,\n thinkingNodeId: string,\n previousThinkingNodeId?: string,\n): IEventContext {\n const thinkingPath = buildThinkingOwnerContext(\n agentOwnerPathBase,\n ownerPathBase,\n rootId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n ).ownerPath;\n const responseNodeId = `response_${thinkingNodeId}`;\n const path: IOwnerPathSegment[] = [...thinkingPath, { type: 'response', id: responseNodeId }];\n return {\n ownerType: EXECUTION_EVENT_PREFIX,\n ownerId: executionId,\n ownerPath: path,\n };\n}\n","import type { IAgentConfig, IAssistantMessage, TExecutionEventCallback } from '../interfaces/agent';\nimport type { TMetadata } from '../interfaces/types';\nimport type { IAIProviderManager } from '../interfaces/manager';\nimport type { IToolManager } from '../interfaces/manager';\nimport type { IChatOptions, TTextDeltaCallback } from '../interfaces/provider';\nimport type { TUniversalMessage } from '../interfaces/messages';\n\n/** Preview length for general content truncation */\nexport const PREVIEW_LENGTH = 100;\n\n/** Preview length for content previews in event data */\nexport const CONTENT_PREVIEW_LENGTH = 200;\n\n/** Preview length for short previews in debug logs */\nexport const SHORT_PREVIEW_LENGTH = 50;\n\n/** Average words per minute for reading time estimation */\nexport const WORDS_PER_MINUTE = 200;\n\n/** Threshold for high complexity response length */\nexport const HIGH_COMPLEXITY_THRESHOLD = 1000;\n\n/** Threshold for medium complexity response length */\nexport const MEDIUM_COMPLEXITY_THRESHOLD = 300;\n\n/** Threshold for high input complexity character count */\nexport const HIGH_INPUT_COMPLEXITY_THRESHOLD = 200;\n\n/** Threshold for medium input complexity character count */\nexport const MEDIUM_INPUT_COMPLEXITY_THRESHOLD = 50;\n\n/** Number of recent messages to show in debug logs */\nexport const LAST_MESSAGES_SLICE = -5;\n\n/** Radix for random ID generation */\nexport const ID_RADIX = 36;\n\n/** Length of random portion of generated IDs */\nexport const ID_RANDOM_LENGTH = 9;\n\n/**\n * Provider and tools information resolved at the start of execution\n */\nexport interface IResolvedProviderInfo {\n provider: {\n chat: (messages: TUniversalMessage[], options: IChatOptions) => Promise<TUniversalMessage>;\n };\n currentInfo: { provider: string };\n aiProviderInfo: {\n providerName: string;\n model: string;\n temperature: number | undefined;\n maxTokens: number | undefined;\n };\n toolsInfo: Array<{\n name: string;\n description: string;\n parameters: string[];\n }>;\n availableTools: ReturnType<IToolManager['getTools']>;\n}\n\n/**\n * Mutable state tracked across execution rounds\n */\nexport interface IExecutionRoundState {\n toolsExecuted: string[];\n currentRound: number;\n runningAssistantCount: number;\n lastTrackedAssistantMessage: IAssistantMessage | undefined;\n /** Cumulative input tokens from API responses (authoritative, not estimated) */\n cumulativeInputTokens: number;\n /** Consecutive model rounds that produced at least one unavailable tool call. */\n consecutiveUnknownToolFailureRounds: number;\n /** Optional instruction used when forcing a final response after loop guard trips. */\n forcedSummaryInstruction?: string;\n}\n\n/**\n * Error with optional execution-specific properties\n */\nexport interface IExecutionError extends Error {\n executionId?: string;\n toolName?: string;\n error?: Error;\n}\n\n/**\n * Type guard to check if error has execution properties\n */\nexport function isExecutionError(error: Error): error is IExecutionError {\n return 'executionId' in error || 'toolName' in error;\n}\n\n/**\n * Execution context for service operations.\n * Applies Type Deduplication Rule: Use standardized metadata type\n */\nexport interface IExecutionContext {\n conversationId?: string;\n sessionId?: string;\n userId?: string;\n messages: TUniversalMessage[];\n config: IAgentConfig;\n metadata?: TMetadata;\n startTime: Date;\n executionId: string;\n /** AbortSignal for cancelling execution */\n signal?: AbortSignal;\n /** Per-run streaming text callback. */\n onTextDelta?: TTextDeltaCallback;\n /** Per-run replay event callback for provider/tool execution boundaries. */\n onExecutionEvent?: TExecutionEventCallback;\n /** Per-run model/tool round limit. Use 0 for no core round cap. */\n maxExecutionRounds?: number;\n}\n\n/**\n * Execution result containing the response and execution metadata\n */\nexport interface IExecutionResult {\n response: string;\n messages: TUniversalMessage[];\n executionId: string;\n duration: number;\n tokensUsed?: number;\n toolsExecuted: string[];\n success: boolean;\n error?: Error;\n /** Whether execution was interrupted by abort */\n interrupted?: boolean;\n}\n\n/**\n * History statistics type returned by ConversationHistory.getStats()\n */\nexport interface IHistoryStats {\n totalConversations: number;\n conversationIds: string[];\n totalMessages: number;\n}\n\n/**\n * Plugin statistics type - using a simpler structure\n */\nexport interface IExecutionServicePluginStats {\n pluginCount: number;\n pluginNames: string[];\n historyStats: IHistoryStats;\n}\n\n/**\n * Count words in text without allocating an intermediate array.\n * Avoids the cost of split(/\\s+/) in hot paths.\n */\nexport function countWords(text: string): number {\n let count = 0;\n let inWord = false;\n for (let i = 0; i < text.length; i++) {\n const isSpace = text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n' || text[i] === '\\r';\n if (!isSpace && !inWord) {\n count++;\n inWord = true;\n } else if (isSpace) {\n inWord = false;\n }\n }\n return count;\n}\n","import type { IEventService, IEventContext } from '../interfaces/event-service';\nimport { bindWithOwnerPath } from '../event-service/index';\nimport { EXECUTION_EVENTS } from './execution-constants';\nimport {\n countWords,\n PREVIEW_LENGTH,\n CONTENT_PREVIEW_LENGTH,\n WORDS_PER_MINUTE,\n HIGH_COMPLEXITY_THRESHOLD,\n MEDIUM_COMPLEXITY_THRESHOLD,\n HIGH_INPUT_COMPLEXITY_THRESHOLD,\n MEDIUM_INPUT_COMPLEXITY_THRESHOLD,\n} from './execution-types';\nimport type { IAgentConfig } from '../interfaces/agent';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { IResolvedProviderInfo } from './execution-types';\nimport type { ExecutionEventEmitter } from './execution-event-emitter';\n\n/**\n * Emit the EXECUTION START event.\n * Extracted from ExecutionEventEmitter to reduce file size.\n */\nexport function emitExecutionStartEvent(\n emitter: ExecutionEventEmitter,\n input: string,\n config: IAgentConfig,\n messages: TUniversalMessage[],\n resolved: IResolvedProviderInfo,\n conversationId: string,\n executionId: string,\n): void {\n emitter.emitExecution(\n EXECUTION_EVENTS.START,\n {\n parameters: {\n input,\n agentConfiguration: resolved.aiProviderInfo,\n availableTools: resolved.toolsInfo,\n toolCount: resolved.toolsInfo.length,\n hasTools: resolved.toolsInfo.length > 0,\n systemMessage: config.defaultModel.systemMessage,\n provider: config.defaultModel.provider,\n model: config.defaultModel.model,\n temperature: config.defaultModel.temperature,\n maxTokens: config.defaultModel.maxTokens,\n },\n metadata: {\n method: 'execute',\n inputLength: input.length,\n messageCount: messages.length,\n aiProvider: resolved.aiProviderInfo.providerName,\n model: resolved.aiProviderInfo.model,\n toolsAvailable: resolved.toolsInfo.map((t) => t.name),\n agentCapabilities: {\n canUseTools: resolved.toolsInfo.length > 0,\n supportedActions: resolved.toolsInfo.map((t) => t.name),\n },\n },\n },\n conversationId,\n executionId,\n );\n}\n\n/**\n * Emit the USER_MESSAGE event.\n * Extracted from ExecutionEventEmitter to reduce file size.\n */\nexport function emitUserMessageEvent(\n emitter: ExecutionEventEmitter,\n input: string,\n conversationId: string,\n executionId: string,\n): void {\n emitter.emitExecution(\n EXECUTION_EVENTS.USER_MESSAGE,\n {\n parameters: {\n input,\n userPrompt: input,\n userMessageContent: input,\n messageLength: input.length,\n wordCount: countWords(input),\n characterCount: input.length,\n },\n metadata: {\n messageRole: 'user',\n inputLength: input.length,\n messageType: 'user_message',\n hasQuestions: input.includes('?'),\n containsUrgency: /urgent|asap|critical|emergency/i.test(input),\n estimatedComplexity:\n input.length > HIGH_INPUT_COMPLEXITY_THRESHOLD\n ? 'high'\n : input.length > MEDIUM_INPUT_COMPLEXITY_THRESHOLD\n ? 'medium'\n : 'low',\n },\n },\n conversationId,\n executionId,\n );\n}\n\n/**\n * Emit the ASSISTANT_MESSAGE_COMPLETE event.\n * Extracted from ExecutionEventEmitter to reduce file size.\n */\nexport function emitAssistantMessageComplete(\n emitter: ExecutionEventEmitter,\n baseEventService: IEventService,\n assistantResponse: { content?: string | null; timestamp?: Date },\n executionId: string,\n currentRound: number,\n conversationId: string,\n thinkingNodeId: string,\n previousThinkingNodeId: string | undefined,\n): void {\n if (typeof assistantResponse.content !== 'string' || assistantResponse.content.length === 0) {\n throw new Error('[EXECUTION] assistant response must have content or tool calls');\n }\n if (!(assistantResponse.timestamp instanceof Date)) {\n throw new Error('[EXECUTION] assistant response timestamp is required');\n }\n const responseContent = assistantResponse.content;\n const responseStartTime = assistantResponse.timestamp;\n const responseDuration = new Date().getTime() - responseStartTime.getTime();\n\n emitter.emitWithContext(\n EXECUTION_EVENTS.ASSISTANT_MESSAGE_COMPLETE,\n {\n parameters: {\n assistantMessage: responseContent,\n responseLength: responseContent.length,\n wordCount: countWords(responseContent),\n responseTime: responseDuration,\n contentPreview:\n responseContent.length > CONTENT_PREVIEW_LENGTH\n ? responseContent.substring(0, CONTENT_PREVIEW_LENGTH) + '...'\n : responseContent,\n },\n result: {\n success: true,\n data: responseContent.substring(0, PREVIEW_LENGTH) + '...',\n fullResponse: responseContent,\n responseMetrics: {\n length: responseContent.length,\n estimatedReadTime: Math.ceil(countWords(responseContent) / WORDS_PER_MINUTE),\n hasCodeBlocks: /```/.test(responseContent),\n hasLinks: /https?:\\/\\//.test(responseContent),\n complexity:\n responseContent.length > HIGH_COMPLEXITY_THRESHOLD\n ? 'high'\n : responseContent.length > MEDIUM_COMPLEXITY_THRESHOLD\n ? 'medium'\n : 'low',\n },\n },\n metadata: {\n executionId,\n round: currentRound,\n completed: true,\n reason: 'no_tool_calls',\n responseCharacteristics: {\n hasQuestions: responseContent.includes('?'),\n isError: /error|fail|wrong/i.test(responseContent),\n isComplete: /complete|done|finish/i.test(responseContent),\n containsNumbers: /\\d/.test(responseContent),\n },\n },\n },\n () =>\n emitter.buildResponseOwnerContext(\n conversationId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n ),\n (ctx) => {\n if (!ctx.ownerType || !ctx.ownerId) {\n throw new Error('[EXECUTION] Missing owner context for response event');\n }\n return bindWithOwnerPath(baseEventService, {\n ownerType: ctx.ownerType,\n ownerId: ctx.ownerId,\n ownerPath: ctx.ownerPath,\n });\n },\n );\n}\n\n/**\n * Emit TOOL_RESULTS_READY and TOOL_RESULTS_TO_LLM events.\n * Extracted from ExecutionEventEmitter to reduce file size.\n */\nexport function emitToolResultsEvents(\n emitter: ExecutionEventEmitter,\n baseEventService: IEventService,\n assistantToolCalls: Array<{ id?: string }>,\n toolSummary: { results: Array<{ toolName?: string }> },\n toolsExecuted: string[],\n conversationId: string,\n executionId: string,\n currentRound: number,\n thinkingNodeId: string,\n previousThinkingNodeId: string | undefined,\n): void {\n const toolCallIds = assistantToolCalls.map((toolCall) => {\n if (!toolCall.id || toolCall.id.length === 0) {\n throw new Error('[EXECUTION] Tool call missing id for tool results ready payload');\n }\n return toolCall.id;\n });\n if (toolCallIds.length === 0) {\n throw new Error('[EXECUTION] Tool results ready requires toolCallIds');\n }\n\n const buildCtx = () =>\n emitter.buildThinkingOwnerContext(\n conversationId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n const resolveService = (ctx: IEventContext) => {\n if (!ctx.ownerType || !ctx.ownerId) {\n throw new Error('[EXECUTION] Missing owner context for tool results event');\n }\n return bindWithOwnerPath(baseEventService, {\n ownerType: ctx.ownerType,\n ownerId: ctx.ownerId,\n ownerPath: ctx.ownerPath,\n });\n };\n\n emitter.emitWithContext(\n EXECUTION_EVENTS.TOOL_RESULTS_READY,\n {\n parameters: { toolCallIds, round: currentRound },\n metadata: { round: currentRound },\n },\n buildCtx,\n resolveService,\n );\n\n emitter.emitWithContext(\n EXECUTION_EVENTS.TOOL_RESULTS_TO_LLM,\n {\n parameters: {\n toolsExecuted: toolsExecuted.length,\n round: currentRound,\n },\n metadata: {\n toolsExecuted: toolSummary.results.map((r) => {\n if (!r.toolName || (r.toolName as string).length === 0) {\n throw new Error('[EXECUTION] Tool result missing toolName');\n }\n return r.toolName;\n }),\n round: currentRound,\n },\n },\n buildCtx,\n resolveService,\n );\n}\n","import type { IExecutionContextInjection } from '../interfaces/agent';\nimport type { ILogger } from '../utils/logger';\nimport type {\n IEventService,\n IEventContext,\n IOwnerPathSegment,\n IExecutionEventData,\n IToolEventData,\n IBaseEventData,\n} from '../interfaces/event-service';\nimport { isDefaultEventService, bindWithOwnerPath } from '../event-service/index';\nimport { TOOL_EVENT_PREFIX } from './tool-execution-service';\nimport type { IAgentConfig } from '../interfaces/agent';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { IResolvedProviderInfo } from './execution-types';\nimport {\n buildBaseOwnerPath,\n buildExecutionOwnerContext,\n buildThinkingOwnerContext,\n buildToolOwnerContext,\n buildResponseOwnerContext,\n} from './execution-event-helpers';\nimport {\n emitAssistantMessageComplete as emitAssistantMessageCompleteHelper,\n emitToolResultsEvents as emitToolResultsEventsHelper,\n emitExecutionStartEvent as emitExecutionStartEventHelper,\n emitUserMessageEvent as emitUserMessageEventHelper,\n} from './execution-event-emitter-high-level';\n\n/**\n * Encapsulates all event emission logic for ExecutionService.\n * Manages owner path construction and event service scoping.\n */\nexport class ExecutionEventEmitter {\n private readonly baseEventService: IEventService;\n private readonly logger: ILogger;\n private readonly ownerPathBase: IOwnerPathSegment[];\n private readonly toolEventServices: Map<string, IEventService>;\n private agentOwnerPathBase: IOwnerPathSegment[];\n\n constructor(\n baseEventService: IEventService,\n logger: ILogger,\n executionContext?: IExecutionContextInjection,\n ) {\n this.baseEventService = baseEventService;\n this.logger = logger;\n this.ownerPathBase = buildBaseOwnerPath(executionContext);\n this.toolEventServices = new Map();\n this.agentOwnerPathBase = [];\n }\n\n /**\n * Prepare owner path bases for a conversation\n */\n prepareOwnerPathBases(conversationId: string): void {\n this.toolEventServices.clear();\n const ownerPath = [...this.ownerPathBase, { type: 'agent', id: conversationId }];\n this.agentOwnerPathBase = ownerPath;\n }\n\n /**\n * Reset owner path bases after execution\n */\n resetOwnerPathBases(): void {\n this.toolEventServices.clear();\n this.agentOwnerPathBase = [];\n }\n\n /**\n * Ensure a scoped event service exists for a tool\n */\n ensureToolEventService(\n ownerId: string | undefined,\n ownerPath: IOwnerPathSegment[] | undefined,\n ): IEventService {\n if (isDefaultEventService(this.baseEventService)) {\n return this.baseEventService;\n }\n if (!ownerId) {\n throw new Error('[EVENT-SERVICE] Missing ownerId for tool event context');\n }\n if (!ownerPath || ownerPath.length === 0) {\n throw new Error('[EVENT-SERVICE] Missing ownerPath for tool event context');\n }\n if (this.toolEventServices.has(ownerId)) {\n return this.toolEventServices.get(ownerId)!;\n }\n const scoped = bindWithOwnerPath(this.baseEventService, {\n ownerType: TOOL_EVENT_PREFIX,\n ownerId,\n ownerPath: ownerPath.map((segment) => ({ ...segment })),\n });\n this.toolEventServices.set(ownerId, scoped);\n return scoped;\n }\n\n /**\n * Clear tool event services (e.g., between rounds)\n */\n clearToolEventServices(): void {\n this.toolEventServices.clear();\n }\n\n /**\n * Get the base event service\n */\n getBaseEventService(): IEventService {\n return this.baseEventService;\n }\n\n // --- Owner context builders (delegating to pure helpers) ---\n\n buildExecutionOwnerContext(rootId: string, executionId: string): IEventContext {\n return buildExecutionOwnerContext(\n this.agentOwnerPathBase,\n this.ownerPathBase,\n rootId,\n executionId,\n );\n }\n\n buildThinkingOwnerContext(\n rootId: string,\n executionId: string,\n thinkingNodeId: string,\n previousThinkingNodeId?: string,\n ): IEventContext {\n return buildThinkingOwnerContext(\n this.agentOwnerPathBase,\n this.ownerPathBase,\n rootId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n }\n\n buildToolOwnerContext(rootId: string, executionId: string, toolCallId: string): IEventContext {\n return buildToolOwnerContext(\n this.agentOwnerPathBase,\n this.ownerPathBase,\n rootId,\n executionId,\n toolCallId,\n );\n }\n\n buildResponseOwnerContext(\n rootId: string,\n executionId: string,\n thinkingNodeId: string,\n previousThinkingNodeId?: string,\n ): IEventContext {\n return buildResponseOwnerContext(\n this.agentOwnerPathBase,\n this.ownerPathBase,\n rootId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n }\n\n // --- Emit helpers ---\n\n emitExecution(\n eventType: string,\n data: Omit<IExecutionEventData, 'timestamp'>,\n rootId: string,\n executionId: string,\n ): void {\n this.emitWithContext(\n eventType,\n data,\n () => this.buildExecutionOwnerContext(rootId, executionId),\n (context) => {\n if (!context.ownerType || !context.ownerId) {\n throw new Error('[EXECUTION] Missing owner context for execution event');\n }\n return bindWithOwnerPath(this.baseEventService, {\n ownerType: context.ownerType,\n ownerId: context.ownerId,\n ownerPath: context.ownerPath,\n });\n },\n );\n }\n\n emitTool(\n eventType: string,\n data: Omit<IToolEventData, 'timestamp'>,\n rootId: string,\n executionId: string,\n toolCallId: string,\n ): void {\n this.emitWithContext(\n eventType,\n data,\n () => this.buildToolOwnerContext(rootId, executionId, toolCallId),\n (context) => this.ensureToolEventService(context.ownerId, context.ownerPath),\n );\n }\n\n emitWithContext<TEvent extends IBaseEventData>(\n eventType: string,\n data: Omit<TEvent, 'timestamp'>,\n buildContext: () => IEventContext,\n resolveService: (context: IEventContext) => IEventService,\n ): void {\n if (isDefaultEventService(this.baseEventService)) {\n return;\n }\n const context = buildContext();\n const service = resolveService(context);\n const payload: TEvent = {\n timestamp: new Date(),\n ...(data as Omit<TEvent, 'timestamp'>),\n } as TEvent;\n service.emit(eventType, payload, context);\n }\n\n // --- High-level event emitters ---\n\n emitExecutionStartEvent(\n input: string,\n config: IAgentConfig,\n messages: TUniversalMessage[],\n resolved: IResolvedProviderInfo,\n conversationId: string,\n executionId: string,\n ): void {\n emitExecutionStartEventHelper(\n this,\n input,\n config,\n messages,\n resolved,\n conversationId,\n executionId,\n );\n }\n\n emitUserMessageEvent(input: string, conversationId: string, executionId: string): void {\n emitUserMessageEventHelper(this, input, conversationId, executionId);\n }\n\n emitAssistantMessageComplete(\n assistantResponse: { content?: string | null; timestamp?: Date },\n executionId: string,\n currentRound: number,\n conversationId: string,\n thinkingNodeId: string,\n previousThinkingNodeId: string | undefined,\n ): void {\n emitAssistantMessageCompleteHelper(\n this,\n this.baseEventService,\n assistantResponse,\n executionId,\n currentRound,\n conversationId,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n }\n\n emitToolResultsEvents(\n assistantToolCalls: Array<{ id?: string }>,\n toolSummary: { results: Array<{ toolName?: string }> },\n toolsExecuted: string[],\n conversationId: string,\n executionId: string,\n currentRound: number,\n thinkingNodeId: string,\n previousThinkingNodeId: string | undefined,\n ): void {\n emitToolResultsEventsHelper(\n this,\n this.baseEventService,\n assistantToolCalls,\n toolSummary,\n toolsExecuted,\n conversationId,\n executionId,\n currentRound,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n }\n}\n","import type { IPluginContext } from '../interfaces/types';\nimport type {\n IPluginContract,\n IPluginHooks,\n IPluginOptions,\n IPluginStats,\n IPluginErrorContext,\n} from '../abstracts/abstract-plugin';\nimport type { ILogger } from '../utils/logger';\nimport { EXECUTION_EVENT_PREFIX, EXECUTION_EVENTS } from './execution-constants';\n\n/** Combined plugin type used throughout the execution service */\nexport type TPluginWithHooks = IPluginContract<IPluginOptions, IPluginStats> & IPluginHooks;\n\n/** Handler for a single plugin hook invocation */\ntype TPluginHookHandler = (plugin: TPluginWithHooks, context: IPluginContext) => Promise<void>;\n\n/** Map from hook name to its handler function */\nconst HOOK_HANDLERS: Record<string, TPluginHookHandler> = {\n beforeRun: async (plugin, context) => {\n if (plugin.beforeRun && context.input) {\n await plugin.beforeRun(context.input, context.metadata);\n }\n },\n afterRun: async (plugin, context) => {\n if (plugin.afterRun && context.input && context.response) {\n await plugin.afterRun(context.input, context.response, context.metadata);\n }\n },\n beforeProviderCall: async (plugin, context) => {\n if (plugin.beforeProviderCall && context.messages) {\n await plugin.beforeProviderCall(context.messages);\n }\n },\n afterProviderCall: async (plugin, context) => {\n if (plugin.afterProviderCall && context.messages && context.responseMessage) {\n await plugin.afterProviderCall(context.messages, context.responseMessage);\n }\n },\n onError: async (plugin, context) => {\n if (plugin.onError && context.error) {\n const errorContext: IPluginErrorContext = {\n action: `${EXECUTION_EVENT_PREFIX}.${EXECUTION_EVENTS.ERROR}`,\n metadata: {},\n };\n\n const executionIdValue = context.executionContext?.['executionId'];\n if (typeof executionIdValue === 'string' && executionIdValue.length > 0) {\n errorContext.executionId = executionIdValue;\n }\n const sessionIdValue = context.executionContext?.['sessionId'];\n if (typeof sessionIdValue === 'string' && sessionIdValue.length > 0) {\n errorContext.sessionId = sessionIdValue;\n }\n const userIdValue = context.executionContext?.['userId'];\n if (typeof userIdValue === 'string' && userIdValue.length > 0) {\n errorContext.userId = userIdValue;\n }\n\n await plugin.onError(context.error, errorContext);\n }\n },\n};\n\n/**\n * Dispatch a hook call to all plugins that implement it.\n * Uses a handler map instead of a switch for lower cyclomatic complexity.\n */\nexport async function callPluginHook(\n plugins: ReadonlyArray<TPluginWithHooks>,\n hookName: string,\n context: IPluginContext,\n logger: ILogger,\n): Promise<void> {\n const handler = HOOK_HANDLERS[hookName];\n if (!handler) {\n return;\n }\n\n for (const plugin of plugins) {\n try {\n await handler(plugin, context);\n } catch (error) {\n logger.warn('Plugin hook failed', {\n pluginName: plugin.name,\n hookName,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n}\n","import type { IToolCall } from '../interfaces/messages';\nimport type { IToolExecutionBatchContext, ToolExecutionService } from './tool-execution-service';\nimport type { ExecutionEventEmitter } from './execution-event-emitter';\nimport type { ILogger } from '../utils/logger';\nimport { isExecutionError } from './execution-types';\nimport type { IExecutionError } from './execution-types';\nimport { EXECUTION_EVENTS } from './execution-constants';\nimport type { IStreamChunk } from './execution-stream';\n\n/**\n * Execute tool calls detected during streaming and yield result chunks.\n * Extracted from execution-stream.ts to reduce file size.\n */\nexport async function* executeStreamToolCalls(\n toolCalls: IToolCall[],\n conversationStore: {\n addToolMessageWithId: (\n content: string,\n toolCallId: string,\n toolName: string,\n metadata?: Record<string, string | number | boolean>,\n ) => void;\n },\n streamingConversationId: string,\n executionId: string,\n toolExecutionService: ToolExecutionService,\n eventEmitter: ExecutionEventEmitter,\n logger: ILogger,\n): AsyncGenerator<IStreamChunk> {\n logger.debug('[EXECUTION-SERVICE-STREAM] Executing tools:', {\n tools: toolCalls.map((tc) => tc.function.name),\n });\n\n const streamingRootId = streamingConversationId;\n const streamingThinkingNodeId = `thinking_${streamingRootId}_${Date.now()}_${executionId}`;\n const streamingOwnerPathBase = [\n ...eventEmitter.buildExecutionOwnerContext(streamingRootId, executionId).ownerPath,\n { type: 'thinking', id: streamingThinkingNodeId },\n ];\n const toolRequests = toolExecutionService.createExecutionRequestsWithContext(toolCalls, {\n ownerPathBase: streamingOwnerPathBase,\n });\n const toolContext: IToolExecutionBatchContext = {\n requests: toolRequests,\n mode: 'parallel',\n maxConcurrency: 5,\n continueOnError: true,\n };\n\n const toolSummary = await toolExecutionService.executeTools(toolContext);\n\n for (const toolCall of toolCalls) {\n if (!toolCall.id) {\n throw new Error('[EXECUTION] Tool call missing id in streaming mode');\n }\n if (!toolCall.function?.name || toolCall.function.name.length === 0) {\n throw new Error(\n `[EXECUTION] Tool call \"${toolCall.id}\" missing function name in streaming mode`,\n );\n }\n\n const result = toolSummary.results.find((r) => r.executionId === toolCall.id);\n const error = toolSummary.errors.find(\n (e) => isExecutionError(e) && e.executionId === toolCall.id,\n );\n\n let content: string;\n let metadata: Record<string, string | number | boolean> = {\n executionId,\n };\n\n if (result && result.success) {\n if (typeof result.result === 'undefined') {\n throw new Error('[EXECUTION] Tool result missing result payload in streaming mode');\n }\n content = typeof result.result === 'string' ? result.result : JSON.stringify(result.result);\n metadata['success'] = true;\n if (result.toolName) {\n metadata['toolName'] = result.toolName;\n }\n\n yield {\n chunk: `\\n[Tool: ${toolCall.function.name} executed successfully]`,\n isComplete: false,\n };\n } else if (error) {\n const execError = error as IExecutionError;\n const execMessage = (() => {\n if (execError.error?.message) return execError.error.message;\n if (execError.message) return execError.message;\n return '';\n })();\n if (!execMessage || execMessage.length === 0) {\n throw new Error('[EXECUTION] Tool execution error missing message in streaming mode');\n }\n content = `Error: ${execMessage}`;\n metadata['success'] = false;\n metadata['error'] = execMessage;\n if (execError.toolName) {\n metadata['toolName'] = execError.toolName;\n }\n\n yield {\n chunk: `\\n[Tool: ${toolCall.function.name} failed: ${execMessage}]`,\n isComplete: false,\n };\n } else {\n throw new Error(\n `[EXECUTION] Missing tool result for tool call \"${toolCall.id}\" in streaming mode`,\n );\n }\n\n conversationStore.addToolMessageWithId(content, toolCall.id, toolCall.function.name, metadata);\n }\n\n const streamingToolCallIds = toolCalls.map((toolCall) => {\n if (!toolCall.id || toolCall.id.length === 0) {\n throw new Error('[EXECUTION] Tool call missing id for streaming tool results ready payload');\n }\n return toolCall.id;\n });\n if (streamingToolCallIds.length === 0) {\n throw new Error('[EXECUTION] Tool results ready requires toolCallIds in streaming mode');\n }\n eventEmitter.emitExecution(\n EXECUTION_EVENTS.TOOL_RESULTS_READY,\n {\n parameters: {\n toolCallIds: streamingToolCallIds,\n round: 1,\n },\n metadata: {\n toolsExecuted: toolSummary.results.map((r) => {\n if (!r.toolName || r.toolName.length === 0) {\n throw new Error('[EXECUTION] Tool result missing toolName');\n }\n return r.toolName;\n }),\n round: 1,\n },\n },\n streamingConversationId,\n executionId,\n );\n}\n","import type { IAgentConfig, IAssistantMessage } from '../interfaces/agent';\nimport type { IPluginContext, TMetadata } from '../interfaces/types';\nimport type { IAIProviderManager } from '../interfaces/manager';\nimport type { IToolManager } from '../interfaces/manager';\nimport type { IChatOptions } from '../interfaces/provider';\nimport type { IToolCall, TUniversalMessage } from '../interfaces/messages';\nimport type { IToolExecutionBatchContext } from './tool-execution-service';\nimport type { ToolExecutionService } from './tool-execution-service';\nimport type { ConversationHistory } from '../managers/conversation-history-manager';\nimport type { ILogger } from '../utils/logger';\nimport type { ExecutionEventEmitter } from './execution-event-emitter';\nimport type { TPluginWithHooks } from './plugin-hook-dispatcher';\nimport { callPluginHook } from './plugin-hook-dispatcher';\nimport type { IExecutionContext } from './execution-types';\nimport { executeStreamToolCalls } from './execution-stream-tools';\n\n/** Streaming chunk yielded by executeStream */\nexport interface IStreamChunk {\n chunk: string;\n isComplete: boolean;\n}\n\n/** Dependencies required by executeStream */\nexport interface IStreamDependencies {\n aiProviders: IAIProviderManager;\n tools: IToolManager;\n conversationHistory: ConversationHistory;\n toolExecutionService: ToolExecutionService;\n plugins: ReadonlyArray<TPluginWithHooks>;\n logger: ILogger;\n eventEmitter: ExecutionEventEmitter;\n generateExecutionId: () => string;\n}\n\n/**\n * Execute with streaming response.\n * Extracted from ExecutionService to reduce file size.\n */\nexport async function* executeStream(\n input: string,\n _messages: TUniversalMessage[],\n config: IAgentConfig,\n context: Partial<IExecutionContext> | undefined,\n deps: IStreamDependencies,\n): AsyncGenerator<IStreamChunk> {\n const {\n aiProviders,\n tools,\n conversationHistory,\n toolExecutionService,\n plugins,\n logger,\n eventEmitter,\n } = deps;\n\n logger.debug('ExecutionService.executeStream called');\n\n const executionId = deps.generateExecutionId();\n const startTime = Date.now();\n if (!context?.conversationId || context.conversationId.length === 0) {\n throw new Error('[EXECUTION] conversationId is required for streaming');\n }\n const streamingConversationId = context.conversationId;\n eventEmitter.prepareOwnerPathBases(streamingConversationId);\n\n try {\n const conversationStore = conversationHistory.getConversationStore(context.conversationId);\n\n if (input) {\n conversationStore.addUserMessage(input, { executionId });\n }\n\n await callPluginHook(\n plugins,\n 'beforeRun',\n {\n input,\n ...(context?.metadata ? { metadata: context.metadata as TMetadata } : {}),\n },\n logger,\n );\n\n const currentInfo = aiProviders.getCurrentProvider();\n if (!currentInfo) {\n throw new Error('No AI provider configured');\n }\n\n const provider = aiProviders.getProvider(currentInfo.provider);\n if (!provider) {\n throw new Error(`AI provider '${currentInfo.provider}' not found`);\n }\n\n if (typeof provider.chatStream !== 'function') {\n throw new Error('Provider must have chatStream method to support streaming execution');\n }\n\n logger.debug('ExecutionService calling provider.chatStream');\n\n const conversationMessages = conversationStore.getMessages();\n\n const configToolsLength = Array.isArray(config.tools) ? config.tools.length : undefined;\n logger.debug('[EXECUTION-SERVICE] config.tools:', {\n length: configToolsLength,\n });\n const toolSchemas = tools.getTools();\n const toolSchemasLength = Array.isArray(toolSchemas) ? toolSchemas.length : undefined;\n logger.debug('[EXECUTION-SERVICE] this.tools.getTools():', {\n length: toolSchemasLength,\n });\n logger.debug('[EXECUTION-SERVICE] config.tools exists:', {\n exists: !!config.tools,\n });\n logger.debug('[EXECUTION-SERVICE] config.tools.length > 0:', {\n hasTools: config.tools && config.tools.length > 0,\n });\n\n const chatOptions: IChatOptions = {\n model: config.defaultModel.model,\n ...(config.tools && config.tools.length > 0 && { tools: tools.getTools() }),\n };\n\n logger.debug('[EXECUTION-SERVICE] Final chatOptions has tools:', {\n hasTools: !!chatOptions.tools,\n });\n const chatOptionsToolsLength = Array.isArray(chatOptions.tools)\n ? chatOptions.tools.length\n : undefined;\n logger.debug('[EXECUTION-SERVICE] Final chatOptions.tools length:', {\n length: chatOptionsToolsLength,\n });\n\n const chatStream = provider.chatStream;\n if (!chatStream) {\n throw new Error('Provider does not support streaming');\n }\n\n const stream = chatStream.call(provider, conversationMessages, chatOptions);\n let fullResponse = '';\n let toolCalls: IToolCall[] = [];\n let currentToolCallIndex = -1;\n\n for await (const chunk of stream) {\n if (chunk.content) {\n fullResponse += chunk.content;\n yield { chunk: chunk.content, isComplete: false };\n }\n\n if (chunk.role === 'assistant') {\n const assistantChunk = chunk as IAssistantMessage;\n if (Array.isArray(assistantChunk.toolCalls) && assistantChunk.toolCalls.length > 0) {\n for (const chunkToolCall of assistantChunk.toolCalls) {\n if (chunkToolCall.id && chunkToolCall.id !== '') {\n if (!chunkToolCall.type || chunkToolCall.type.length === 0) {\n throw new Error(\n `[EXECUTION] Tool call \"${chunkToolCall.id}\" missing type in stream`,\n );\n }\n if (!chunkToolCall.function?.name || chunkToolCall.function.name.length === 0) {\n throw new Error(\n `[EXECUTION] Tool call \"${chunkToolCall.id}\" missing function name in stream`,\n );\n }\n if (typeof chunkToolCall.function.arguments !== 'string') {\n throw new Error(\n `[EXECUTION] Tool call \"${chunkToolCall.id}\" missing arguments in stream`,\n );\n }\n currentToolCallIndex = toolCalls.length;\n toolCalls.push({\n id: chunkToolCall.id,\n type: chunkToolCall.type,\n function: {\n name: chunkToolCall.function.name,\n arguments: chunkToolCall.function.arguments,\n },\n });\n logger.debug(\n `[TOOL-STREAM] New tool call started: ${chunkToolCall.id} (${chunkToolCall.function?.name})`,\n );\n } else if (currentToolCallIndex >= 0) {\n const hasNameFragment =\n typeof chunkToolCall.function?.name === 'string' &&\n chunkToolCall.function.name.length > 0;\n const hasArgumentsFragment =\n typeof chunkToolCall.function?.arguments === 'string' &&\n chunkToolCall.function.arguments.length > 0;\n if (!hasNameFragment && !hasArgumentsFragment) {\n throw new Error(\n `[EXECUTION] Tool call fragment missing name/arguments for ${toolCalls[currentToolCallIndex].id}`,\n );\n }\n if (hasNameFragment) {\n toolCalls[currentToolCallIndex].function.name += chunkToolCall.function!.name;\n }\n if (hasArgumentsFragment) {\n toolCalls[currentToolCallIndex].function.arguments +=\n chunkToolCall.function!.arguments;\n }\n const fragmentPreview = hasArgumentsFragment\n ? chunkToolCall.function!.arguments\n : chunkToolCall.function!.name;\n logger.debug(\n `[TOOL-STREAM] Adding fragment to tool ${toolCalls[currentToolCallIndex].id}: \"${fragmentPreview}\"`,\n );\n }\n }\n }\n }\n }\n\n logger.debug('[EXECUTION-SERVICE-STREAM] Stream completed, toolCalls detected:', {\n count: toolCalls.length,\n });\n\n if (typeof fullResponse !== 'string') {\n throw new Error('[EXECUTION] Streaming response content is required');\n }\n conversationStore.addAssistantMessage(fullResponse, toolCalls, {\n executionId,\n });\n\n if (toolCalls.length > 0) {\n yield* executeStreamToolCalls(\n toolCalls,\n conversationStore,\n streamingConversationId,\n executionId,\n toolExecutionService,\n eventEmitter,\n logger,\n );\n }\n\n await callPluginHook(\n plugins,\n 'afterRun',\n {\n input,\n response: fullResponse,\n ...(context?.metadata ? { metadata: context.metadata as TMetadata } : {}),\n },\n logger,\n );\n\n yield { chunk: '', isComplete: true };\n } catch (error) {\n logger.error('ExecutionService streaming execution failed', {\n error: error instanceof Error ? error.message : String(error),\n executionTime: Date.now() - startTime,\n });\n\n await callPluginHook(\n plugins,\n 'onError',\n {\n input,\n error: error instanceof Error ? error : new Error(String(error)),\n ...(context?.metadata ? { metadata: context.metadata as TMetadata } : {}),\n },\n logger,\n );\n\n throw error;\n } finally {\n eventEmitter.resetOwnerPathBases();\n }\n}\n","import type { IAgentConfig, IAssistantMessage, IToolMessage } from '../interfaces/agent';\nimport type { IAIProviderManager } from '../interfaces/manager';\nimport type { IToolManager } from '../interfaces/manager';\nimport { type ConversationStore } from '../managers/conversation-history-manager';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { TPluginWithHooks } from './plugin-hook-dispatcher';\nimport { callPluginHook } from './plugin-hook-dispatcher';\nimport type { ILogger } from '../utils/logger';\nimport type { ExecutionEventEmitter } from './execution-event-emitter';\nimport { EXECUTION_EVENTS } from './execution-constants';\nimport {\n type IResolvedProviderInfo,\n type IExecutionContext,\n type IExecutionResult,\n ID_RADIX,\n ID_RANDOM_LENGTH,\n} from './execution-types';\n\n/**\n * Resolve the current AI provider and available tools from managers.\n * Pure function — no class instance needed.\n */\nexport function resolveProviderAndTools(\n aiProviders: IAIProviderManager,\n tools: IToolManager,\n config: IAgentConfig,\n): IResolvedProviderInfo {\n const currentInfo = aiProviders.getCurrentProvider();\n const provider = currentInfo ? aiProviders.getProvider(currentInfo.provider) : null;\n if (!currentInfo || !currentInfo.provider || !provider) {\n throw new Error('[EXECUTION] Provider is required');\n }\n const availableTools = tools.getTools();\n const aiProviderInfo = {\n providerName: currentInfo.provider,\n model: config.defaultModel.model,\n temperature: config.defaultModel.temperature,\n maxTokens: config.defaultModel.maxTokens,\n };\n const toolsInfo = availableTools.map((tool) => {\n const paramSchema = tool.parameters as { properties?: Record<string, object> } | undefined;\n const props = paramSchema?.properties;\n if (!tool.description || tool.description.length === 0) {\n throw new Error(`[EXECUTION] Tool \"${tool.name}\" is missing description`);\n }\n return {\n name: tool.name,\n description: tool.description,\n parameters: props && typeof props === 'object' ? Object.keys(props) : [],\n };\n });\n return { provider, currentInfo, aiProviderInfo, toolsInfo, availableTools };\n}\n\n/**\n * Validate that the resolved provider is usable.\n */\nexport function validateProvider(resolved: IResolvedProviderInfo): void {\n if (!resolved.currentInfo) throw new Error('No AI provider configured');\n if (!resolved.provider)\n throw new Error(`AI provider '${resolved.currentInfo.provider}' not found`);\n if (typeof resolved.provider.chat !== 'function') {\n throw new Error('Provider must have chat method to support execution');\n }\n}\n\n/**\n * Initialize or restore a conversation store for the given conversation.\n */\nexport function initializeConversationStore(\n conversationHistory: { getConversationStore: (id: string) => ConversationStore },\n conversationId: string,\n messages: TUniversalMessage[],\n config: IAgentConfig,\n executionId: string,\n): ConversationStore {\n const session = conversationHistory.getConversationStore(conversationId);\n if (session.getMessageCount() === 0 && messages.length > 0) {\n for (const msg of messages) {\n if (msg.role === 'user') {\n session.addUserMessage(msg.content, msg.metadata, msg.parts);\n } else if (msg.role === 'assistant') {\n session.addAssistantMessage(\n msg.content,\n (msg as IAssistantMessage).toolCalls,\n msg.metadata,\n msg.parts,\n );\n } else if (msg.role === 'system') {\n session.addSystemMessage(msg.content, msg.metadata, msg.parts);\n } else if (msg.role === 'tool') {\n const toolName = msg.metadata?.['toolName'];\n if (typeof toolName !== 'string' || toolName.length === 0) {\n throw new Error('[EXECUTION] Tool message missing toolName metadata');\n }\n session.addToolMessageWithId(\n msg.content,\n (msg as IToolMessage).toolCallId,\n toolName,\n msg.metadata,\n msg.parts,\n );\n }\n }\n }\n if (config.systemMessage) {\n session.addSystemMessage(config.systemMessage, { executionId });\n }\n return session;\n}\n\n/**\n * Build the final IExecutionResult from the completed conversation store.\n */\nexport function buildFinalResult(\n conversationStore: ConversationStore,\n executionId: string,\n startTime: Date,\n toolsExecuted: string[],\n): IExecutionResult {\n const finalMessages = conversationStore.getMessages();\n // Find last assistant message with actual content (skip stripped tool-round messages)\n const lastAssistantMessage = finalMessages\n .filter(\n (msg) =>\n msg.role === 'assistant' && typeof msg.content === 'string' && msg.content.length > 0,\n )\n .pop();\n const response: string = lastAssistantMessage\n ? (lastAssistantMessage.content as string)\n : 'No response received. The context window may be full.';\n const duration = Date.now() - startTime.getTime();\n return {\n response,\n messages: finalMessages.map((msg) => {\n if (typeof msg.content !== 'string')\n throw new Error('[EXECUTION] Message content is required');\n return {\n role: msg.role,\n content: msg.content,\n timestamp: msg.timestamp,\n metadata: msg.metadata,\n ...(msg.role === 'assistant' && 'toolCalls' in msg ? { toolCalls: msg.toolCalls } : {}),\n ...(msg.role === 'tool' && 'toolCallId' in msg ? { toolCallId: msg.toolCallId } : {}),\n };\n }) as TUniversalMessage[],\n executionId,\n duration,\n tokensUsed: finalMessages\n .filter((msg) => msg.metadata?.['usage'])\n .reduce((sum, msg) => {\n const usage = msg.metadata?.['usage'];\n if (usage && typeof usage === 'object' && 'totalTokens' in usage) {\n const totalTokens = Number(usage.totalTokens);\n if (Number.isNaN(totalTokens))\n throw new Error('[EXECUTION] totalTokens must be a number');\n return sum + totalTokens;\n }\n return sum;\n }, 0),\n toolsExecuted,\n success: !!lastAssistantMessage,\n };\n}\n\n/**\n * Handle a non-abort error from the execution pipeline:\n * fires onError plugin hook and emits the error event.\n */\nexport async function handleExecutionError(\n error: unknown,\n fullContext: IExecutionContext,\n startTime: Date,\n conversationId: string,\n executionId: string,\n plugins: TPluginWithHooks[],\n logger: ILogger,\n eventEmitter: ExecutionEventEmitter,\n): Promise<void> {\n const duration = Date.now() - startTime.getTime();\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n await callPluginHook(\n plugins,\n 'onError',\n {\n error: normalizedError,\n executionContext: convertExecutionContextToPluginFormat(fullContext),\n },\n logger,\n );\n logger.error('Execution pipeline failed', {\n executionId,\n conversationId,\n duration,\n error: error instanceof Error ? error.message : String(error),\n });\n eventEmitter.emitExecution(\n EXECUTION_EVENTS.ERROR,\n {\n error: error instanceof Error ? error.message : String(error),\n metadata: { method: 'execute', success: false, duration },\n },\n conversationId,\n executionId,\n );\n}\n\n/**\n * Generate a unique execution ID.\n */\nexport function generateExecutionId(): string {\n return `exec_${Date.now()}_${Math.random().toString(ID_RADIX).substr(2, ID_RANDOM_LENGTH)}`;\n}\n\n/**\n * Assert that a conversationId is present and non-empty, throwing with context label.\n */\nexport function requireConversationId(\n context: { conversationId?: string } | undefined,\n label: string,\n): string {\n if (!context?.conversationId || context.conversationId.length === 0) {\n throw new Error(`[EXECUTION] conversationId is required for ${label}`);\n }\n return context.conversationId;\n}\n\nexport function buildFullExecutionContext(\n messages: TUniversalMessage[],\n config: IAgentConfig,\n startTime: Date,\n executionId: string,\n conversationId: string,\n context?: Partial<IExecutionContext>,\n): IExecutionContext {\n return {\n messages,\n config,\n startTime,\n executionId,\n conversationId,\n ...(context?.sessionId && { sessionId: context.sessionId }),\n ...(context?.userId && { userId: context.userId }),\n ...(context?.metadata && { metadata: context.metadata }),\n ...(context?.signal && { signal: context.signal }),\n ...(context?.onTextDelta && { onTextDelta: context.onTextDelta }),\n ...(context?.onExecutionEvent && { onExecutionEvent: context.onExecutionEvent }),\n ...(context?.maxExecutionRounds !== undefined && {\n maxExecutionRounds: context.maxExecutionRounds,\n }),\n };\n}\n\n/**\n * Convert an IExecutionContext to the flat record format expected by plugin hooks.\n */\nexport function convertExecutionContextToPluginFormat(\n context: IExecutionContext,\n): Record<string, string | number | boolean> {\n const conversationId = requireConversationId(context, 'plugin-context');\n const payload: Record<string, string | number | boolean> = {\n conversationId,\n executionId: context.executionId,\n startTime: context.startTime.toISOString(),\n messageCount: context.messages.length,\n };\n if (context.sessionId) payload.sessionId = context.sessionId;\n if (context.userId) payload.userId = context.userId;\n return payload;\n}\n","/**\n * Provider call helpers for execution rounds.\n * Extracted from execution-round.ts for single-responsibility.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { IAgentConfig, IAssistantMessage } from '../interfaces/agent';\nimport type { IChatOptions } from '../interfaces/provider';\nimport type { IToolCall, TUniversalMessage } from '../interfaces/messages';\nimport type { ILogger } from '../utils/logger';\nimport type { ExecutionCacheService } from './cache/execution-cache-service';\nimport type { IResolvedProviderInfo, IExecutionRoundState } from './execution-types';\n\ntype TProviderChat = (\n messages: TUniversalMessage[],\n options: IChatOptions,\n) => Promise<TUniversalMessage>;\n\n/** Compute thinking context IDs for event tracking */\nexport function computeRoundThinkingContext(\n conversationId: string,\n roundState: IExecutionRoundState,\n): { thinkingNodeId: string; previousThinkingNodeId: string | undefined } {\n const shouldChainFromPreviousToolResult =\n Array.isArray(roundState.lastTrackedAssistantMessage?.toolCalls) &&\n roundState.lastTrackedAssistantMessage.toolCalls.length > 0;\n const thinkingNodeId = `thinking_${conversationId}_round${roundState.runningAssistantCount + 1}`;\n const previousThinkingNodeId = shouldChainFromPreviousToolResult\n ? `thinking_${conversationId}_round${roundState.runningAssistantCount}`\n : undefined;\n return { thinkingNodeId, previousThinkingNodeId };\n}\n\n/** Call the AI provider with optional cache lookup/store */\nexport async function callProviderWithCache(\n conversationMessages: TUniversalMessage[],\n config: IAgentConfig,\n resolved: IResolvedProviderInfo,\n cacheService?: ExecutionCacheService,\n overrides?: Partial<IChatOptions>,\n): Promise<TUniversalMessage> {\n if (!config.defaultModel?.model) {\n throw new Error('Model is required in defaultModel configuration. Please specify a model.');\n }\n if (typeof config.defaultModel.model !== 'string' || config.defaultModel.model.trim() === '') {\n throw new Error('Model must be a non-empty string in defaultModel configuration.');\n }\n\n const chatOptions: IChatOptions = {\n model: config.defaultModel.model,\n ...(config.defaultModel.maxTokens !== undefined && {\n maxTokens: config.defaultModel.maxTokens,\n }),\n ...(config.defaultModel.temperature !== undefined && {\n temperature: config.defaultModel.temperature,\n }),\n ...(resolved.availableTools.length > 0 && { tools: resolved.availableTools }),\n ...overrides,\n };\n const providerChat = resolved.provider.chat.bind(resolved.provider) as TProviderChat;\n\n if (cacheService) {\n const cachedResponse = cacheService.lookup(\n conversationMessages,\n config.defaultModel.model,\n config.defaultModel.provider,\n { temperature: config.defaultModel.temperature, maxTokens: config.defaultModel.maxTokens },\n );\n if (cachedResponse) {\n return {\n role: 'assistant',\n content: cachedResponse,\n timestamp: new Date(),\n id: randomUUID(),\n state: 'complete' as const,\n };\n }\n const response = await callProviderWithIdleTimeout(\n providerChat,\n conversationMessages,\n chatOptions,\n config.timeout,\n );\n if (typeof response.content === 'string') {\n cacheService.store(\n conversationMessages,\n config.defaultModel.model,\n config.defaultModel.provider,\n response.content,\n { temperature: config.defaultModel.temperature, maxTokens: config.defaultModel.maxTokens },\n );\n }\n return response;\n }\n\n return callProviderWithIdleTimeout(\n providerChat,\n conversationMessages,\n chatOptions,\n config.timeout,\n );\n}\n\nasync function callProviderWithIdleTimeout(\n chat: TProviderChat,\n messages: TUniversalMessage[],\n options: IChatOptions,\n timeoutMs: number | undefined,\n): Promise<TUniversalMessage> {\n const normalizedTimeoutMs = normalizeTimeoutMs(timeoutMs);\n const upstreamSignal = options.signal;\n if (normalizedTimeoutMs === undefined && upstreamSignal === undefined) {\n return chat(messages, options);\n }\n if (upstreamSignal?.aborted) {\n throw createAbortError();\n }\n\n const controller = new AbortController();\n let idleTimer: ReturnType<typeof setTimeout> | undefined;\n let settled = false;\n let rejectGuard: ((reason: Error) => void) | undefined;\n\n const clearIdleTimer = (): void => {\n if (idleTimer !== undefined) {\n clearTimeout(idleTimer);\n idleTimer = undefined;\n }\n };\n\n const failWith = (error: Error): void => {\n if (settled) return;\n settled = true;\n rejectGuard?.(error);\n controller.abort(error);\n };\n\n const resetIdleTimer = (): void => {\n if (normalizedTimeoutMs === undefined || settled) return;\n clearIdleTimer();\n idleTimer = setTimeout(() => {\n failWith(new Error(`Provider call idle timeout after ${normalizedTimeoutMs}ms`));\n }, normalizedTimeoutMs);\n };\n\n const handleUpstreamAbort = (): void => {\n failWith(createAbortError());\n };\n upstreamSignal?.addEventListener('abort', handleUpstreamAbort, { once: true });\n\n const originalOnTextDelta = options.onTextDelta;\n const guardedOptions: IChatOptions = {\n ...options,\n signal: controller.signal,\n ...(originalOnTextDelta !== undefined\n ? {\n onTextDelta: (delta: string): void => {\n resetIdleTimer();\n originalOnTextDelta(delta);\n },\n }\n : {}),\n };\n\n resetIdleTimer();\n\n try {\n return await Promise.race([\n chat(messages, guardedOptions),\n new Promise<never>((_, reject) => {\n rejectGuard = reject;\n }),\n ]);\n } finally {\n settled = true;\n clearIdleTimer();\n upstreamSignal?.removeEventListener('abort', handleUpstreamAbort);\n }\n}\n\nfunction normalizeTimeoutMs(timeoutMs: number | undefined): number | undefined {\n if (timeoutMs === undefined || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n return undefined;\n }\n return timeoutMs;\n}\n\nfunction createAbortError(): Error {\n const error = new Error('aborted');\n error.name = 'AbortError';\n return error;\n}\n\n/** Validate and normalize the provider response */\nexport function validateAndExtractResponse(\n response: TUniversalMessage,\n executionId: string,\n conversationId: string | undefined,\n currentRound: number,\n logger: ILogger,\n): { assistantResponse: IAssistantMessage; assistantToolCalls: IToolCall[] } {\n const assistantToolCallsFromResponse =\n response.role === 'assistant' ? (response as IAssistantMessage).toolCalls : undefined;\n\n const hasToolCalls =\n Array.isArray(assistantToolCallsFromResponse) && assistantToolCallsFromResponse.length > 0;\n if (typeof response.content !== 'string' && !hasToolCalls) {\n throw new Error('[EXECUTION] Provider response must have content or tool calls');\n }\n if (assistantToolCallsFromResponse && !Array.isArray(assistantToolCallsFromResponse)) {\n throw new Error('[EXECUTION] assistant toolCalls must be an array');\n }\n const responseContent = response.content ?? '';\n logger.debug(`[ROUND-${currentRound}] Provider response completed`, {\n executionId,\n conversationId,\n round: currentRound,\n responseLength: responseContent.length,\n hasToolCalls:\n Array.isArray(assistantToolCallsFromResponse) && assistantToolCallsFromResponse.length > 0,\n toolCallsCount: Array.isArray(assistantToolCallsFromResponse)\n ? assistantToolCallsFromResponse.length\n : 0,\n });\n\n if (response.role !== 'assistant') {\n throw new Error(`Unexpected response role: ${response.role}`);\n }\n\n const assistantResponse = response as IAssistantMessage;\n const assistantToolCalls = assistantResponse.toolCalls ?? [];\n if (!Array.isArray(assistantToolCalls)) {\n throw new Error('[EXECUTION] assistantResponse.toolCalls must be an array');\n }\n\n return { assistantResponse, assistantToolCalls };\n}\n","/**\n * Claude model definitions — SSOT for model metadata.\n * Source: https://platform.claude.com/docs/en/about-claude/models/overview\n */\n\nexport interface IModelDefinition {\n /** Human-readable model name */\n name: string;\n /** API model identifier */\n id: string;\n /** Context window size in tokens */\n contextWindow: number;\n /** Maximum output tokens */\n maxOutput: number;\n}\n\n/**\n * Known Claude models (4.5+).\n * Keyed by API model ID for fast lookup.\n */\nexport const CLAUDE_MODELS: Record<string, IModelDefinition> = {\n 'claude-opus-4-6': {\n name: 'Claude Opus 4.6',\n id: 'claude-opus-4-6',\n contextWindow: 1_000_000,\n maxOutput: 128_000,\n },\n 'claude-sonnet-4-6': {\n name: 'Claude Sonnet 4.6',\n id: 'claude-sonnet-4-6',\n contextWindow: 1_000_000,\n maxOutput: 64_000,\n },\n 'claude-haiku-4-5': {\n name: 'Claude Haiku 4.5',\n id: 'claude-haiku-4-5',\n contextWindow: 200_000,\n maxOutput: 64_000,\n },\n 'claude-haiku-4-5-20251001': {\n name: 'Claude Haiku 4.5',\n id: 'claude-haiku-4-5-20251001',\n contextWindow: 200_000,\n maxOutput: 64_000,\n },\n 'claude-sonnet-4-5': {\n name: 'Claude Sonnet 4.5',\n id: 'claude-sonnet-4-5',\n contextWindow: 200_000,\n maxOutput: 64_000,\n },\n 'claude-sonnet-4-5-20250929': {\n name: 'Claude Sonnet 4.5',\n id: 'claude-sonnet-4-5-20250929',\n contextWindow: 200_000,\n maxOutput: 64_000,\n },\n 'claude-opus-4-5': {\n name: 'Claude Opus 4.5',\n id: 'claude-opus-4-5',\n contextWindow: 200_000,\n maxOutput: 64_000,\n },\n 'claude-opus-4-5-20251101': {\n name: 'Claude Opus 4.5',\n id: 'claude-opus-4-5-20251101',\n contextWindow: 200_000,\n maxOutput: 64_000,\n },\n};\n\nexport const DEFAULT_CONTEXT_WINDOW = 200_000;\n\n/** Get context window size for a model ID. Falls back to DEFAULT_CONTEXT_WINDOW. */\nexport function getModelContextWindow(modelId: string): number {\n return CLAUDE_MODELS[modelId]?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n}\n\nexport const DEFAULT_MAX_OUTPUT = 16_384;\n\n/** Get max output tokens for a model ID. Falls back to DEFAULT_MAX_OUTPUT. */\nexport function getModelMaxOutput(modelId: string): number {\n return CLAUDE_MODELS[modelId]?.maxOutput ?? DEFAULT_MAX_OUTPUT;\n}\n\n/** Get human-readable model name for a model ID. Falls back to the ID itself. */\nexport function getModelName(modelId: string): string {\n return CLAUDE_MODELS[modelId]?.name ?? modelId;\n}\n\n/** Format token count as human-readable (e.g., 200K, 1M, 1.2M). Minimum unit is K. */\nexport function formatTokenCount(tokens: number): string {\n if (tokens >= 1_000_000) {\n const m = tokens / 1_000_000;\n return Number.isInteger(m) ? `${m}M` : `${parseFloat(m.toFixed(1))}M`;\n }\n // Minimum unit is K — values below 1000 show as \"<1K\" or \"0K\"\n if (tokens <= 0) return '0K';\n if (tokens < 1_000) return '<1K';\n const k = tokens / 1_000;\n return Number.isInteger(k) ? `${k}K` : `${parseFloat(k.toFixed(1))}K`;\n}\n","import type { TUniversalMessage, TUniversalMessageMetadata } from '../interfaces/messages.js';\n\nexport interface IMessageTokenUsage {\n readonly inputTokens: number;\n readonly outputTokens: number;\n readonly totalTokens?: number;\n}\n\ninterface IProviderUsageLike {\n readonly promptTokens?: number;\n readonly completionTokens?: number;\n readonly totalTokens?: number;\n readonly inputTokens?: number;\n readonly outputTokens?: number;\n}\n\ntype TMessageWithProviderUsage = TUniversalMessage & {\n readonly usage?: IProviderUsageLike;\n};\n\n/** Read normalized provider usage from a universal message when present. */\nexport function readTokenUsageFromMessage(\n message: TUniversalMessage,\n): IMessageTokenUsage | undefined {\n const metadataUsage = readTokenUsageFromMetadata(message.metadata);\n const topLevelUsage = readTokenUsageFromProviderUsage(\n (message as TMessageWithProviderUsage).usage,\n );\n return metadataUsage ?? topLevelUsage;\n}\n\nexport function readTokenUsageFromMetadata(\n metadata: TUniversalMessageMetadata | undefined,\n): IMessageTokenUsage | undefined {\n if (!metadata) return undefined;\n\n const direct = readTokenUsageFromProviderUsage({\n inputTokens: numberFromMetadata(metadata, 'inputTokens'),\n outputTokens: numberFromMetadata(metadata, 'outputTokens'),\n promptTokens: numberFromMetadata(metadata, 'promptTokens'),\n completionTokens: numberFromMetadata(metadata, 'completionTokens'),\n totalTokens: numberFromMetadata(metadata, 'totalTokens'),\n });\n if (direct) return direct;\n\n const nested = metadata['usage'];\n if (typeof nested === 'string') {\n return readTokenUsageFromJson(nested);\n }\n if (isNumberRecord(nested)) {\n return readTokenUsageFromProviderUsage(nested);\n }\n return undefined;\n}\n\nfunction readTokenUsageFromJson(value: string): IMessageTokenUsage | undefined {\n try {\n const parsed = JSON.parse(value) as IProviderUsageLike;\n return readTokenUsageFromProviderUsage(parsed);\n } catch {\n return undefined;\n }\n}\n\nfunction readTokenUsageFromProviderUsage(\n usage: IProviderUsageLike | undefined,\n): IMessageTokenUsage | undefined {\n if (!usage) return undefined;\n const inputTokens = firstFiniteNumber(usage.inputTokens, usage.promptTokens);\n const outputTokens = firstFiniteNumber(usage.outputTokens, usage.completionTokens);\n if (inputTokens === undefined || outputTokens === undefined) return undefined;\n const totalTokens = firstFiniteNumber(usage.totalTokens);\n return {\n inputTokens,\n outputTokens,\n ...(totalTokens !== undefined && { totalTokens }),\n };\n}\n\nfunction numberFromMetadata(\n metadata: TUniversalMessageMetadata,\n key: string,\n): number | undefined {\n const value = metadata[key];\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction firstFiniteNumber(...values: Array<number | undefined>): number | undefined {\n return values.find(\n (value): value is number => typeof value === 'number' && Number.isFinite(value),\n );\n}\n\nfunction isNumberRecord(\n value: TUniversalMessageMetadata[string] | undefined,\n): value is Record<string, number> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.values(value).every((item) => typeof item === 'number' && Number.isFinite(item))\n );\n}\n","import type { TUniversalMessage } from '../interfaces/messages.js';\nimport { readTokenUsageFromMessage } from './token-usage.js';\n\nexport const CONTEXT_ESTIMATE_CHARS_PER_TOKEN = 4;\n\nexport interface IContextTokenEstimateOptions {\n readonly usageFloorTokens?: number;\n}\n\nexport interface IContextTokenEstimate {\n readonly usedTokens: number;\n readonly serializedTokens: number;\n readonly providerTokens?: number;\n readonly usageFloorTokens?: number;\n}\n\nexport function estimateSerializedContextTokens(\n messages: readonly TUniversalMessage[],\n): number {\n return Math.ceil(JSON.stringify(messages).length / CONTEXT_ESTIMATE_CHARS_PER_TOKEN);\n}\n\nexport function estimateContextTokensFromMessages(\n messages: readonly TUniversalMessage[],\n options: IContextTokenEstimateOptions = {},\n): IContextTokenEstimate {\n const serializedTokens = estimateSerializedContextTokens(messages);\n const providerEstimate = readLatestProviderTokens(messages);\n const providerTokens = providerEstimate?.tokens;\n const usageFloorTokens = normalizeUsageFloorTokens(options.usageFloorTokens);\n const providerUsageIsTerminal = providerEstimate?.index === messages.length - 1;\n const usedTokens = providerUsageIsTerminal\n ? Math.max(providerTokens ?? 0, usageFloorTokens ?? 0)\n : Math.max(serializedTokens, providerTokens ?? 0, usageFloorTokens ?? 0);\n\n return {\n usedTokens,\n serializedTokens,\n ...(providerTokens !== undefined && { providerTokens }),\n ...(usageFloorTokens !== undefined && { usageFloorTokens }),\n };\n}\n\nfunction readLatestProviderTokens(\n messages: readonly TUniversalMessage[],\n): { tokens: number; index: number } | undefined {\n for (let index = messages.length - 1; index >= 0; index--) {\n const usage = readTokenUsageFromMessage(messages[index]);\n if (usage) {\n return {\n tokens: usage.totalTokens ?? usage.inputTokens + usage.outputTokens,\n index,\n };\n }\n }\n return undefined;\n}\n\nfunction normalizeUsageFloorTokens(value: number | undefined): number | undefined {\n if (value === undefined || !Number.isFinite(value) || value <= 0) {\n return undefined;\n }\n return Math.ceil(value);\n}\n","import type { TToolMetadata } from '../interfaces/tool';\nimport type { IToolCall, TUniversalMessageMetadata } from '../interfaces/messages';\nimport type { ILogger } from '../utils/logger';\nimport type { ConversationStore } from '../managers/conversation-history-manager';\nimport { estimateContextTokensFromMessages } from '../context/estimation';\nimport { isExecutionError, PREVIEW_LENGTH } from './execution-types';\nimport { UNKNOWN_TOOL_ERROR_CODE } from './tool-execution-service';\n\n/** Result of addToolResultsToHistory indicating whether context overflow occurred */\nexport interface IToolResultsOutcome {\n contextOverflowed: boolean;\n addedCount: number;\n skippedCount: number;\n unknownToolFailureCount: number;\n unknownToolNames: string[];\n}\n\nconst CONTEXT_OVERFLOW_TOOL_SKIP_MESSAGE =\n 'Error: Context window near capacity. Tool execution result skipped. Respond with available results and re-request skipped tools if needed.';\n\nexport function isUnknownToolExecutionResult(result: {\n success: boolean;\n metadata?: { errorCode?: string };\n}): boolean {\n return !result.success && result.metadata?.errorCode === UNKNOWN_TOOL_ERROR_CODE;\n}\n\n/** Add tool execution results to conversation history in call order */\nexport function addToolResultsToHistory(\n assistantToolCalls: IToolCall[],\n toolSummary: {\n results: Array<{\n executionId?: string;\n toolName?: string;\n success: boolean;\n result?: unknown;\n error?: string;\n metadata?: TToolMetadata;\n }>;\n errors: Error[];\n },\n conversationStore: ConversationStore,\n currentRound: number,\n logger: ILogger,\n contextBudget?: { contextLimit: number; cumulativeInputTokens: number },\n): IToolResultsOutcome {\n const TOOL_RESULT_OVERFLOW_THRESHOLD = 0.8;\n let contextOverflowed = false;\n let addedCount = 0;\n let skippedCount = 0;\n\n for (const toolCall of assistantToolCalls) {\n if (!toolCall.id) {\n throw new Error(`Tool call missing ID: ${JSON.stringify(toolCall)}`);\n }\n const toolCallName = toolCall.function?.name;\n if (!toolCallName || toolCallName.length === 0) {\n throw new Error(`[EXECUTION] Tool call \"${toolCall.id}\" missing function name`);\n }\n\n if (contextOverflowed) {\n logger.warn('[ROUND] Skipping tool result due to context overflow', {\n toolCallId: toolCall.id,\n toolName: toolCallName,\n round: currentRound,\n });\n conversationStore.addToolMessageWithId(\n CONTEXT_OVERFLOW_TOOL_SKIP_MESSAGE,\n toolCall.id,\n toolCallName,\n { round: currentRound, success: false, error: 'context_overflow', toolName: toolCallName },\n );\n skippedCount++;\n continue;\n }\n\n const result = toolSummary.results.find((r) => r.executionId === toolCall.id);\n const error = toolSummary.errors.find(\n (e) => isExecutionError(e) && e.executionId === toolCall.id,\n );\n\n let content: string;\n let metadata: TUniversalMessageMetadata = { round: currentRound };\n\n if (result && result.success) {\n if (typeof result.result === 'undefined') {\n throw new Error('[EXECUTION] Tool result missing result payload');\n }\n content = typeof result.result === 'string' ? result.result : JSON.stringify(result.result);\n metadata['success'] = true;\n if (result.toolName) metadata['toolName'] = result.toolName;\n } else if (result && !result.success) {\n if (!result.error || result.error.length === 0) {\n throw new Error('[EXECUTION] Tool result missing error message');\n }\n content = `Error: ${result.error}`;\n metadata['success'] = false;\n metadata['error'] = result.error;\n if (result.toolName) metadata['toolName'] = result.toolName;\n if (result.metadata?.errorCode === UNKNOWN_TOOL_ERROR_CODE) {\n metadata['errorCode'] = UNKNOWN_TOOL_ERROR_CODE;\n if (typeof result.metadata.requestedTool === 'string') {\n metadata['requestedTool'] = result.metadata.requestedTool;\n }\n if (Array.isArray(result.metadata.availableTools)) {\n metadata['availableTools'] = result.metadata.availableTools.filter(\n (toolName): toolName is string => typeof toolName === 'string',\n );\n }\n }\n } else if (error) {\n const execError = error as { error?: Error; message: string; toolName?: string };\n const execMessage = (() => {\n if (execError.error?.message) return execError.error.message;\n if (execError.message) return execError.message;\n return '';\n })();\n if (!execMessage || execMessage.length === 0) {\n throw new Error('[EXECUTION] Tool execution error missing message');\n }\n content = `Error: ${execMessage}`;\n metadata['success'] = false;\n metadata['error'] = execMessage;\n if (execError.toolName) metadata['toolName'] = execError.toolName;\n } else {\n throw new Error(`No execution result found for tool call ID: ${toolCall.id}`);\n }\n\n logger.debug('Adding tool result to conversation', {\n toolCallId: toolCall.id,\n toolName: toolCallName,\n content: content.substring(0, PREVIEW_LENGTH),\n round: currentRound,\n currentHistoryLength: conversationStore.getMessages().length,\n });\n\n conversationStore.addToolMessageWithId(content, toolCall.id, toolCallName, metadata);\n\n if (contextBudget) {\n const estimate = estimateContextTokensFromMessages(conversationStore.getMessages(), {\n usageFloorTokens: contextBudget.cumulativeInputTokens,\n });\n const estimatedTokens = estimate.usedTokens;\n if (estimatedTokens > contextBudget.contextLimit * TOOL_RESULT_OVERFLOW_THRESHOLD) {\n logger.warn(\n '[ROUND] Context budget exceeded after tool result — skipping remaining tools',\n {\n estimatedTokens,\n contextLimit: contextBudget.contextLimit,\n toolCallId: toolCall.id,\n round: currentRound,\n },\n );\n contextOverflowed = true;\n }\n }\n\n addedCount++;\n\n logger.debug('Tool result added to history', {\n toolCallId: toolCall.id,\n newHistoryLength: conversationStore.getMessages().length,\n round: currentRound,\n });\n }\n\n return {\n contextOverflowed,\n addedCount,\n skippedCount,\n unknownToolFailureCount: 0,\n unknownToolNames: [],\n };\n}\n","import type {\n IAgentConfig,\n TExecutionEventCallback,\n TExecutionEventData,\n} from '../interfaces/agent';\nimport type { IToolCall } from '../interfaces/messages';\nimport type { IToolExecutionBatchContext } from './tool-execution-service';\nimport type { ConversationStore } from '../managers/conversation-history-manager';\nimport { getModelContextWindow } from '../context/models';\nimport { type IExecutionRoundState } from './execution-types';\nimport type { IRoundDependencies } from './execution-round';\nimport {\n type IToolResultsOutcome,\n addToolResultsToHistory,\n isUnknownToolExecutionResult,\n} from './execution-round-tool-results';\nexport type { IToolResultsOutcome } from './execution-round-tool-results';\n\n/** Execute tools from assistant tool calls and add results to conversation history */\nexport async function executeAndRecordToolCalls(\n assistantToolCalls: IToolCall[],\n conversationStore: ConversationStore,\n conversationId: string,\n executionId: string,\n currentRound: number,\n thinkingNodeId: string,\n previousThinkingNodeId: string | undefined,\n roundState: IExecutionRoundState,\n deps: IRoundDependencies,\n config?: IAgentConfig,\n signal?: AbortSignal,\n onExecutionEvent?: TExecutionEventCallback,\n): Promise<IToolResultsOutcome> {\n const { toolExecutionService, logger, eventEmitter } = deps;\n\n logger.debug('Tool calls detected, executing tools', {\n toolCallCount: assistantToolCalls.length,\n round: currentRound,\n toolCalls: assistantToolCalls.map((tc: IToolCall) => ({ id: tc.id, name: tc.function?.name })),\n });\n\n const toolOwnerPathBase = eventEmitter.buildThinkingOwnerContext(\n conversationId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n ).ownerPath;\n const expectedCountForBatch = assistantToolCalls.length;\n const batchId = `${thinkingNodeId}`;\n const toolRequestsBase = toolExecutionService.createExecutionRequestsWithContext(\n assistantToolCalls,\n {\n ownerPathBase: toolOwnerPathBase,\n metadataFactory: (toolCall) => ({\n conversationId,\n round: currentRound,\n directParentId: thinkingNodeId,\n batchId,\n expectedCount: expectedCountForBatch,\n toolCallId: toolCall.id,\n }),\n },\n );\n const toolRequests = toolRequestsBase.map((request) => {\n if (!request.ownerId) {\n throw new Error('[EXECUTION] Tool request missing ownerId');\n }\n return {\n ...request,\n eventService: eventEmitter.ensureToolEventService(request.ownerId, request.ownerPath),\n baseEventService: eventEmitter.getBaseEventService(),\n };\n });\n const toolContext: IToolExecutionBatchContext = {\n requests: toolRequests,\n mode: 'parallel',\n maxConcurrency: 5,\n continueOnError: true,\n signal,\n };\n\n onExecutionEvent?.('tool_batch_started', {\n executionId,\n conversationId,\n round: currentRound,\n batchId,\n mode: toolContext.mode,\n maxConcurrency: toolContext.maxConcurrency,\n requestCount: toolRequests.length,\n tools: toolRequests.map((request) => request.toolName),\n } as TExecutionEventData);\n toolRequests.forEach((request, index) => {\n onExecutionEvent?.('tool_execution_request', {\n executionId,\n conversationId,\n round: currentRound,\n batchId,\n index,\n toolName: request.toolName,\n toolCallId: request.executionId,\n parameters: request.parameters,\n ownerPath: request.ownerPath,\n } as TExecutionEventData);\n });\n\n const toolSummary = await toolExecutionService.executeTools(toolContext);\n const unknownToolNames = toolSummary.results\n .filter(isUnknownToolExecutionResult)\n .map((result) => result.toolName)\n .filter((toolName): toolName is string => typeof toolName === 'string' && toolName.length > 0);\n\n toolSummary.results.forEach((result, index) => {\n onExecutionEvent?.('tool_execution_result', {\n executionId,\n conversationId,\n round: currentRound,\n batchId,\n index,\n toolName: result.toolName,\n toolCallId: result.executionId,\n success: result.success,\n result: result.result,\n error: result.error,\n metadata: result.metadata,\n } as TExecutionEventData);\n });\n\n roundState.toolsExecuted.push(\n ...toolSummary.results\n .filter((result) => !isUnknownToolExecutionResult(result))\n .map((r) => {\n if (!r.toolName || r.toolName.length === 0) {\n throw new Error('[EXECUTION] Tool result missing toolName');\n }\n return r.toolName;\n }),\n );\n\n const contextLimit = getModelContextWindow(config?.defaultModel?.model ?? '');\n const messageCountBeforeToolResults = conversationStore.getMessages().length;\n const toolResultsOutcome = addToolResultsToHistory(\n assistantToolCalls,\n toolSummary,\n conversationStore,\n currentRound,\n logger,\n { contextLimit, cumulativeInputTokens: roundState.cumulativeInputTokens },\n );\n const addedToolMessages = conversationStore.getMessages().slice(messageCountBeforeToolResults);\n addedToolMessages.forEach((message, offset) => {\n onExecutionEvent?.('tool_message_committed', {\n executionId,\n conversationId,\n round: currentRound,\n batchId,\n index: offset,\n message,\n } as TExecutionEventData);\n onExecutionEvent?.('history_mutation', {\n executionId,\n conversationId,\n round: currentRound,\n batchId,\n mutation: 'append_message',\n index: messageCountBeforeToolResults + offset,\n message,\n } as TExecutionEventData);\n });\n\n eventEmitter.emitToolResultsEvents(\n assistantToolCalls,\n toolSummary,\n roundState.toolsExecuted,\n conversationId,\n executionId,\n currentRound,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n\n eventEmitter.clearToolEventServices();\n\n return {\n ...toolResultsOutcome,\n unknownToolFailureCount: unknownToolNames.length,\n unknownToolNames,\n };\n}\n","import type { TUniversalMessage } from '../interfaces/messages';\nimport { readTokenUsageFromMessage } from '../context/token-usage';\n\nexport interface IAssistantUsageMetadata {\n inputTokens: number;\n outputTokens: number;\n usage: {\n totalTokens: number;\n inputTokens: number;\n outputTokens: number;\n };\n}\n\nexport function collectAssistantUsageMetadata(\n message: TUniversalMessage,\n): IAssistantUsageMetadata | undefined {\n const usage = readTokenUsageFromMessage(message);\n if (!usage) return undefined;\n\n const totalTokens = usage.totalTokens ?? usage.inputTokens + usage.outputTokens;\n return {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n usage: {\n totalTokens,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n },\n };\n}\n","import type { IAgentConfig } from '../interfaces/agent';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { ILogger } from '../utils/logger';\nimport type { ConversationStore } from '../managers/conversation-history-manager';\nimport { estimateContextTokensFromMessages } from '../context/estimation';\nimport { getModelContextWindow } from '../context/models';\nimport type { IExecutionRoundState } from './execution-types';\n\nexport const CONTEXT_HARD_BLOCK_THRESHOLD = 0.95;\n\nexport interface IContextCapacityDecision {\n readonly shouldBlock: boolean;\n readonly estimatedTokens: number;\n readonly contextLimit: number;\n readonly thresholdTokens: number;\n readonly thresholdPercentage: number;\n readonly usedPercentage: number;\n readonly serializedTokens: number;\n readonly providerTokens?: number;\n readonly usageFloorTokens?: number;\n}\n\nexport function getContextCapacityDecision(\n messages: readonly TUniversalMessage[],\n model: string,\n usageFloorTokens: number,\n): IContextCapacityDecision {\n const estimate = estimateContextTokensFromMessages(messages, { usageFloorTokens });\n const contextLimit = getModelContextWindow(model);\n const thresholdTokens = contextLimit * CONTEXT_HARD_BLOCK_THRESHOLD;\n const usedPercentage =\n contextLimit > 0 ? Math.round((estimate.usedTokens / contextLimit) * 10_000) / 100 : 100;\n\n return {\n shouldBlock: estimate.usedTokens > thresholdTokens,\n estimatedTokens: estimate.usedTokens,\n contextLimit,\n thresholdTokens,\n thresholdPercentage: CONTEXT_HARD_BLOCK_THRESHOLD * 100,\n usedPercentage,\n serializedTokens: estimate.serializedTokens,\n ...(estimate.providerTokens !== undefined && { providerTokens: estimate.providerTokens }),\n ...(estimate.usageFloorTokens !== undefined && {\n usageFloorTokens: estimate.usageFloorTokens,\n }),\n };\n}\n\n/** Check context capacity; if near limit, add a hard-block message and return true. */\nexport function handleContextCapacityBlock(\n conversationMessages: readonly TUniversalMessage[],\n config: IAgentConfig,\n roundState: IExecutionRoundState,\n conversationStore: ConversationStore,\n logger: ILogger,\n currentRound: number,\n): boolean {\n const contextDecision = getContextCapacityDecision(\n conversationMessages,\n config.defaultModel.model,\n roundState.cumulativeInputTokens,\n );\n if (!contextDecision.shouldBlock) return false;\n\n logger.warn('[ROUND] Context hard-capacity prevention before provider call', {\n estimatedTokens: contextDecision.estimatedTokens,\n contextLimit: contextDecision.contextLimit,\n thresholdTokens: contextDecision.thresholdTokens,\n thresholdPercentage: contextDecision.thresholdPercentage,\n serializedTokens: contextDecision.serializedTokens,\n providerTokens: contextDecision.providerTokens ?? 0,\n usageFloorTokens: contextDecision.usageFloorTokens ?? 0,\n round: currentRound,\n });\n conversationStore.addAssistantMessage(\n `Context window is near capacity. Cannot process further in this round. Estimated ${contextDecision.estimatedTokens.toLocaleString()} / ${contextDecision.contextLimit.toLocaleString()} tokens (${Math.round(contextDecision.usedPercentage)}%) exceeds the hard-block threshold ${Math.round(contextDecision.thresholdPercentage)}%. Run /compact and retry.`,\n [],\n {\n round: currentRound,\n contextOverflow: true,\n estimatedTokens: contextDecision.estimatedTokens,\n contextLimit: contextDecision.contextLimit,\n thresholdTokens: contextDecision.thresholdTokens,\n thresholdPercentage: contextDecision.thresholdPercentage,\n serializedTokens: contextDecision.serializedTokens,\n providerTokens: contextDecision.providerTokens ?? 0,\n usageFloorTokens: contextDecision.usageFloorTokens ?? 0,\n usedPercentage: contextDecision.usedPercentage,\n },\n );\n return true;\n}\n","import type { TProviderNativeRawPayloadCallback } from '../interfaces/provider';\nimport type { IAgentConfig, TExecutionEventData } from '../interfaces/agent';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { IExecutionContext, IResolvedProviderInfo } from './execution-types';\nimport type { ConversationStore } from '../managers/conversation-history-manager';\nimport type { ExecutionCacheService } from './cache/execution-cache-service';\nimport type { ILogger } from '../utils/logger';\nimport { callProviderWithCache } from './execution-round-provider';\n\nexport interface IRoundStreamingCallbacks {\n wrappedOnTextDelta: (delta: string) => void;\n wrappedOnProviderNativeRawPayload: TProviderNativeRawPayloadCallback;\n}\n\nexport function createRoundStreamingCallbacks(\n fullContext: IExecutionContext,\n conversationStore: ConversationStore,\n executionId: string,\n currentRound: number,\n): IRoundStreamingCallbacks {\n let streamDeltaSequence = 0;\n let providerNativeRawPayloadSequence = 0;\n\n const wrappedOnTextDelta = (delta: string): void => {\n fullContext.onExecutionEvent?.('provider_stream_raw_delta', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n sequence: streamDeltaSequence,\n delta,\n } as TExecutionEventData);\n streamDeltaSequence++;\n conversationStore.appendStreaming(delta);\n fullContext.onTextDelta?.(delta);\n };\n\n const wrappedOnProviderNativeRawPayload: TProviderNativeRawPayloadCallback = (event): void => {\n const sequence = event.sequence ?? providerNativeRawPayloadSequence;\n providerNativeRawPayloadSequence = Math.max(providerNativeRawPayloadSequence, sequence + 1);\n fullContext.onExecutionEvent?.('provider_native_raw_payload', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n ...event,\n sequence,\n } as TExecutionEventData);\n };\n\n return { wrappedOnTextDelta, wrappedOnProviderNativeRawPayload };\n}\n\n/** Call the provider with event emissions. Returns null if round should break; throws on abort. */\nexport async function callRoundProviderWithEvents(\n conversationMessages: TUniversalMessage[],\n config: IAgentConfig,\n resolved: IResolvedProviderInfo,\n cacheService: ExecutionCacheService | undefined,\n fullContext: IExecutionContext,\n conversationStore: ConversationStore,\n currentRound: number,\n executionId: string,\n logger: ILogger,\n wrappedOnTextDelta: (delta: string) => void,\n wrappedOnProviderNativeRawPayload: TProviderNativeRawPayloadCallback,\n): Promise<TUniversalMessage | null> {\n try {\n fullContext.onExecutionEvent?.('provider_request', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n provider: resolved.currentInfo.provider,\n model: config.defaultModel.model,\n messages: conversationMessages,\n tools: resolved.availableTools,\n } as TExecutionEventData);\n const response = await callProviderWithCache(\n conversationMessages,\n config,\n resolved,\n cacheService,\n {\n signal: fullContext.signal,\n onTextDelta: wrappedOnTextDelta,\n onProviderNativeRawPayload: wrappedOnProviderNativeRawPayload,\n },\n );\n fullContext.onExecutionEvent?.('provider_response_raw', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n response,\n responseKind: 'provider-normalized-message',\n } as TExecutionEventData);\n fullContext.onExecutionEvent?.('provider_response_normalized', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n response,\n toolCallsCount:\n response.role === 'assistant' && Array.isArray(response.toolCalls)\n ? response.toolCalls.length\n : 0,\n } as TExecutionEventData);\n return response;\n } catch (providerError) {\n // allow-fallback: provider errors terminate the round, not the process\n const isAbortError =\n providerError instanceof Error &&\n (providerError.name === 'AbortError' ||\n providerError.message.includes('aborted') ||\n providerError.message.includes('abort'));\n if (isAbortError) {\n conversationStore.commitAssistant('interrupted', { round: currentRound });\n throw providerError;\n }\n conversationStore.discardPending();\n const errMsg = providerError instanceof Error ? providerError.message : String(providerError);\n logger.error('[ROUND] Provider call failed', { error: errMsg, round: currentRound });\n conversationStore.addAssistantMessage(`Request failed: ${errMsg}`, [], {\n round: currentRound,\n providerError: true,\n });\n return null;\n }\n}\n","import type { IAgentConfig, TExecutionEventData } from '../interfaces/agent';\nimport type { TUniversalMessage, TMessageState } from '../interfaces/messages';\nimport type { ToolExecutionService } from './tool-execution-service';\nimport type { ILogger } from '../utils/logger';\nimport type { ExecutionEventEmitter } from './execution-event-emitter';\nimport type { ExecutionCacheService } from './cache/execution-cache-service';\nimport type { ConversationStore } from '../managers/conversation-history-manager';\nimport type { TPluginWithHooks } from './plugin-hook-dispatcher';\nimport { callPluginHook } from './plugin-hook-dispatcher';\nimport { bindWithOwnerPath } from '../event-service/index';\nimport { EXECUTION_EVENTS } from './execution-constants';\nimport {\n type IResolvedProviderInfo,\n type IExecutionRoundState,\n type IExecutionContext,\n SHORT_PREVIEW_LENGTH,\n LAST_MESSAGES_SLICE,\n} from './execution-types';\nimport {\n computeRoundThinkingContext,\n validateAndExtractResponse,\n} from './execution-round-provider';\nimport { executeAndRecordToolCalls } from './execution-round-tools';\nimport { collectAssistantUsageMetadata } from './execution-usage';\nimport { handleContextCapacityBlock } from './execution-round-context';\nimport {\n createRoundStreamingCallbacks,\n callRoundProviderWithEvents,\n} from './execution-round-streaming';\nexport type { IToolResultsOutcome } from './execution-round-tools';\nexport {\n computeRoundThinkingContext,\n callProviderWithCache,\n validateAndExtractResponse,\n} from './execution-round-provider';\nexport { executeAndRecordToolCalls } from './execution-round-tools';\nexport { addToolResultsToHistory } from './execution-round-tool-results';\nexport {\n CONTEXT_HARD_BLOCK_THRESHOLD,\n type IContextCapacityDecision,\n getContextCapacityDecision,\n} from './execution-round-context';\n\nconst MAX_CONSECUTIVE_UNKNOWN_TOOL_FAILURE_ROUNDS = 2;\n\n/** Dependencies required by the round executor */\nexport interface IRoundDependencies {\n toolExecutionService: ToolExecutionService;\n plugins: ReadonlyArray<TPluginWithHooks>;\n logger: ILogger;\n eventEmitter: ExecutionEventEmitter;\n cacheService?: ExecutionCacheService;\n}\n\n/** Execute a single round of the conversation loop. Returns true if loop should break. */\nexport async function executeRound(\n roundState: IExecutionRoundState,\n maxRounds: number,\n conversationStore: ConversationStore,\n conversationId: string,\n executionId: string,\n fullContext: IExecutionContext,\n config: IAgentConfig,\n resolved: IResolvedProviderInfo,\n deps: IRoundDependencies,\n): Promise<boolean> {\n const { plugins, logger, eventEmitter, cacheService } = deps;\n const currentRound = roundState.currentRound;\n\n logger.debug(`[ROUND-${currentRound}] Starting execution round ${currentRound}`, {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n maxRounds,\n });\n\n const conversationMessages = conversationStore.getMessages();\n const { thinkingNodeId, previousThinkingNodeId } = computeRoundThinkingContext(\n conversationId,\n roundState,\n );\n\n await callPluginHook(plugins, 'beforeProviderCall', { messages: conversationMessages }, logger);\n\n logger.debug('Sending messages to AI provider', {\n round: currentRound,\n messageCount: conversationMessages.length,\n lastFewMessages: conversationMessages.slice(LAST_MESSAGES_SLICE).map((m) => ({\n role: m.role,\n content: m.content?.substring(0, SHORT_PREVIEW_LENGTH),\n hasToolCalls: 'toolCalls' in m ? !!m.toolCalls?.length : false,\n toolCallId: 'toolCallId' in m ? m.toolCallId : undefined,\n })),\n });\n\n eventEmitter.emitWithContext(\n EXECUTION_EVENTS.ASSISTANT_MESSAGE_START,\n {\n parameters: { round: currentRound, messageCount: conversationMessages.length },\n metadata: { round: currentRound, thinkingNodeId },\n },\n () =>\n eventEmitter.buildThinkingOwnerContext(\n conversationId,\n executionId,\n thinkingNodeId,\n previousThinkingNodeId,\n ),\n (ctx) => {\n if (!ctx.ownerType || !ctx.ownerId) {\n throw new Error('[EXECUTION] Missing owner context for thinking event');\n }\n return bindWithOwnerPath(eventEmitter.getBaseEventService(), {\n ownerType: ctx.ownerType,\n ownerId: ctx.ownerId,\n ownerPath: ctx.ownerPath,\n });\n },\n );\n\n // Pre-send hard-capacity check. Routine compaction is owned by agent-sessions; this guard is\n // only a last safety stop when the effective context estimate is already near the model limit.\n if (\n handleContextCapacityBlock(\n conversationMessages,\n config,\n roundState,\n conversationStore,\n logger,\n currentRound,\n )\n ) {\n return true;\n }\n\n if (currentRound > 1) {\n fullContext.onTextDelta?.('\\n\\n');\n }\n\n conversationStore.beginAssistant();\n\n const { wrappedOnTextDelta, wrappedOnProviderNativeRawPayload } = createRoundStreamingCallbacks(\n fullContext,\n conversationStore,\n executionId,\n currentRound,\n );\n\n const response = await callRoundProviderWithEvents(\n conversationMessages,\n config,\n resolved,\n cacheService,\n fullContext,\n conversationStore,\n currentRound,\n executionId,\n logger,\n wrappedOnTextDelta,\n wrappedOnProviderNativeRawPayload,\n );\n if (response === null) return true;\n\n const { assistantResponse, assistantToolCalls } = validateAndExtractResponse(\n response,\n executionId,\n fullContext.conversationId,\n currentRound,\n logger,\n );\n\n await callPluginHook(\n plugins,\n 'afterProviderCall',\n { messages: conversationMessages, responseMessage: response },\n logger,\n );\n\n const responseHasText =\n typeof assistantResponse.content === 'string' && assistantResponse.content.trim().length > 0;\n if (assistantToolCalls.length === 0 && !responseHasText) {\n logger.warn('[ROUND] Provider returned empty assistant response without tool calls', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n });\n conversationStore.discardPending();\n return true;\n }\n\n const usageMetadata = collectAssistantUsageMetadata(assistantResponse);\n const inputTokens = usageMetadata?.inputTokens ?? 0;\n\n if (inputTokens > 0) {\n roundState.cumulativeInputTokens = inputTokens;\n }\n\n if (assistantResponse.content && !conversationStore.getPendingContent()) {\n conversationStore.appendStreaming(assistantResponse.content);\n }\n\n for (const tc of assistantToolCalls) {\n conversationStore.appendToolCall(tc);\n }\n\n const messageState: TMessageState = fullContext.signal?.aborted ? 'interrupted' : 'complete';\n conversationStore.commitAssistant(messageState, {\n round: currentRound,\n ...(usageMetadata ?? {}),\n });\n const committedAssistantMessage = conversationStore.getMessages().at(-1);\n fullContext.onExecutionEvent?.('assistant_message_committed', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n message: assistantResponse,\n } as TExecutionEventData);\n if (committedAssistantMessage) {\n fullContext.onExecutionEvent?.('history_mutation', {\n executionId,\n conversationId: fullContext.conversationId,\n round: currentRound,\n mutation: 'append_message',\n index: conversationStore.getMessages().length - 1,\n message: committedAssistantMessage,\n } as TExecutionEventData);\n }\n roundState.runningAssistantCount++;\n roundState.lastTrackedAssistantMessage = assistantResponse;\n\n if (assistantToolCalls.length === 0) {\n logger.debug(\n `[AGENT-FLOW-CONTROL] Round ${currentRound} completed - no tool calls, execution finished for agent ${fullContext.conversationId}`,\n );\n eventEmitter.emitAssistantMessageComplete(\n assistantResponse,\n executionId,\n currentRound,\n conversationId,\n thinkingNodeId,\n previousThinkingNodeId,\n );\n return true;\n }\n\n const toolOutcome = await executeAndRecordToolCalls(\n assistantToolCalls,\n conversationStore,\n conversationId,\n executionId,\n currentRound,\n thinkingNodeId,\n previousThinkingNodeId,\n roundState,\n deps,\n config,\n fullContext.signal,\n fullContext.onExecutionEvent,\n );\n\n if (toolOutcome.contextOverflowed) {\n logger.warn(\n '[ROUND] Tool results partially skipped due to context overflow — continuing to let AI respond',\n { added: toolOutcome.addedCount, skipped: toolOutcome.skippedCount, round: currentRound },\n );\n }\n\n if (toolOutcome.unknownToolFailureCount > 0) {\n roundState.consecutiveUnknownToolFailureRounds += 1;\n } else {\n roundState.consecutiveUnknownToolFailureRounds = 0;\n }\n\n if (\n roundState.consecutiveUnknownToolFailureRounds >= MAX_CONSECUTIVE_UNKNOWN_TOOL_FAILURE_ROUNDS\n ) {\n const unavailableTools = [...new Set(toolOutcome.unknownToolNames)].sort();\n roundState.forcedSummaryInstruction = [\n `The model repeatedly requested unavailable tool(s): ${unavailableTools.join(', ')}.`,\n 'Those tool calls were not executed because they are not registered tools.',\n 'Respond to the user now with that reason and use the available tool results already in the conversation history.',\n ].join(' ');\n logger.warn('[ROUND] Stopping repeated unavailable tool-call loop', {\n unavailableTools,\n consecutiveRounds: roundState.consecutiveUnknownToolFailureRounds,\n round: currentRound,\n });\n return true;\n }\n\n logger.debug(\n `Round ${currentRound} completed - continuing to next round for agent ${fullContext.conversationId}`,\n );\n return false;\n}\n","import type { IAgentConfig } from '../interfaces/agent';\nimport type { ConversationStore } from '../managers/conversation-history-manager';\nimport type { TPluginWithHooks } from './plugin-hook-dispatcher';\nimport { callPluginHook } from './plugin-hook-dispatcher';\nimport type { ILogger } from '../utils/logger';\nimport type { TMetadata } from '../interfaces/types';\nimport type { ExecutionEventEmitter } from './execution-event-emitter';\nimport { EXECUTION_EVENTS } from './execution-constants';\nimport { randomUUID } from 'node:crypto';\nimport type { ToolExecutionService } from './tool-execution-service';\nimport type { ExecutionCacheService } from './cache/execution-cache-service';\nimport { executeRound } from './execution-round';\nimport {\n type IResolvedProviderInfo,\n type IExecutionContext,\n type IExecutionResult,\n type IExecutionRoundState,\n PREVIEW_LENGTH,\n} from './execution-types';\nimport { buildFinalResult } from './execution-service-helpers';\n\nexport const DEFAULT_MAX_EXECUTION_ROUNDS = 10;\nexport const UNLIMITED_EXECUTION_ROUNDS = 0;\n\nfunction resolveMaxExecutionRounds(config: IAgentConfig, context: IExecutionContext): number {\n const configured = context.maxExecutionRounds ?? config.maxExecutionRounds;\n if (configured === undefined) {\n return DEFAULT_MAX_EXECUTION_ROUNDS;\n }\n if (!Number.isInteger(configured) || configured < 0) {\n throw new Error('[EXECUTION] maxExecutionRounds must be a non-negative integer');\n }\n return configured;\n}\n\nfunction hasRoundCapacity(currentRound: number, maxRounds: number): boolean {\n return maxRounds === UNLIMITED_EXECUTION_ROUNDS || currentRound < maxRounds;\n}\n\n/** Dependencies for running the execution round loop */\nexport interface IExecutionRoundDeps {\n toolExecutionService: ToolExecutionService;\n plugins: TPluginWithHooks[];\n logger: ILogger;\n eventEmitter: ExecutionEventEmitter;\n cacheService?: ExecutionCacheService;\n}\n\n/**\n * Run the execution round loop and (if needed) force a summary call at the end.\n * Mutates roundState.\n */\nexport async function runExecutionLoop(\n conversationStore: ConversationStore,\n conversationId: string,\n executionId: string,\n fullContext: IExecutionContext,\n config: IAgentConfig,\n resolved: IResolvedProviderInfo,\n roundState: IExecutionRoundState,\n signal: AbortSignal | undefined,\n deps: IExecutionRoundDeps,\n): Promise<void> {\n const maxRounds = resolveMaxExecutionRounds(config, fullContext);\n\n while (hasRoundCapacity(roundState.currentRound, maxRounds)) {\n if (signal?.aborted) break;\n roundState.currentRound++;\n const shouldBreak = await executeRound(\n roundState,\n maxRounds,\n conversationStore,\n conversationId,\n executionId,\n fullContext,\n config,\n resolved,\n deps,\n );\n if (shouldBreak) break;\n if (signal?.aborted) break;\n }\n\n // If loop ended without a final text response (e.g., maxRounds reached while\n // AI was still issuing tool calls), make one more provider call so the AI\n // can generate a summary from the results collected so far.\n const allMsgs = conversationStore.getMessages();\n const lastMsg = allMsgs.length > 0 ? allMsgs[allMsgs.length - 1] : undefined;\n const hasTextResponse =\n lastMsg?.role === 'assistant' &&\n typeof lastMsg.content === 'string' &&\n lastMsg.content.length > 0 &&\n (!('toolCalls' in lastMsg) || (lastMsg.toolCalls as unknown[]).length === 0);\n\n if (!hasTextResponse) {\n await forceSummaryCall(\n conversationStore,\n resolved,\n config,\n executionId,\n roundState,\n conversationId,\n fullContext,\n deps.logger,\n maxRounds,\n );\n }\n}\n\n/**\n * When max rounds are exhausted without a text response, force one final provider call\n * to generate a summary.\n */\nexport async function forceSummaryCall(\n conversationStore: ConversationStore,\n resolved: IResolvedProviderInfo,\n config: IAgentConfig,\n executionId: string,\n roundState: IExecutionRoundState,\n conversationId: string,\n fullContext: IExecutionContext,\n logger: ILogger,\n maxRounds: number = DEFAULT_MAX_EXECUTION_ROUNDS,\n): Promise<void> {\n logger.warn('No final text response — forcing summary call', {\n maxRounds: maxRounds === UNLIMITED_EXECUTION_ROUNDS ? 'unlimited' : maxRounds,\n currentRound: roundState.currentRound,\n conversationId,\n });\n try {\n const syntheticMsg =\n roundState.forcedSummaryInstruction ??\n 'Tool round limit reached. Provide your response based on the information gathered so far. If results are incomplete, let the user know what was covered and what remains — the user can request additional analysis in a follow-up message.';\n conversationStore.addUserMessage(syntheticMsg);\n const summaryMessages = conversationStore.getMessages();\n const systemMsg = config.systemMessage ?? '';\n\n const hasSystemMsg = summaryMessages.some(\n (m) => m.role === 'system' && m.content === systemMsg,\n );\n const messagesForProvider =\n systemMsg && !hasSystemMsg\n ? [\n {\n id: randomUUID(),\n role: 'system' as const,\n content: systemMsg,\n state: 'complete' as const,\n timestamp: new Date(),\n },\n ...summaryMessages,\n ]\n : summaryMessages;\n\n const chatOptions: { model: string; onTextDelta?: (delta: string) => void } = {\n model: resolved.aiProviderInfo.model,\n };\n if (fullContext.onTextDelta) {\n chatOptions.onTextDelta = fullContext.onTextDelta;\n }\n\n const forceResponse = await resolved.provider.chat(messagesForProvider, chatOptions);\n\n // Remove synthetic message from history to avoid polluting conversation\n const currentMessages = conversationStore.getMessages();\n const syntheticIndex = currentMessages.findIndex(\n (m) => m.role === 'user' && m.content === syntheticMsg,\n );\n if (syntheticIndex !== -1) {\n const cleaned = currentMessages.filter(\n (m) => !(m.role === 'user' && m.content === syntheticMsg),\n );\n conversationStore.clear();\n for (const m of cleaned) {\n conversationStore.addMessage(m);\n }\n }\n\n const responseText = typeof forceResponse.content === 'string' ? forceResponse.content : '';\n if (responseText) {\n conversationStore.addAssistantMessage(responseText, [], forceResponse.metadata);\n } else {\n conversationStore.addAssistantMessage(\n 'Maximum rounds reached. Partial results available in conversation history.',\n );\n }\n } catch (forceErr) {\n logger.warn('Forced summary call failed', {\n error: forceErr instanceof Error ? forceErr.message : String(forceErr),\n });\n }\n}\n\n/**\n * Finalize the execution after all rounds complete:\n * calls afterRun hooks, logs success, emits COMPLETE event, and returns the result.\n */\nexport async function finalizeExecution(\n input: string,\n conversationStore: ConversationStore,\n executionId: string,\n startTime: Date,\n roundState: IExecutionRoundState,\n conversationId: string,\n interrupted: boolean,\n context: Partial<IExecutionContext> | undefined,\n plugins: TPluginWithHooks[],\n logger: ILogger,\n eventEmitter: ExecutionEventEmitter,\n): Promise<IExecutionResult> {\n const result = {\n ...buildFinalResult(conversationStore, executionId, startTime, roundState.toolsExecuted),\n interrupted,\n };\n\n await callPluginHook(\n plugins,\n 'afterRun',\n {\n input,\n response: result.response,\n metadata: context?.metadata as TMetadata,\n },\n logger,\n );\n\n logger.debug('Execution pipeline completed successfully', {\n executionId,\n conversationId,\n duration: result.duration,\n tokensUsed: result.tokensUsed,\n toolsExecuted: result.toolsExecuted.length,\n rounds: roundState.currentRound,\n });\n\n eventEmitter.emitExecution(\n EXECUTION_EVENTS.COMPLETE,\n {\n result: {\n success: true,\n data: result.response.substring(0, PREVIEW_LENGTH) + '...',\n },\n metadata: {\n method: 'execute',\n success: true,\n duration: result.duration,\n tokensUsed: result.tokensUsed,\n toolsExecuted: result.toolsExecuted,\n },\n },\n conversationId,\n executionId,\n );\n\n return result;\n}\n","import type {\n IAgentConfig,\n IAssistantMessage,\n IExecutionContextInjection,\n} from '../interfaces/agent';\nimport { ToolExecutionService } from './tool-execution-service';\nimport type { IAIProviderManager, IToolManager } from '../interfaces/manager';\nimport { ConversationHistory } from '../managers/conversation-history-manager';\nimport { createLogger, type ILogger } from '../utils/logger';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type { IEventService } from '../interfaces/event-service';\nimport type { ExecutionCacheService } from './cache/execution-cache-service';\n\n// Re-export constants for public API compatibility\nexport { EXECUTION_EVENTS, EXECUTION_EVENT_PREFIX } from './execution-constants';\n\nimport {\n type IExecutionRoundState,\n type IExecutionContext,\n type IExecutionResult,\n type IExecutionServicePluginStats,\n} from './execution-types';\nimport { ExecutionEventEmitter } from './execution-event-emitter';\nimport { callPluginHook, type TPluginWithHooks } from './plugin-hook-dispatcher';\nimport type { TMetadata } from '../interfaces/types';\nimport { executeStream as executeStreamFn } from './execution-stream';\nimport {\n resolveProviderAndTools,\n validateProvider,\n initializeConversationStore,\n handleExecutionError,\n generateExecutionId,\n requireConversationId,\n buildFullExecutionContext,\n} from './execution-service-helpers';\nimport { runExecutionLoop, finalizeExecution } from './execution-pipeline';\n\n/** Orchestrates the execution pipeline: AI provider, tool execution, and plugin lifecycle. */\nexport class ExecutionService {\n private toolExecutionService: ToolExecutionService;\n private aiProviders: IAIProviderManager;\n private tools: IToolManager;\n private conversationHistory: ConversationHistory;\n private plugins: TPluginWithHooks[] = [];\n private logger: ILogger;\n private eventEmitter: ExecutionEventEmitter;\n private cacheService?: ExecutionCacheService;\n\n constructor(\n aiProviders: IAIProviderManager,\n tools: IToolManager,\n conversationHistory: ConversationHistory,\n eventService?: IEventService,\n executionContext?: IExecutionContextInjection,\n cacheService?: ExecutionCacheService,\n ) {\n this.toolExecutionService = new ToolExecutionService(tools);\n this.aiProviders = aiProviders;\n this.tools = tools;\n this.conversationHistory = conversationHistory;\n this.plugins = [];\n this.logger = createLogger('ExecutionService');\n if (!eventService) {\n throw new Error('[EXECUTION] EventService is required');\n }\n this.eventEmitter = new ExecutionEventEmitter(eventService, this.logger, executionContext);\n this.cacheService = cacheService;\n }\n\n /** Register a plugin */\n registerPlugin(plugin: TPluginWithHooks): void {\n const pluginPriority = plugin.priority ?? 0;\n const insertIndex = this.plugins.findIndex((p) => (p.priority ?? 0) < pluginPriority);\n if (insertIndex === -1) {\n this.plugins.push(plugin);\n } else {\n this.plugins.splice(insertIndex, 0, plugin);\n }\n this.logger.debug('Plugin registered', { pluginName: plugin.name, priority: pluginPriority });\n }\n\n /** Remove a plugin */\n removePlugin(pluginName: string): boolean {\n const index = this.plugins.findIndex((p) => p.name === pluginName);\n if (index !== -1) {\n this.plugins.splice(index, 1);\n this.logger.debug('Plugin removed', { pluginName });\n return true;\n }\n return false;\n }\n\n /** Get a plugin by name */\n getPlugin(pluginName: string): TPluginWithHooks | undefined {\n return this.plugins.find((p) => p.name === pluginName);\n }\n\n /** Get all registered plugins */\n getPlugins(): TPluginWithHooks[] {\n return [...this.plugins];\n }\n\n /** Execute the full pipeline with centralized history management */\n async execute(\n input: string,\n messages: TUniversalMessage[],\n config: IAgentConfig,\n context?: Partial<IExecutionContext>,\n ): Promise<IExecutionResult> {\n const executionId = generateExecutionId();\n const startTime = new Date();\n const conversationId = requireConversationId(context, 'execute');\n\n const fullContext = buildFullExecutionContext(\n messages,\n config,\n startTime,\n executionId,\n conversationId,\n context,\n );\n\n this.eventEmitter.prepareOwnerPathBases(conversationId);\n\n this.logger.debug('Starting execution pipeline', {\n executionId,\n conversationId,\n messageCount: messages.length,\n hasContext: !!context,\n });\n\n const resolved = resolveProviderAndTools(this.aiProviders, this.tools, config);\n this.eventEmitter.emitExecutionStartEvent(\n input,\n config,\n messages,\n resolved,\n conversationId,\n executionId,\n );\n\n const conversationStore = initializeConversationStore(\n this.conversationHistory,\n conversationId,\n messages,\n config,\n executionId,\n );\n\n try {\n const messageCountBeforeUser = conversationStore.getMessages().length;\n conversationStore.addUserMessage(input, { executionId });\n const userMessage = conversationStore.getMessages()[messageCountBeforeUser];\n if (userMessage) {\n fullContext.onExecutionEvent?.('history_mutation', {\n executionId,\n conversationId,\n mutation: 'append_message',\n index: messageCountBeforeUser,\n message: userMessage,\n });\n }\n this.eventEmitter.emitUserMessageEvent(input, conversationId, executionId);\n\n await callPluginHook(\n this.plugins,\n 'beforeRun',\n {\n input,\n ...(context?.metadata ? { metadata: context.metadata as TMetadata } : {}),\n },\n this.logger,\n );\n\n validateProvider(resolved);\n\n const roundState: IExecutionRoundState = {\n toolsExecuted: [],\n currentRound: 0,\n runningAssistantCount: 0,\n lastTrackedAssistantMessage: undefined,\n cumulativeInputTokens: 0,\n consecutiveUnknownToolFailureRounds: 0,\n };\n\n for (const msg of conversationStore.getMessages()) {\n if (msg.role === 'assistant') {\n roundState.runningAssistantCount++;\n roundState.lastTrackedAssistantMessage = msg as IAssistantMessage;\n }\n }\n\n await runExecutionLoop(\n conversationStore,\n conversationId,\n executionId,\n fullContext,\n config,\n resolved,\n roundState,\n context?.signal,\n {\n toolExecutionService: this.toolExecutionService,\n plugins: this.plugins,\n logger: this.logger,\n eventEmitter: this.eventEmitter,\n cacheService: this.cacheService,\n },\n );\n\n return finalizeExecution(\n input,\n conversationStore,\n executionId,\n startTime,\n roundState,\n conversationId,\n context?.signal?.aborted ?? false,\n context,\n this.plugins,\n this.logger,\n this.eventEmitter,\n );\n } catch (error) {\n const isAbortError =\n error instanceof Error &&\n (error.name === 'AbortError' ||\n error.message.includes('aborted') ||\n error.message.includes('abort'));\n if (isAbortError) {\n return {\n response: '',\n messages: conversationStore.getMessages(),\n executionId,\n duration: Date.now() - startTime.getTime(),\n toolsExecuted: [],\n success: true,\n interrupted: true,\n };\n }\n await handleExecutionError(\n error,\n fullContext,\n startTime,\n conversationId,\n executionId,\n this.plugins,\n this.logger,\n this.eventEmitter,\n );\n const errMsg = error instanceof Error ? error.message : String(error);\n return {\n response: `Error: ${errMsg}`,\n messages: [],\n tokensUsed: 0,\n toolsExecuted: [],\n duration: Date.now() - startTime.getTime(),\n executionId,\n success: false,\n };\n } finally {\n this.eventEmitter.resetOwnerPathBases();\n }\n }\n\n /** Execute with streaming response */\n async *executeStream(\n input: string,\n messages: TUniversalMessage[],\n config: IAgentConfig,\n context?: Partial<IExecutionContext>,\n ): AsyncGenerator<{ chunk: string; isComplete: boolean }> {\n yield* executeStreamFn(input, messages, config, context, {\n aiProviders: this.aiProviders,\n tools: this.tools,\n conversationHistory: this.conversationHistory,\n toolExecutionService: this.toolExecutionService,\n plugins: this.plugins,\n logger: this.logger,\n eventEmitter: this.eventEmitter,\n generateExecutionId: () => generateExecutionId(),\n });\n }\n\n /** Get execution statistics from plugins */\n async getStats(): Promise<IExecutionServicePluginStats> {\n return {\n pluginCount: this.plugins.length,\n pluginNames: this.plugins.map((p) => p.name),\n historyStats: this.conversationHistory.getStats(),\n };\n }\n\n /** Clear all plugins */\n clearPlugins(): void {\n this.plugins = [];\n this.logger.debug('All plugins cleared');\n }\n}\n","import { AGENT_EVENTS, AGENT_EVENT_PREFIX } from '../../agents/constants';\nimport { EXECUTION_EVENTS, EXECUTION_EVENT_PREFIX } from '../../services/execution-service';\nimport { TOOL_EVENTS, TOOL_EVENT_PREFIX } from '../../services/tool-execution-service';\n\nconst buildEventName = <TPrefix extends string, TLocal extends string>(\n prefix: TPrefix,\n localName: TLocal,\n): `${TPrefix}.${TLocal}` => `${prefix}.${localName}`;\n\nconst EXECUTION_EVENT_NAMES = {\n START: buildEventName(EXECUTION_EVENT_PREFIX, EXECUTION_EVENTS.START),\n COMPLETE: buildEventName(EXECUTION_EVENT_PREFIX, EXECUTION_EVENTS.COMPLETE),\n ERROR: buildEventName(EXECUTION_EVENT_PREFIX, EXECUTION_EVENTS.ERROR),\n} as const;\n\nconst TOOL_EVENT_NAMES = {\n CALL_START: buildEventName(TOOL_EVENT_PREFIX, TOOL_EVENTS.CALL_START),\n CALL_COMPLETE: buildEventName(TOOL_EVENT_PREFIX, TOOL_EVENTS.CALL_COMPLETE),\n CALL_ERROR: buildEventName(TOOL_EVENT_PREFIX, TOOL_EVENTS.CALL_ERROR),\n} as const;\n\nconst AGENT_EVENT_NAMES = {\n EXECUTION_START: buildEventName(AGENT_EVENT_PREFIX, AGENT_EVENTS.EXECUTION_START),\n EXECUTION_COMPLETE: buildEventName(AGENT_EVENT_PREFIX, AGENT_EVENTS.EXECUTION_COMPLETE),\n EXECUTION_ERROR: buildEventName(AGENT_EVENT_PREFIX, AGENT_EVENTS.EXECUTION_ERROR),\n CREATED: buildEventName(AGENT_EVENT_PREFIX, AGENT_EVENTS.CREATED),\n} as const;\n\nexport type TExecutionEventName =\n (typeof EXECUTION_EVENT_NAMES)[keyof typeof EXECUTION_EVENT_NAMES];\ntype TToolEventName = (typeof TOOL_EVENT_NAMES)[keyof typeof TOOL_EVENT_NAMES];\ntype TAgentEventName = (typeof AGENT_EVENT_NAMES)[keyof typeof AGENT_EVENT_NAMES];\n\n/**\n * Event types that can be emitted.\n *\n * IMPORTANT:\n * - Do not use string literals for event names outside this module.\n * - Import and use EVENT_EMITTER_EVENTS instead.\n */\nexport const EVENT_EMITTER_EVENTS = {\n EXECUTION_START: EXECUTION_EVENT_NAMES.START,\n EXECUTION_COMPLETE: EXECUTION_EVENT_NAMES.COMPLETE,\n EXECUTION_ERROR: EXECUTION_EVENT_NAMES.ERROR,\n TOOL_BEFORE_EXECUTE: 'tool.beforeExecute',\n TOOL_AFTER_EXECUTE: 'tool.afterExecute',\n TOOL_SUCCESS: 'tool.success',\n TOOL_ERROR: TOOL_EVENT_NAMES.CALL_ERROR,\n CONVERSATION_START: 'conversation.start',\n CONVERSATION_COMPLETE: 'conversation.complete',\n CONVERSATION_ERROR: 'conversation.error',\n AGENT_EXECUTION_START: AGENT_EVENT_NAMES.EXECUTION_START,\n AGENT_EXECUTION_COMPLETE: AGENT_EVENT_NAMES.EXECUTION_COMPLETE,\n AGENT_EXECUTION_ERROR: AGENT_EVENT_NAMES.EXECUTION_ERROR,\n AGENT_CREATED: AGENT_EVENT_NAMES.CREATED,\n AGENT_DESTROYED: 'agent.destroyed',\n PLUGIN_LOADED: 'plugin.loaded',\n PLUGIN_UNLOADED: 'plugin.unloaded',\n PLUGIN_ERROR: 'plugin.error',\n ERROR_OCCURRED: 'error.occurred',\n WARNING_OCCURRED: 'warning.occurred',\n MODULE_INITIALIZE_START: 'module.initialize.start',\n MODULE_INITIALIZE_COMPLETE: 'module.initialize.complete',\n MODULE_INITIALIZE_ERROR: 'module.initialize.error',\n MODULE_EXECUTION_START: 'module.execution.start',\n MODULE_EXECUTION_COMPLETE: 'module.execution.complete',\n MODULE_EXECUTION_ERROR: 'module.execution.error',\n MODULE_DISPOSE_START: 'module.dispose.start',\n MODULE_DISPOSE_COMPLETE: 'module.dispose.complete',\n MODULE_DISPOSE_ERROR: 'module.dispose.error',\n MODULE_REGISTERED: 'module.registered',\n MODULE_UNREGISTERED: 'module.unregistered',\n EXECUTION_HIERARCHY: 'execution.hierarchy',\n EXECUTION_REALTIME: 'execution.realtime',\n TOOL_REALTIME: 'tool.realtime',\n CUSTOM: 'custom',\n} as const;\n\nexport type TEventName =\n | TExecutionEventName\n | TToolEventName\n | TAgentEventName\n | 'tool.beforeExecute'\n | 'tool.afterExecute'\n | 'tool.success'\n | 'conversation.start'\n | 'conversation.complete'\n | 'conversation.error'\n | 'agent.destroyed'\n | 'plugin.loaded'\n | 'plugin.unloaded'\n | 'plugin.error'\n | 'error.occurred'\n | 'warning.occurred'\n | 'module.initialize.start'\n | 'module.initialize.complete'\n | 'module.initialize.error'\n | 'module.execution.start'\n | 'module.execution.complete'\n | 'module.execution.error'\n | 'module.dispose.start'\n | 'module.dispose.complete'\n | 'module.dispose.error'\n | 'module.registered'\n | 'module.unregistered'\n | 'execution.hierarchy'\n | 'execution.realtime'\n | 'tool.realtime'\n | 'custom';\n\n/**\n * Valid event data value types\n */\nexport type TEventDataValue =\n | string\n | number\n | boolean\n | Date\n | null\n | undefined\n | TEventDataValue[]\n | { [key: string]: TEventDataValue };\n\n/**\n * Event data structure\n */\nexport interface IEventEmitterEventData {\n type: TEventName;\n timestamp: Date;\n executionId?: string;\n sessionId?: string;\n userId?: string;\n data?: Record<string, TEventDataValue>;\n error?: Error;\n metadata?: Record<string, TEventDataValue>;\n}\n\n/**\n * Event listener function\n */\nexport type TEventEmitterListener = (event: IEventEmitterEventData) => void | Promise<void>;\n\n/**\n * Console-like interface for the EventEmitterPlugin.\n *\n * Use this interface for typing instead of the concrete EventEmitterPlugin class.\n */\nexport interface IEventEmitterPlugin {\n on(\n eventType: TEventName,\n listener: TEventEmitterListener,\n options?: {\n once?: boolean;\n filter?: (event: IEventEmitterEventData) => boolean;\n },\n ): string;\n once(\n eventType: TEventName,\n listener: TEventEmitterListener,\n filter?: (event: IEventEmitterEventData) => boolean,\n ): string;\n off(eventType: TEventName, handlerIdOrListener: string | TEventEmitterListener): boolean;\n emit(eventType: TEventName, eventData?: Partial<IEventEmitterEventData>): Promise<void>;\n}\n\n/**\n * Event handler with metadata\n */\nexport interface IEventEmitterHandler {\n id: string;\n listener: TEventEmitterListener;\n once: boolean;\n filter?: (event: IEventEmitterEventData) => boolean;\n}\n","/**\n * Type definitions for AbstractPlugin.\n *\n * Extracted from abstract-plugin.ts to keep each file under 300 lines.\n */\nimport type { IRunOptions } from '../interfaces/agent';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type {\n TToolParameters,\n IToolExecutionResult,\n IToolExecutionContext,\n} from '../interfaces/tool';\nimport type {\n IEventEmitterEventData,\n IEventEmitterPlugin,\n TEventName,\n} from '../plugins/event-emitter/types';\n\n/** Plugin categories for classification */\nexport enum PluginCategory {\n MONITORING = 'monitoring',\n LOGGING = 'logging',\n STORAGE = 'storage',\n NOTIFICATION = 'notification',\n SECURITY = 'security',\n PERFORMANCE = 'performance',\n ERROR_HANDLING = 'error_handling',\n LIMITS = 'limits',\n EVENT_PROCESSING = 'event_processing',\n CUSTOM = 'custom',\n}\n\nconst PRIORITY_CRITICAL = 1000;\nconst PRIORITY_HIGH = 800;\nconst PRIORITY_NORMAL = 500;\nconst PRIORITY_LOW = 200;\nconst PRIORITY_MINIMAL = 100;\n\n/** Plugin priority levels */\nexport enum PluginPriority {\n CRITICAL = PRIORITY_CRITICAL,\n HIGH = PRIORITY_HIGH,\n NORMAL = PRIORITY_NORMAL,\n LOW = PRIORITY_LOW,\n MINIMAL = PRIORITY_MINIMAL,\n}\n\n/** Plugin execution context for all plugins */\nexport interface IPluginExecutionContext {\n executionId?: string;\n sessionId?: string;\n userId?: string;\n messages?: TUniversalMessage[];\n config?: Record<string, string | number | boolean>;\n metadata?: Record<string, string | number | boolean | Date>;\n [key: string]:\n | string\n | number\n | boolean\n | Date\n | string[]\n | number[]\n | boolean[]\n | TUniversalMessage[]\n | Record<string, string | number | boolean>\n | Record<string, string | number | boolean | Date>\n | undefined;\n}\n\n/** Plugin execution result for all plugins */\nexport interface IPluginExecutionResult {\n response?: string;\n content?: string;\n duration?: number;\n tokensUsed?: number;\n toolsExecuted?: number;\n success?: boolean;\n usage?: { totalTokens?: number; promptTokens?: number; completionTokens?: number };\n toolCalls?: Array<{\n id?: string;\n name?: string;\n arguments?: Record<string, string | number | boolean>;\n result?: string | number | boolean | null;\n }>;\n results?: Array<{\n id?: string;\n type?: string;\n data?: string | number | boolean | null;\n success?: boolean;\n }>;\n error?: Error;\n metadata?: Record<string, string | number | boolean | Date>;\n}\n\n/** Error context for plugin error handling */\nexport interface IPluginErrorContext {\n action: string;\n tool?: string;\n parameters?: TToolParameters;\n result?: IToolExecutionResult;\n error?: Error;\n executionId?: string;\n sessionId?: string;\n userId?: string;\n timestamp?: Date;\n attempt?: number;\n stack?: string;\n metadata?: Record<string, string | number | boolean>;\n}\n\n/** Plugin configuration interface */\nexport interface IPluginConfig extends IPluginOptions {\n options?: Record<string, string | number | boolean>;\n}\n\n/** Plugin options that all plugin options should extend */\nexport interface IPluginOptions {\n enabled?: boolean;\n category?: PluginCategory;\n priority?: PluginPriority | number;\n moduleEvents?: TEventName[];\n subscribeToAllModuleEvents?: boolean;\n}\n\n/** Plugin data interface */\nexport interface IPluginData {\n name: string;\n version: string;\n enabled: boolean;\n category: PluginCategory;\n priority: number;\n subscribedEvents: TEventName[];\n metadata?: Record<string, string | number | boolean>;\n}\n\n/** Type-safe plugin interface with specific type parameters */\nexport interface IPluginContract<\n TOptions extends IPluginOptions = IPluginOptions,\n TStats = IPluginStats,\n> {\n name: string;\n version: string;\n enabled: boolean;\n category: PluginCategory;\n priority: number;\n initialize(options?: TOptions): Promise<void>;\n cleanup?(): Promise<void>;\n getData?(): IPluginData;\n getStats?(): TStats;\n subscribeToModuleEvents?(eventEmitter: IEventEmitterPlugin): Promise<void>;\n unsubscribeFromModuleEvents?(eventEmitter: IEventEmitterPlugin): Promise<void>;\n onModuleEvent?(eventName: TEventName, eventData: IEventEmitterEventData): Promise<void> | void;\n}\n\n/** Plugin statistics base interface with common metrics */\nexport interface IPluginStats {\n enabled: boolean;\n calls: number;\n errors: number;\n lastActivity?: Date;\n moduleEventsReceived?: number;\n [key: string]:\n | string\n | number\n | boolean\n | Date\n | string[]\n | number[]\n | boolean[]\n | Record<string, string | number | boolean | Date>\n | undefined;\n}\n\n/** Plugin interface extending IPluginContract */\nexport interface IPlugin extends IPluginContract<IPluginConfig, IPluginStats> {}\n\n/** Plugin lifecycle hooks */\nexport interface IPluginHooks {\n beforeRun?(input: string, options?: IRunOptions): Promise<void> | void;\n afterRun?(input: string, response: string, options?: IRunOptions): Promise<void> | void;\n beforeExecution?(context: IPluginExecutionContext): Promise<void> | void;\n afterExecution?(\n context: IPluginExecutionContext,\n result: IPluginExecutionResult,\n ): Promise<void> | void;\n beforeConversation?(context: IPluginExecutionContext): Promise<void> | void;\n afterConversation?(\n context: IPluginExecutionContext,\n result: IPluginExecutionResult,\n ): Promise<void> | void;\n beforeToolCall?(toolName: string, parameters: TToolParameters): Promise<void> | void;\n beforeToolExecution?(\n context: IPluginExecutionContext,\n toolData: IToolExecutionContext,\n ): Promise<void> | void;\n afterToolCall?(\n toolName: string,\n parameters: TToolParameters,\n result: IToolExecutionResult,\n ): Promise<void> | void;\n afterToolExecution?(\n context: IPluginExecutionContext,\n toolResults: IPluginExecutionResult,\n ): Promise<void> | void;\n beforeProviderCall?(messages: TUniversalMessage[]): Promise<void> | void;\n afterProviderCall?(\n messages: TUniversalMessage[],\n response: TUniversalMessage,\n ): Promise<void> | void;\n onStreamingChunk?(chunk: TUniversalMessage): Promise<void> | void;\n onError?(error: Error, context?: IPluginErrorContext): Promise<void> | void;\n onMessageAdded?(message: TUniversalMessage): Promise<void> | void;\n onModuleEvent?(eventName: TEventName, eventData: IEventEmitterEventData): Promise<void> | void;\n}\n","/**\n * Abstract class for all plugins with type parameter support.\n *\n * Type definitions live in ./abstract-plugin-types.ts.\n */\nimport type { IRunOptions } from '../interfaces/agent';\nimport type { TUniversalMessage } from '../interfaces/messages';\nimport type {\n TToolParameters,\n IToolExecutionResult,\n IToolExecutionContext,\n} from '../interfaces/tool';\nimport type {\n IEventEmitterEventData,\n IEventEmitterPlugin,\n TEventName,\n} from '../plugins/event-emitter/types';\nimport { EVENT_EMITTER_EVENTS } from '../plugins/event-emitter/types';\nimport { createLogger, type ILogger } from '../utils/logger';\nimport type {\n IPluginOptions,\n IPluginStats,\n IPluginConfig,\n IPluginData,\n IPluginContract,\n IPluginHooks,\n IPluginExecutionContext,\n IPluginExecutionResult,\n IPluginErrorContext,\n} from './abstract-plugin-types';\nimport { PluginCategory, PluginPriority } from './abstract-plugin-types';\n\n// Re-export all types for backward compatibility\nexport type {\n IPluginOptions,\n IPluginStats,\n IPluginConfig,\n IPluginData,\n IPluginContract,\n IPluginHooks,\n IPluginExecutionContext,\n IPluginExecutionResult,\n IPluginErrorContext,\n};\nexport type { IPlugin } from './abstract-plugin-types';\nexport { PluginCategory, PluginPriority };\n\n/**\n * Abstract class for all plugins with type parameter support.\n * Provides plugin lifecycle management and common functionality.\n * @template TOptions - Plugin options type that extends IPluginOptions\n * @template TStats - Plugin statistics type\n */\nexport abstract class AbstractPlugin<\n TOptions extends IPluginOptions = IPluginOptions,\n TStats extends IPluginStats = IPluginStats,\n >\n implements IPluginContract<TOptions, TStats>, IPluginHooks\n{\n abstract readonly name: string;\n abstract readonly version: string;\n public enabled = true;\n public category: PluginCategory = PluginCategory.CUSTOM;\n public priority: number = PluginPriority.NORMAL;\n protected options: TOptions | undefined;\n protected eventEmitter: IEventEmitterPlugin | undefined;\n protected subscribedEvents: TEventName[] = [];\n protected eventHandlers = new Map<TEventName, string[]>();\n protected readonly pluginLogger: ILogger = createLogger('AbstractPlugin');\n protected stats = {\n calls: 0,\n errors: 0,\n moduleEventsReceived: 0,\n lastActivity: undefined as Date | undefined,\n };\n\n async initialize(options?: TOptions): Promise<void> {\n this.options = options;\n if (options && 'enabled' in options && typeof options.enabled === 'boolean')\n this.enabled = options.enabled;\n else this.enabled = true;\n if (options?.category) this.category = options.category;\n if (options?.priority !== undefined)\n this.priority = typeof options.priority === 'number' ? options.priority : options.priority;\n }\n\n async subscribeToModuleEvents(eventEmitter: IEventEmitterPlugin): Promise<void> {\n this.eventEmitter = eventEmitter;\n if (!this.options) return;\n const eventsToSubscribe: TEventName[] = [];\n if (this.options.subscribeToAllModuleEvents) {\n eventsToSubscribe.push(\n EVENT_EMITTER_EVENTS.MODULE_INITIALIZE_START,\n EVENT_EMITTER_EVENTS.MODULE_INITIALIZE_COMPLETE,\n EVENT_EMITTER_EVENTS.MODULE_INITIALIZE_ERROR,\n EVENT_EMITTER_EVENTS.MODULE_EXECUTION_START,\n EVENT_EMITTER_EVENTS.MODULE_EXECUTION_COMPLETE,\n EVENT_EMITTER_EVENTS.MODULE_EXECUTION_ERROR,\n EVENT_EMITTER_EVENTS.MODULE_DISPOSE_START,\n EVENT_EMITTER_EVENTS.MODULE_DISPOSE_COMPLETE,\n EVENT_EMITTER_EVENTS.MODULE_DISPOSE_ERROR,\n );\n }\n if (this.options.moduleEvents) eventsToSubscribe.push(...this.options.moduleEvents);\n for (const eventType of eventsToSubscribe) {\n const handlerId = this.eventEmitter.on(\n eventType,\n async (eventData: IEventEmitterEventData) => {\n try {\n this.stats.moduleEventsReceived++;\n this.stats.lastActivity = new Date();\n await this.onModuleEvent?.(eventType, eventData);\n } catch (error) {\n this.stats.errors++;\n const safeError = error instanceof Error ? error : new Error(String(error));\n this.pluginLogger.error(\n `Plugin \"${this.name}\" failed to handle module event \"${String(eventType)}\"`,\n { plugin: this.name, eventType: String(eventType), error: safeError.message },\n );\n }\n },\n );\n const existing = this.eventHandlers.get(eventType);\n if (existing) existing.push(handlerId);\n else this.eventHandlers.set(eventType, [handlerId]);\n this.subscribedEvents.push(eventType);\n }\n }\n\n async unsubscribeFromModuleEvents(eventEmitter: IEventEmitterPlugin): Promise<void> {\n for (const [eventType, handlerIds] of this.eventHandlers.entries()) {\n for (const handlerId of handlerIds) eventEmitter.off(eventType, handlerId);\n }\n this.eventHandlers.clear();\n this.subscribedEvents = [];\n this.eventEmitter = undefined;\n }\n\n async dispose(): Promise<void> {\n if (this.eventEmitter) await this.unsubscribeFromModuleEvents(this.eventEmitter);\n }\n enable(): void {\n this.enabled = true;\n }\n disable(): void {\n this.enabled = false;\n }\n isEnabled(): boolean {\n return this.enabled;\n }\n getConfig(): IPluginConfig {\n return {};\n }\n updateConfig(_config: IPluginConfig): void {\n /* override in subclass */\n }\n\n getData(): IPluginData {\n return {\n name: this.name,\n version: this.version,\n enabled: this.enabled,\n category: this.category,\n priority: this.priority,\n subscribedEvents: [...this.subscribedEvents],\n metadata: {\n moduleEventsReceived: this.stats.moduleEventsReceived,\n totalCalls: this.stats.calls,\n totalErrors: this.stats.errors,\n },\n };\n }\n\n clearData?(): void;\n\n getStatus(): {\n name: string;\n version: string;\n enabled: boolean;\n initialized: boolean;\n category: PluginCategory;\n priority: number;\n subscribedEventsCount: number;\n hasEventEmitter: boolean;\n } {\n return {\n name: this.name,\n version: this.version,\n enabled: this.enabled,\n initialized: true,\n category: this.category,\n priority: this.priority,\n subscribedEventsCount: this.subscribedEvents.length,\n hasEventEmitter: !!this.eventEmitter,\n };\n }\n\n getStats(): TStats {\n const baseStats: IPluginStats = {\n enabled: this.enabled,\n calls: this.stats.calls,\n errors: this.stats.errors,\n moduleEventsReceived: this.stats.moduleEventsReceived,\n ...(this.stats.lastActivity && { lastActivity: this.stats.lastActivity }),\n };\n return baseStats as TStats;\n }\n\n protected updateCallStats(): void {\n this.stats.calls++;\n this.stats.lastActivity = new Date();\n }\n protected updateErrorStats(): void {\n this.stats.errors++;\n this.stats.lastActivity = new Date();\n }\n\n // Optional lifecycle hooks - plugins can override these\n async beforeRun?(input: string, options?: IRunOptions): Promise<void>;\n async afterRun?(input: string, response: string, options?: IRunOptions): Promise<void>;\n async beforeExecution?(context: IPluginExecutionContext): Promise<void>;\n async afterExecution?(\n context: IPluginExecutionContext,\n result: IPluginExecutionResult,\n ): Promise<void>;\n async beforeConversation?(context: IPluginExecutionContext): Promise<void>;\n async afterConversation?(\n context: IPluginExecutionContext,\n result: IPluginExecutionResult,\n ): Promise<void>;\n async beforeToolCall?(toolName: string, parameters: TToolParameters): Promise<void>;\n async beforeToolExecution?(\n context: IPluginExecutionContext,\n toolData: IToolExecutionContext,\n ): Promise<void>;\n async afterToolCall?(\n toolName: string,\n parameters: TToolParameters,\n result: IToolExecutionResult,\n ): Promise<void>;\n async afterToolExecution?(\n context: IPluginExecutionContext,\n toolResults: IPluginExecutionResult,\n ): Promise<void>;\n async beforeProviderCall?(messages: TUniversalMessage[]): Promise<void>;\n async afterProviderCall?(\n messages: TUniversalMessage[],\n response: TUniversalMessage,\n ): Promise<void>;\n async onStreamingChunk?(chunk: TUniversalMessage): Promise<void>;\n async onError?(error: Error, context?: IPluginErrorContext): Promise<void>;\n async onMessageAdded?(message: TUniversalMessage): Promise<void>;\n async onModuleEvent?(eventName: TEventName, eventData: IEventEmitterEventData): Promise<void>;\n}\n","import type {\n IExecutor,\n IChatExecutionRequest,\n IStreamExecutionRequest,\n} from '../interfaces/executor';\nimport type { TUniversalMessage, IAssistantMessage } from '../interfaces/messages';\nimport type { TLoggerData } from '../interfaces/types';\nimport type { ILogger } from '../utils/logger';\nimport { SilentLogger } from '../utils/logger';\n\n/**\n * @fileoverview Abstract Executor Base Class\n *\n * 🎯 ABSTRACT CLASS - DO NOT DEPEND ON CONCRETE IMPLEMENTATIONS\n *\n * Provides shared execution helpers (retry, timeout, validation, logging) for all\n * executor implementations. Concrete executors should extend this class and inject\n * their own logger implementation if they need custom logging behavior.\n *\n * @example\n * ```typescript\n * export class MyCustomExecutor extends AbstractExecutor {\n * async executeChat(request: IChatExecutionRequest): Promise<AssistantMessage> {\n * return this.withRetry(() => this.performChat(request));\n * }\n * }\n * ```\n */\nexport abstract class AbstractExecutor implements IExecutor {\n /**\n * Logger injected via constructor (defaults to abstract logger)\n */\n protected readonly logger: ILogger;\n\n constructor(logger: ILogger = SilentLogger) {\n this.logger = logger;\n }\n\n abstract readonly name: string;\n abstract readonly version: string;\n\n /**\n * Execute a chat completion request\n * Must be implemented by concrete executor classes\n */\n abstract executeChat(request: IChatExecutionRequest): Promise<IAssistantMessage>;\n\n /**\n * Execute a streaming chat completion request\n * Optional - can be implemented by concrete executor classes\n */\n abstract executeChatStream?(request: IStreamExecutionRequest): AsyncIterable<TUniversalMessage>;\n\n /**\n * Check if the executor supports tool calling\n * Default implementation returns false, can be overridden\n */\n supportsTools(): boolean {\n return false;\n }\n\n /**\n * Validate executor configuration\n * Default implementation returns true, can be overridden\n */\n validateConfig(): boolean {\n return true;\n }\n\n /**\n * Clean up resources when executor is no longer needed\n * Default implementation does nothing, can be overridden\n */\n async dispose?(): Promise<void> {\n // Default: no cleanup needed\n }\n\n /**\n * Execute function with retry logic\n *\n * @param fn - Function to execute with retries\n * @param maxRetries - Maximum number of retry attempts (default: 3)\n * @param retryDelay - Delay between retries in milliseconds (default: 1000)\n * @returns Promise resolving to function result\n */\n protected async withRetry<T>(\n fn: () => Promise<T>,\n maxRetries: number = 3,\n retryDelay: number = 1000,\n ): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < maxRetries) {\n this.logger.warn?.(\n `[${this.name}] Attempt ${attempt + 1} failed, retrying in ${retryDelay}ms`,\n {\n error: lastError.message,\n attempt: attempt + 1,\n maxRetries,\n },\n );\n await this.delay(retryDelay);\n }\n }\n }\n\n throw lastError!;\n }\n\n /**\n * Execute function with timeout\n *\n * @param promise - Promise to execute with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @returns Promise resolving to function result\n */\n protected withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n let timerId: ReturnType<typeof setTimeout>;\n return Promise.race([\n promise.then((result) => {\n clearTimeout(timerId);\n return result;\n }),\n new Promise<never>((_, reject) => {\n timerId = setTimeout(\n () => reject(new Error(`Operation timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n }),\n ]);\n }\n\n /**\n * Delay execution for specified milliseconds\n *\n * @param ms - Milliseconds to delay\n * @returns Promise that resolves after the delay\n */\n protected delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Log debug information (only if logging is enabled)\n *\n * @param message - Log message\n * @param data - Optional data to log\n */\n protected logDebug(message: string, data?: TLoggerData): void {\n this.logger.debug?.(`[${this.name}] ${message}`, data);\n }\n\n /**\n * Log error information\n *\n * @param message - Log message\n * @param error - Error object\n * @param data - Optional additional data\n */\n protected logError(message: string, error: Error, data?: TLoggerData): void {\n this.logger.error?.(`[${this.name}] ${message}`, {\n error: error.message,\n stack: error.stack,\n ...data,\n });\n }\n\n /**\n * Validate that request has required fields\n *\n * @param request - Chat execution request to validate\n * @throws Error if validation fails\n */\n protected validateRequest(request: IChatExecutionRequest): void {\n if (!request.messages || request.messages.length === 0) {\n throw new Error('Request must include at least one message');\n }\n\n if (!request.provider) {\n throw new Error('Request must specify a provider');\n }\n\n if (!request.model) {\n throw new Error('Request must specify a model');\n }\n }\n\n /**\n * Validate that response is properly formatted\n *\n * @param response - Response to validate\n * @throws Error if validation fails\n */\n protected validateResponse(response: TUniversalMessage): void {\n if (!response.role) {\n throw new Error('Response must have a role');\n }\n\n const hasToolCalls =\n response.role === 'assistant' &&\n 'toolCalls' in response &&\n Array.isArray((response as IAssistantMessage).toolCalls) &&\n (response as IAssistantMessage).toolCalls!.length > 0;\n if (!response.content && !hasToolCalls) {\n throw new Error('Response must have content or tool calls');\n }\n }\n}\n","/**\n * @fileoverview Abstract Tool Base Class\n *\n * 🎯 ABSTRACT CLASS - DO NOT DEPEND ON CONCRETE IMPLEMENTATIONS\n *\n * This is a pure abstract base class that defines the interface and common behavior\n * for all tools. It follows strict architectural principles:\n *\n * - Depends ONLY on interfaces (EventService interface, not concrete implementations)\n * - Does NOT import concrete classes\n * - Uses Dependency Injection for all dependencies\n * - Handles undefined dependencies gracefully (Null Object Pattern)\n *\n * Concrete implementations should be handled\n * by the caller who creates the tool instance, not by this abstract class.\n *\n * @example\n * ```typescript\n * // ✅ CORRECT: Caller prepares an owner-bound EventService and injects it\n * // (Example: bind to the current tool call identity and ownerPath.)\n * const toolEventService = bindWithOwnerPath(baseEventService, {\n * ownerType: 'tool',\n * ownerId: toolCallId,\n * ownerPath,\n * });\n * const tool = new MyTool({ eventService: toolEventService });\n *\n * // ❌ WRONG: AbstractTool creates concrete EventService\n * // This violates Dependency Inversion Principle\n * ```\n */\n\nimport type {\n IToolResult,\n IToolExecutionContext,\n IParameterValidationResult,\n TToolParameters,\n} from '../interfaces/tool';\nimport type { IToolSchema } from '../interfaces/provider';\nimport type { ILogger } from '../utils/logger';\nimport { SilentLogger } from '../utils/logger';\nimport type { IBaseEventData, IEventService } from '../interfaces/event-service';\n\n/**\n * Options for AbstractTool construction\n */\nexport interface IAbstractToolOptions {\n /**\n * Optional logger for tool operations\n * Defaults to SilentLogger if not provided\n */\n logger?: ILogger;\n\n /**\n * Optional event service for unified event emission\n * If not provided, tool will operate silently without emitting events\n *\n * The caller should provide an EventService configured with appropriate settings\n * (e.g., ownerPrefix='tool' for tool events)\n *\n * @since 2.1.0\n */\n eventService?: IEventService;\n}\n\n/**\n * Tool execution function type with proper parameter constraints\n */\nexport type TToolExecutionFunction<TParams = TToolParameters, TResult = IToolResult> = (\n parameters: TParams,\n) => Promise<TResult> | TResult;\n\n/**\n * Abstract tool interface with type parameters for enhanced type safety\n *\n * @template TParams - Tool parameters type (defaults to AbstractToolParameters for backward compatibility)\n * @template TResult - Tool result type (defaults to ToolResult for backward compatibility)\n */\nexport interface IAbstractTool<TParams = TToolParameters, TResult = IToolResult> {\n name: string;\n description: string;\n parameters: IToolSchema['parameters'];\n execute: TToolExecutionFunction<TParams, TResult>;\n}\n\n/**\n * Type-safe tool interface with type parameters\n *\n * @template TParameters - Tool parameters type (defaults to AbstractToolParameters for backward compatibility)\n * @template TResult - Tool result type (defaults to ToolResult for backward compatibility)\n */\nexport interface IToolContract<TParameters = TToolParameters, TResult = IToolResult> {\n readonly schema: IToolSchema;\n execute(parameters: TParameters, context: IToolExecutionContext): Promise<TResult>;\n validate(parameters: TParameters): boolean;\n validateParameters(parameters: TParameters): IParameterValidationResult;\n getDescription(): string;\n getName(): string;\n}\n\n/**\n * Runtime tool instance contract used by Robota internals.\n *\n * Tools passed into Agent configuration must support EventService injection\n * so Robota can emit unified tool lifecycle events.\n */\nexport interface IToolWithEventService<TParameters = TToolParameters, TResult = IToolResult>\n extends IToolContract<TParameters, TResult> {\n setEventService(eventService: IEventService | undefined): void;\n}\n\n/**\n * Abstract base class for tools with type parameter support\n * Provides type-safe parameter handling and result processing\n *\n * 🎯 ARCHITECTURAL PRINCIPLES:\n * - Pure abstract class - depends only on interfaces\n * - No concrete class dependencies (EventService interface only)\n * - Dependency Injection for all external dependencies\n * - Graceful degradation (undefined dependencies = silent operation)\n *\n * @template TParameters - Tool parameters type (defaults to TToolParameters)\n * @template TResult - Tool result type (defaults to ToolResult for backward compatibility)\n */\nexport abstract class AbstractTool<TParameters = TToolParameters, TResult = IToolResult>\n implements IToolWithEventService<TParameters, TResult>\n{\n abstract readonly schema: IToolSchema;\n\n /**\n * Logger for tool operations\n */\n protected readonly logger: ILogger;\n\n /**\n * EventService for direct event emission (optional)\n * If undefined, tool operates silently without emitting events\n */\n private eventService: IEventService | undefined;\n\n /**\n * Constructor with simplified options\n *\n * 🎯 DEPENDENCY INJECTION:\n * All dependencies are injected via options parameter\n * No concrete classes are instantiated within this constructor\n *\n * @param options - Configuration options for the tool\n */\n constructor(options: IAbstractToolOptions = {}) {\n // Accept eventService as-is (no wrapping, no transformation)\n // Caller is responsible for providing properly configured EventService\n this.eventService = options.eventService;\n this.logger = options.logger ?? SilentLogger;\n }\n\n /**\n * Set EventService for post-construction injection\n *\n * 🎯 DEPENDENCY INJECTION:\n * Accepts EventService as-is without transformation\n * Caller is responsible for providing properly configured EventService\n *\n * @param eventService - EventService instance to use for event emission (or undefined for silent operation)\n */\n setEventService(eventService: IEventService | undefined): void {\n this.eventService = eventService;\n }\n\n /**\n * Get current EventService (for testing/inspection)\n */\n protected getEventService(): IEventService | undefined {\n return this.eventService;\n }\n\n /**\n * Emit event through EventService (if available)\n * If EventService is not available, silently ignores the event (Null Object Pattern)\n *\n * @param eventType - Type of event to emit\n * @param data - Event data\n */\n protected emitEvent(eventType: string, data: IBaseEventData): void {\n if (!this.eventService) {\n // Silent operation - no EventService available\n return;\n }\n this.eventService.emit(eventType, data);\n }\n\n /**\n * Execute tool with simplified lifecycle\n * @param parameters - Tool parameters\n * @param context - Optional execution context\n * @returns Promise resolving to tool result\n */\n async execute(parameters: TParameters, context: IToolExecutionContext): Promise<TResult> {\n return await this.executeImpl(parameters, context);\n }\n\n /**\n * Concrete implementation of tool execution\n * This method should be implemented by subclasses to provide actual tool logic\n *\n * @param parameters - Tool parameters\n * @param context - Optional execution context\n * @returns Promise resolving to tool result\n */\n protected abstract executeImpl(\n parameters: TParameters,\n context: IToolExecutionContext,\n ): Promise<TResult>;\n\n validate(parameters: TParameters): boolean {\n const required = this.schema.parameters.required || [];\n return required.every(\n (field) => field in (parameters as Record<string, string | number | boolean>),\n );\n }\n\n /**\n * Validate tool parameters with detailed result (default implementation)\n */\n validateParameters(parameters: TParameters): IParameterValidationResult {\n const required = this.schema.parameters.required || [];\n const errors: string[] = [];\n const paramObj = parameters as Record<string, string | number | boolean>;\n\n for (const field of required) {\n if (!(field in paramObj)) {\n errors.push(`Missing required parameter: ${field}`);\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n }\n\n getDescription(): string {\n return this.schema.description;\n }\n\n getName(): string {\n return this.schema.name;\n }\n}\n","import type { TUniversalMessage } from '../interfaces/messages';\nimport type { IUniversalObjectValue } from '../interfaces/types';\n\n/**\n * Provider message format type.\n *\n * Provider packages own concrete message shapes. Core only carries the generic\n * conversion hook and never branches on provider names.\n */\nexport type TProviderMessage = TUniversalMessage | IUniversalObjectValue;\n\nexport type TMessageFormatConverter<TMessage extends TProviderMessage = TProviderMessage> = (\n messages: readonly TUniversalMessage[],\n) => TMessage[];\n\nexport type TMessageConverterRegistry = Readonly<Record<string, TMessageFormatConverter>>;\n\n/**\n * Universal message converter utility\n *\n * The converter is registry-based so provider-specific message conversion is\n * injected by provider packages or callers instead of being hardcoded in core.\n */\nexport class MessageConverter {\n /**\n * Convert messages using an injected converter or converter registry.\n */\n static toProviderFormat(\n messages: TUniversalMessage[],\n converter?: TMessageFormatConverter | string,\n registry: TMessageConverterRegistry = {},\n ): TProviderMessage[] {\n if (typeof converter === 'function') {\n return converter(messages);\n }\n\n if (typeof converter === 'string') {\n const registeredConverter = registry[converter];\n if (registeredConverter !== undefined) {\n return registeredConverter(messages);\n }\n }\n\n return this.toUniversalFormat(messages);\n }\n\n /**\n * Convert to universal format (no conversion)\n */\n private static toUniversalFormat(messages: TUniversalMessage[]): TUniversalMessage[] {\n return messages;\n }\n\n /**\n * Extract system message from messages\n */\n static extractSystemMessage(messages: TUniversalMessage[]): string | undefined {\n const systemMsg = messages.find((msg) => msg.role === 'system');\n return systemMsg?.content;\n }\n\n /**\n * Filter non-system messages\n */\n static filterNonSystemMessages(messages: TUniversalMessage[]): TUniversalMessage[] {\n return messages.filter((msg) => msg.role !== 'system');\n }\n}\n","import type { IAgentConfig } from '../interfaces/agent';\n\nconst MAX_SYSTEM_MESSAGE_LENGTH = 1000;\nconst MAX_TOOLS_WARNING_THRESHOLD = 20;\nconst MAX_INPUT_LENGTH = 10000;\nconst MIN_API_KEY_LENGTH = 10;\n\n/**\n * Validation result interface\n */\nexport interface ISimpleValidationResult {\n isValid: boolean;\n errors: string[];\n warnings?: string[];\n}\n\n/**\n * Validation utility class\n */\nexport class Validator {\n /**\n * Validate agent configuration\n */\n static validateAgentConfig(config: Partial<IAgentConfig>): ISimpleValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Required fields validation for new API\n if (!config.name) {\n errors.push('name is required');\n }\n\n if (!config.aiProviders || config.aiProviders.length === 0) {\n errors.push('aiProviders array is required and must have at least one provider');\n }\n\n if (!config.defaultModel) {\n errors.push('defaultModel is required');\n } else {\n if (!config.defaultModel.provider) {\n errors.push('defaultModel.provider is required');\n }\n if (!config.defaultModel.model) {\n errors.push('defaultModel.model is required');\n }\n }\n\n // Provider validation\n if (config.aiProviders && config.defaultModel?.provider) {\n const providerNames = config.aiProviders.map((p) => p.name);\n if (!providerNames.includes(config.defaultModel.provider)) {\n errors.push(\n `defaultModel.provider \"${config.defaultModel.provider}\" is not found in aiProviders list`,\n );\n }\n }\n\n // Optional field validation for defaultModel\n if (config.defaultModel?.temperature !== undefined) {\n if (\n typeof config.defaultModel.temperature !== 'number' ||\n config.defaultModel.temperature < 0 ||\n config.defaultModel.temperature > 2\n ) {\n errors.push('defaultModel.temperature must be a number between 0 and 2');\n }\n }\n\n if (config.defaultModel?.maxTokens !== undefined) {\n if (typeof config.defaultModel.maxTokens !== 'number' || config.defaultModel.maxTokens <= 0) {\n errors.push('defaultModel.maxTokens must be a positive number');\n }\n }\n\n // Warnings for best practices\n if (config.systemMessage && config.systemMessage.length > MAX_SYSTEM_MESSAGE_LENGTH) {\n warnings.push(\n 'systemMessage is quite long, consider keeping it concise for better performance',\n );\n }\n\n if (config.tools && config.tools.length > MAX_TOOLS_WARNING_THRESHOLD) {\n warnings.push(\n 'Large number of tools may impact performance, consider grouping related tools',\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Validate user input string\n */\n static validateUserInput(input: string): ISimpleValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!input || typeof input !== 'string') {\n errors.push('Input must be a non-empty string');\n } else {\n if (input.trim().length === 0) {\n errors.push('Input cannot be only whitespace');\n }\n\n if (input.length > MAX_INPUT_LENGTH) {\n warnings.push('Very long input may be truncated by AI providers');\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Validate provider name\n */\n static validateProviderName(name: string): ISimpleValidationResult {\n const errors: string[] = [];\n\n if (!name || typeof name !== 'string') {\n errors.push('Provider name must be a non-empty string');\n } else {\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {\n errors.push(\n 'Provider name must start with a letter and contain only letters, numbers, underscores, and hyphens',\n );\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Validate model name\n */\n static validateModelName(name: string): ISimpleValidationResult {\n const errors: string[] = [];\n\n if (!name || typeof name !== 'string') {\n errors.push('Model name must be a non-empty string');\n } else {\n if (name.trim().length === 0) {\n errors.push('Model name cannot be only whitespace');\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Validate API key format (basic check)\n */\n static validateApiKey(apiKey: string): ISimpleValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!apiKey || typeof apiKey !== 'string') {\n errors.push('API key must be a non-empty string');\n return { isValid: false, errors };\n }\n\n // General security checks\n if (apiKey.length < MIN_API_KEY_LENGTH) {\n errors.push('API key appears to be too short');\n }\n\n if (/\\s/.test(apiKey)) {\n errors.push('API key should not contain whitespace');\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n }\n}\n\n// Standalone validation functions for convenience\nexport const validateAgentConfig = Validator.validateAgentConfig;\nexport const validateUserInput = Validator.validateUserInput;\nexport const validateProviderName = Validator.validateProviderName;\nexport const validateModelName = Validator.validateModelName;\nexport const validateApiKey = Validator.validateApiKey;\n","import type { ILogger } from './logger';\nimport type { TTimerId } from './index';\n\ninterface IPeriodicTaskOptions {\n name: string;\n intervalMs: number;\n}\n\n/**\n * Start a periodic async task with consistent error logging.\n * SSOT helper to avoid duplicating setInterval(async () => ...) patterns.\n */\nexport function startPeriodicTask(\n logger: ILogger,\n options: IPeriodicTaskOptions,\n task: () => Promise<void>,\n): TTimerId {\n const timer: TTimerId = setInterval(() => {\n void (async () => {\n try {\n await task();\n } catch (error) {\n logger.error('Periodic task failed', {\n task: options.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n })();\n }, options.intervalMs);\n\n return timer;\n}\n\nexport function stopPeriodicTask(timer: TTimerId | undefined): void {\n if (!timer) return;\n clearInterval(timer);\n}\n","/**\n * Message factory functions for conversation messages.\n *\n * Extracted from conversation-history-manager.ts.\n *\n * Note: Type guards live in interfaces/messages.ts (SSOT) and are NOT duplicated here.\n */\nimport { randomUUID } from 'node:crypto';\n\nimport type {\n IAssistantMessage,\n TUniversalMessageMetadata,\n ISystemMessage,\n IToolCall,\n IToolMessage,\n IUserMessage,\n TUniversalMessagePart,\n TMessageState,\n} from '../interfaces/messages';\n\n/** Create a user message. */\nexport function createUserMessage(\n content: string,\n options?: {\n name?: string;\n metadata?: TUniversalMessageMetadata;\n parts?: TUniversalMessagePart[];\n },\n): IUserMessage {\n const message: IUserMessage = {\n id: randomUUID(),\n role: 'user',\n content,\n state: 'complete',\n timestamp: new Date(),\n };\n if (options?.name) message.name = options.name;\n if (options?.metadata) message.metadata = options.metadata;\n if (options?.parts) message.parts = options.parts;\n return message;\n}\n\n/** Create an assistant message. */\nexport function createAssistantMessage(\n content: string | null,\n options?: {\n toolCalls?: IToolCall[];\n metadata?: TUniversalMessageMetadata;\n parts?: TUniversalMessagePart[];\n state?: TMessageState;\n },\n): IAssistantMessage {\n const message: IAssistantMessage = {\n id: randomUUID(),\n role: 'assistant',\n content,\n state: options?.state ?? 'complete',\n timestamp: new Date(),\n };\n if (options?.toolCalls) message.toolCalls = options.toolCalls;\n if (options?.metadata) message.metadata = options.metadata;\n if (options?.parts) message.parts = options.parts;\n return message;\n}\n\n/** Create a system message. */\nexport function createSystemMessage(\n content: string,\n options?: {\n name?: string;\n metadata?: TUniversalMessageMetadata;\n parts?: TUniversalMessagePart[];\n },\n): ISystemMessage {\n const message: ISystemMessage = {\n id: randomUUID(),\n role: 'system',\n content,\n state: 'complete',\n timestamp: new Date(),\n };\n if (options?.name) message.name = options.name;\n if (options?.metadata) message.metadata = options.metadata;\n if (options?.parts) message.parts = options.parts;\n return message;\n}\n\n/** Create a tool message. */\nexport function createToolMessage(\n content: string,\n options: {\n toolCallId: string;\n name?: string;\n metadata?: TUniversalMessageMetadata;\n parts?: TUniversalMessagePart[];\n },\n): IToolMessage {\n const message: IToolMessage = {\n id: randomUUID(),\n role: 'tool',\n content,\n toolCallId: options.toolCallId,\n state: 'complete',\n timestamp: new Date(),\n };\n if (options.name) message.name = options.name;\n if (options.metadata) message.metadata = options.metadata;\n if (options.parts) message.parts = options.parts;\n return message;\n}\n","/**\n * In-memory conversation history implementations.\n *\n * SimpleConversationHistory and PersistentSystemConversationHistory.\n */\nimport type {\n TUniversalMessageMetadata,\n TUniversalMessageRole,\n IToolCall,\n TUniversalMessage,\n TUniversalMessagePart,\n IHistoryEntry,\n} from '../interfaces/messages';\nimport {\n isSystemMessage,\n messageToHistoryEntry,\n chatEntryToMessage,\n isChatEntry,\n} from '../interfaces/messages';\nimport {\n createUserMessage,\n createAssistantMessage,\n createSystemMessage,\n createToolMessage,\n} from './conversation-message-factory';\nimport type { IConversationHistory } from './conversation-history-manager';\n\n/**\n * Default conversation history implementation.\n * In-memory storage with optional message count limiting.\n * @public\n */\nexport class SimpleConversationHistory implements IConversationHistory {\n protected readonly maxMessages: number;\n private entries: IHistoryEntry[] = [];\n\n constructor(options?: { maxMessages?: number }) {\n this.maxMessages = options?.maxMessages || 0;\n }\n\n /** Add a chat message (converted to IHistoryEntry internally) */\n addMessage(message: TUniversalMessage): void {\n this.entries.push(messageToHistoryEntry(message));\n this.applyMessageLimit();\n }\n\n /** Add a raw history entry (for events, etc.) */\n addEntry(entry: IHistoryEntry): void {\n this.entries.push(entry);\n }\n\n /** Get all history entries (universal timeline) */\n getHistory(): IHistoryEntry[] {\n return [...this.entries];\n }\n\n addUserMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.addMessage(\n createUserMessage(content, { ...(metadata && { metadata }), ...(parts && { parts }) }),\n );\n }\n\n addAssistantMessage(\n content: string | null,\n toolCalls?: IToolCall[],\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.addMessage(\n createAssistantMessage(content, {\n ...(toolCalls && { toolCalls }),\n ...(metadata && { metadata }),\n ...(parts && { parts }),\n }),\n );\n }\n\n addSystemMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.addMessage(\n createSystemMessage(content, { ...(metadata && { metadata }), ...(parts && { parts }) }),\n );\n }\n\n addToolMessageWithId(\n content: string,\n toolCallId: string,\n toolName: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.addMessage(\n createToolMessage(content, {\n toolCallId,\n name: toolName,\n ...(metadata && { metadata }),\n ...(parts && { parts }),\n }),\n );\n }\n\n /** Get chat messages only (backward compatible) */\n getMessages(): TUniversalMessage[] {\n return this.entries.filter(isChatEntry).map(chatEntryToMessage);\n }\n getMessagesByRole(role: TUniversalMessageRole): TUniversalMessage[] {\n return this.getMessages().filter((m) => m.role === role);\n }\n getRecentMessages(count: number): TUniversalMessage[] {\n return this.getMessages().slice(-count);\n }\n getMessageCount(): number {\n return this.entries.filter(isChatEntry).length;\n }\n clear(): void {\n this.entries = [];\n }\n\n /** @internal — limits chat entries only, preserves event entries */\n protected applyMessageLimit(): void {\n if (this.maxMessages <= 0) return;\n const chatEntries = this.entries.filter(isChatEntry);\n if (chatEntries.length <= this.maxMessages) return;\n\n const chatMessages = chatEntries.map(chatEntryToMessage);\n const systemMessages = chatMessages.filter(isSystemMessage);\n const nonSystem = chatMessages.filter((msg) => !isSystemMessage(msg));\n const available = Math.max(0, this.maxMessages - systemMessages.length);\n const keepMessages = [...systemMessages, ...nonSystem.slice(-available)];\n const keepIds = new Set(keepMessages.map((m) => m.id));\n\n // Keep all event entries + kept chat entries\n this.entries = this.entries.filter((e) => !isChatEntry(e) || keepIds.has(e.id));\n }\n}\n\n/**\n * Conversation history with persistent system prompt.\n * @public\n */\nexport class PersistentSystemConversationHistory implements IConversationHistory {\n private readonly history: SimpleConversationHistory;\n private systemPrompt: string;\n\n constructor(systemPrompt: string, options?: { maxMessages?: number }) {\n this.systemPrompt = systemPrompt;\n this.history = new SimpleConversationHistory(options);\n this.history.addSystemMessage(this.systemPrompt);\n }\n\n addMessage(message: TUniversalMessage): void {\n this.history.addMessage(message);\n }\n addUserMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addUserMessage(content, metadata, parts);\n }\n addAssistantMessage(\n content: string | null,\n toolCalls?: IToolCall[],\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addAssistantMessage(content, toolCalls, metadata, parts);\n }\n addSystemMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addSystemMessage(content, metadata, parts);\n }\n addToolMessageWithId(\n content: string,\n toolCallId: string,\n toolName: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addToolMessageWithId(content, toolCallId, toolName, metadata, parts);\n }\n addEntry(entry: IHistoryEntry): void {\n this.history.addEntry(entry);\n }\n getHistory(): IHistoryEntry[] {\n return this.history.getHistory();\n }\n getMessages(): TUniversalMessage[] {\n return this.history.getMessages();\n }\n getMessagesByRole(role: TUniversalMessageRole): TUniversalMessage[] {\n return this.history.getMessagesByRole(role);\n }\n getRecentMessages(count: number): TUniversalMessage[] {\n return this.history.getRecentMessages(count);\n }\n getMessageCount(): number {\n return this.history.getMessageCount();\n }\n\n clear(): void {\n this.history.clear();\n this.history.addSystemMessage(this.systemPrompt);\n }\n\n updateSystemPrompt(systemPrompt: string): void {\n this.systemPrompt = systemPrompt;\n const nonSystem = this.history.getMessages().filter((msg) => !isSystemMessage(msg));\n this.history.clear();\n this.history.addSystemMessage(this.systemPrompt);\n nonSystem.forEach((message) => this.history.addMessage(message));\n }\n\n getSystemPrompt(): string {\n return this.systemPrompt;\n }\n}\n","/**\n * ConversationStore — streaming state management and API format conversion.\n *\n * In-memory history classes live in ./conversation-store-history.ts.\n */\nimport { randomUUID } from 'node:crypto';\nimport type {\n TUniversalMessageMetadata,\n TUniversalMessageRole,\n IToolCall,\n TUniversalMessage,\n TUniversalMessagePart,\n IAssistantMessage,\n IHistoryEntry,\n TMessageState,\n} from '../interfaces/messages';\nimport { isAssistantMessage, isToolMessage } from '../interfaces/messages';\nimport type { IConversationHistory } from './conversation-history-manager';\nimport { SimpleConversationHistory } from './conversation-store-history';\n\n/** API message format for provider consumption */\nexport interface IProviderApiMessage {\n role: string;\n content: string | null;\n tool_calls?: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }>;\n tool_call_id?: string;\n}\n\n/** State of an in-progress assistant response being streamed */\ninterface IStreamingState {\n id: string;\n content: string;\n toolCalls: IToolCall[];\n}\n\n/**\n * Conversation store with duplicate prevention and API format conversion.\n * @public\n */\nexport class ConversationStore implements IConversationHistory {\n private history: SimpleConversationHistory;\n private pendingAssistant: IStreamingState | null = null;\n\n constructor(maxMessages: number = 100) {\n this.history = new SimpleConversationHistory({ maxMessages });\n }\n\n addMessage(message: TUniversalMessage): void {\n this.history.addMessage(message);\n }\n addUserMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addUserMessage(content, metadata, parts);\n }\n addAssistantMessage(\n content: string | null,\n toolCalls?: IToolCall[],\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addAssistantMessage(content, toolCalls, metadata, parts);\n }\n addSystemMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addSystemMessage(content, metadata, parts);\n }\n\n addToolMessage(\n content: string,\n toolCallId: string,\n toolName?: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addToolMessageWithId(content, toolCallId, toolName || 'unknown', metadata, parts);\n }\n\n addToolMessageWithId(\n content: string,\n toolCallId: string,\n toolName: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void {\n this.history.addToolMessageWithId(content, toolCallId, toolName, metadata, parts);\n }\n\n /** Add a raw history entry (events, etc.) */\n addEntry(entry: IHistoryEntry): void {\n this.history.addEntry(entry);\n }\n\n /** Get all history entries (universal timeline) */\n getHistory(): IHistoryEntry[] {\n return this.history.getHistory();\n }\n\n getMessages(): TUniversalMessage[] {\n return this.history.getMessages();\n }\n getMessagesByRole(role: TUniversalMessageRole): TUniversalMessage[] {\n return this.history.getMessagesByRole(role);\n }\n getRecentMessages(count: number): TUniversalMessage[] {\n return this.history.getRecentMessages(count);\n }\n getMessageCount(): number {\n return this.history.getMessageCount();\n }\n\n /** Begin a new assistant response. Must be called before provider call.\n * Ensures pendingAssistant exists so commitAssistant always has data to save. */\n beginAssistant(): void {\n if (!this.pendingAssistant) {\n this.pendingAssistant = {\n id: randomUUID(),\n content: '',\n toolCalls: [],\n };\n }\n }\n\n /** Append streaming text delta to pending assistant response */\n appendStreaming(delta: string): void {\n if (!this.pendingAssistant) {\n this.pendingAssistant = {\n id: randomUUID(),\n content: '',\n toolCalls: [],\n };\n }\n this.pendingAssistant.content += delta;\n }\n\n /** Append a tool call to pending assistant response (deduplicates by id) */\n appendToolCall(toolCall: IToolCall): void {\n if (!this.pendingAssistant) {\n this.pendingAssistant = {\n id: randomUUID(),\n content: '',\n toolCalls: [],\n };\n }\n if (!this.pendingAssistant.toolCalls.some((tc) => tc.id === toolCall.id)) {\n this.pendingAssistant.toolCalls.push(toolCall);\n }\n }\n\n /**\n * Commit pending assistant response to history.\n * Precondition: beginAssistant() must have been called before the provider call.\n * History is append-only — this always adds a message.\n */\n commitAssistant(state: TMessageState, metadata?: TUniversalMessageMetadata): void {\n if (!this.pendingAssistant) return; // No pending state — error paths use addAssistantMessage directly\n const pending = this.pendingAssistant;\n const hasToolCalls = pending.toolCalls.length > 0;\n // History records everything — text is always preserved.\n // Context savings is compaction's responsibility, not history's.\n const content = pending.content;\n const message: IAssistantMessage = {\n id: pending.id,\n role: 'assistant',\n content,\n state,\n timestamp: new Date(),\n ...(hasToolCalls && { toolCalls: pending.toolCalls }),\n ...(metadata && { metadata }),\n };\n this.history.addMessage(message);\n this.pendingAssistant = null;\n }\n\n /** Discard pending assistant response without saving */\n discardPending(): void {\n this.pendingAssistant = null;\n }\n\n /** Returns true if there is accumulated pending assistant state (streaming or tool calls) */\n hasPendingAssistant(): boolean {\n return this.pendingAssistant !== null;\n }\n\n /** Get pending assistant content (empty string if no content streamed yet) */\n getPendingContent(): string {\n return this.pendingAssistant?.content ?? '';\n }\n\n getMessagesForAPI(): IProviderApiMessage[] {\n return this.history.getMessages().map((msg) => {\n const apiMsg: IProviderApiMessage = { role: msg.role, content: msg.content };\n // Annotate interrupted assistant messages for model awareness\n if (isAssistantMessage(msg) && msg.state === 'interrupted') {\n apiMsg.content = (apiMsg.content || '') + '\\n\\n[This response was interrupted by the user]';\n }\n if (isAssistantMessage(msg) && msg.toolCalls) {\n apiMsg.tool_calls = msg.toolCalls;\n }\n if (isToolMessage(msg)) {\n apiMsg.tool_call_id = msg.toolCallId;\n }\n return apiMsg;\n });\n }\n\n clear(): void {\n this.history.clear();\n }\n}\n","/**\n * Multi-session conversation history manager.\n *\n * Message factories live in ./conversation-message-factory.ts.\n * Store implementations live in ./conversation-store.ts.\n */\nimport { createLogger, type ILogger } from '../utils/logger';\nimport type {\n TUniversalMessageMetadata,\n TUniversalMessageRole,\n IToolCall,\n TUniversalMessage,\n TUniversalMessagePart,\n IHistoryEntry,\n} from '../interfaces/messages';\n\n// Re-export type guards from interfaces (SSOT)\nexport {\n isUserMessage,\n isAssistantMessage,\n isSystemMessage,\n isToolMessage,\n} from '../interfaces/messages';\n\n// Re-export factory functions from conversation-message-factory\nexport {\n createUserMessage,\n createAssistantMessage,\n createSystemMessage,\n createToolMessage,\n} from './conversation-message-factory';\n\nexport {\n SimpleConversationHistory,\n PersistentSystemConversationHistory,\n} from './conversation-store-history';\n\nexport { ConversationStore } from './conversation-store';\n\nexport type { IProviderApiMessage } from './conversation-store';\n\nimport { ConversationStore } from './conversation-store';\n\nconst DEFAULT_MAX_MESSAGES_PER_CONVERSATION = 100;\nconst DEFAULT_MAX_CONVERSATIONS = 50;\n\n/** Interface for managing conversation history. @public */\nexport interface IConversationHistory {\n addMessage(message: TUniversalMessage): void;\n addUserMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void;\n addAssistantMessage(\n content: string | null,\n toolCalls?: IToolCall[],\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void;\n addSystemMessage(\n content: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void;\n addToolMessageWithId(\n content: string,\n toolCallId: string,\n toolName: string,\n metadata?: TUniversalMessageMetadata,\n parts?: TUniversalMessagePart[],\n ): void;\n addEntry(entry: IHistoryEntry): void;\n getHistory(): IHistoryEntry[];\n getMessages(): TUniversalMessage[];\n getMessagesByRole(role: TUniversalMessageRole): TUniversalMessage[];\n getRecentMessages(count: number): TUniversalMessage[];\n clear(): void;\n getMessageCount(): number;\n}\n\n/** Configuration options for ConversationHistory manager */\nexport interface IConversationHistoryOptions {\n maxMessagesPerConversation?: number;\n maxConversations?: number;\n}\n\n/** Multi-session conversation history manager. @public */\nexport class ConversationHistory {\n private conversations = new Map<string, ConversationStore>();\n private logger: ILogger;\n private readonly maxMessagesPerConversation: number;\n private readonly maxConversations: number;\n\n constructor(options: IConversationHistoryOptions = {}) {\n this.maxMessagesPerConversation =\n options.maxMessagesPerConversation || DEFAULT_MAX_MESSAGES_PER_CONVERSATION;\n this.maxConversations = options.maxConversations || DEFAULT_MAX_CONVERSATIONS;\n this.logger = createLogger('ConversationHistory');\n }\n\n getConversationStore(conversationId: string): ConversationStore {\n if (!this.conversations.has(conversationId)) {\n if (this.conversations.size >= this.maxConversations) this.cleanupOldConversations();\n this.conversations.set(\n conversationId,\n new ConversationStore(this.maxMessagesPerConversation),\n );\n }\n return this.conversations.get(conversationId)!;\n }\n\n hasConversation(conversationId: string): boolean {\n return this.conversations.has(conversationId);\n }\n\n removeConversation(conversationId: string): boolean {\n const removed = this.conversations.delete(conversationId);\n if (removed) this.logger.debug('Removed conversation', { conversationId });\n return removed;\n }\n\n clearAll(): void {\n const count = this.conversations.size;\n this.conversations.clear();\n this.logger.debug('Cleared all conversations', { removedCount: count });\n }\n\n getStats(): { totalConversations: number; conversationIds: string[]; totalMessages: number } {\n const conversationIds = Array.from(this.conversations.keys());\n const totalMessages = Array.from(this.conversations.values()).reduce(\n (sum, s) => sum + s.getMessageCount(),\n 0,\n );\n return { totalConversations: this.conversations.size, conversationIds, totalMessages };\n }\n\n /** @internal */\n private cleanupOldConversations(): void {\n if (this.conversations.size === 0) return;\n const firstKey = this.conversations.keys().next().value;\n if (firstKey) this.conversations.delete(firstKey);\n }\n}\n","import type {\n IChatExecutionRequest,\n IStreamExecutionRequest,\n ILocalExecutorConfig,\n} from '../interfaces/executor';\nimport type { TUniversalMessage, IAssistantMessage } from '../interfaces/messages';\nimport type { IChatOptions } from '../interfaces/provider';\nimport { AbstractExecutor } from '../abstracts/abstract-executor';\n\n/**\n * Local executor that directly delegates to AI provider instances\n *\n * This executor maintains a registry of AI provider instances and delegates\n * chat execution requests to the appropriate provider based on the provider\n * name in the request. This is the \"traditional\" execution mode where\n * API calls are made directly from the client.\n *\n * @example\n * ```typescript\n * import { LocalExecutor } from '@robota-sdk/agent-core';\n * import { OpenAIProvider } from '@robota-sdk/agent-provider/openai';\n *\n * const executor = new LocalExecutor();\n * executor.registerProvider('openai', new OpenAIProvider({ apiKey: 'sk-...' }));\n *\n * const response = await executor.executeChat({\n * messages: [{ role: 'user', content: 'Hello!' }],\n * provider: 'openai',\n * model: 'gpt-4'\n * });\n * ```\n */\nexport class LocalExecutor extends AbstractExecutor {\n readonly name = 'local';\n readonly version = '1.0.0';\n\n private providers = new Map<string, IAIProviderInstance>();\n private config: Required<ILocalExecutorConfig>;\n\n constructor(config: ILocalExecutorConfig = {}) {\n super();\n this.config = {\n timeout: 30000,\n maxRetries: 3,\n retryDelay: 1000,\n enableLogging: false,\n ...config,\n };\n }\n\n /**\n * Register an AI provider instance for use with this executor\n *\n * @param name - Provider name (e.g., 'openai', 'anthropic', 'google')\n * @param provider - Provider instance that implements the required chat methods\n */\n registerProvider(name: string, provider: IAIProviderInstance): void {\n this.providers.set(name, provider);\n }\n\n /**\n * Unregister an AI provider\n *\n * @param name - Provider name to remove\n */\n unregisterProvider(name: string): void {\n this.providers.delete(name);\n }\n\n /**\n * Get registered provider instance\n *\n * @param name - Provider name\n * @returns Provider instance or undefined if not registered\n */\n getProvider(name: string): IAIProviderInstance | undefined {\n return this.providers.get(name);\n }\n\n /**\n * Execute a chat completion request by delegating to the appropriate provider\n */\n async executeChat(request: IChatExecutionRequest): Promise<IAssistantMessage> {\n this.validateRequest(request);\n\n const provider = this.providers.get(request.provider);\n if (!provider) {\n throw new Error(`Provider \"${request.provider}\" not registered with LocalExecutor`);\n }\n\n if (!provider.chat) {\n throw new Error(`Provider \"${request.provider}\" does not implement chat method`);\n }\n\n if (this.config.enableLogging) {\n this.logDebug(`Executing chat with provider: ${request.provider}, model: ${request.model}`);\n }\n\n try {\n // Delegate to provider's chat method with retry logic\n const response = await this.withRetry(\n async () => {\n return await this.withTimeout(\n provider.chat!(request.messages, {\n ...request.options,\n model: request.model,\n tools: request.tools,\n }),\n this.config.timeout,\n );\n },\n this.config.maxRetries,\n this.config.retryDelay,\n );\n\n // Ensure response is properly typed as AssistantMessage\n if (response.role !== 'assistant') {\n throw new Error(`Expected assistant message, got ${response.role}`);\n }\n\n this.validateResponse(response);\n return response as IAssistantMessage;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logError('Chat execution failed', err, {\n provider: request.provider,\n model: request.model,\n });\n throw err;\n }\n }\n\n /**\n * Execute a streaming chat completion request\n */\n async *executeChatStream(request: IStreamExecutionRequest): AsyncIterable<TUniversalMessage> {\n this.validateRequest(request);\n\n const provider = this.providers.get(request.provider);\n if (!provider) {\n throw new Error(`Provider \"${request.provider}\" not registered with LocalExecutor`);\n }\n\n if (!provider.chatStream) {\n throw new Error(`Provider \"${request.provider}\" does not implement chatStream method`);\n }\n\n if (this.config.enableLogging) {\n this.logDebug(\n `Executing streaming chat with provider: ${request.provider}, model: ${request.model}`,\n );\n }\n\n try {\n // Delegate to provider's chatStream method\n const stream = provider.chatStream(request.messages, {\n ...request.options,\n model: request.model,\n tools: request.tools,\n });\n\n for await (const chunk of stream) {\n this.validateResponse(chunk);\n yield chunk;\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logError('Streaming chat execution failed', err, {\n provider: request.provider,\n model: request.model,\n });\n throw err;\n }\n }\n\n /**\n * Check if any registered providers support tools\n */\n override supportsTools(): boolean {\n for (const provider of this.providers.values()) {\n if (provider.supportsTools && provider.supportsTools()) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Validate executor configuration and all registered providers\n */\n override validateConfig(): boolean {\n try {\n // Validate executor config\n if (this.config.timeout <= 0) {\n return false;\n }\n if (this.config.maxRetries < 0) {\n return false;\n }\n if (this.config.retryDelay < 0) {\n return false;\n }\n\n // Validate all registered providers\n for (const provider of this.providers.values()) {\n if (provider.validateConfig && !provider.validateConfig()) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Clean up all registered providers\n */\n override async dispose(): Promise<void> {\n if (this.config.enableLogging) {\n this.logDebug(`Disposing ${this.providers.size} providers`);\n }\n\n const disposePromises: Promise<void>[] = [];\n\n for (const provider of this.providers.values()) {\n if (provider.dispose) {\n disposePromises.push(provider.dispose());\n }\n }\n\n await Promise.all(disposePromises);\n this.providers.clear();\n }\n}\n\n/**\n * Interface that AI provider instances must implement to work with LocalExecutor\n *\n * This interface represents the subset of AI provider methods that LocalExecutor\n * needs to delegate to. It's designed to be compatible with existing BaseAIProvider\n * implementations from @robota-sdk packages.\n */\nexport interface IAIProviderInstance {\n /** Provider name */\n readonly name?: string;\n\n /** Chat completion method */\n chat?(messages: TUniversalMessage[], options?: IChatOptions): Promise<TUniversalMessage>;\n\n /** Streaming chat completion method */\n chatStream?(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage>;\n\n /** Check if provider supports tools */\n supportsTools?(): boolean;\n\n /** Validate provider configuration */\n validateConfig?(): boolean;\n\n /** Clean up provider resources */\n dispose?(): Promise<void>;\n}\n","export const ENV_REFERENCE_PREFIX = '$ENV:';\n\nexport function isEnvReference(value: string): boolean {\n return value.startsWith(ENV_REFERENCE_PREFIX);\n}\n\nexport function formatEnvReference(name: string): string {\n return `${ENV_REFERENCE_PREFIX}${name}`;\n}\n\nexport function resolveEnvReference(value: string): string | undefined {\n if (!isEnvReference(value)) {\n return value;\n }\n const envName = value.slice(ENV_REFERENCE_PREFIX.length).trim();\n if (envName.length === 0) {\n return undefined;\n }\n return process.env[envName];\n}\n\nexport function hasUsableSecretReference(value: string | undefined): boolean {\n if (value === undefined || value.length === 0) {\n return false;\n }\n return resolveEnvReference(value) !== undefined;\n}\n","export interface IEventEmitterMetricsSnapshot {\n totalEmitted: number;\n totalErrors: number;\n}\n\nexport interface IEventEmitterMetrics {\n incrementEmitted(): void;\n incrementErrors(): void;\n getSnapshot(): IEventEmitterMetricsSnapshot;\n}\n\nexport class InMemoryEventEmitterMetrics implements IEventEmitterMetrics {\n private totalEmitted = 0;\n private totalErrors = 0;\n\n incrementEmitted(): void {\n this.totalEmitted += 1;\n }\n\n incrementErrors(): void {\n this.totalErrors += 1;\n }\n\n getSnapshot(): IEventEmitterMetricsSnapshot {\n return {\n totalEmitted: this.totalEmitted,\n totalErrors: this.totalErrors,\n };\n }\n}\n","/**\n * Helper functions for EventEmitterPlugin.\n *\n * Extracted from plugins/event-emitter-plugin.ts to keep that file under 300 lines.\n * Contains validation logic, event processing, and stats computation.\n */\nimport { PluginError } from '../utils/errors';\nimport type { ILogger } from '../utils/logger';\nimport type {\n IEventEmitterEventData,\n TEventDataValue,\n TEventName,\n TEventEmitterListener,\n} from './event-emitter/types';\nimport type {\n IEventEmitterHandlerRegistration,\n IEventEmitterPluginOptions,\n IEventEmitterPluginStats,\n} from './event-emitter/plugin-types';\nimport type { IEventEmitterMetrics } from './event-emitter/metrics';\n\n/**\n * Validate EventEmitterPlugin constructor options.\n * Throws PluginError if any value is out of range.\n */\nexport function validateEventEmitterOptions(\n options: IEventEmitterPluginOptions,\n pluginName: string,\n): void {\n if (options.maxListeners !== undefined && options.maxListeners < 0)\n throw new PluginError(\n `Invalid maxListeners option: ${options.maxListeners}. Must be a non-negative number.`,\n pluginName,\n { maxListeners: options.maxListeners },\n );\n if (\n options.buffer !== undefined &&\n options.buffer.maxSize !== undefined &&\n options.buffer.maxSize < 0\n )\n throw new PluginError(\n `Invalid buffer.maxSize option: ${options.buffer.maxSize}. Must be a non-negative number.`,\n pluginName,\n { bufferMaxSize: options.buffer.maxSize },\n );\n if (\n options.buffer !== undefined &&\n options.buffer.flushInterval !== undefined &&\n options.buffer.flushInterval < 0\n )\n throw new PluginError(\n `Invalid buffer.flushInterval option: ${options.buffer.flushInterval}. Must be a non-negative number.`,\n pluginName,\n { bufferFlushInterval: options.buffer.flushInterval },\n );\n}\n\n/**\n * Execute a single registered event handler, catching errors via metrics.\n */\nexport async function executeEventHandler(\n handler: IEventEmitterHandlerRegistration,\n event: IEventEmitterEventData,\n metrics: IEventEmitterMetrics,\n catchErrors: boolean,\n logger: ILogger,\n): Promise<void> {\n try {\n await handler.listener(event);\n } catch (error) {\n metrics.incrementErrors();\n if (catchErrors) {\n logger.error('Event handler error', {\n eventType: event.type,\n handlerId: handler.id,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n throw error instanceof Error ? error : new Error(String(error));\n }\n}\n\n/**\n * Process a single event by dispatching it to matching registered handlers.\n * Handles once-only removal and async vs sequential dispatch.\n */\nexport async function processEvent(\n event: IEventEmitterEventData,\n handlers: Map<TEventName, IEventEmitterHandlerRegistration[]>,\n asyncMode: boolean,\n offFn: (eventType: TEventName, id: string) => void,\n execHandler: (\n handler: IEventEmitterHandlerRegistration,\n event: IEventEmitterEventData,\n ) => Promise<void>,\n): Promise<void> {\n const eventHandlers = handlers.get(event.type);\n if (!eventHandlers || eventHandlers.length === 0) return;\n const handlersToCall = eventHandlers.filter((h) => !h.filter || h.filter(event));\n if (handlersToCall.length === 0) return;\n for (const h of handlersToCall.filter((h) => h.once)) offFn(event.type, h.id);\n if (asyncMode) {\n await Promise.all(handlersToCall.map((h) => execHandler(h, event)));\n return;\n }\n for (const h of handlersToCall) await execHandler(h, event);\n}\n\n/**\n * Compute the listener-count stats portion of EventEmitterPlugin.getStats().\n */\nexport function computeListenerStats(\n handlers: Map<TEventName, IEventEmitterHandlerRegistration[]>,\n): { listenerCounts: Partial<Record<TEventName, number>>; totalListeners: number } {\n const listenerCounts: Partial<Record<TEventName, number>> = {};\n let totalListeners = 0;\n for (const [eventType, hs] of handlers) {\n listenerCounts[eventType] = hs.length;\n totalListeners += hs.length;\n }\n return { listenerCounts, totalListeners };\n}\n\n/**\n * Build the full IEventEmitterPluginStats object.\n */\nexport function buildEventEmitterStats(\n base: Omit<\n IEventEmitterPluginStats,\n | 'eventTypes'\n | 'listenerCounts'\n | 'totalListeners'\n | 'bufferedEvents'\n | 'totalEmitted'\n | 'totalErrors'\n >,\n handlers: Map<TEventName, IEventEmitterHandlerRegistration[]>,\n bufferedEvents: number,\n metrics: IEventEmitterMetrics,\n): IEventEmitterPluginStats {\n const { listenerCounts, totalListeners } = computeListenerStats(handlers);\n const metricsSnapshot = metrics.getSnapshot();\n const enabled = base.enabled as boolean;\n const calls = base.calls as number;\n const errors = base.errors as number;\n return {\n enabled,\n calls,\n errors,\n eventTypes: Array.from(handlers.keys()),\n listenerCounts,\n totalListeners,\n bufferedEvents,\n totalEmitted: metricsSnapshot.totalEmitted,\n totalErrors: metricsSnapshot.totalErrors,\n };\n}\n\n/** Register a handler in the handlers map, enforcing max listeners. */\nexport function registerHandler(\n handlers: Map<TEventName, IEventEmitterHandlerRegistration[]>,\n eventType: TEventName,\n handlerId: string,\n listener: TEventEmitterListener,\n options: { once?: boolean; filter?: (event: IEventEmitterEventData) => boolean } | undefined,\n maxListeners: number,\n pluginName: string,\n): void {\n if (!handlers.has(eventType)) handlers.set(eventType, []);\n const hs = handlers.get(eventType)!;\n if (hs.length >= maxListeners) {\n throw new PluginError(\n `Maximum listeners (${maxListeners}) exceeded for event type: ${eventType}`,\n pluginName,\n { eventType, currentListeners: hs.length },\n );\n }\n hs.push({\n id: handlerId,\n listener,\n once: options?.once ?? false,\n ...(options?.filter && { filter: options.filter }),\n });\n}\n\n/** Remove a handler by id or listener reference. Returns true if removed. */\nexport function unregisterHandler(\n handlers: Map<TEventName, IEventEmitterHandlerRegistration[]>,\n eventType: TEventName,\n handlerIdOrListener: string | TEventEmitterListener,\n): boolean {\n const hs = handlers.get(eventType);\n if (!hs) return false;\n const index =\n typeof handlerIdOrListener === 'string'\n ? hs.findIndex((h) => h.id === handlerIdOrListener)\n : hs.findIndex((h) => h.listener === handlerIdOrListener);\n if (index !== -1) {\n hs.splice(index, 1);\n return true;\n }\n return false;\n}\n\nexport function buildToolCallEmitData(\n context: { executionId?: string; sessionId?: string; userId?: string },\n toolCall: { name?: string; id?: string; result?: string | number | boolean | null },\n duration: number | undefined,\n): Partial<IEventEmitterEventData> {\n const hasResult = toolCall.result !== null && toolCall.result !== undefined;\n return {\n executionId: context.executionId,\n sessionId: context.sessionId,\n userId: context.userId,\n data: {\n toolName: toolCall.name || '',\n toolId: toolCall.id || '',\n toolResult: hasResult ? String(toolCall.result) : undefined,\n duration: duration as TEventDataValue,\n success: hasResult,\n },\n };\n}\n","import {\n AbstractPlugin,\n type IPluginExecutionContext,\n type IPluginExecutionResult,\n type IPluginErrorContext,\n PluginCategory,\n PluginPriority,\n} from '../abstracts/abstract-plugin';\nimport type { IToolExecutionContext } from '../interfaces/tool';\nimport { createLogger, type ILogger } from '../utils/logger';\nimport type { TTimerId } from '../utils';\nimport {\n EVENT_EMITTER_EVENTS,\n type IEventEmitterEventData,\n type TEventDataValue,\n type TEventName,\n type TEventEmitterListener,\n} from './event-emitter/types';\nimport { InMemoryEventEmitterMetrics, type IEventEmitterMetrics } from './event-emitter/metrics';\nimport type {\n IEventEmitterHandlerRegistration,\n IEventEmitterPluginOptions,\n IEventEmitterPluginStats,\n} from './event-emitter/plugin-types';\nimport {\n validateEventEmitterOptions,\n executeEventHandler,\n processEvent as processEventHelper,\n buildEventEmitterStats,\n registerHandler,\n unregisterHandler,\n buildToolCallEmitData,\n} from './event-emitter-helpers';\n\n// Re-export types that were originally exported from this file\nexport type { TEventName };\nexport type {\n TEventExecutionValue,\n IEventExecutionContextData,\n TEventEmitterMetadata,\n IEventEmitterPluginExecutionContext,\n IEventEmitterPluginExecutionResult,\n IEventEmitterHierarchicalEventData,\n IEventEmitterPluginOptions,\n IEventEmitterPluginStats,\n} from './event-emitter/plugin-types';\nexport type { IEventEmitterEventData, TEventEmitterListener };\n\nconst DEFAULT_MAX_LISTENERS = 100;\n\n/** Provides pub/sub event coordination during the agent execution lifecycle. */\nexport class EventEmitterPlugin extends AbstractPlugin<\n IEventEmitterPluginOptions,\n IEventEmitterPluginStats\n> {\n name = 'EventEmitterPlugin';\n version = '1.0.0';\n\n private pluginOptions: Required<Omit<IEventEmitterPluginOptions, 'metrics'>>;\n private logger: ILogger;\n private handlers = new Map<TEventName, IEventEmitterHandlerRegistration[]>();\n private eventBuffer: IEventEmitterEventData[] = [];\n private nextHandlerId = 1;\n private bufferTimer?: TTimerId;\n private metrics: IEventEmitterMetrics;\n\n constructor(options: IEventEmitterPluginOptions = {}) {\n super();\n this.logger = createLogger('EventEmitterPlugin');\n this.metrics = options.metrics ?? new InMemoryEventEmitterMetrics();\n validateEventEmitterOptions(options, this.name);\n\n this.pluginOptions = {\n enabled: options.enabled ?? true,\n events: options.events ?? [\n EVENT_EMITTER_EVENTS.AGENT_EXECUTION_START,\n EVENT_EMITTER_EVENTS.AGENT_EXECUTION_COMPLETE,\n EVENT_EMITTER_EVENTS.AGENT_EXECUTION_ERROR,\n EVENT_EMITTER_EVENTS.TOOL_BEFORE_EXECUTE,\n EVENT_EMITTER_EVENTS.TOOL_AFTER_EXECUTE,\n EVENT_EMITTER_EVENTS.TOOL_SUCCESS,\n EVENT_EMITTER_EVENTS.TOOL_ERROR,\n ],\n maxListeners: options.maxListeners ?? DEFAULT_MAX_LISTENERS,\n async: options.async ?? true,\n catchErrors: options.catchErrors ?? true,\n filters:\n options.filters ?? ({} as Record<TEventName, (event: IEventEmitterEventData) => boolean>),\n buffer: options.buffer ?? { enabled: false, maxSize: 1000, flushInterval: 5000 },\n category: options.category ?? PluginCategory.EVENT_PROCESSING,\n priority: options.priority ?? PluginPriority.HIGH,\n moduleEvents: options.moduleEvents ?? [],\n subscribeToAllModuleEvents: options.subscribeToAllModuleEvents ?? false,\n };\n\n if (this.pluginOptions.buffer.enabled) {\n this.bufferTimer = setInterval(() => {\n this.flushBuffer();\n }, this.pluginOptions.buffer.flushInterval);\n }\n }\n\n override async beforeExecution(context: IPluginExecutionContext): Promise<void> {\n await this.emit(EVENT_EMITTER_EVENTS.AGENT_EXECUTION_START, {\n executionId: context.executionId,\n sessionId: context.sessionId,\n userId: context.userId,\n data: {\n messageCount: context.messages?.length || 0,\n ...(context.config && { config: context.config }),\n },\n });\n }\n\n override async afterExecution(\n context: IPluginExecutionContext,\n result: IPluginExecutionResult,\n ): Promise<void> {\n await this.emit(EVENT_EMITTER_EVENTS.AGENT_EXECUTION_COMPLETE, {\n executionId: context.executionId,\n sessionId: context.sessionId,\n userId: context.userId,\n data: {\n duration: result?.duration,\n tokensUsed: result?.tokensUsed,\n toolsExecuted: result?.toolsExecuted,\n },\n });\n }\n\n override async beforeConversation(context: IPluginExecutionContext): Promise<void> {\n await this.emit(EVENT_EMITTER_EVENTS.CONVERSATION_START, {\n executionId: context.executionId,\n sessionId: context.sessionId,\n userId: context.userId,\n data: {\n messages: context.messages?.map((msg) => ({\n role: msg.role,\n content: msg.content || '',\n timestamp: msg.timestamp ? msg.timestamp.toISOString() : new Date().toISOString(),\n })),\n config: context.config as Record<string, TEventDataValue>,\n },\n });\n }\n\n override async afterConversation(\n context: IPluginExecutionContext,\n result: IPluginExecutionResult,\n ): Promise<void> {\n await this.emit(EVENT_EMITTER_EVENTS.CONVERSATION_COMPLETE, {\n executionId: context.executionId,\n sessionId: context.sessionId,\n userId: context.userId,\n data: {\n response: result.content || result.response,\n tokensUsed: result.usage?.totalTokens || result.tokensUsed,\n toolCalls: result.toolCalls?.map((call) => ({\n id: call.id || '',\n name: call.name || '',\n arguments: JSON.stringify(call.arguments || {}),\n result: String(call.result || ''),\n })),\n },\n });\n }\n\n override async beforeToolExecution(\n context: IPluginExecutionContext,\n toolData: IToolExecutionContext,\n ): Promise<void> {\n if (!toolData) return;\n await this.emit(EVENT_EMITTER_EVENTS.TOOL_BEFORE_EXECUTE, {\n executionId: context.executionId,\n sessionId: context.sessionId,\n userId: context.userId,\n data: {\n toolName: toolData.toolName,\n toolId: toolData.executionId,\n arguments: JSON.stringify(toolData.parameters ?? {}),\n },\n });\n }\n\n override async afterToolExecution(\n context: IPluginExecutionContext,\n toolResults: IPluginExecutionResult,\n ): Promise<void> {\n if (!toolResults.toolCalls || toolResults.toolCalls.length === 0) return;\n for (const toolCall of toolResults.toolCalls) {\n const eventType =\n toolCall.result === null\n ? EVENT_EMITTER_EVENTS.TOOL_ERROR\n : EVENT_EMITTER_EVENTS.TOOL_SUCCESS;\n const baseData = buildToolCallEmitData(context, toolCall, toolResults.duration);\n await this.emit(eventType, baseData);\n await this.emit(EVENT_EMITTER_EVENTS.TOOL_AFTER_EXECUTE, {\n ...baseData,\n data: { ...baseData.data, toolResult: String(toolCall.result || '') },\n });\n }\n }\n\n override async onError(error: Error, context?: IPluginErrorContext): Promise<void> {\n await this.emit(EVENT_EMITTER_EVENTS.AGENT_EXECUTION_ERROR, {\n executionId: context?.executionId,\n sessionId: context?.sessionId,\n userId: context?.userId,\n error: error instanceof Error ? error : new Error(String(error)),\n data: { action: context?.action, tool: context?.tool, attempt: context?.attempt },\n });\n }\n\n on(\n eventType: TEventName,\n listener: TEventEmitterListener,\n options?: { once?: boolean; filter?: (event: IEventEmitterEventData) => boolean },\n ): string {\n const handlerId = `handler_${this.nextHandlerId++}`;\n registerHandler(\n this.handlers,\n eventType,\n handlerId,\n listener,\n options,\n this.pluginOptions.maxListeners,\n this.name,\n );\n return handlerId;\n }\n\n once(\n eventType: TEventName,\n listener: TEventEmitterListener,\n filter?: (event: IEventEmitterEventData) => boolean,\n ): string {\n return this.on(eventType, listener, { once: true, ...(filter && { filter }) });\n }\n\n off(eventType: TEventName, handlerIdOrListener: string | TEventEmitterListener): boolean {\n return unregisterHandler(this.handlers, eventType, handlerIdOrListener);\n }\n\n async emit(\n eventType: TEventName,\n eventData: Partial<IEventEmitterEventData> = {},\n ): Promise<void> {\n if (!this.pluginOptions.events.includes(eventType)) return;\n const event: IEventEmitterEventData = { type: eventType, timestamp: new Date(), ...eventData };\n const globalFilter = this.pluginOptions.filters[eventType];\n if (globalFilter && !globalFilter(event)) return;\n this.metrics.incrementEmitted();\n if (this.pluginOptions.buffer.enabled) {\n this.eventBuffer.push(event);\n if (this.eventBuffer.length >= this.pluginOptions.buffer.maxSize) this.flushBuffer();\n return;\n }\n await this.processEvent(event);\n }\n\n private async processEvent(event: IEventEmitterEventData): Promise<void> {\n await processEventHelper(\n event,\n this.handlers,\n this.pluginOptions.async,\n (t, id) => this.off(t, id),\n (h, e) =>\n executeEventHandler(h, e, this.metrics, this.pluginOptions.catchErrors, this.logger),\n );\n }\n\n async flushBuffer(): Promise<void> {\n if (this.eventBuffer.length === 0) return;\n const events = [...this.eventBuffer];\n this.eventBuffer = [];\n for (const event of events) await this.processEvent(event);\n }\n\n override getStats(): IEventEmitterPluginStats {\n return buildEventEmitterStats(\n super.getStats(),\n this.handlers,\n this.eventBuffer.length,\n this.metrics,\n );\n }\n\n clearAllListeners(): void {\n this.handlers.clear();\n }\n\n async destroy(): Promise<void> {\n if (this.bufferTimer) clearInterval(this.bufferTimer);\n await this.flushBuffer();\n this.clearAllListeners();\n }\n}\n","/**\n * Builtin type registrations and helper logic for ModuleDescriptorRegistry.\n *\n * Extracted from module-type-registry.ts to keep each file under 300 lines.\n * @internal\n */\nimport type { IModuleDescriptor } from '../abstracts/abstract-module';\nimport { ModuleCategory, ModuleLayer } from '../abstracts/abstract-module';\nimport type {\n IModuleDescriptorValidationResult,\n IModuleDependencyResolution,\n} from './module-type-registry';\n\n/** @internal */\nexport function getBuiltinTypeDescriptors(): IModuleDescriptor[] {\n return [\n {\n type: 'storage',\n category: ModuleCategory.STORAGE,\n layer: ModuleLayer.INFRASTRUCTURE,\n capabilities: ['data-persistence', 'data-retrieval'],\n },\n {\n type: 'memory-storage',\n category: ModuleCategory.STORAGE,\n layer: ModuleLayer.INFRASTRUCTURE,\n dependencies: ['storage'],\n capabilities: ['in-memory-storage', 'fast-access'],\n },\n {\n type: 'file-storage',\n category: ModuleCategory.STORAGE,\n layer: ModuleLayer.INFRASTRUCTURE,\n dependencies: ['storage'],\n capabilities: ['persistent-storage', 'file-system-access'],\n },\n {\n type: 'text-processing',\n category: ModuleCategory.PROCESSING,\n layer: ModuleLayer.APPLICATION,\n capabilities: ['text-analysis', 'content-transformation'],\n },\n {\n type: 'file-processing',\n category: ModuleCategory.PROCESSING,\n layer: ModuleLayer.APPLICATION,\n dependencies: ['storage'],\n capabilities: ['file-parsing', 'content-extraction'],\n },\n {\n type: 'api-integration',\n category: ModuleCategory.INTEGRATION,\n layer: ModuleLayer.APPLICATION,\n capabilities: ['external-api-access', 'data-synchronization'],\n },\n {\n type: 'database-integration',\n category: ModuleCategory.INTEGRATION,\n layer: ModuleLayer.INFRASTRUCTURE,\n dependencies: ['storage'],\n capabilities: ['database-access', 'query-execution'],\n },\n {\n type: 'rag',\n category: ModuleCategory.CAPABILITY,\n layer: ModuleLayer.DOMAIN,\n dependencies: ['storage', 'text-processing'],\n capabilities: ['document-search', 'context-retrieval', 'semantic-search'],\n },\n {\n type: 'speech-processing',\n category: ModuleCategory.CAPABILITY,\n layer: ModuleLayer.DOMAIN,\n capabilities: ['speech-to-text', 'text-to-speech', 'audio-processing'],\n },\n {\n type: 'image-analysis',\n category: ModuleCategory.CAPABILITY,\n layer: ModuleLayer.DOMAIN,\n capabilities: ['image-recognition', 'visual-analysis', 'content-extraction'],\n },\n ];\n}\n\n/** Validate a module type descriptor. @internal */\nexport function validateTypeDescriptor(\n typeDescriptor: IModuleDescriptor,\n getType: (type: string) => IModuleDescriptor | undefined,\n): IModuleDescriptorValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n if (!typeDescriptor.type || typeDescriptor.type.trim() === '')\n errors.push('Module type is required and cannot be empty');\n if (!typeDescriptor.category) errors.push('Module category is required');\n if (!typeDescriptor.layer) errors.push('Module layer is required');\n if (typeDescriptor.type && !/^[a-zA-Z][a-zA-Z0-9-_]*$/.test(typeDescriptor.type))\n errors.push(\n 'Module type must start with a letter and contain only letters, numbers, hyphens, and underscores',\n );\n if (typeDescriptor.dependencies) {\n for (const dep of typeDescriptor.dependencies) {\n if (!dep || dep.trim() === '') errors.push('Dependencies cannot be empty');\n }\n if (typeDescriptor.dependencies.includes(typeDescriptor.type))\n errors.push('Module cannot depend on itself');\n }\n if (typeDescriptor.capabilities) {\n for (const cap of typeDescriptor.capabilities) {\n if (!cap || cap.trim() === '') errors.push('Capabilities cannot be empty');\n }\n }\n if (typeDescriptor.dependencies) {\n const layerOrder = [\n ModuleLayer.INFRASTRUCTURE,\n ModuleLayer.CORE,\n ModuleLayer.APPLICATION,\n ModuleLayer.DOMAIN,\n ModuleLayer.PRESENTATION,\n ];\n const currentIdx = layerOrder.indexOf(typeDescriptor.layer);\n for (const depType of typeDescriptor.dependencies) {\n const depDesc = getType(depType);\n if (depDesc) {\n const depIdx = layerOrder.indexOf(depDesc.layer);\n if (depIdx > currentIdx)\n warnings.push(\n `Module '${typeDescriptor.type}' (${typeDescriptor.layer}) depends on '${depType}' (${depDesc.layer}) which is in a higher layer`,\n );\n }\n }\n }\n return { valid: errors.length === 0, errors, warnings };\n}\n\n/** Resolve module dependencies via topological sort. @internal */\nexport function resolveDependenciesHelper(\n moduleTypes: string[],\n getType: (type: string) => IModuleDescriptor | undefined,\n hasType: (type: string) => boolean,\n): IModuleDependencyResolution {\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const order: string[] = [];\n const circularDependencies: string[][] = [];\n const missingDependencies: string[] = [];\n for (const moduleType of moduleTypes) {\n const descriptor = getType(moduleType);\n if (!descriptor) {\n missingDependencies.push(moduleType);\n continue;\n }\n if (descriptor.dependencies) {\n for (const dep of descriptor.dependencies) {\n if (!hasType(dep) && !missingDependencies.includes(dep)) missingDependencies.push(dep);\n }\n }\n }\n const visit = (moduleType: string, path: string[] = []): void => {\n if (visiting.has(moduleType)) {\n const cycleStart = path.indexOf(moduleType);\n circularDependencies.push(path.slice(cycleStart).concat([moduleType]));\n return;\n }\n if (visited.has(moduleType)) return;\n const descriptor = getType(moduleType);\n if (!descriptor) return;\n visiting.add(moduleType);\n const newPath = [...path, moduleType];\n if (descriptor.dependencies) {\n for (const dep of descriptor.dependencies) {\n if (moduleTypes.includes(dep) || hasType(dep)) visit(dep, newPath);\n }\n }\n visiting.delete(moduleType);\n visited.add(moduleType);\n order.push(moduleType);\n };\n for (const moduleType of moduleTypes) {\n if (!visited.has(moduleType)) visit(moduleType);\n }\n return {\n resolved: missingDependencies.length === 0 && circularDependencies.length === 0,\n order,\n circularDependencies,\n missingDependencies,\n };\n}\n\n/** Check compatibility between module types. @internal */\nexport function checkCompatibilityHelper(\n moduleTypes: string[],\n getType: (type: string) => IModuleDescriptor | undefined,\n): {\n compatible: boolean;\n conflicts: Array<{ module1: string; module2: string; reason: string }>;\n suggestions: string[];\n} {\n const conflicts: Array<{ module1: string; module2: string; reason: string }> = [];\n const suggestions: string[] = [];\n const modulesByLayer = new Map<ModuleLayer, string[]>();\n for (const moduleType of moduleTypes) {\n const descriptor = getType(moduleType);\n if (descriptor) {\n if (!modulesByLayer.has(descriptor.layer)) modulesByLayer.set(descriptor.layer, []);\n modulesByLayer.get(descriptor.layer)!.push(moduleType);\n }\n }\n const capabilityProviders = new Map<string, string[]>();\n for (const moduleType of moduleTypes) {\n const descriptor = getType(moduleType);\n if (descriptor?.capabilities) {\n for (const cap of descriptor.capabilities) {\n if (!capabilityProviders.has(cap)) capabilityProviders.set(cap, []);\n capabilityProviders.get(cap)!.push(moduleType);\n }\n }\n }\n for (const [capability, providers] of Array.from(capabilityProviders.entries())) {\n if (providers.length > 1) {\n for (let i = 0; i < providers.length; i++) {\n for (let j = i + 1; j < providers.length; j++) {\n const m1 = providers[i];\n const m2 = providers[j];\n if (m1 && m2)\n conflicts.push({\n module1: m1,\n module2: m2,\n reason: `Both modules provide capability '${capability}'`,\n });\n }\n }\n }\n }\n if (conflicts.length > 0) {\n suggestions.push('Consider using only one module per capability');\n suggestions.push('Check if modules can be configured to avoid conflicts');\n }\n if (!modulesByLayer.has(ModuleLayer.INFRASTRUCTURE) && moduleTypes.length > 1)\n suggestions.push('Consider adding infrastructure modules for better foundation');\n return { compatible: conflicts.length === 0, conflicts, suggestions };\n}\n\n/** Build registry stats. @internal */\nexport function buildTypeRegistryStats(registeredTypes: Map<string, IModuleDescriptor>): {\n totalTypes: number;\n typesByCategory: Record<ModuleCategory, number>;\n typesByLayer: Record<ModuleLayer, number>;\n typesWithDependencies: number;\n typesWithCapabilities: number;\n} {\n const typesByCategory: Record<ModuleCategory, number> = {\n [ModuleCategory.CORE]: 0,\n [ModuleCategory.STORAGE]: 0,\n [ModuleCategory.PROCESSING]: 0,\n [ModuleCategory.INTEGRATION]: 0,\n [ModuleCategory.INTERFACE]: 0,\n [ModuleCategory.CAPABILITY]: 0,\n };\n const typesByLayer: Record<ModuleLayer, number> = {\n [ModuleLayer.INFRASTRUCTURE]: 0,\n [ModuleLayer.CORE]: 0,\n [ModuleLayer.APPLICATION]: 0,\n [ModuleLayer.DOMAIN]: 0,\n [ModuleLayer.PRESENTATION]: 0,\n };\n let typesWithDependencies = 0;\n let typesWithCapabilities = 0;\n for (const descriptor of registeredTypes.values()) {\n typesByCategory[descriptor.category]++;\n typesByLayer[descriptor.layer]++;\n if (descriptor.dependencies && descriptor.dependencies.length > 0) typesWithDependencies++;\n if (descriptor.capabilities && descriptor.capabilities.length > 0) typesWithCapabilities++;\n }\n return {\n totalTypes: registeredTypes.size,\n typesByCategory,\n typesByLayer,\n typesWithDependencies,\n typesWithCapabilities,\n };\n}\n","/**\n * Registry for managing module types dynamically.\n *\n * Builtin registrations and helpers live in ./module-type-registry-helpers.ts.\n */\nimport { ModuleCategory, ModuleLayer, type IModuleDescriptor } from '../abstracts/abstract-module';\nimport { createLogger, type ILogger } from '../utils/logger';\nimport { ConfigurationError } from '../utils/errors';\nimport {\n getBuiltinTypeDescriptors,\n validateTypeDescriptor,\n resolveDependenciesHelper,\n checkCompatibilityHelper,\n buildTypeRegistryStats,\n} from './module-type-registry-helpers';\n\n/** Module type validation result */\nexport interface IModuleDescriptorValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/** Module dependency resolution result */\nexport interface IModuleDependencyResolution {\n resolved: boolean;\n order: string[];\n circularDependencies: string[][];\n missingDependencies: string[];\n}\n\n/** Module compatibility check result */\nexport interface IModuleCompatibilityResult {\n compatible: boolean;\n conflicts: Array<{ module1: string; module2: string; reason: string }>;\n suggestions: string[];\n}\n\n/**\n * Registry for managing module types dynamically.\n * Provides type validation, dependency resolution, and compatibility checking.\n */\nexport class ModuleDescriptorRegistry {\n private registeredTypes = new Map<string, IModuleDescriptor>();\n private logger: ILogger;\n\n constructor() {\n this.logger = createLogger('ModuleDescriptorRegistry');\n this.registerBuiltinTypes();\n }\n\n registerType(typeDescriptor: IModuleDescriptor): void {\n const validation = this.validateTypeDescriptor(typeDescriptor);\n if (!validation.valid)\n throw new ConfigurationError(\n `Invalid module type descriptor: ${validation.errors.join(', ')}`,\n { type: typeDescriptor.type, errors: validation.errors },\n );\n if (this.registeredTypes.has(typeDescriptor.type)) {\n const existing = this.registeredTypes.get(typeDescriptor.type);\n this.logger.warn('Overriding existing module type', {\n type: typeDescriptor.type,\n previousCategory: existing?.category || 'unknown',\n newCategory: typeDescriptor.category,\n });\n }\n this.registeredTypes.set(typeDescriptor.type, typeDescriptor);\n this.logger.info('Module type registered', {\n type: typeDescriptor.type,\n category: typeDescriptor.category,\n layer: typeDescriptor.layer,\n dependencies: typeDescriptor.dependencies?.length || 0,\n capabilities: typeDescriptor.capabilities?.length || 0,\n });\n }\n\n unregisterType(type: string): boolean {\n if (!this.registeredTypes.has(type)) return false;\n const dependentTypes = this.findDependentTypes(type);\n if (dependentTypes.length > 0)\n throw new ConfigurationError(\n `Cannot unregister module type '${type}' - it is required by: ${dependentTypes.join(', ')}`,\n { type, dependentTypes },\n );\n this.registeredTypes.delete(type);\n this.logger.info('Module type unregistered', { type });\n return true;\n }\n\n getType(type: string): IModuleDescriptor | undefined {\n return this.registeredTypes.get(type);\n }\n getAllTypes(): IModuleDescriptor[] {\n return Array.from(this.registeredTypes.values());\n }\n getTypesByCategory(category: ModuleCategory): IModuleDescriptor[] {\n return Array.from(this.registeredTypes.values()).filter((t) => t.category === category);\n }\n getTypesByLayer(layer: ModuleLayer): IModuleDescriptor[] {\n return Array.from(this.registeredTypes.values()).filter((t) => t.layer === layer);\n }\n hasType(type: string): boolean {\n return this.registeredTypes.has(type);\n }\n\n validateTypeDescriptor(typeDescriptor: IModuleDescriptor): IModuleDescriptorValidationResult {\n return validateTypeDescriptor(typeDescriptor, (t) => this.getType(t));\n }\n\n resolveDependencies(moduleTypes: string[]): IModuleDependencyResolution {\n return resolveDependenciesHelper(\n moduleTypes,\n (t) => this.getType(t),\n (t) => this.hasType(t),\n );\n }\n\n checkCompatibility(moduleTypes: string[]): IModuleCompatibilityResult {\n return checkCompatibilityHelper(moduleTypes, (t) => this.getType(t));\n }\n\n private findDependentTypes(type: string): string[] {\n const deps: string[] = [];\n for (const [rt, desc] of this.registeredTypes) {\n if (desc.dependencies?.includes(type)) deps.push(rt);\n }\n return deps;\n }\n\n private registerBuiltinTypes(): void {\n for (const desc of getBuiltinTypeDescriptors()) this.registerType(desc);\n this.logger.info('Built-in module types registered', { totalTypes: this.registeredTypes.size });\n }\n\n clearAllTypes(): void {\n this.registeredTypes.clear();\n this.logger.info('All module types cleared');\n }\n\n getStats(): {\n totalTypes: number;\n typesByCategory: Record<ModuleCategory, number>;\n typesByLayer: Record<ModuleLayer, number>;\n typesWithDependencies: number;\n typesWithCapabilities: number;\n } {\n return buildTypeRegistryStats(this.registeredTypes);\n }\n}\n","/**\n * Module validation helpers for ModuleRegistry.\n *\n * Extracted from module-registry.ts to keep each file under 300 lines.\n * @internal\n */\nimport type { IModule } from '../abstracts/abstract-module';\nimport type { ModuleDescriptorRegistry } from './module-type-registry';\nimport { ConfigurationError } from '../utils/errors';\nimport type { ILogger } from '../utils/logger';\n\n/** Validate a module before registration. @internal */\nexport function validateModule(\n module: IModule,\n typeRegistry: ModuleDescriptorRegistry,\n logger: ILogger,\n): void {\n if (!module.name || module.name.trim() === '') {\n throw new ConfigurationError('Module name is required');\n }\n if (!module.version || module.version.trim() === '') {\n throw new ConfigurationError('Module version is required');\n }\n const moduleType = module.getModuleType();\n const validation = typeRegistry.validateTypeDescriptor(moduleType);\n if (!validation.valid) {\n throw new ConfigurationError(`Invalid module type: ${validation.errors.join(', ')}`, {\n moduleName: module.name,\n errors: validation.errors,\n });\n }\n if (validation.warnings.length > 0) {\n logger.warn('Module type validation warnings', {\n moduleName: module.name,\n warnings: validation.warnings,\n });\n }\n}\n\n/** Validate module dependencies against the type registry and registered modules. @internal */\nexport async function validateModuleDependencies(\n module: IModule,\n typeRegistry: ModuleDescriptorRegistry,\n registeredModules: Map<string, IModule>,\n logger: ILogger,\n): Promise<void> {\n const moduleType = module.getModuleType();\n if (!moduleType.dependencies || moduleType.dependencies.length === 0) return;\n\n for (const depType of moduleType.dependencies) {\n if (!typeRegistry.hasType(depType)) {\n throw new ConfigurationError(\n `Module '${module.name}' depends on unregistered type '${depType}'`,\n { moduleName: module.name, dependencyType: depType },\n );\n }\n }\n\n const availableTypes = new Set<string>();\n for (const registeredModule of registeredModules.values()) {\n availableTypes.add(registeredModule.getModuleType().type);\n }\n const missing: string[] = [];\n for (const depType of moduleType.dependencies) {\n if (!availableTypes.has(depType)) missing.push(depType);\n }\n if (missing.length > 0) {\n logger.warn('Module has unmet dependencies', {\n moduleName: module.name,\n missingDependencies: missing,\n });\n }\n}\n\n/** Find modules that depend on the given module. @internal */\nexport function findDependentModules(moduleName: string, modules: Map<string, IModule>): string[] {\n const targetModule = modules.get(moduleName);\n if (!targetModule) return [];\n const targetType = targetModule.getModuleType().type;\n const dependents: string[] = [];\n for (const [name, module] of modules.entries()) {\n if (name === moduleName) continue;\n if (module.getModuleType().dependencies?.includes(targetType)) dependents.push(name);\n }\n return dependents;\n}\n\n/** Compute registry-wide statistics. @internal */\nexport interface IModuleRegistryStats {\n totalModules: number;\n initializedModules: number;\n enabledModules: number;\n modulesByType: Record<string, number>;\n totalExecutions: number;\n totalSuccessfulExecutions: number;\n totalFailedExecutions: number;\n averageExecutionTime: number;\n}\n\n/** @internal */\nexport interface IModuleExecutionStats {\n totalExecutions: number;\n successfulExecutions: number;\n failedExecutions: number;\n averageExecutionTime: number;\n lastExecutionTime?: Date;\n totalExecutionTime: number;\n}\n\n/** Build registry stats. @internal */\nexport function buildRegistryStats(\n modules: Map<string, IModule>,\n moduleStats: Map<string, IModuleExecutionStats>,\n): IModuleRegistryStats {\n const modulesByType: Record<string, number> = {};\n let initializedModules = 0;\n let enabledModules = 0;\n let totalExecutions = 0;\n let totalSuccessfulExecutions = 0;\n let totalFailedExecutions = 0;\n let totalExecutionTime = 0;\n\n for (const module of modules.values()) {\n const type = module.getModuleType().type;\n modulesByType[type] = (modulesByType[type] || 0) + 1;\n if (module.isInitialized()) initializedModules++;\n if (module.isEnabled()) enabledModules++;\n }\n for (const stats of moduleStats.values()) {\n totalExecutions += stats.totalExecutions;\n totalSuccessfulExecutions += stats.successfulExecutions;\n totalFailedExecutions += stats.failedExecutions;\n totalExecutionTime += stats.totalExecutionTime;\n }\n\n return {\n totalModules: modules.size,\n initializedModules,\n enabledModules,\n modulesByType,\n totalExecutions,\n totalSuccessfulExecutions,\n totalFailedExecutions,\n averageExecutionTime: totalExecutions > 0 ? totalExecutionTime / totalExecutions : 0,\n };\n}\n","/**\n * Registry for managing module instances.\n *\n * Validation helpers live in ./module-registry-validation.ts.\n */\nimport type {\n IBaseModuleOptions,\n IModule,\n IModuleExecutionContext,\n IModuleExecutionResult,\n} from '../abstracts/abstract-module';\nimport type { IEventEmitterPlugin } from '../plugins/event-emitter/types';\nimport { ModuleDescriptorRegistry } from './module-type-registry';\nimport { createLogger, type ILogger } from '../utils/logger';\nimport { ConfigurationError } from '../utils/errors';\nimport {\n validateModule,\n validateModuleDependencies,\n findDependentModules,\n buildRegistryStats,\n} from './module-registry-validation';\nimport type { IModuleExecutionStats, IModuleRegistryStats } from './module-registry-validation';\n\nexport type { IModuleExecutionStats };\n\nexport const MODULE_REGISTRY_EVENTS = {\n REGISTERED: 'module.registered',\n UNREGISTERED: 'module.unregistered',\n} as const;\n\nexport interface IModuleRegistrationOptions {\n autoInitialize?: boolean;\n initOptions?: IBaseModuleOptions;\n validateDependencies?: boolean;\n initTimeout?: number;\n}\n\nexport interface IModuleStatus {\n name: string;\n type: string;\n enabled: boolean;\n initialized: boolean;\n hasEventEmitter: boolean;\n registrationTime: Date;\n initializationTime?: Date;\n lastActivity?: Date;\n dependencies: string[];\n dependents: string[];\n}\n\nexport class ModuleRegistry {\n private modules = new Map<string, IModule>();\n private moduleOptions = new Map<string, IBaseModuleOptions>();\n private moduleStatuses = new Map<string, IModuleStatus>();\n private moduleStats = new Map<string, IModuleExecutionStats>();\n private registrationOrder: string[] = [];\n private initializationOrder: string[] = [];\n private typeRegistry: ModuleDescriptorRegistry;\n private eventEmitter: IEventEmitterPlugin | undefined;\n private logger: ILogger;\n private isDisposing = false;\n\n constructor(eventEmitter?: IEventEmitterPlugin, typeRegistry?: ModuleDescriptorRegistry) {\n this.eventEmitter = eventEmitter;\n this.typeRegistry = typeRegistry ?? new ModuleDescriptorRegistry();\n this.logger = createLogger('ModuleRegistry');\n }\n\n async registerModule(module: IModule, options: IModuleRegistrationOptions = {}): Promise<void> {\n if (this.isDisposing) throw new ConfigurationError('Cannot register modules during disposal');\n validateModule(module, this.typeRegistry, this.logger);\n if (this.modules.has(module.name))\n throw new ConfigurationError(`Module with name '${module.name}' is already registered`, {\n moduleName: module.name,\n });\n if (options.validateDependencies !== false)\n await validateModuleDependencies(module, this.typeRegistry, this.modules, this.logger);\n\n this.modules.set(module.name, module);\n this.moduleOptions.set(module.name, options.initOptions || {});\n this.registrationOrder.push(module.name);\n const moduleType = module.getModuleType();\n this.moduleStatuses.set(module.name, {\n name: module.name,\n type: moduleType.type,\n enabled: module.isEnabled(),\n initialized: false,\n hasEventEmitter: !!this.eventEmitter,\n registrationTime: new Date(),\n dependencies: moduleType.dependencies || [],\n dependents: [],\n });\n this.moduleStats.set(module.name, {\n totalExecutions: 0,\n successfulExecutions: 0,\n failedExecutions: 0,\n averageExecutionTime: 0,\n totalExecutionTime: 0,\n });\n\n if (options.autoInitialize) await this.initializeModule(module.name, options.initTimeout);\n if (this.eventEmitter)\n await this.eventEmitter.emit(MODULE_REGISTRY_EVENTS.REGISTERED, {\n data: { moduleName: module.name, moduleType: moduleType.type },\n timestamp: new Date(),\n });\n }\n\n async unregisterModule(moduleName: string): Promise<boolean> {\n const module = this.modules.get(moduleName);\n if (!module) return false;\n const dependents = findDependentModules(moduleName, this.modules);\n if (dependents.length > 0)\n throw new ConfigurationError(\n `Cannot unregister module '${moduleName}' - it is required by: ${dependents.join(', ')}`,\n { moduleName, dependents },\n );\n if (module.isInitialized() && module.dispose) await module.dispose();\n this.modules.delete(moduleName);\n this.moduleOptions.delete(moduleName);\n this.moduleStatuses.delete(moduleName);\n this.moduleStats.delete(moduleName);\n const ri = this.registrationOrder.indexOf(moduleName);\n if (ri !== -1) this.registrationOrder.splice(ri, 1);\n const ii = this.initializationOrder.indexOf(moduleName);\n if (ii !== -1) this.initializationOrder.splice(ii, 1);\n if (this.eventEmitter)\n await this.eventEmitter.emit(MODULE_REGISTRY_EVENTS.UNREGISTERED, {\n data: { moduleName },\n timestamp: new Date(),\n });\n return true;\n }\n\n async initializeModule(moduleName: string, timeout?: number): Promise<void> {\n const module = this.modules.get(moduleName);\n if (!module) throw new ConfigurationError(`Module '${moduleName}' not found`);\n if (module.isInitialized()) return;\n const options = this.moduleOptions.get(moduleName);\n const initPromise = module.initialize(options, this.eventEmitter);\n if (timeout && timeout > 0) {\n let timerId: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timerId = setTimeout(() => {\n reject(new Error(`Module '${moduleName}' initialization timed out after ${timeout}ms`));\n }, timeout);\n });\n await Promise.race([\n initPromise.then((result) => {\n clearTimeout(timerId);\n return result;\n }),\n timeoutPromise,\n ]);\n } else {\n await initPromise;\n }\n const status = this.moduleStatuses.get(moduleName);\n if (status) {\n status.initialized = true;\n status.initializationTime = new Date();\n }\n if (!this.initializationOrder.includes(moduleName)) this.initializationOrder.push(moduleName);\n }\n\n async initializeAllModules(timeout?: number): Promise<void> {\n const moduleNames = Array.from(this.modules.keys());\n if (moduleNames.length === 0) return;\n const moduleTypes = moduleNames.map((name) => this.modules.get(name)!.getModuleType().type);\n const resolution = this.typeRegistry.resolveDependencies(moduleTypes);\n if (!resolution.resolved) {\n const errors: string[] = [];\n if (resolution.missingDependencies.length > 0)\n errors.push(`Missing dependencies: ${resolution.missingDependencies.join(', ')}`);\n if (resolution.circularDependencies.length > 0)\n errors.push(\n `Circular dependencies: ${resolution.circularDependencies.map((c) => c.join(' -> ')).join('; ')}`,\n );\n throw new ConfigurationError(`Cannot initialize modules: ${errors.join('; ')}`, {\n missingDependencies: resolution.missingDependencies,\n circularDependencies: resolution.circularDependencies.map((c) => c.join(' -> ')),\n });\n }\n for (const moduleType of resolution.order) {\n const mn = moduleNames.find(\n (name) => this.modules.get(name)!.getModuleType().type === moduleType,\n );\n if (mn) await this.initializeModule(mn, timeout);\n }\n }\n\n async executeModule(\n moduleName: string,\n context: IModuleExecutionContext,\n ): Promise<IModuleExecutionResult> {\n const module = this.modules.get(moduleName);\n if (!module) throw new ConfigurationError(`Module '${moduleName}' not found`);\n if (!module.isInitialized())\n throw new ConfigurationError(`Module '${moduleName}' is not initialized`);\n if (!module.isEnabled()) throw new ConfigurationError(`Module '${moduleName}' is disabled`);\n const stats = this.moduleStats.get(moduleName)!;\n const startTime = Date.now();\n try {\n if (!module.execute)\n throw new ConfigurationError(`Module '${moduleName}' does not support execute()`);\n const result = await module.execute(context);\n const duration = Date.now() - startTime;\n stats.totalExecutions++;\n stats.successfulExecutions++;\n stats.totalExecutionTime += duration;\n stats.averageExecutionTime = stats.totalExecutionTime / stats.totalExecutions;\n stats.lastExecutionTime = new Date();\n const status = this.moduleStatuses.get(moduleName);\n if (status) status.lastActivity = new Date();\n return result;\n } catch (error) {\n const duration = Date.now() - startTime;\n stats.totalExecutions++;\n stats.failedExecutions++;\n stats.totalExecutionTime += duration;\n stats.averageExecutionTime = stats.totalExecutionTime / stats.totalExecutions;\n stats.lastExecutionTime = new Date();\n throw error;\n }\n }\n\n getModule(moduleName: string): IModule | undefined {\n return this.modules.get(moduleName);\n }\n getModulesByType(moduleType: string): IModule[] {\n return Array.from(this.modules.values()).filter((m) => m.getModuleType().type === moduleType);\n }\n getAllModules(): IModule[] {\n return Array.from(this.modules.values());\n }\n getModuleNames(): string[] {\n return Array.from(this.modules.keys());\n }\n hasModule(moduleName: string): boolean {\n return this.modules.has(moduleName);\n }\n getModuleStatus(moduleName: string): IModuleStatus | undefined {\n return this.moduleStatuses.get(moduleName);\n }\n getAllModuleStatuses(): IModuleStatus[] {\n return Array.from(this.moduleStatuses.values());\n }\n getModuleStats(moduleName: string): IModuleExecutionStats | undefined {\n return this.moduleStats.get(moduleName);\n }\n getAllModuleStats(): Record<string, IModuleExecutionStats> {\n const s: Record<string, IModuleExecutionStats> = {};\n for (const [n, ms] of this.moduleStats.entries()) s[n] = { ...ms };\n return s;\n }\n\n async disposeAllModules(): Promise<void> {\n this.isDisposing = true;\n const reverseOrder = [...this.initializationOrder].reverse();\n for (const moduleName of reverseOrder) {\n const module = this.modules.get(moduleName);\n if (module && module.isInitialized()) {\n try {\n if (module.dispose) await module.dispose();\n const s = this.moduleStatuses.get(moduleName);\n if (s) s.initialized = false;\n } catch (error) {\n this.logger.error('Failed to dispose module', {\n name: moduleName,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n this.initializationOrder = [];\n this.isDisposing = false;\n }\n\n clearAllModules(): void {\n this.modules.clear();\n this.moduleOptions.clear();\n this.moduleStatuses.clear();\n this.moduleStats.clear();\n this.registrationOrder = [];\n this.initializationOrder = [];\n this.isDisposing = false;\n }\n\n getRegistryStats(): IModuleRegistryStats {\n return buildRegistryStats(this.modules, this.moduleStats);\n }\n}\n","import type { IAIProviderManager } from '../interfaces/manager';\nimport type { IAIProvider } from '../interfaces/provider';\nimport { AbstractManager } from '../abstracts/abstract-manager';\nimport { ConfigurationError, ValidationError } from '../utils/errors';\nimport { Validator } from '../utils/validation';\nimport { logger } from '../utils/logger';\n\n/**\n * AI Provider Manager - manages AI provider instances\n * Manages registration, selection, and state of AI providers\n * Instance-based for isolated provider management\n * @internal\n */\nexport class AIProviders extends AbstractManager implements IAIProviderManager {\n private providers = new Map<string, IAIProvider>();\n private currentProvider: string | undefined;\n private currentModel: string | undefined;\n\n constructor() {\n super();\n }\n\n /**\n * Initialize the manager\n */\n protected async doInitialize(): Promise<void> {\n logger.debug('AIProviders initialized');\n }\n\n /**\n * Cleanup manager resources\n */\n protected async doDispose(): Promise<void> {\n // Close all providers\n for (const [name, provider] of this.providers) {\n try {\n if (provider.close) {\n await provider.close();\n }\n logger.debug(`Closed AI provider: ${name}`);\n } catch (error) {\n logger.warn(`Failed to close AI provider ${name}`, {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n this.providers.clear();\n this.currentProvider = undefined;\n this.currentModel = undefined;\n\n logger.debug('AIProviders disposed');\n }\n\n /**\n * Register an AI provider\n */\n addProvider(name: string, provider: IAIProvider): void {\n this.ensureInitialized();\n\n // Validate provider name\n const nameValidation = Validator.validateProviderName(name);\n if (!nameValidation.isValid) {\n throw new ValidationError(`Invalid provider name: ${nameValidation.errors.join(', ')}`);\n }\n\n // Validate provider\n if (!provider || typeof provider !== 'object' || provider === null || Array.isArray(provider)) {\n throw new ValidationError('Provider must be a valid object instance');\n }\n\n if (!provider.name || typeof provider.name !== 'string') {\n throw new ValidationError('Provider must have a valid name');\n }\n\n if (typeof provider.chat !== 'function') {\n throw new ValidationError('Provider must have a chat method');\n }\n\n // Check for duplicate registration\n if (this.providers.has(name)) {\n logger.warn(`Provider \"${name}\" is already registered, overriding`, {\n providerName: name,\n existingProvider: this.providers.get(name)?.name,\n });\n }\n\n this.providers.set(name, provider);\n logger.debug(`AI provider \"${name}\" registered successfully`, {\n providerName: name,\n version: provider.version,\n supportsStreaming: typeof provider.chatStream === 'function',\n });\n }\n\n /**\n * Remove an AI provider\n */\n removeProvider(name: string): void {\n this.ensureInitialized();\n\n if (!this.providers.has(name)) {\n logger.warn(`Attempted to remove non-existent provider \"${name}\"`);\n return;\n }\n\n // Close provider if it has close method\n const provider = this.providers.get(name);\n if (provider?.close) {\n provider.close().catch((error: Error) => {\n logger.warn(`Failed to close provider ${name}`, {\n error: error.message,\n });\n });\n }\n\n this.providers.delete(name);\n\n // Clear current selection if this was the current provider\n if (this.currentProvider === name) {\n this.currentProvider = undefined;\n this.currentModel = undefined;\n logger.debug(`Cleared current provider selection after removing \"${name}\"`);\n }\n\n logger.debug(`AI provider \"${name}\" removed successfully`);\n }\n\n /**\n * Get registered provider by name\n */\n getProvider(name: string): IAIProvider | undefined {\n this.ensureInitialized();\n return this.providers.get(name);\n }\n\n /**\n * Get all registered providers\n */\n getProviders(): Record<string, IAIProvider> {\n this.ensureInitialized();\n return Object.fromEntries(this.providers);\n }\n\n /**\n * Set current provider and model\n */\n setCurrentProvider(name: string, model: string): void {\n this.ensureInitialized();\n\n // Validate provider exists\n const provider = this.providers.get(name);\n if (!provider) {\n throw new ConfigurationError(`Provider \"${name}\" is not registered`);\n }\n\n // Note: Model validation is now handled at runtime in ChatOptions\n // No pre-validation needed since models are provider-specific\n\n this.currentProvider = name;\n this.currentModel = model;\n\n logger.debug(`Current AI provider set to \"${name}\" with model \"${model}\"`);\n }\n\n /**\n * Get current provider and model\n */\n getCurrentProvider(): { provider: string; model: string } | undefined {\n this.ensureInitialized();\n\n if (!this.currentProvider || !this.currentModel) {\n return undefined;\n }\n\n return {\n provider: this.currentProvider,\n model: this.currentModel,\n };\n }\n\n /**\n * Check if provider is configured\n */\n isConfigured(): boolean {\n this.ensureInitialized();\n return !!(\n this.currentProvider &&\n this.currentModel &&\n this.providers.has(this.currentProvider)\n );\n }\n\n /**\n * Get available models for a provider\n * Note: In the new architecture, models are handled by each provider internally\n */\n getAvailableModels(providerName: string): string[] {\n this.ensureInitialized();\n\n const provider = this.providers.get(providerName);\n if (!provider) {\n throw new ConfigurationError(`Provider \"${providerName}\" is not registered`);\n }\n\n // Return empty array since models are now provider-specific and handled internally\n logger.warn(\n `getAvailableModels() is deprecated. Models are now handled by providers internally.`,\n );\n return [];\n }\n\n /**\n * Get current provider instance\n */\n getCurrentProviderInstance(): IAIProvider | undefined {\n if (!this.isConfigured() || !this.currentProvider) {\n return undefined;\n }\n\n return this.providers.get(this.currentProvider);\n }\n\n /**\n * Get provider names\n */\n getProviderNames(): string[] {\n this.ensureInitialized();\n return Array.from(this.providers.keys());\n }\n\n /**\n * Get providers by pattern\n */\n getProvidersByPattern(pattern: string | RegExp): Record<string, IAIProvider> {\n this.ensureInitialized();\n\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n const result: Record<string, IAIProvider> = {};\n\n for (const [name, provider] of this.providers) {\n if (regex.test(name)) {\n result[name] = provider;\n }\n }\n\n return result;\n }\n\n /**\n * Check if provider supports streaming\n */\n supportsStreaming(providerName?: string): boolean {\n this.ensureInitialized();\n\n const name = providerName || this.currentProvider;\n if (!name) {\n return false;\n }\n\n const provider = this.providers.get(name);\n return !!(provider && typeof provider.chatStream === 'function');\n }\n\n /**\n * Get provider count\n */\n getProviderCount(): number {\n this.ensureInitialized();\n return this.providers.size;\n }\n}\n","import type { ITool, IToolRegistry } from '../interfaces/tool';\nimport type { IToolSchema } from '../interfaces/provider';\nimport { ValidationError } from '../utils/errors';\nimport { logger } from '../utils/logger';\n\n/**\n * Tool registry implementation\n * Manages tool registration, validation, and retrieval\n */\nexport class ToolRegistry implements IToolRegistry {\n private tools = new Map<string, ITool>();\n\n /**\n * Register a tool\n */\n register(tool: ITool): void {\n if (!tool.schema?.name) {\n throw new ValidationError('Tool must have a valid schema with name');\n }\n\n const toolName = tool.schema.name;\n\n // Validate tool schema\n this.validateToolSchema(tool.schema);\n\n // Check for duplicate registration\n if (this.tools.has(toolName)) {\n logger.warn(`Tool \"${toolName}\" is already registered, overriding`, {\n toolName,\n existingTool: this.tools.get(toolName)?.constructor.name,\n });\n }\n\n this.tools.set(toolName, tool);\n logger.debug(`Tool \"${toolName}\" registered successfully`, {\n toolName,\n toolType: tool.constructor.name,\n parameters: Object.keys(tool.schema.parameters?.properties || {}),\n });\n }\n\n /**\n * Unregister a tool\n */\n unregister(name: string): void {\n if (!this.tools.has(name)) {\n logger.warn(`Attempted to unregister non-existent tool \"${name}\"`);\n return;\n }\n\n this.tools.delete(name);\n logger.debug(`Tool \"${name}\" unregistered successfully`);\n }\n\n /**\n * Get tool by name\n */\n get(name: string): ITool | undefined {\n return this.tools.get(name);\n }\n\n /**\n * Get all registered tools\n */\n getAll(): ITool[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Get tool schemas\n */\n getSchemas(): IToolSchema[] {\n const tools = this.getAll();\n\n logger.debug('[TOOL-FLOW] ToolRegistry.getSchemas() - Tools before schema extraction', {\n count: tools.length,\n tools: tools.map((t) => ({\n name: t.schema?.name ?? 'unnamed',\n hasSchema: !!t.schema,\n schemaType: typeof t.schema,\n toolType: t.constructor?.name || 'unknown',\n })),\n });\n\n return this.getAll().map((tool) => tool.schema);\n }\n\n /**\n * Check if tool exists\n */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /**\n * Clear all tools\n */\n clear(): void {\n const toolCount = this.tools.size;\n this.tools.clear();\n logger.debug(`Cleared ${toolCount} tools from registry`);\n }\n\n /**\n * Get tool names\n */\n getToolNames(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * Get tools by pattern\n */\n getToolsByPattern(pattern: string | RegExp): ITool[] {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n return this.getAll().filter((tool) => regex.test(tool.schema.name));\n }\n\n /**\n * Get tool count\n */\n size(): number {\n return this.tools.size;\n }\n\n /**\n * Validate tool schema\n */\n private validateToolSchema(schema: IToolSchema): void {\n if (!schema.name || typeof schema.name !== 'string') {\n throw new ValidationError('Tool schema must have a valid name');\n }\n\n if (!schema.description || typeof schema.description !== 'string') {\n throw new ValidationError('Tool schema must have a description');\n }\n\n if (\n !schema.parameters ||\n typeof schema.parameters !== 'object' ||\n schema.parameters === null ||\n Array.isArray(schema.parameters)\n ) {\n throw new ValidationError('Tool schema must have parameters object');\n }\n\n if (schema.parameters.type !== 'object') {\n throw new ValidationError('Tool parameters type must be \"object\"');\n }\n\n // Validate parameter properties\n if (schema.parameters.properties) {\n for (const propName of Object.keys(schema.parameters.properties)) {\n const propSchema = schema.parameters.properties[propName];\n if (!propSchema?.type) {\n throw new ValidationError(`Parameter \"${propName}\" must have a type`);\n }\n\n const validTypes = ['string', 'number', 'boolean', 'array', 'object'];\n if (!validTypes.includes(propSchema.type)) {\n throw new ValidationError(\n `Parameter \"${propName}\" has invalid type \"${propSchema.type}\"`,\n );\n }\n }\n }\n\n // Validate required fields exist in properties\n if (schema.parameters.required) {\n const properties = schema.parameters.properties || {};\n for (const requiredField of schema.parameters.required) {\n if (!properties[requiredField]) {\n throw new ValidationError(\n `Required parameter \"${requiredField}\" is not defined in properties`,\n );\n }\n }\n }\n }\n}\n","import type {\n IFunctionTool,\n IToolResult,\n IToolExecutionContext,\n IParameterValidationResult,\n TToolExecutor,\n TToolParameters,\n IEventService,\n} from '../interfaces/tool';\nimport type { IToolSchema, IParameterSchema } from '../interfaces/provider';\nimport { ToolExecutionError, ValidationError } from '../utils/errors';\nimport type { TUniversalValue } from '../interfaces/types';\n\n/**\n * Function tool implementation\n * Wraps a JavaScript function as a tool with schema validation\n *\n * Implements IFunctionTool without extending AbstractTool to avoid\n * circular runtime dependency (tools -> agents -> tools).\n */\nexport class FunctionTool implements IFunctionTool {\n readonly schema: IToolSchema;\n readonly fn: TToolExecutor;\n private eventService: IEventService | undefined;\n\n constructor(schema: IToolSchema, fn: TToolExecutor) {\n this.schema = schema;\n this.fn = fn;\n this.validateConstructorInputs();\n }\n\n /**\n * Get tool name\n */\n getName(): string {\n return this.schema.name;\n }\n\n /**\n * Set EventService for post-construction injection.\n * Accepts EventService as-is without transformation.\n * Caller is responsible for providing properly configured EventService.\n */\n setEventService(eventService: IEventService | undefined): void {\n this.eventService = eventService;\n }\n\n /**\n * Execute the function tool\n */\n async execute(\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<IToolResult> {\n const toolName = this.schema.name;\n\n // Validate parameters before execution\n if (!this.validate(parameters)) {\n const errors = this.getValidationErrors(parameters);\n throw new ValidationError(`Invalid parameters for tool \"${toolName}\": ${errors.join(', ')}`);\n }\n\n // Execute the function\n const startTime = Date.now();\n let result: TUniversalValue;\n try {\n result = await this.fn(parameters, context);\n } catch (error) {\n if (error instanceof ToolExecutionError || error instanceof ValidationError) {\n throw error;\n }\n\n throw new ToolExecutionError(\n `Function tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n toolName,\n error instanceof Error ? error : new Error(String(error)),\n {\n parameterCount: Object.keys(parameters || {}).length,\n hasContext: !!context,\n },\n );\n }\n\n const executionTime = Date.now() - startTime;\n\n return {\n success: true,\n data: result,\n metadata: {\n executionTime,\n toolName,\n parameters,\n },\n };\n }\n\n /**\n * Validate parameters (simple boolean result)\n */\n validate(parameters: TToolParameters): boolean {\n return this.getValidationErrors(parameters).length === 0;\n }\n\n /**\n * Validate tool parameters with detailed result\n */\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n const errors = this.getValidationErrors(parameters);\n return {\n isValid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get tool description\n */\n getDescription(): string {\n return this.schema.description;\n }\n\n /**\n * Get detailed validation errors\n */\n private getValidationErrors(parameters: TToolParameters): string[] {\n const errors: string[] = [];\n const required = this.schema.parameters.required || [];\n const properties = this.schema.parameters.properties || {};\n\n // Check required parameters\n for (const field of required) {\n if (!(field in parameters)) {\n errors.push(`Missing required parameter: ${field}`);\n }\n }\n\n // Check parameter types and constraints\n for (const [key, value] of Object.entries(parameters)) {\n const paramSchema = properties[key];\n if (!paramSchema) {\n errors.push(`Unknown parameter: ${key}`);\n continue;\n }\n\n const typeError = this.validateParameterType(key, value, paramSchema);\n if (typeError) {\n errors.push(typeError);\n }\n }\n\n return errors;\n }\n\n /**\n * Validate individual parameter type\n */\n private validateParameterType(\n key: string,\n value: TUniversalValue,\n schema: IParameterSchema,\n ): string | undefined {\n const expectedType = schema['type'];\n\n switch (expectedType) {\n case 'string':\n if (typeof value !== 'string') {\n return `Parameter \"${key}\" must be a string, got ${typeof value}`;\n }\n break;\n\n case 'number':\n if (typeof value !== 'number' || isNaN(value)) {\n return `Parameter \"${key}\" must be a number, got ${typeof value}`;\n }\n break;\n\n case 'boolean':\n if (typeof value !== 'boolean') {\n return `Parameter \"${key}\" must be a boolean, got ${typeof value}`;\n }\n break;\n\n case 'array':\n if (!Array.isArray(value)) {\n return `Parameter \"${key}\" must be an array, got ${typeof value}`;\n }\n // Check array items if specified\n if (schema.items) {\n for (let i = 0; i < value.length; i++) {\n const itemError = this.validateParameterType(`${key}[${i}]`, value[i], schema.items);\n if (itemError) {\n return itemError;\n }\n }\n }\n break;\n\n case 'object':\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return `Parameter \"${key}\" must be an object, got ${typeof value}`;\n }\n break;\n }\n\n // Check enum constraints\n if (schema.enum && schema.enum.length > 0) {\n const enumValues = schema.enum;\n let isValidEnum = false;\n\n // Type-safe enum checking based on JSONSchemaEnum type\n for (const enumValue of enumValues) {\n if (value === enumValue) {\n isValidEnum = true;\n break;\n }\n }\n\n if (!isValidEnum) {\n return `Parameter \"${key}\" must be one of: ${enumValues.join(', ')}, got ${value}`;\n }\n }\n\n return undefined;\n }\n\n /**\n * Validate constructor inputs\n */\n private validateConstructorInputs(): void {\n if (!this.schema) {\n throw new ValidationError('Tool schema is required');\n }\n\n if (!this.fn || typeof this.fn !== 'function') {\n throw new ValidationError('Tool function is required and must be a function');\n }\n\n if (!this.schema.name) {\n throw new ValidationError('Tool schema must have a name');\n }\n }\n}\n","import type { IToolManager } from '../interfaces/manager';\nimport type { IToolSchema } from '../interfaces/provider';\nimport type {\n ITool,\n TToolExecutor,\n TToolParameters,\n IToolExecutionContext,\n} from '../interfaces/tool';\nimport type { TUniversalValue } from '../interfaces/types';\nimport { AbstractManager } from '../abstracts/abstract-manager';\nimport { ToolRegistry, FunctionTool } from '../tool-registry';\nimport { ToolExecutionError } from '../utils/errors';\nimport { logger } from '../utils/logger';\n\n/**\n * Tool Manager - manages tool registration and execution\n * Manages tool registration and execution using Tool Registry\n * Instance-based for isolated tool management\n * @internal\n */\nexport class Tools extends AbstractManager implements IToolManager {\n private registry: ToolRegistry;\n private allowedTools?: string[];\n\n constructor() {\n super();\n this.registry = new ToolRegistry();\n }\n\n /**\n * Initialize the manager\n */\n protected async doInitialize(): Promise<void> {\n logger.debug('Tools initialized');\n }\n\n /**\n * Cleanup manager resources\n */\n protected async doDispose(): Promise<void> {\n this.registry.clear();\n delete this.allowedTools;\n logger.debug('Tools disposed');\n }\n\n /**\n * Register a tool with schema and executor function\n */\n addTool(schema: IToolSchema, executor: TToolExecutor): void {\n this.ensureInitialized();\n\n const tool = new FunctionTool(schema, executor);\n this.registry.register(tool);\n\n logger.debug(`Tool \"${schema.name}\" registered successfully`);\n }\n\n /**\n * Remove a tool by name\n */\n removeTool(name: string): void {\n this.ensureInitialized();\n this.registry.unregister(name);\n }\n\n /**\n * Get tool interface by name\n */\n getTool(name: string): ITool | undefined {\n this.ensureInitialized();\n return this.registry.get(name);\n }\n\n /**\n * Get tool schema by name\n */\n getToolSchema(name: string): IToolSchema | undefined {\n this.ensureInitialized();\n const tool = this.registry.get(name);\n return tool?.schema;\n }\n\n /**\n * Get all registered tool schemas\n */\n getTools(): IToolSchema[] {\n this.ensureInitialized();\n\n const schemas = this.registry.getSchemas();\n\n // Filter by allowed tools if set\n if (this.allowedTools) {\n return schemas.filter((schema) => this.allowedTools!.includes(schema.name));\n }\n\n return schemas;\n }\n\n /**\n * Execute a tool with parameters\n */\n async executeTool(\n name: string,\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<TUniversalValue> {\n this.ensureInitialized();\n\n // Check if tool is allowed\n if (this.allowedTools && !this.allowedTools.includes(name)) {\n throw new ToolExecutionError(`Tool \"${name}\" is not in the allowed tools list`, name);\n }\n\n const tool = this.registry.get(name);\n if (!tool) {\n throw new ToolExecutionError(`Tool \"${name}\" is not registered`, name);\n }\n\n let result;\n try {\n result = await tool.execute(parameters, context);\n } catch (error) {\n // Re-wrap errors thrown by tools to ensure instanceof checks work\n // when tools are loaded from dist packages\n if (error instanceof Error) {\n throw new ToolExecutionError(error.message, name, error);\n }\n throw new ToolExecutionError(String(error), name);\n }\n\n if (!result.success) {\n throw new ToolExecutionError(result.error || 'Tool execution failed', name, undefined, {\n parameters: JSON.stringify(parameters),\n result: JSON.stringify(result),\n });\n }\n\n if (typeof result.data === 'undefined') {\n throw new ToolExecutionError('Tool execution succeeded but returned no data', name);\n }\n return result.data;\n }\n\n /**\n * Check if tool exists\n */\n hasTool(name: string): boolean {\n this.ensureInitialized();\n return this.registry.has(name);\n }\n\n /**\n * Set allowed tools for filtering\n */\n setAllowedTools(tools: string[]): void {\n this.ensureInitialized();\n this.allowedTools = [...tools];\n logger.debug(`Set allowed tools: ${tools.join(', ')}`);\n }\n\n /**\n * Get allowed tools\n */\n getAllowedTools(): string[] | undefined {\n this.ensureInitialized();\n return this.allowedTools ? [...this.allowedTools] : undefined;\n }\n\n /**\n * Get tool registry instance (for advanced operations)\n */\n getRegistry(): ToolRegistry {\n this.ensureInitialized();\n return this.registry;\n }\n\n /**\n * Get tool count\n */\n getToolCount(): number {\n this.ensureInitialized();\n return this.registry.size();\n }\n}\n","import type { IAgentTemplate, IAgentConfig } from '../interfaces/agent';\nimport { createLogger, type ILogger } from '../utils/logger';\n\n/**\n * Reusable type definitions for agent templates\n */\n\n/**\n * Agent template configuration data type\n * Used for storing template configuration values\n */\nexport type TAgentTemplateConfigurationData = Record<\n string,\n string | number | boolean | string[] | number[] | boolean[]\n>;\n\n/**\n * Template application result\n */\nexport interface ITemplateApplicationResult {\n /** Applied configuration */\n config: IAgentConfig;\n /** Template that was applied */\n template: IAgentTemplate;\n /** Any warnings during application */\n warnings: string[];\n /** Whether config was modified during application */\n modified: boolean;\n}\n\n/**\n * Agent Templates implementation\n * Manages agent templates for AgentFactory\n * Instance-based for isolated template management\n */\nexport class AgentTemplates {\n private templates = new Map<string, IAgentTemplate>();\n private logger: ILogger;\n\n constructor() {\n this.logger = createLogger('AgentTemplates');\n this.logger.info('AgentTemplates initialized');\n }\n\n /**\n * Register a template\n */\n registerTemplate(template: IAgentTemplate): void {\n if (!template.id) {\n throw new Error('Template must have an ID');\n }\n\n if (this.templates.has(template.id)) {\n this.logger.warn(`Template \"${template.id}\" is already registered, overriding`);\n }\n\n this.templates.set(template.id, template);\n this.logger.info(`Template \"${template.id}\" registered successfully`, {\n templateId: template.id,\n category: template.category,\n tags: template.tags,\n });\n }\n\n /**\n * Unregister a template\n */\n unregisterTemplate(templateId: string): boolean {\n const removed = this.templates.delete(templateId);\n if (removed) {\n this.logger.info(`Template \"${templateId}\" unregistered`);\n } else {\n this.logger.warn(`Attempted to unregister non-existent template \"${templateId}\"`);\n }\n return removed;\n }\n\n /**\n * Get all templates\n */\n getTemplates(): IAgentTemplate[] {\n return Array.from(this.templates.values());\n }\n\n /**\n * Get template by ID\n */\n getTemplate(templateId: string): IAgentTemplate | undefined {\n return this.templates.get(templateId);\n }\n\n /**\n * Find templates by criteria\n */\n findTemplates(criteria: {\n category?: string;\n tags?: string[];\n provider?: string;\n model?: string;\n }): IAgentTemplate[] {\n return this.getTemplates().filter((template) => {\n // Check category\n if (criteria.category && template.category !== criteria.category) {\n return false;\n }\n\n // Check tags\n if (criteria.tags && criteria.tags.length > 0) {\n const hasAnyTag = criteria.tags.some((tag) => template.tags?.includes(tag));\n if (!hasAnyTag) {\n return false;\n }\n }\n\n // Check provider\n if (criteria.provider && template.config.defaultModel?.provider !== criteria.provider) {\n return false;\n }\n\n // Check model\n if (criteria.model && template.config.defaultModel?.model !== criteria.model) {\n return false;\n }\n\n return true;\n });\n }\n\n /**\n * Apply template to configuration\n */\n applyTemplate(\n template: IAgentTemplate,\n overrides: Partial<IAgentConfig> = {},\n ): ITemplateApplicationResult {\n const warnings: string[] = [];\n let modified = false;\n\n // Start with template configuration\n const config: IAgentConfig = { ...template.config };\n\n // Apply overrides with type-safe approach\n const mergedConfig: IAgentConfig = { ...config, ...overrides };\n\n // Check for modifications by comparing specific known fields\n const checkField = (fieldName: keyof IAgentConfig): void => {\n if (fieldName in overrides && config[fieldName] !== overrides[fieldName]) {\n modified = true;\n if (config[fieldName] !== undefined) {\n warnings.push(\n `Override: ${fieldName} changed from \"${String(config[fieldName])}\" to \"${String(overrides[fieldName])}\"`,\n );\n }\n }\n };\n\n // Check common override fields\n if (overrides.name !== undefined) checkField('name');\n if (overrides.systemMessage !== undefined) checkField('systemMessage');\n\n // Use the merged config\n const finalConfig = mergedConfig;\n\n this.logger.debug('Template applied', {\n templateId: template.id,\n overridesCount: Object.keys(overrides).length,\n warningsCount: warnings.length,\n modified,\n });\n\n return {\n config: finalConfig,\n template,\n warnings,\n modified,\n };\n }\n\n /**\n * Check if template exists\n */\n hasTemplate(templateId: string): boolean {\n return this.templates.has(templateId);\n }\n\n /**\n * Get template count\n */\n getTemplateCount(): number {\n return this.templates.size;\n }\n\n /**\n * Clear all templates\n */\n clearAll(): void {\n this.templates.clear();\n this.logger.info('All templates cleared');\n }\n\n /**\n * Get template statistics\n */\n getStats(): {\n totalTemplates: number;\n categories: string[];\n tags: string[];\n providers: string[];\n models: string[];\n } {\n const templates = this.getTemplates();\n const categories = [\n ...new Set(\n templates\n .map((t) => t.category)\n .filter(\n (category): category is string => typeof category === 'string' && category.length > 0,\n ),\n ),\n ];\n const tags = [...new Set(templates.flatMap((t) => t.tags || []))];\n const providers = [\n ...new Set(\n templates\n .map((t) => t.config.defaultModel?.provider)\n .filter(\n (provider): provider is string => typeof provider === 'string' && provider.length > 0,\n ),\n ),\n ];\n const models = [\n ...new Set(\n templates\n .map((t) => t.config.defaultModel?.model)\n .filter((model): model is string => typeof model === 'string' && model.length > 0),\n ),\n ];\n\n return {\n totalTemplates: templates.length,\n categories,\n tags,\n providers,\n models,\n };\n }\n}\n","import type { IAgent, IAgentConfig } from '../interfaces/agent';\nimport { ConfigurationError } from '../utils/errors';\n\nconst MAX_CONCURRENT_AGENTS = 100;\nconst DEFAULT_TEMPERATURE = 0.7;\nconst ID_RADIX = 36;\nconst AGENT_ID_SUBSTR_END = 8;\n\n/**\n * Configuration options for AgentFactory\n */\nexport interface IAgentFactoryOptions {\n /** Default model to use if not specified in config */\n defaultModel?: string;\n /** Default provider to use if not specified in config */\n defaultProvider?: string;\n /** Maximum number of concurrent agents */\n maxConcurrentAgents?: number;\n /** Default system message for agents */\n defaultSystemMessage?: string;\n /** Enable strict configuration validation */\n strictValidation?: boolean;\n}\n\n/**\n * Agent creation statistics\n */\nexport interface IAgentCreationStats {\n /** Total number of agents created */\n totalCreated: number;\n /** Number of currently active agents */\n activeCount: number;\n /** Number of agents created from templates */\n fromTemplates: number;\n /** Number of custom configured agents */\n customConfigured: number;\n /** Template vs custom creation ratio (fromTemplates / totalCreated) */\n templateUsageRatio: number;\n}\n\n/**\n * Agent lifecycle events\n */\nexport interface IAgentLifecycleEvents {\n /** Called before agent creation */\n beforeCreate?: (config: IAgentConfig) => Promise<void> | void;\n /** Called after successful agent creation */\n afterCreate?: (agent: IAgent<IAgentConfig>, config: IAgentConfig) => Promise<void> | void;\n /** Called when agent creation fails */\n onCreateError?: (error: Error, config: IAgentConfig) => Promise<void> | void;\n /** Called when agent is destroyed */\n onDestroy?: (agentId: string) => Promise<void> | void;\n}\n\n/** Resolved (all-required) factory options */\nexport type TResolvedFactoryOptions = Required<IAgentFactoryOptions>;\n\n/**\n * Build a Required<IAgentFactoryOptions> from partial user input.\n */\nexport function resolveFactoryOptions(options: IAgentFactoryOptions): TResolvedFactoryOptions {\n return {\n defaultModel: options.defaultModel || 'gpt-4',\n defaultProvider: options.defaultProvider || 'openai',\n maxConcurrentAgents: options.maxConcurrentAgents || MAX_CONCURRENT_AGENTS,\n defaultSystemMessage: options.defaultSystemMessage || 'You are a helpful AI assistant.',\n strictValidation: options.strictValidation ?? true,\n };\n}\n\n/**\n * Apply default configuration values to a partial agent config.\n */\nexport function applyAgentDefaults(\n config: Partial<IAgentConfig>,\n options: TResolvedFactoryOptions,\n): IAgentConfig {\n if (!config.aiProviders || config.aiProviders.length === 0) {\n throw new ConfigurationError('At least one AI provider must be specified in aiProviders array');\n }\n\n const defaultModel = config.defaultModel || {\n provider: config.aiProviders[0]?.name || options.defaultProvider,\n model: options.defaultModel,\n temperature: 0.7,\n systemMessage: options.defaultSystemMessage,\n };\n\n return {\n id: config.id || generateAgentId(),\n name: config.name || 'Unnamed Agent',\n aiProviders: config.aiProviders,\n defaultModel: {\n provider: defaultModel.provider,\n model: defaultModel.model,\n temperature: defaultModel.temperature ?? DEFAULT_TEMPERATURE,\n ...(defaultModel.maxTokens !== undefined && { maxTokens: defaultModel.maxTokens }),\n ...(defaultModel.topP !== undefined && { topP: defaultModel.topP }),\n systemMessage: defaultModel.systemMessage || options.defaultSystemMessage,\n },\n tools: config.tools || [],\n plugins: config.plugins || [],\n metadata: config.metadata || {},\n ...(config.logging && { logging: config.logging }),\n ...(config.conversationId && { conversationId: config.conversationId }),\n ...config,\n };\n}\n\n/**\n * Generate a unique agent ID.\n */\nexport function generateAgentId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(ID_RADIX).substring(2, AGENT_ID_SUBSTR_END);\n return `agent_${timestamp}_${random}`;\n}\n\n/**\n * Update creation statistics in-place and return the updated object.\n */\nexport function updateCreationStats(\n stats: IAgentCreationStats,\n fromTemplate: boolean,\n): IAgentCreationStats {\n stats.totalCreated++;\n stats.activeCount++;\n\n if (fromTemplate) {\n stats.fromTemplates++;\n } else {\n stats.customConfigured++;\n }\n\n stats.templateUsageRatio = stats.totalCreated > 0 ? stats.fromTemplates / stats.totalCreated : 0;\n\n return stats;\n}\n\n// Re-export constant so consumers can use it if needed\nexport { MAX_CONCURRENT_AGENTS };\n","import type { IAgent, IAgentConfig, IAgentTemplate } from '../interfaces/agent';\nimport { ConfigurationError, ValidationError } from '../utils/errors';\nimport { validateAgentConfig } from '../utils/validation';\nimport { createLogger, type ILogger } from '../utils/logger';\nimport { AgentTemplates, type ITemplateApplicationResult } from './agent-templates';\nimport {\n applyAgentDefaults,\n generateAgentId,\n resolveFactoryOptions,\n updateCreationStats,\n type IAgentFactoryOptions,\n type IAgentCreationStats,\n type IAgentLifecycleEvents,\n type TResolvedFactoryOptions,\n} from './agent-factory-helpers';\n\nexport type {\n IAgentFactoryOptions,\n IAgentCreationStats,\n IAgentLifecycleEvents,\n} from './agent-factory-helpers';\n\n/**\n * Agent Factory for creating and managing agents\n * Instance-based for isolated agent factory management\n */\nexport class AgentFactory {\n private agentTemplates: AgentTemplates;\n private initialized = false;\n private logger: ILogger;\n private options: TResolvedFactoryOptions;\n private activeAgents: Map<string, IAgent<IAgentConfig>>;\n private creationStats: IAgentCreationStats;\n private lifecycleEvents: IAgentLifecycleEvents;\n\n constructor(options: IAgentFactoryOptions = {}, lifecycleEvents: IAgentLifecycleEvents = {}) {\n this.agentTemplates = new AgentTemplates();\n this.logger = createLogger('AgentFactory');\n this.options = resolveFactoryOptions(options);\n this.activeAgents = new Map();\n this.creationStats = {\n totalCreated: 0,\n activeCount: 0,\n fromTemplates: 0,\n customConfigured: 0,\n templateUsageRatio: 0,\n };\n this.lifecycleEvents = lifecycleEvents;\n\n this.logger.debug('AgentFactory initialized', {\n maxConcurrentAgents: this.options.maxConcurrentAgents,\n strictValidation: this.options.strictValidation,\n hasDefaultModel: !!this.options.defaultModel,\n hasDefaultProvider: !!this.options.defaultProvider,\n hasLifecycleEvents: this.lifecycleEvents !== null,\n });\n }\n\n /**\n * Initialize the factory\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n this.logger.debug('Initializing AgentFactory');\n this.initialized = true;\n this.logger.debug('AgentFactory initialization completed');\n }\n\n /**\n * Create a new agent instance\n */\n async createAgent(\n AgentClass: new (config: IAgentConfig) => IAgent<IAgentConfig>,\n config: Partial<IAgentConfig>,\n fromTemplate: boolean = false,\n ): Promise<IAgent<IAgentConfig>> {\n // Apply defaults before try so fullConfig is available in catch\n let fullConfig: IAgentConfig | undefined;\n try {\n // Check concurrent agent limit\n if (this.activeAgents.size >= this.options.maxConcurrentAgents) {\n throw new ConfigurationError(\n `Maximum concurrent agents limit reached: ${this.options.maxConcurrentAgents}`,\n );\n }\n\n // Apply default configuration\n fullConfig = applyAgentDefaults(config, this.options);\n\n // Validate configuration\n if (this.options.strictValidation) {\n const validation = validateAgentConfig(fullConfig);\n if (!validation.isValid) {\n throw new ValidationError(`Invalid agent configuration: ${validation.errors.join(', ')}`);\n }\n }\n\n // Call before create lifecycle event\n if (this.lifecycleEvents.beforeCreate) {\n await this.lifecycleEvents.beforeCreate(fullConfig);\n }\n\n // Create agent instance\n const agent = new AgentClass(fullConfig);\n\n // Initialize agent if it has an initialize method\n interface IInitializableAgent {\n initialize(): Promise<void>;\n }\n const maybeInitializable = agent as Partial<IInitializableAgent>;\n if (typeof maybeInitializable.initialize === 'function') {\n await maybeInitializable.initialize();\n }\n\n // Track agent\n const agentId = generateAgentId();\n this.activeAgents.set(agentId, agent);\n\n // Update statistics\n updateCreationStats(this.creationStats, fromTemplate);\n\n // Call after create lifecycle event\n if (this.lifecycleEvents.afterCreate) {\n await this.lifecycleEvents.afterCreate(agent, fullConfig);\n }\n\n this.logger.info('Agent created successfully', {\n agentId,\n model: fullConfig.defaultModel.model,\n provider: fullConfig.defaultModel.provider,\n });\n\n return agent;\n } catch (error) {\n // Call error lifecycle event\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n if (this.lifecycleEvents.onCreateError && fullConfig) {\n await this.lifecycleEvents.onCreateError(normalizedError, fullConfig);\n }\n\n this.logger.error('Failed to create agent', {\n error: normalizedError.message,\n model: config.defaultModel?.model,\n provider: config.defaultModel?.provider,\n hasTools: !!config.tools?.length,\n });\n throw normalizedError;\n }\n }\n\n /**\n * Create agent from template\n */\n async createFromTemplate(\n AgentClass: new (config: IAgentConfig) => IAgent<IAgentConfig>,\n templateId: string,\n overrides: Partial<IAgentConfig> = {},\n ): Promise<IAgent<IAgentConfig>> {\n const template = this.agentTemplates.getTemplate(templateId);\n if (!template) {\n throw new ConfigurationError(`Template not found: ${templateId}`);\n }\n\n // Apply template to configuration\n const templateResult = this.applyTemplate(template, overrides);\n\n if (templateResult.warnings.length > 0) {\n this.logger.warn('Template application warnings', {\n templateId,\n warnings: templateResult.warnings,\n });\n }\n\n // Create agent with template configuration\n const agent = await this.createAgent(AgentClass, templateResult.config, true);\n\n this.logger.info('Agent created from template', {\n templateId,\n modified: templateResult.modified,\n warnings: templateResult.warnings.length,\n });\n\n return agent;\n }\n\n /**\n * Register a template\n */\n registerTemplate(template: IAgentTemplate): void {\n this.agentTemplates.registerTemplate(template);\n }\n\n /**\n * Unregister a template\n */\n unregisterTemplate(templateId: string): boolean {\n return this.agentTemplates.unregisterTemplate(templateId);\n }\n\n /**\n * Get all templates\n */\n getTemplates(): IAgentTemplate[] {\n return this.agentTemplates.getTemplates();\n }\n\n /**\n * Get template by ID\n */\n getTemplate(templateId: string): IAgentTemplate | undefined {\n return this.agentTemplates.getTemplate(templateId);\n }\n\n /**\n * Find templates by criteria\n */\n findTemplates(criteria: {\n category?: string;\n tags?: string[];\n provider?: string;\n model?: string;\n }): IAgentTemplate[] {\n return this.agentTemplates.findTemplates(criteria);\n }\n\n /**\n * Apply template to configuration\n */\n applyTemplate(\n template: IAgentTemplate,\n overrides: Partial<IAgentConfig> = {},\n ): ITemplateApplicationResult {\n return this.agentTemplates.applyTemplate(\n template,\n overrides as import('../interfaces/types').TConfigData,\n );\n }\n\n /**\n * Destroy an agent\n */\n async destroyAgent(agentId: string): Promise<boolean> {\n const agent = this.activeAgents.get(agentId);\n if (!agent) {\n return false;\n }\n\n try {\n // Cleanup agent if it has a cleanup method\n interface ICleanableAgent {\n cleanup(): Promise<void>;\n }\n const maybeCleanable = agent as Partial<ICleanableAgent>;\n if (typeof maybeCleanable.cleanup === 'function') {\n await maybeCleanable.cleanup();\n }\n\n // Remove from tracking\n this.activeAgents.delete(agentId);\n this.creationStats.activeCount--;\n\n // Call destroy lifecycle event\n if (this.lifecycleEvents.onDestroy) {\n await this.lifecycleEvents.onDestroy(agentId);\n }\n\n this.logger.info('Agent destroyed', { agentId });\n return true;\n } catch (error) {\n this.logger.error('Error destroying agent', {\n agentId,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n /**\n * Get creation statistics\n */\n getCreationStats(): IAgentCreationStats {\n return { ...this.creationStats };\n }\n\n /**\n * Get all active agents\n */\n getActiveAgents(): Map<string, IAgent<IAgentConfig>> {\n return new Map(this.activeAgents);\n }\n\n /**\n * Validate agent configuration\n */\n validateConfiguration(config: Partial<IAgentConfig>): { isValid: boolean; errors: string[] } {\n return validateAgentConfig(config);\n }\n}\n","/**\n * Configuration and tool management delegate for the Robota agent.\n *\n * Extracted from robota.ts to keep the main class under 300 lines.\n */\nimport type { IAgentConfig, IExecutionContextInjection } from '../interfaces/agent';\nimport type { IToolWithEventService } from '../abstracts/abstract-tool';\nimport type { AbstractTool } from '../abstracts/abstract-tool';\nimport type { AIProviders } from '../managers/ai-provider-manager';\nimport type { Tools } from '../managers/tool-manager';\nimport type { IEventService } from '../interfaces/event-service';\nimport type { ILogger } from '../utils/logger';\nimport type { IToolExecutionContext, TToolParameters } from '../interfaces/tool';\nimport type { TUniversalValue } from '../interfaces/types';\nimport { ConfigurationError } from '../utils/errors';\nimport { AGENT_EVENTS } from '../agents/constants';\n\n/** Agent statistics metadata type */\nexport type TAgentStatsMetadata = Record<string, string | number | boolean | Date | string[]>;\n\n/**\n * Validates the agent configuration format.\n * @internal\n */\nexport function validateAgentConfig(config: IAgentConfig): void {\n if (!config.name) {\n throw new ConfigurationError('Agent name is required', { component: 'Robota' });\n }\n\n if (!config.aiProviders || config.aiProviders.length === 0) {\n throw new ConfigurationError('At least one AI provider is required', { component: 'Robota' });\n }\n\n if (!config.defaultModel) {\n throw new ConfigurationError('Default model configuration is required', {\n component: 'Robota',\n });\n }\n\n if (!config.defaultModel.provider || !config.defaultModel.model) {\n throw new ConfigurationError('Default model must specify both provider and model', {\n component: 'Robota',\n });\n }\n\n const providerNames = config.aiProviders.map((p) => p.name);\n const duplicates = providerNames.filter((name, index) => providerNames.indexOf(name) !== index);\n if (duplicates.length > 0) {\n throw new ConfigurationError(`Duplicate AI provider names: ${duplicates.join(', ')}`, {\n component: 'Robota',\n duplicates,\n });\n }\n\n if (!providerNames.includes(config.defaultModel.provider)) {\n throw new ConfigurationError(\n `Default provider '${config.defaultModel.provider}' not found in AI providers list. Available: ${providerNames.join(', ')}`,\n {\n component: 'Robota',\n defaultProvider: config.defaultModel.provider,\n availableProviders: providerNames,\n },\n );\n }\n}\n\n/**\n * Manages model/tool/config updates on behalf of a Robota instance.\n * @internal\n */\nexport class RobotaConfigManager {\n constructor(\n private readonly logger: ILogger,\n private readonly getAIProviders: () => AIProviders,\n private readonly getTools: () => Tools,\n private readonly getEventService: () => IEventService | undefined,\n private readonly isReady: () => boolean,\n private readonly ensureReady: () => Promise<void>,\n private readonly getConfig: () => IAgentConfig,\n private readonly setConfig: (c: IAgentConfig) => void,\n private readonly getConfigVersion: () => number,\n private readonly bumpConfigVersion: () => number,\n private readonly getConfigUpdatedAt: () => number,\n private readonly setConfigUpdatedAt: (t: number) => void,\n private readonly emitAgentEvent: (eventType: string, data: Record<string, unknown>) => void,\n ) {}\n\n /** Update tools for this agent instance. */\n async updateTools(next: Array<IToolWithEventService>): Promise<{ version: number }> {\n await this.ensureReady();\n\n if (!Array.isArray(next)) {\n throw new ConfigurationError('updateTools: next must be an array of tools');\n }\n\n const registry = this.getTools().getRegistry();\n registry.clear();\n\n const toolNames: string[] = [];\n const eventService = this.getEventService();\n for (const tool of next) {\n if (eventService) {\n tool.setEventService(eventService);\n }\n const toolExecutor = async (\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<TUniversalValue> => {\n if (!context) {\n throw new Error('[ROBOTA] Missing ToolExecutionContext for tool execution');\n }\n const result = await tool.execute(parameters, context);\n return result.data;\n };\n this.getTools().addTool(tool.schema, toolExecutor);\n const nm = tool.schema.name;\n if (typeof nm === 'string' && nm.length > 0) toolNames.push(nm);\n }\n\n const config = this.getConfig();\n config.tools = next;\n this.setConfig(config);\n const version = this.bumpConfigVersion();\n this.setConfigUpdatedAt(Date.now());\n\n this.emitAgentEvent(AGENT_EVENTS.CONFIG_UPDATED, {\n parameters: {\n tools: toolNames,\n systemMessage: config.defaultModel.systemMessage,\n provider: config.defaultModel.provider,\n model: config.defaultModel.model,\n temperature: config.defaultModel.temperature,\n maxTokens: config.defaultModel.maxTokens,\n },\n metadata: { version },\n });\n\n return { version };\n }\n\n /** Update configuration partially. Currently supports tools. */\n async updateConfiguration(patch: Partial<IAgentConfig>): Promise<{ version: number }> {\n if (patch.tools) {\n return this.updateTools(patch.tools);\n }\n throw new ConfigurationError('updateConfiguration: only tools patch is supported at this time');\n }\n\n /** Read-only configuration overview for UI. */\n async getConfiguration(): Promise<{\n version: number;\n tools: Array<{ name: string; parameters?: string[] }>;\n updatedAt: number;\n metadata?: TAgentStatsMetadata;\n }> {\n await this.ensureReady();\n const schemas = this.getTools().getTools();\n const tools = schemas.map((s) => ({\n name: s.name,\n parameters: (() => {\n const params = s.parameters as { properties?: Record<string, object> } | undefined;\n const props = params?.properties;\n return props && typeof props === 'object' ? Object.keys(props) : undefined;\n })(),\n }));\n return {\n version: this.getConfigVersion(),\n tools,\n updatedAt: this.getConfigUpdatedAt(),\n metadata: undefined,\n };\n }\n\n /** Set the current model configuration (complete replacement). */\n setModel(modelConfig: {\n provider: string;\n model: string;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n systemMessage?: string;\n }): void {\n if (!modelConfig.provider || !modelConfig.model) {\n throw new ConfigurationError('Both provider and model are required', { component: 'Robota' });\n }\n\n if (!this.isReady()) {\n throw new ConfigurationError(\n 'Agent must be fully initialized before changing model configuration',\n { component: 'Robota' },\n );\n }\n\n const aiProviders = this.getAIProviders();\n const availableProviders = aiProviders.getProviderNames();\n if (!availableProviders.includes(modelConfig.provider)) {\n throw new ConfigurationError(\n `AI Provider '${modelConfig.provider}' not found. Available: ${availableProviders.join(', ')}`,\n { component: 'Robota', provider: modelConfig.provider, availableProviders },\n );\n }\n\n aiProviders.setCurrentProvider(modelConfig.provider, modelConfig.model);\n\n const config = this.getConfig();\n this.setConfig({\n ...config,\n defaultModel: {\n ...config.defaultModel,\n provider: modelConfig.provider,\n model: modelConfig.model,\n ...(modelConfig.temperature !== undefined && { temperature: modelConfig.temperature }),\n ...(modelConfig.maxTokens !== undefined && { maxTokens: modelConfig.maxTokens }),\n ...(modelConfig.topP !== undefined && { topP: modelConfig.topP }),\n ...(modelConfig.systemMessage !== undefined && {\n systemMessage: modelConfig.systemMessage,\n }),\n },\n });\n\n this.logger.debug('Model configuration updated', modelConfig);\n }\n\n /** Get the current model configuration. */\n getModel(): {\n provider: string;\n model: string;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n systemMessage?: string;\n } {\n if (!this.isReady()) {\n throw new ConfigurationError(\n 'Agent must be fully initialized before getting model configuration',\n { component: 'Robota' },\n );\n }\n\n const currentProviderInfo = this.getAIProviders().getCurrentProvider();\n if (!currentProviderInfo) {\n throw new ConfigurationError('No provider is currently set', { component: 'Robota' });\n }\n\n const config = this.getConfig();\n return {\n provider: currentProviderInfo.provider,\n model: currentProviderInfo.model,\n ...(config.defaultModel.temperature !== undefined && {\n temperature: config.defaultModel.temperature,\n }),\n ...(config.defaultModel.maxTokens !== undefined && {\n maxTokens: config.defaultModel.maxTokens,\n }),\n ...(config.defaultModel.topP !== undefined && { topP: config.defaultModel.topP }),\n ...(config.defaultModel.systemMessage !== undefined && {\n systemMessage: config.defaultModel.systemMessage,\n }),\n };\n }\n\n /** Register a new tool for function calling. */\n registerTool(tool: AbstractTool, tools: Tools): void {\n if (tools.hasTool(tool.schema.name)) {\n throw new Error(\n `[STRICT-POLICY][EMITTER-CONTRACT] Duplicate tool registration attempted: ${tool.schema.name}. ` +\n `Tool registration flow must provide a single authoritative registration path.`,\n );\n }\n\n const toolExecutor = async (\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<TUniversalValue> => {\n if (!context) {\n throw new Error('[ROBOTA] Missing ToolExecutionContext for tool execution');\n }\n const result = await tool.execute(parameters, context);\n return result.data;\n };\n tools.addTool(tool.schema, toolExecutor);\n this.logger.debug('Tool registered', { toolName: tool.schema.name });\n }\n}\n","/**\n * Module management delegate for the Robota agent.\n *\n * Extracted from robota.ts to keep the main class under 300 lines.\n * All public method signatures are preserved via delegation.\n */\nimport type { IModule } from '../abstracts/abstract-module';\nimport type { ModuleRegistry } from '../managers/module-registry';\nimport type { IModuleResultData, IModuleExecutionContext } from '../abstracts/abstract-module';\nimport type { ILogger } from '../utils/logger';\n\n/**\n * Manages module lifecycle on behalf of a Robota instance.\n * @internal\n */\nexport class RobotaModuleManager {\n constructor(\n private readonly agentName: string,\n private readonly moduleRegistry: ModuleRegistry,\n private readonly logger: ILogger,\n private readonly isReady: () => boolean,\n private readonly ensureReady: () => Promise<void>,\n ) {}\n\n /**\n * Register a new module with the agent\n */\n async registerModule(\n module: IModule,\n options?: { autoInitialize?: boolean; validateDependencies?: boolean },\n ): Promise<void> {\n await this.ensureReady();\n\n await this.moduleRegistry.registerModule(module, {\n autoInitialize: options?.autoInitialize ?? true,\n validateDependencies: options?.validateDependencies ?? true,\n });\n\n this.logger.info('Module registered', {\n moduleName: module.name,\n moduleType: module.getModuleType().type,\n });\n }\n\n /**\n * Unregister a module from the agent\n */\n async unregisterModule(moduleName: string): Promise<boolean> {\n if (!this.isReady()) {\n return false;\n }\n\n const result = await this.moduleRegistry.unregisterModule(moduleName);\n\n if (result) {\n this.logger.info('Module unregistered', { moduleName });\n }\n\n return result;\n }\n\n /**\n * Get a module by name\n */\n getModule(moduleName: string): IModule | undefined {\n if (!this.isReady()) {\n return undefined;\n }\n return this.moduleRegistry.getModule(moduleName);\n }\n\n /**\n * Get modules by type\n */\n getModulesByType(moduleType: string): IModule[] {\n if (!this.isReady()) {\n return [];\n }\n return this.moduleRegistry.getModulesByType(moduleType);\n }\n\n /**\n * Get all registered modules\n */\n getModules(): IModule[] {\n if (!this.isReady()) {\n return [];\n }\n return this.moduleRegistry.getAllModules();\n }\n\n /**\n * Get all registered module names\n */\n getModuleNames(): string[] {\n if (!this.isReady()) {\n return [];\n }\n return this.moduleRegistry.getModuleNames();\n }\n\n /**\n * Check if a module is registered\n */\n hasModule(moduleName: string): boolean {\n if (!this.isReady()) {\n return false;\n }\n return this.moduleRegistry.hasModule(moduleName);\n }\n\n /**\n * Execute a module by name\n */\n async executeModule(\n moduleName: string,\n context: {\n executionId?: string;\n sessionId?: string;\n userId?: string;\n metadata?: Record<string, string | number | boolean | Date>;\n },\n ): Promise<{ success: boolean; data?: IModuleResultData; error?: Error; duration?: number }> {\n await this.ensureReady();\n\n const executionContext: IModuleExecutionContext = {\n agentName: this.agentName,\n ...(context.executionId && { executionId: context.executionId }),\n ...(context.sessionId && { sessionId: context.sessionId }),\n ...(context.userId && { userId: context.userId }),\n ...(context.metadata && { metadata: context.metadata }),\n };\n\n return await this.moduleRegistry.executeModule(moduleName, executionContext);\n }\n\n /**\n * Get module execution statistics\n */\n getModuleStats(moduleName: string):\n | {\n totalExecutions: number;\n successfulExecutions: number;\n failedExecutions: number;\n averageExecutionTime: number;\n lastExecutionTime?: Date;\n }\n | undefined {\n if (!this.isReady()) {\n return undefined;\n }\n return this.moduleRegistry.getModuleStats(moduleName);\n }\n}\n","/**\n * Plugin management delegate for the Robota agent.\n *\n * Extracted from robota.ts to keep the main class under 300 lines.\n * All public method signatures are preserved via delegation.\n */\nimport type {\n IPluginContract,\n IPluginHooks,\n IPluginOptions,\n IPluginStats,\n} from '../abstracts/abstract-plugin';\nimport type { ExecutionService } from '../services/execution-service';\nimport type { ILogger } from '../utils/logger';\nimport { ConfigurationError } from '../utils/errors';\n\n/**\n * Manages plugin lifecycle on behalf of a Robota instance.\n * @internal\n */\nexport class RobotaPluginManager {\n constructor(\n private readonly logger: ILogger,\n private readonly isReady: () => boolean,\n private readonly getExecutionService: () => ExecutionService | undefined,\n ) {}\n\n /**\n * Add a plugin to the agent at runtime.\n */\n addPlugin(plugin: IPluginContract<IPluginOptions, IPluginStats> & IPluginHooks): void {\n const executionService = this.getExecutionService();\n if (!this.isReady() || !executionService) {\n throw new ConfigurationError(\n 'Cannot add plugin before agent is fully initialized. Await an operation like run() first, or pass plugins via the constructor config.',\n { pluginName: plugin.name },\n );\n }\n executionService.registerPlugin(plugin);\n this.logger.debug('Plugin added', { pluginName: plugin.name });\n }\n\n /**\n * Remove a plugin from the agent by name.\n */\n removePlugin(pluginName: string): boolean {\n const executionService = this.getExecutionService();\n if (!executionService) {\n return false;\n }\n const removed = executionService.removePlugin(pluginName);\n if (removed) {\n this.logger.debug('Plugin removed', { pluginName });\n }\n return removed;\n }\n\n /**\n * Get a specific plugin by name.\n */\n getPlugin(\n pluginName: string,\n ): (IPluginContract<IPluginOptions, IPluginStats> & IPluginHooks) | undefined {\n const executionService = this.getExecutionService();\n if (!executionService) {\n return undefined;\n }\n return executionService.getPlugin(pluginName);\n }\n\n /**\n * Get all registered plugins.\n */\n getPlugins(): Array<IPluginContract<IPluginOptions, IPluginStats> & IPluginHooks> {\n const executionService = this.getExecutionService();\n if (!executionService) {\n return [];\n }\n return executionService.getPlugins();\n }\n\n /**\n * Get all registered plugin names.\n */\n getPluginNames(): string[] {\n const executionService = this.getExecutionService();\n if (!this.isReady() || !executionService) {\n return [];\n }\n return executionService.getPlugins().map((plugin) => plugin.name);\n }\n}\n","/**\n * Factory functions for creating the Robota delegate managers.\n *\n * Extracted from core/robota.ts to keep that file under 300 lines.\n * Creates RobotaModuleManager, RobotaPluginManager, and RobotaConfigManager\n * with all required closures bound to the Robota instance state.\n */\nimport type { ILogger } from '../utils/logger';\nimport type { IAgentConfig } from '../interfaces/agent';\nimport type { IAgentEventData } from '../interfaces/event-service';\nimport type { AIProviders } from '../managers/ai-provider-manager';\nimport type { Tools } from '../managers/tool-manager';\nimport type { IEventService } from '../interfaces/event-service';\nimport type { ExecutionService } from '../services/execution-service';\nimport { ModuleRegistry } from '../managers/module-registry';\nimport { RobotaModuleManager } from './robota-module-manager';\nimport { RobotaPluginManager } from './robota-plugin-manager';\nimport { RobotaConfigManager } from './robota-config-manager';\n\n/**\n * Mutable state references for the Robota instance.\n * All fields are accessed via getters/setters to allow live binding.\n */\nexport interface IRobotaDelegateState {\n getName: () => string;\n getModuleRegistry: () => ModuleRegistry;\n getLogger: () => ILogger;\n getIsFullyInitialized: () => boolean;\n ensureFullyInitialized: () => Promise<void>;\n getExecutionService: () => ExecutionService;\n getAiProviders: () => AIProviders;\n getTools: () => Tools;\n getEventService: () => IEventService;\n getConfig: () => IAgentConfig;\n setConfig: (c: IAgentConfig) => void;\n getConfigVersion: () => number;\n incrementConfigVersion: () => number;\n getConfigUpdatedAt: () => number;\n setConfigUpdatedAt: (t: number) => void;\n emitAgentEvent: (eventType: string, data: Record<string, unknown>) => void;\n}\n\n/**\n * Create all three delegate managers for a Robota instance.\n */\nexport function createRobotaDelegates(state: IRobotaDelegateState): {\n moduleManager: RobotaModuleManager;\n pluginManager: RobotaPluginManager;\n configManager: RobotaConfigManager;\n} {\n const moduleManager = new RobotaModuleManager(\n state.getName(),\n state.getModuleRegistry(),\n state.getLogger(),\n state.getIsFullyInitialized,\n state.ensureFullyInitialized,\n );\n\n const pluginManager = new RobotaPluginManager(\n state.getLogger(),\n state.getIsFullyInitialized,\n state.getExecutionService,\n );\n\n const configManager = new RobotaConfigManager(\n state.getLogger(),\n state.getAiProviders,\n state.getTools,\n state.getEventService,\n state.getIsFullyInitialized,\n state.ensureFullyInitialized,\n state.getConfig,\n (c: IAgentConfig) => state.setConfig(c),\n state.getConfigVersion,\n state.incrementConfigVersion,\n state.getConfigUpdatedAt,\n (t: number) => state.setConfigUpdatedAt(t),\n (eventType: string, data: Record<string, unknown>) =>\n state.emitAgentEvent(eventType, data as Omit<IAgentEventData, 'timestamp'>),\n );\n\n return { moduleManager, pluginManager, configManager };\n}\n","import jsSHA from 'jssha';\nimport type { TUniversalMessage } from '../../interfaces/messages';\nimport type { ICacheKey } from '../../interfaces/cache';\n\ninterface ICacheKeyOptions {\n temperature?: number;\n maxTokens?: number;\n}\n\nexport class CacheKeyBuilder {\n build(\n messages: TUniversalMessage[],\n model: string,\n provider: string,\n options?: ICacheKeyOptions,\n ): ICacheKey {\n const serializable = messages.map((m) => ({\n role: m.role,\n content: m.content,\n }));\n\n const payload = JSON.stringify({\n messages: serializable,\n model,\n provider,\n temperature: options?.temperature,\n maxTokens: options?.maxTokens,\n });\n\n return {\n hash: this.sha256(payload),\n model,\n provider,\n };\n }\n\n computeIntegrityHash(content: string): string {\n return this.sha256(content);\n }\n\n private sha256(input: string): string {\n const shaObj = new jsSHA('SHA-256', 'TEXT');\n shaObj.update(input);\n return shaObj.getHash('HEX');\n }\n}\n","import type { ICacheEntry, ICacheStorage, ICacheStats } from '../../interfaces/cache';\nimport { CacheIntegrityError } from '../../utils/errors';\nimport { CacheKeyBuilder } from './cache-key-builder';\n\ninterface IMemoryCacheStorageOptions {\n maxEntries: number;\n ttlMs: number;\n}\n\nexport class MemoryCacheStorage implements ICacheStorage {\n private readonly cache = new Map<string, ICacheEntry>();\n private readonly accessOrder: string[] = [];\n private readonly maxEntries: number;\n private readonly ttlMs: number;\n private readonly keyBuilder = new CacheKeyBuilder();\n private hits = 0;\n private misses = 0;\n\n constructor(options: IMemoryCacheStorageOptions) {\n this.maxEntries = options.maxEntries;\n this.ttlMs = options.ttlMs;\n }\n\n get(hash: string): ICacheEntry | undefined {\n const entry = this.cache.get(hash);\n\n if (!entry) {\n this.misses++;\n return undefined;\n }\n\n if (Date.now() - entry.timestamp > this.ttlMs) {\n this.cache.delete(hash);\n this.removeFromAccessOrder(hash);\n this.misses++;\n return undefined;\n }\n\n const expectedHash = this.keyBuilder.computeIntegrityHash(entry.response);\n if (entry.integrityHash !== expectedHash) {\n this.cache.delete(hash);\n this.removeFromAccessOrder(hash);\n throw new CacheIntegrityError(`Integrity check failed for cache entry ${hash}`, {\n hash,\n expected: expectedHash,\n actual: entry.integrityHash,\n });\n }\n\n this.touchAccessOrder(hash);\n this.hits++;\n return entry;\n }\n\n set(entry: ICacheEntry): void {\n const hash = entry.key.hash;\n\n if (!this.cache.has(hash) && this.cache.size >= this.maxEntries) {\n this.evictLRU();\n }\n\n this.cache.set(hash, entry);\n this.touchAccessOrder(hash);\n }\n\n delete(hash: string): boolean {\n if (this.cache.has(hash)) {\n this.cache.delete(hash);\n this.removeFromAccessOrder(hash);\n return true;\n }\n return false;\n }\n\n clear(): void {\n this.cache.clear();\n this.accessOrder.length = 0;\n this.hits = 0;\n this.misses = 0;\n }\n\n getStats(): ICacheStats {\n const total = this.hits + this.misses;\n return {\n hits: this.hits,\n misses: this.misses,\n entries: this.cache.size,\n hitRate: total === 0 ? 0 : this.hits / total,\n };\n }\n\n private touchAccessOrder(hash: string): void {\n this.removeFromAccessOrder(hash);\n this.accessOrder.push(hash);\n }\n\n private removeFromAccessOrder(hash: string): void {\n const idx = this.accessOrder.indexOf(hash);\n if (idx !== -1) {\n this.accessOrder.splice(idx, 1);\n }\n }\n\n private evictLRU(): void {\n const lruHash = this.accessOrder.shift();\n if (lruHash) {\n this.cache.delete(lruHash);\n }\n }\n}\n","import type { TUniversalMessage } from '../../interfaces/messages';\nimport type { ICacheStorage, ICacheStats } from '../../interfaces/cache';\nimport { CacheKeyBuilder } from './cache-key-builder';\n\nexport class ExecutionCacheService {\n constructor(\n private readonly storage: ICacheStorage,\n private readonly keyBuilder: CacheKeyBuilder,\n ) {}\n\n lookup(\n messages: TUniversalMessage[],\n model: string,\n provider: string,\n options?: { temperature?: number; maxTokens?: number },\n ): string | undefined {\n const key = this.keyBuilder.build(messages, model, provider, options);\n const entry = this.storage.get(key.hash);\n return entry ? entry.response : undefined;\n }\n\n store(\n messages: TUniversalMessage[],\n model: string,\n provider: string,\n response: string,\n options?: { temperature?: number; maxTokens?: number },\n ): void {\n const key = this.keyBuilder.build(messages, model, provider, options);\n this.storage.set({\n key,\n response,\n timestamp: Date.now(),\n integrityHash: this.keyBuilder.computeIntegrityHash(response),\n });\n }\n\n getStats(): ICacheStats {\n return this.storage.getStats();\n }\n}\n","/**\n * Async initialization logic for the Robota agent.\n *\n * Extracted from robota.ts to keep the main class under 300 lines.\n */\nimport type { IAgentConfig } from '../interfaces/agent';\nimport type { AIProviders } from '../managers/ai-provider-manager';\nimport type { Tools } from '../managers/tool-manager';\nimport type { AgentFactory } from '../managers/agent-factory';\nimport type { ConversationHistory } from '../managers/conversation-history-manager';\nimport type { ModuleRegistry } from '../managers/module-registry';\nimport type { EventEmitterPlugin } from '../plugins/event-emitter-plugin';\nimport { ExecutionService } from '../services/execution-service';\nimport { CacheKeyBuilder, MemoryCacheStorage, ExecutionCacheService } from '../services/cache';\nimport type { IEventService } from '../interfaces/event-service';\nimport { AbstractTool } from '../abstracts/abstract-tool';\nimport type { ILogger } from '../utils/logger';\nimport type { IToolExecutionContext, TToolParameters } from '../interfaces/tool';\nimport type { TUniversalValue } from '../interfaces/types';\n\n/**\n * Context required for async initialization.\n * @internal\n */\nexport interface IRobotaInitContext {\n config: IAgentConfig;\n aiProviders: AIProviders;\n tools: Tools;\n agentFactory: AgentFactory;\n conversationHistory: ConversationHistory;\n moduleRegistry: ModuleRegistry;\n eventEmitter: EventEmitterPlugin;\n eventService: IEventService;\n logger: ILogger;\n}\n\n/**\n * Performs the full async initialization of a Robota instance.\n * Returns the created ExecutionService.\n * @internal\n */\nexport async function performAsyncInitialization(\n ctx: IRobotaInitContext,\n): Promise<ExecutionService> {\n const {\n config,\n aiProviders,\n tools,\n agentFactory,\n conversationHistory,\n moduleRegistry,\n eventEmitter,\n eventService,\n logger,\n } = ctx;\n\n logger.debug('Starting Robota initialization with independent managers');\n\n // Initialize all instance-specific managers\n await Promise.all([aiProviders.initialize(), tools.initialize(), agentFactory.initialize()]);\n\n // Register AI providers\n if (config.aiProviders) {\n for (const provider of config.aiProviders) {\n aiProviders.addProvider(provider.name, provider);\n }\n }\n\n // Set current provider from defaultModel\n if (config.defaultModel) {\n aiProviders.setCurrentProvider(config.defaultModel.provider, config.defaultModel.model);\n }\n\n // Register modules if provided\n if (config.modules) {\n for (const module of config.modules) {\n await moduleRegistry.registerModule(module, {\n autoInitialize: true,\n validateDependencies: true,\n });\n }\n logger.debug('Modules registered and initialized', {\n moduleCount: config.modules.length,\n moduleNames: config.modules.map((m) => m.name),\n });\n }\n\n // Register tools\n if (config.tools) {\n for (const tool of config.tools) {\n if (tool instanceof AbstractTool && eventService) {\n tool.setEventService(eventService);\n }\n const toolExecutor = async (\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<TUniversalValue> => {\n if (!context) {\n throw new Error('[ROBOTA] Missing ToolExecutionContext for tool execution');\n }\n const result = await tool.execute(parameters, context);\n return result.data;\n };\n tools.addTool(tool.schema, toolExecutor);\n logger.debug('Tool registered during initialization', { toolName: tool.schema.name });\n }\n }\n\n // Build cache service if cache config is provided\n let cacheService: ExecutionCacheService | undefined;\n if (config.cache?.enabled) {\n const cacheStorage = new MemoryCacheStorage({\n maxEntries: config.cache.maxEntries,\n ttlMs: config.cache.ttlMs,\n });\n cacheService = new ExecutionCacheService(cacheStorage, new CacheKeyBuilder());\n }\n\n const executionService = new ExecutionService(\n aiProviders,\n tools,\n conversationHistory,\n eventService,\n config.executionContext,\n cacheService,\n );\n\n // Register plugins with ExecutionService\n if (config.plugins) {\n for (const plugin of config.plugins) {\n executionService.registerPlugin(plugin);\n if (plugin.subscribeToModuleEvents) {\n await plugin.subscribeToModuleEvents(eventEmitter);\n logger.debug('Plugin subscribed to module events', { pluginName: plugin.name });\n }\n }\n }\n\n logger.debug('Robota initialization completed successfully with independent managers');\n return executionService;\n}\n\n/**\n * Mutable init state passed to performDoAsyncInit.\n */\nexport interface IRobotaInitState {\n ctx: IRobotaInitContext;\n setExecutionService: (svc: ExecutionService) => void;\n setFullyInitialized: (v: boolean) => void;\n}\n\n/**\n * Wraps performAsyncInitialization with the standard error handling pattern\n * from the Robota class, setting executionService and isFullyInitialized on success.\n */\nexport async function performDoAsyncInit(state: IRobotaInitState): Promise<void> {\n try {\n const svc = await performAsyncInitialization(state.ctx);\n state.setExecutionService(svc);\n state.setFullyInitialized(true);\n } catch (error) {\n state.ctx.logger.error('Robota initialization failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n","/**\n * Execution methods (run, runStream) for the Robota agent.\n *\n * Extracted from robota.ts to keep the main class under 300 lines.\n */\nimport type { TUniversalMessage, IAgentConfig, IRunOptions } from '../interfaces/agent';\nimport type { ExecutionService } from '../services/execution-service';\nimport type { IExecutionContext } from '../services/execution-types';\nimport type { ILogger } from '../utils/logger';\nimport type { IAgentEventData } from '../interfaces/event-service';\nimport { AGENT_EVENTS } from '../agents/constants';\n\n/** Dependencies required by the execution helpers. @internal */\nexport interface IRobotaExecutionDeps {\n readonly conversationId: string;\n readonly config: IAgentConfig;\n readonly logger: ILogger;\n getHistory(): TUniversalMessage[];\n getExecutionService(): ExecutionService;\n emitAgentEvent(eventType: string, data: Omit<IAgentEventData, 'timestamp'>): void;\n}\n\nfunction buildRunContext(\n deps: IRobotaExecutionDeps,\n options: IRunOptions,\n): Partial<IExecutionContext> {\n return {\n conversationId: deps.conversationId,\n ...(options.sessionId && { sessionId: options.sessionId }),\n ...(options.userId && { userId: options.userId }),\n ...(options.metadata && { metadata: options.metadata }),\n ...(options.signal && { signal: options.signal }),\n ...(options.onTextDelta && { onTextDelta: options.onTextDelta }),\n ...(options.onExecutionEvent && { onExecutionEvent: options.onExecutionEvent }),\n ...(options.maxExecutionRounds !== undefined && {\n maxExecutionRounds: options.maxExecutionRounds,\n }),\n };\n}\n\n/** Execute a single conversation turn. @internal */\nexport async function robotaRun(\n deps: IRobotaExecutionDeps,\n input: string,\n options: IRunOptions = {},\n): Promise<string> {\n try {\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_START, {});\n\n deps.logger.debug('Starting Robota execution', {\n inputLength: input.length,\n conversationId: deps.conversationId,\n sessionId: options.sessionId || 'none',\n userId: options.userId || 'none',\n hasMetadata: !!options.metadata,\n });\n\n const messages = deps.getHistory();\n const executionConfig: IAgentConfig = { ...deps.config };\n\n const result = await deps\n .getExecutionService()\n .execute(input, messages, executionConfig, buildRunContext(deps, options));\n\n deps.logger.debug('Robota execution completed', {\n success: result.success,\n duration: result.duration,\n tokensUsed: result.tokensUsed,\n toolsExecuted: result.toolsExecuted,\n interrupted: result.interrupted,\n });\n\n if (result.interrupted) {\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_COMPLETE, {});\n return result.response;\n }\n\n if (!result.success && result.error) {\n throw result.error;\n }\n\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_COMPLETE, {});\n return result.response;\n } catch (error) {\n deps.logger.error('Robota execution failed', {\n error: error instanceof Error ? error.message : String(error),\n conversationId: deps.conversationId,\n });\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_ERROR, {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n\n/** Execute a streaming conversation turn. @internal */\nexport async function* robotaRunStream(\n deps: IRobotaExecutionDeps,\n input: string,\n options: IRunOptions = {},\n): AsyncGenerator<string, void, undefined> {\n try {\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_START, {});\n\n deps.logger.debug('Starting Robota streaming execution', {\n inputLength: input.length,\n conversationId: deps.conversationId,\n sessionId: options.sessionId || 'none',\n userId: options.userId || 'none',\n hasMetadata: !!options.metadata,\n });\n\n const messages = deps.getHistory();\n const executionConfig: IAgentConfig = { ...deps.config };\n\n const stream = deps.getExecutionService().executeStream(input, messages, executionConfig, {\n conversationId: deps.conversationId,\n ...(options.sessionId && { sessionId: options.sessionId }),\n ...(options.userId && { userId: options.userId }),\n ...(options.metadata && { metadata: options.metadata }),\n });\n\n for await (const chunk of stream) {\n yield chunk.chunk;\n }\n } catch (error) {\n deps.logger.error('Robota streaming execution failed', {\n error: error instanceof Error ? error.message : String(error),\n conversationId: deps.conversationId,\n });\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_ERROR, {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n } finally {\n deps.emitAgentEvent(AGENT_EVENTS.EXECUTION_COMPLETE, {});\n }\n}\n","/**\n * Lifecycle and stats helpers for the Robota agent.\n *\n * Extracted from robota.ts to keep the main class under 300 lines.\n */\nimport type { TUniversalMessage } from '../interfaces/agent';\nimport type { AIProviders } from '../managers/ai-provider-manager';\nimport type { Tools } from '../managers/tool-manager';\nimport type { ModuleRegistry } from '../managers/module-registry';\nimport type { EventEmitterPlugin } from '../plugins/event-emitter-plugin';\nimport type { ExecutionService } from '../services/execution-service';\nimport type { ILogger } from '../utils/logger';\nimport type { TAgentStatsMetadata } from './robota-config-manager';\n\n/** Dependencies required by getStats. @internal */\nexport interface IRobotaStatsDeps {\n readonly name: string;\n readonly version: string;\n readonly conversationId: string;\n readonly startTime: number;\n readonly isFullyInitialized: boolean;\n aiProviders: AIProviders;\n tools: Tools;\n getPluginNames(): string[];\n getModuleNames(): string[];\n getHistory(): TUniversalMessage[];\n}\n\n/** Build comprehensive agent statistics. @internal */\nexport function buildAgentStats(deps: IRobotaStatsDeps): {\n name: string;\n version: string;\n conversationId: string;\n providers: string[];\n currentProvider: string | null;\n tools: string[];\n plugins: string[];\n modules: string[];\n historyLength: number;\n historyStats: TAgentStatsMetadata;\n uptime: number;\n} {\n const providers = deps.isFullyInitialized ? deps.aiProviders.getProviderNames() : [];\n const currentProviderInfo = deps.isFullyInitialized\n ? deps.aiProviders.getCurrentProvider()\n : null;\n const currentProvider = currentProviderInfo ? currentProviderInfo.provider : null;\n const tools = deps.isFullyInitialized ? deps.tools.getTools().map((tool) => tool.name) : [];\n const plugins = deps.getPluginNames();\n const modules = deps.getModuleNames();\n const history = deps.getHistory();\n const uptime = Date.now() - deps.startTime;\n\n const roleCounts = { user: 0, assistant: 0, system: 0, tool: 0 };\n for (const msg of history) {\n if (msg.role in roleCounts) {\n roleCounts[msg.role as keyof typeof roleCounts]++;\n }\n }\n\n return {\n name: deps.name,\n version: deps.version,\n conversationId: deps.conversationId,\n providers,\n currentProvider,\n tools,\n plugins,\n modules,\n historyLength: history.length,\n historyStats: {\n userMessages: roleCounts.user,\n assistantMessages: roleCounts.assistant,\n systemMessages: roleCounts.system,\n toolMessages: roleCounts.tool,\n },\n uptime,\n };\n}\n\n/** Dependencies required by destroy. @internal */\nexport interface IRobotaDestroyDeps {\n readonly name: string;\n readonly isFullyInitialized: boolean;\n moduleRegistry: ModuleRegistry;\n eventEmitter: EventEmitterPlugin;\n executionService: ExecutionService | undefined;\n logger: ILogger;\n resetState(): void;\n}\n\n/** Destroy and clean up the agent instance. @internal */\nexport async function destroyAgent(deps: IRobotaDestroyDeps): Promise<void> {\n deps.logger.debug('Destroying Robota instance', { name: deps.name });\n\n try {\n if (deps.isFullyInitialized && deps.moduleRegistry) {\n await deps.moduleRegistry.disposeAllModules();\n deps.logger.debug('All modules disposed');\n }\n\n if (deps.executionService) {\n const plugins = deps.executionService.getPlugins();\n for (const plugin of plugins) {\n if (plugin.unsubscribeFromModuleEvents && deps.eventEmitter) {\n await plugin.unsubscribeFromModuleEvents(deps.eventEmitter);\n }\n }\n deps.logger.debug('ExecutionService plugins cleaned up');\n }\n\n if (deps.moduleRegistry) {\n deps.moduleRegistry.clearAllModules();\n deps.logger.debug('ModuleRegistry cleared');\n }\n\n if (deps.eventEmitter) {\n await deps.eventEmitter.destroy();\n deps.logger.debug('EventEmitter disposed');\n }\n\n deps.resetState();\n deps.logger.info('Robota instance destroyed successfully', { name: deps.name });\n } catch (error) {\n deps.logger.error('Error during Robota destruction', {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n","/**\n * History helper functions for the Robota agent.\n *\n * These standalone functions operate on ConversationHistory + a conversationId,\n * extracted from core/robota.ts to keep that file under 300 lines.\n */\nimport type { TUniversalMessage } from '../interfaces/agent';\nimport type { IHistoryEntry } from '../interfaces/messages';\nimport type { ConversationHistory } from '../managers/conversation-history-manager';\n\n/**\n * Return the current conversation messages as TUniversalMessage[].\n */\nexport function getHistory(\n conversationHistory: ConversationHistory,\n conversationId: string,\n): TUniversalMessage[] {\n const session = conversationHistory.getConversationStore(conversationId);\n return session.getMessages().map((msg) => ({\n id: msg.id,\n role: msg.role,\n content: msg.content,\n state: msg.state,\n timestamp: msg.timestamp,\n metadata: msg.metadata,\n ...(msg.role === 'assistant' && 'toolCalls' in msg ? { toolCalls: msg.toolCalls } : {}),\n ...(msg.role === 'tool' && 'toolCallId' in msg\n ? { toolCallId: (msg as { toolCallId: string }).toolCallId }\n : {}),\n ...(msg.role === 'tool' && 'name' in msg ? { name: (msg as { name: string }).name } : {}),\n })) as TUniversalMessage[];\n}\n\n/**\n * Return the full history timeline (IHistoryEntry[]) including events.\n */\nexport function getFullHistory(\n conversationHistory: ConversationHistory,\n conversationId: string,\n): IHistoryEntry[] {\n const store = conversationHistory.getConversationStore(conversationId);\n return store.getHistory();\n}\n\n/**\n * Add an event entry to history.\n */\nexport function addHistoryEntry(\n conversationHistory: ConversationHistory,\n conversationId: string,\n entry: IHistoryEntry,\n): void {\n const store = conversationHistory.getConversationStore(conversationId);\n store.addEntry(entry);\n}\n\n/**\n * Clear all messages in the conversation.\n */\nexport function clearHistory(\n conversationHistory: ConversationHistory,\n conversationId: string,\n): void {\n conversationHistory.getConversationStore(conversationId).clear();\n}\n\n/**\n * Inject a message into conversation history without triggering execution.\n */\nexport function injectMessage(\n conversationHistory: ConversationHistory,\n conversationId: string,\n role: 'user' | 'assistant' | 'system' | 'tool',\n content: string,\n options?: { toolCallId?: string; name?: string },\n): void {\n const session = conversationHistory.getConversationStore(conversationId);\n if (role === 'tool' && options?.toolCallId) {\n session.addToolMessageWithId(content, options.toolCallId, options.name ?? 'unknown');\n } else if (role === 'assistant') {\n session.addAssistantMessage(content, []);\n } else if (role === 'system') {\n session.addSystemMessage(content);\n } else {\n session.addUserMessage(content);\n }\n}\n","/**\n * Event-related helpers for the Robota agent class.\n *\n * Extracted from core/robota.ts to keep that file under 300 lines.\n * Handles agent event emission and owner path construction.\n */\nimport { AGENT_EVENTS, AGENT_EVENT_PREFIX } from '../agents/constants';\nimport type {\n IEventService,\n IOwnerPathSegment,\n IAgentEventData,\n} from '../interfaces/event-service';\nimport { isDefaultEventService } from '../event-service/index';\nimport type { IAgentConfig, IExecutionContextInjection } from '../interfaces/agent';\nimport { EventEmitterPlugin } from '../plugins/event-emitter-plugin';\nimport { EVENT_EMITTER_EVENTS } from '../plugins/event-emitter/types';\n\n/**\n * Emit the AGENT_EVENTS.CREATED event with tool and model parameters.\n */\nexport function emitCreatedEvent(\n config: IAgentConfig,\n emitFn: (eventType: string, data: Omit<IAgentEventData, 'timestamp'>) => void,\n): void {\n const toolNames: string[] = Array.isArray(config.tools)\n ? config.tools\n .map((t) => {\n const sn = t?.schema?.name;\n if (typeof sn === 'string' && sn.length > 0) return sn;\n const nm = (t as { name?: string } | undefined)?.name;\n if (typeof nm === 'string' && nm.length > 0) return nm;\n return '';\n })\n .filter((n): n is string => typeof n === 'string' && n.length > 0)\n : [];\n emitFn(AGENT_EVENTS.CREATED, {\n parameters: {\n tools: toolNames,\n systemMessage: config.defaultModel.systemMessage,\n provider: config.defaultModel.provider,\n model: config.defaultModel.model,\n temperature: config.defaultModel.temperature,\n maxTokens: config.defaultModel.maxTokens,\n },\n });\n}\n\n/**\n * Emit an agent event via the agentEventService.\n * No-ops when the service is the default (no-op) implementation.\n */\nexport function emitAgentEvent(\n agentEventService: IEventService,\n conversationId: string,\n executionContext: IExecutionContextInjection | undefined,\n eventType: string,\n data: Omit<IAgentEventData, 'timestamp'>,\n): void {\n if (isDefaultEventService(agentEventService)) return;\n agentEventService.emit(\n eventType,\n { timestamp: new Date(), ...data },\n {\n ownerType: AGENT_EVENT_PREFIX,\n ownerId: conversationId,\n ownerPath: buildOwnerPath(conversationId, executionContext),\n },\n );\n}\n\n/**\n * Create an EventEmitterPlugin configured for module lifecycle events.\n * Used by the Robota constructor to avoid a 14-line inline EventEmitterPlugin instantiation.\n */\nexport function createModuleEventEmitter(): EventEmitterPlugin {\n return new EventEmitterPlugin({\n enabled: true,\n events: [\n EVENT_EMITTER_EVENTS.MODULE_INITIALIZE_START,\n EVENT_EMITTER_EVENTS.MODULE_INITIALIZE_COMPLETE,\n EVENT_EMITTER_EVENTS.MODULE_INITIALIZE_ERROR,\n EVENT_EMITTER_EVENTS.MODULE_EXECUTION_START,\n EVENT_EMITTER_EVENTS.MODULE_EXECUTION_COMPLETE,\n EVENT_EMITTER_EVENTS.MODULE_EXECUTION_ERROR,\n EVENT_EMITTER_EVENTS.MODULE_DISPOSE_START,\n EVENT_EMITTER_EVENTS.MODULE_DISPOSE_COMPLETE,\n EVENT_EMITTER_EVENTS.MODULE_DISPOSE_ERROR,\n ],\n });\n}\n\n/**\n * Build the owner path segment array for an agent.\n */\nexport function buildOwnerPath(\n conversationId: string,\n executionContext?: IExecutionContextInjection,\n): IOwnerPathSegment[] {\n const base = executionContext?.ownerPath?.length\n ? executionContext.ownerPath.map((segment) => ({ ...segment }))\n : [];\n return [...base, { type: 'agent', id: conversationId }];\n}\n","import type { IAgentConfig, IRunOptions, TUniversalMessage } from '../interfaces/agent';\nimport type {\n IPluginContract,\n IPluginHooks,\n IPluginOptions,\n IPluginStats,\n} from '../abstracts/abstract-plugin';\nimport type { IModule } from '../abstracts/abstract-module';\nimport { AbstractAgent } from '../abstracts/abstract-agent';\nimport type {\n TModuleStats,\n TRegisterModuleOptions,\n TExecuteModuleContext,\n TExecuteModuleResult,\n} from './robota-types';\n\nexport type TPlugin = IPluginContract<IPluginOptions, IPluginStats> & IPluginHooks;\n\ninterface IModuleManagerProxy {\n registerModule(module: IModule, options?: TRegisterModuleOptions): Promise<void>;\n unregisterModule(moduleName: string): Promise<boolean>;\n getModule(moduleName: string): IModule | undefined;\n getModulesByType(moduleType: string): IModule[];\n getModules(): IModule[];\n getModuleNames(): string[];\n hasModule(moduleName: string): boolean;\n executeModule(moduleName: string, context: TExecuteModuleContext): Promise<TExecuteModuleResult>;\n getModuleStats(moduleName: string): TModuleStats;\n}\n\ninterface IPluginManagerProxy {\n addPlugin(plugin: TPlugin): void;\n removePlugin(pluginName: string): boolean;\n getPlugin(pluginName: string): TPlugin | undefined;\n getPlugins(): TPlugin[];\n getPluginNames(): string[];\n}\n\nexport abstract class RobotaBase extends AbstractAgent<\n IAgentConfig,\n IRunOptions,\n TUniversalMessage\n> {\n protected moduleManager!: IModuleManagerProxy;\n protected pluginManager!: IPluginManagerProxy;\n\n addPlugin(plugin: TPlugin): void {\n this.pluginManager.addPlugin(plugin);\n }\n removePlugin(pluginName: string): boolean {\n return this.pluginManager.removePlugin(pluginName);\n }\n getPlugin(pluginName: string): TPlugin | undefined {\n return this.pluginManager.getPlugin(pluginName);\n }\n getPlugins(): TPlugin[] {\n return this.pluginManager.getPlugins();\n }\n getPluginNames(): string[] {\n return this.pluginManager.getPluginNames();\n }\n\n async registerModule(module: IModule, options?: TRegisterModuleOptions): Promise<void> {\n return this.moduleManager.registerModule(module, options);\n }\n async unregisterModule(moduleName: string): Promise<boolean> {\n return this.moduleManager.unregisterModule(moduleName);\n }\n getModule(moduleName: string): IModule | undefined {\n return this.moduleManager.getModule(moduleName);\n }\n getModulesByType(moduleType: string): IModule[] {\n return this.moduleManager.getModulesByType(moduleType);\n }\n getModules(): IModule[] {\n return this.moduleManager.getModules();\n }\n getModuleNames(): string[] {\n return this.moduleManager.getModuleNames();\n }\n hasModule(moduleName: string): boolean {\n return this.moduleManager.hasModule(moduleName);\n }\n async executeModule(\n moduleName: string,\n context: TExecuteModuleContext,\n ): Promise<TExecuteModuleResult> {\n return this.moduleManager.executeModule(moduleName, context);\n }\n getModuleStats(moduleName: string): TModuleStats {\n return this.moduleManager.getModuleStats(moduleName);\n }\n}\n","import type { TUniversalMessage, IAgentConfig, IRunOptions, IAgent } from '../interfaces/agent';\nimport { ModuleRegistry } from '../managers/module-registry';\nimport { EventEmitterPlugin } from '../plugins/event-emitter-plugin';\nimport { AIProviders } from '../managers/ai-provider-manager';\nimport { Tools } from '../managers/tool-manager';\nimport { AgentFactory } from '../managers/agent-factory';\nimport { ConversationHistory } from '../managers/conversation-history-manager';\nimport type { ExecutionService } from '../services/execution-service';\nimport type { IEventService, IAgentEventData } from '../interfaces/event-service';\nimport { DEFAULT_ABSTRACT_EVENT_SERVICE, bindWithOwnerPath } from '../event-service/index';\nimport type { AbstractTool, IToolWithEventService } from '../abstracts/abstract-tool';\nimport { createLogger, setGlobalLogLevel, type ILogger } from '../utils/logger';\nimport type { IHistoryEntry } from '../interfaces/messages';\nimport type { IModelConfig, IConfigurationSnapshot } from './robota-types';\nimport { validateAgentConfig } from './robota-config-manager';\nimport { createRobotaDelegates } from './robota-delegate-factory';\nimport type { RobotaConfigManager } from './robota-config-manager';\nimport { performDoAsyncInit } from './robota-initializer';\nimport { robotaRun, robotaRunStream, type IRobotaExecutionDeps } from './robota-execution';\nimport { buildAgentStats, destroyAgent } from './robota-lifecycle';\nimport {\n getHistory,\n getFullHistory,\n addHistoryEntry,\n clearHistory,\n injectMessage,\n} from './robota-history';\nimport {\n emitCreatedEvent,\n emitAgentEvent,\n buildOwnerPath,\n createModuleEventEmitter,\n} from './robota-events';\nimport { RobotaBase } from './robota-base';\n\nconst ID_RADIX = 36;\nconst ID_RANDOM_LENGTH = 9;\n\nexport type { TAgentStatsMetadata } from './robota-config-manager';\n\n/** @public */\nexport class Robota\n extends RobotaBase\n implements IAgent<IAgentConfig, IRunOptions, TUniversalMessage>\n{\n public readonly name: string;\n public readonly version: string = '1.0.0';\n\n private aiProviders: AIProviders;\n private tools: Tools;\n private agentFactory: AgentFactory;\n private conversationHistory: ConversationHistory;\n private moduleRegistry: ModuleRegistry;\n private eventEmitter: EventEmitterPlugin;\n private executionService!: ExecutionService;\n private eventService: IEventService;\n private agentEventService: IEventService;\n protected override config: IAgentConfig;\n private conversationId: string;\n private logger: ILogger;\n private initializationPromise?: Promise<void> | undefined;\n private isFullyInitialized = false;\n private startTime: number;\n private configVersion: number = 1;\n private configUpdatedAt: number = Date.now();\n private configManager!: RobotaConfigManager;\n\n constructor(config: IAgentConfig) {\n super();\n this.name = config.name;\n this.config = config;\n this.conversationId =\n config.conversationId ||\n `conv_${Date.now()}_${Math.random().toString(ID_RADIX).substr(2, ID_RANDOM_LENGTH)}`;\n this.logger = createLogger('Robota');\n this.startTime = Date.now();\n\n if (config.logging) {\n if (config.logging.level) setGlobalLogLevel(config.logging.level);\n if (config.logging.enabled === false) setGlobalLogLevel('silent');\n }\n\n validateAgentConfig(config);\n\n this.aiProviders = new AIProviders();\n this.tools = new Tools();\n this.agentFactory = new AgentFactory();\n this.conversationHistory = new ConversationHistory();\n this.eventEmitter = createModuleEventEmitter();\n this.moduleRegistry = new ModuleRegistry(this.eventEmitter);\n\n this.eventService = config.eventService || DEFAULT_ABSTRACT_EVENT_SERVICE;\n this.agentEventService = bindWithOwnerPath(this.eventService, {\n ownerType: 'agent',\n ownerId: this.conversationId,\n ownerPath: buildOwnerPath(this.conversationId, this.config.executionContext),\n });\n\n const delegates = createRobotaDelegates({\n getName: () => this.name,\n getModuleRegistry: () => this.moduleRegistry,\n getLogger: () => this.logger,\n getIsFullyInitialized: () => this.isFullyInitialized,\n ensureFullyInitialized: () => this.ensureFullyInitialized(),\n getExecutionService: () => this.executionService,\n getAiProviders: () => this.aiProviders,\n getTools: () => this.tools,\n getEventService: () => this.eventService,\n getConfig: () => this.config,\n setConfig: (c) => {\n this.config = c;\n },\n getConfigVersion: () => this.configVersion,\n incrementConfigVersion: () => ++this.configVersion,\n getConfigUpdatedAt: () => this.configUpdatedAt,\n setConfigUpdatedAt: (t) => {\n this.configUpdatedAt = t;\n },\n emitAgentEvent: (t, d) => this.emitAgentEvent(t, d as Omit<IAgentEventData, 'timestamp'>),\n });\n this.moduleManager = delegates.moduleManager;\n this.pluginManager = delegates.pluginManager;\n this.configManager = delegates.configManager;\n emitCreatedEvent(this.config, (t, d) => this.emitAgentEvent(t, d));\n }\n\n async run(input: string, options: IRunOptions = {}): Promise<string> {\n await this.ensureFullyInitialized();\n return robotaRun(this.executionDeps(), input, options);\n }\n\n async *runStream(\n input: string,\n options: IRunOptions = {},\n ): AsyncGenerator<string, void, undefined> {\n await this.ensureFullyInitialized();\n yield* robotaRunStream(this.executionDeps(), input, options);\n }\n\n private executionDeps(): IRobotaExecutionDeps {\n return {\n conversationId: this.conversationId,\n config: this.config,\n logger: this.logger,\n getHistory: () => this.getHistory(),\n getExecutionService: () => this.executionService,\n emitAgentEvent: (t, d) => this.emitAgentEvent(t, d),\n };\n }\n\n override getHistory(): TUniversalMessage[] {\n return getHistory(this.conversationHistory, this.conversationId);\n }\n getFullHistory(): IHistoryEntry[] {\n return getFullHistory(this.conversationHistory, this.conversationId);\n }\n addHistoryEntry(entry: IHistoryEntry): void {\n addHistoryEntry(this.conversationHistory, this.conversationId, entry);\n }\n override clearHistory(): void {\n clearHistory(this.conversationHistory, this.conversationId);\n }\n injectMessage(\n role: 'user' | 'assistant' | 'system' | 'tool',\n content: string,\n options?: { toolCallId?: string; name?: string },\n ): void {\n injectMessage(this.conversationHistory, this.conversationId, role, content, options);\n }\n\n async updateTools(next: Array<IToolWithEventService>): Promise<{ version: number }> {\n return this.configManager.updateTools(next);\n }\n async updateConfiguration(patch: Partial<IAgentConfig>): Promise<{ version: number }> {\n return this.configManager.updateConfiguration(patch);\n }\n async getConfiguration(): Promise<IConfigurationSnapshot> {\n return this.configManager.getConfiguration();\n }\n setModel(mc: IModelConfig): void {\n this.configManager.setModel(mc);\n }\n getModel(): IModelConfig {\n return this.configManager.getModel();\n }\n registerTool(tool: AbstractTool): void {\n this.configManager.registerTool(tool, this.tools);\n }\n unregisterTool(toolName: string): void {\n this.tools.removeTool(toolName);\n }\n getConfig(): IAgentConfig {\n return { ...this.config };\n }\n\n getStats() {\n return buildAgentStats({\n name: this.name,\n version: this.version,\n conversationId: this.conversationId,\n startTime: this.startTime,\n isFullyInitialized: this.isFullyInitialized,\n aiProviders: this.aiProviders,\n tools: this.tools,\n getPluginNames: () => this.getPluginNames(),\n getModuleNames: () => this.getModuleNames(),\n getHistory: () => this.getHistory(),\n });\n }\n\n async destroy(): Promise<void> {\n await destroyAgent({\n name: this.name,\n isFullyInitialized: this.isFullyInitialized,\n moduleRegistry: this.moduleRegistry,\n eventEmitter: this.eventEmitter,\n executionService: this.executionService,\n logger: this.logger,\n resetState: () => {\n this.isFullyInitialized = false;\n this.initializationPromise = undefined as Promise<void> | undefined;\n },\n });\n }\n\n protected override async initialize(): Promise<void> {\n await this.ensureFullyInitialized();\n }\n\n private async ensureFullyInitialized(): Promise<void> {\n if (this.isFullyInitialized) return;\n if (!this.initializationPromise) this.initializationPromise = this.doAsyncInit();\n await this.initializationPromise;\n }\n\n private doAsyncInit(): Promise<void> {\n return performDoAsyncInit({\n ctx: {\n config: this.config,\n aiProviders: this.aiProviders,\n tools: this.tools,\n agentFactory: this.agentFactory,\n conversationHistory: this.conversationHistory,\n moduleRegistry: this.moduleRegistry,\n eventEmitter: this.eventEmitter,\n eventService: this.eventService,\n logger: this.logger,\n },\n setExecutionService: (svc) => {\n this.executionService = svc;\n },\n setFullyInitialized: (v) => {\n this.isFullyInitialized = v;\n },\n });\n }\n\n private emitAgentEvent(eventType: string, data: Omit<IAgentEventData, 'timestamp'>): void {\n emitAgentEvent(\n this.agentEventService,\n this.conversationId,\n this.config.executionContext,\n eventType,\n data,\n );\n }\n}\n","import type {\n IBaseEventData,\n IEventContext,\n IEventService,\n TEventListener,\n} from '../interfaces/event-service';\nimport type {\n IEventHistoryModule,\n IEventHistoryRecord,\n IEventHistorySnapshot,\n} from '../interfaces/history-module';\n\nexport class EventHistoryModule implements IEventHistoryModule {\n private readonly store: IEventHistoryModule;\n private readonly listener: TEventListener;\n private sequenceId = 0;\n\n constructor(store: IEventHistoryModule, eventService: IEventService) {\n this.store = store;\n this.listener = (eventName: string, eventData: IBaseEventData, context?: IEventContext) => {\n if (!context?.ownerPath?.length) {\n throw new Error(`[HISTORY-MODULE] Missing ownerPath for ${eventName}`);\n }\n const record: IEventHistoryRecord = {\n eventName,\n sequenceId: this.nextSequenceId(),\n timestamp: eventData.timestamp,\n eventData,\n context,\n };\n this.store.append(record);\n };\n eventService.subscribe(this.listener);\n }\n\n append(record: IEventHistoryRecord): void {\n this.store.append(record);\n }\n\n read(fromSequenceId: number, toSequenceId?: number): IEventHistoryRecord[] {\n return this.store.read(fromSequenceId, toSequenceId);\n }\n\n readStream(fromSequenceId: number, toSequenceId?: number): AsyncIterable<IEventHistoryRecord> {\n return this.store.readStream(fromSequenceId, toSequenceId);\n }\n\n getSnapshot(): IEventHistorySnapshot | undefined {\n return this.store.getSnapshot?.();\n }\n\n detach(eventService: IEventService): void {\n eventService.unsubscribe(this.listener);\n }\n\n private nextSequenceId(): number {\n this.sequenceId += 1;\n return this.sequenceId;\n }\n}\n","import type { IEventService } from '../interfaces/event-service';\nimport type { IUniversalObjectValue, TUniversalValue } from '../interfaces/types';\n\n/**\n * Configuration for execution proxy\n */\nexport interface IExecutionProxyConfig {\n eventService: IEventService;\n sourceType: 'agent' | 'team' | 'tool';\n sourceId: string;\n enabledEvents?: {\n execution?: boolean;\n toolCall?: boolean;\n task?: boolean;\n };\n}\n\n/** Internal target shape for proxy interception */\nexport type TExecutionProxyTarget = Record<string, TUniversalValue>;\n\n/** Internal args shape for proxy interception */\nexport type TExecutionProxyArgs = TUniversalValue[];\n\n/**\n * Metadata extractor function type\n */\nexport type TMetadataExtractor = (\n target: TExecutionProxyTarget,\n methodName: string,\n args: TExecutionProxyArgs,\n) => Record<string, TUniversalValue>;\n\n/**\n * Method configuration for proxy\n */\nexport interface IMethodConfig {\n startEvent?: string;\n completeEvent?: string;\n errorEvent?: string;\n extractMetadata?: TMetadataExtractor;\n extractResult?: (result: TUniversalValue) => Record<string, TUniversalValue>;\n}\n\n/**\n * Narrow TUniversalValue to IUniversalObjectValue (object, not array, not Date).\n */\nexport function asObjectValue(\n input: TUniversalValue | undefined,\n): IUniversalObjectValue | undefined {\n if (!input || typeof input !== 'object' || Array.isArray(input) || input instanceof Date) {\n return undefined;\n }\n return input as IUniversalObjectValue;\n}\n\n/**\n * Return the string length of input, or 0 if not a string.\n */\nexport function getStringLength(input: TUniversalValue | undefined): number {\n return typeof input === 'string' ? input.length : 0;\n}\n","import type { IBaseEventData, IEventService } from '../interfaces/event-service';\nimport { EXECUTION_EVENTS } from '../services/execution-service';\nimport { TOOL_EVENTS } from '../services/tool-execution-service';\nimport { AGENT_EVENTS } from '../agents/constants';\nimport { TASK_EVENTS } from '../event-service/index';\nimport type { TUniversalValue } from '../interfaces/types';\nimport {\n asObjectValue,\n getStringLength,\n type IExecutionProxyConfig,\n type IMethodConfig,\n type TExecutionProxyTarget,\n type TExecutionProxyArgs,\n} from './execution-proxy-types';\n\nexport type {\n IExecutionProxyConfig,\n IMethodConfig,\n TMetadataExtractor,\n} from './execution-proxy-types';\n\nconst ID_RADIX = 36;\nconst ID_RANDOM_LENGTH = 9;\n\n/**\n * ExecutionProxy - Automatic event emission using Proxy pattern\n *\n * This class wraps target objects and automatically emits events\n * around method execution without modifying business logic.\n *\n * Benefits:\n * - Zero business logic pollution\n * - Automatic event emission\n * - Configurable per method\n * - AOP (Aspect-Oriented Programming) pattern\n */\nexport class ExecutionProxy<T extends object = object> {\n private config: IExecutionProxyConfig;\n private methodConfigs: Map<string, IMethodConfig> = new Map();\n\n constructor(config: IExecutionProxyConfig) {\n this.config = config;\n }\n\n /**\n * Configure specific methods for event emission\n */\n configureMethod(methodName: string, config: IMethodConfig): this {\n this.methodConfigs.set(methodName, config);\n return this;\n }\n\n /**\n * Configure multiple methods with standard patterns\n */\n configureStandardMethods(): this {\n // Agent execution methods\n if (this.config.sourceType === 'agent') {\n this.configureMethod('run', {\n startEvent: AGENT_EVENTS.EXECUTION_START,\n completeEvent: AGENT_EVENTS.EXECUTION_COMPLETE,\n errorEvent: AGENT_EVENTS.EXECUTION_ERROR,\n extractMetadata: (target, methodName, args) => ({\n inputLength: getStringLength(args[0]),\n conversationId: target.conversationId,\n options: asObjectValue(args[1]) || {},\n }),\n extractResult: (result) => ({ response: result }),\n });\n\n this.configureMethod('runStream', {\n startEvent: AGENT_EVENTS.EXECUTION_START,\n completeEvent: AGENT_EVENTS.EXECUTION_COMPLETE,\n errorEvent: AGENT_EVENTS.EXECUTION_ERROR,\n extractMetadata: (target, methodName, args) => ({\n inputLength: getStringLength(args[0]),\n conversationId: target.conversationId,\n streaming: true,\n options: asObjectValue(args[1]) || {},\n }),\n });\n }\n\n // Team task assignment methods\n if (this.config.sourceType === 'team') {\n this.configureMethod('assignTask', {\n startEvent: TASK_EVENTS.ASSIGNED,\n completeEvent: TASK_EVENTS.COMPLETED,\n errorEvent: EXECUTION_EVENTS.ERROR,\n extractMetadata: (target, methodName, args) => {\n const params = asObjectValue(args[0]);\n return {\n taskDescription: params?.jobDescription,\n agentTemplate: params?.agentTemplate,\n priority: params?.priority,\n allowFurtherDelegation: params?.allowFurtherDelegation,\n };\n },\n extractResult: (result) => ({\n result: asObjectValue(result)?.result,\n agentId: asObjectValue(result)?.agentId,\n metadata: asObjectValue(result)?.metadata,\n }),\n });\n\n this.configureMethod('execute', {\n startEvent: EXECUTION_EVENTS.START,\n completeEvent: EXECUTION_EVENTS.COMPLETE,\n errorEvent: EXECUTION_EVENTS.ERROR,\n extractMetadata: (target, methodName, args) => ({\n taskDescription: args[0],\n teamMode: true,\n }),\n extractResult: (result) => ({ response: result }),\n });\n }\n\n // Tool execution methods\n if (this.config.sourceType === 'tool') {\n this.configureMethod('execute', {\n startEvent: TOOL_EVENTS.CALL_START,\n completeEvent: TOOL_EVENTS.CALL_COMPLETE,\n errorEvent: TOOL_EVENTS.CALL_ERROR,\n extractMetadata: (target, methodName, args) => ({\n toolName: asObjectValue(target.schema)?.name || target.constructor.name,\n parameters: args[0],\n parametersCount: asObjectValue(args[0])\n ? Object.keys(asObjectValue(args[0]) || {}).length\n : 0,\n context: args[1],\n }),\n extractResult: (result) => ({\n result:\n typeof asObjectValue(result)?.data === 'string'\n ? asObjectValue(result)?.data || ''\n : JSON.stringify(asObjectValue(result)?.data),\n success: asObjectValue(result)?.success,\n }),\n });\n }\n\n return this;\n }\n\n /**\n * Create a proxy wrapper around the target object\n */\n wrap(target: T): T {\n return new Proxy(target, {\n get: (target, prop, receiver) => {\n const originalMethod = Reflect.get(target, prop, receiver);\n if (typeof prop !== 'string') {\n return originalMethod;\n }\n const methodName = prop;\n\n // Only wrap methods that are configured\n if (typeof originalMethod === 'function' && this.methodConfigs.has(methodName)) {\n const methodConfig = this.methodConfigs.get(methodName)!;\n\n return async (...args: TExecutionProxyArgs) => {\n const startTime = Date.now();\n const executionId = this.generateExecutionId();\n const proxyTarget = target as TExecutionProxyTarget;\n\n try {\n // Emit start event\n if (methodConfig.startEvent) {\n const metadata =\n methodConfig.extractMetadata?.(proxyTarget, methodName, args) || {};\n this.emitEvent(methodConfig.startEvent, {\n timestamp: new Date(),\n metadata: {\n ...metadata,\n executionId,\n methodName,\n phase: 'start',\n },\n });\n }\n\n // Execute original method\n const result = (await originalMethod.apply(target, args)) as TUniversalValue;\n const duration = Date.now() - startTime;\n\n // Emit complete event\n if (methodConfig.completeEvent) {\n const extractedResult = methodConfig.extractResult?.(result) || {};\n const metadata =\n methodConfig.extractMetadata?.(proxyTarget, methodName, args) || {};\n this.emitEvent(methodConfig.completeEvent, {\n timestamp: new Date(),\n ...extractedResult,\n metadata: {\n ...metadata,\n executionId,\n methodName,\n duration,\n phase: 'complete',\n success: true,\n },\n });\n }\n\n return result;\n } catch (error) {\n const duration = Date.now() - startTime;\n\n // Emit error event\n if (methodConfig.errorEvent) {\n const metadata =\n methodConfig.extractMetadata?.(proxyTarget, methodName, args) || {};\n this.emitEvent(methodConfig.errorEvent, {\n timestamp: new Date(),\n error: error instanceof Error ? error.message : String(error),\n metadata: {\n ...metadata,\n executionId,\n methodName,\n duration,\n phase: 'error',\n errorName: error instanceof Error ? error.name : 'UnknownError',\n success: false,\n },\n });\n }\n\n throw error;\n }\n };\n }\n\n return originalMethod;\n },\n }) as T;\n }\n\n /**\n * Emit event with standard ServiceEventData format\n */\n private emitEvent(eventType: string, additionalData: Partial<IBaseEventData>): void {\n const baseMetadata = {\n emitterSourceType: this.config.sourceType,\n emitterSourceId: this.config.sourceId,\n };\n\n const eventData: IBaseEventData = {\n timestamp: new Date(),\n ...(additionalData.metadata\n ? { metadata: { ...baseMetadata, ...additionalData.metadata } }\n : { metadata: baseMetadata }),\n ...additionalData,\n };\n\n this.config.eventService.emit(eventType, eventData);\n }\n\n /**\n * Generate unique execution ID\n */\n private generateExecutionId(): string {\n return `${this.config.sourceType}-${this.config.sourceId}-${Date.now()}-${Math.random().toString(ID_RADIX).substr(2, ID_RANDOM_LENGTH)}`;\n }\n}\n\n/**\n * Factory function to create execution proxy with standard configuration\n */\nexport function createExecutionProxy<T extends object>(\n target: T,\n config: IExecutionProxyConfig,\n): T {\n const proxy = new ExecutionProxy<T>(config);\n proxy.configureStandardMethods();\n return proxy.wrap(target);\n}\n\n/**\n * Decorator function for automatic event emission\n * Usage: @withEventEmission(eventService, 'agent', 'agent-id')\n */\nexport function withEventEmission(\n eventService: IEventService,\n sourceType: 'agent' | 'team' | 'tool',\n sourceId: string,\n) {\n return function <T extends object>(target: T): T {\n return createExecutionProxy(target, {\n eventService,\n sourceType,\n sourceId,\n }) as T;\n };\n}\n","/**\n * Permission system types — Claude Code compatible permission model.\n */\n\n/**\n * Permission modes (Claude Code compatible)\n * - plan: read-only tools only\n * - default: reads auto, writes/bash need approval\n * - acceptEdits: reads + writes auto, bash needs approval\n * - bypassPermissions: all tools auto\n */\nexport type TPermissionMode = 'plan' | 'default' | 'acceptEdits' | 'bypassPermissions';\n\n/**\n * Friendly trust level aliases\n * - safe → plan\n * - moderate → default\n * - full → acceptEdits\n */\nexport type TTrustLevel = 'safe' | 'moderate' | 'full';\n\nexport const TRUST_TO_MODE: Record<TTrustLevel, TPermissionMode> = {\n safe: 'plan',\n moderate: 'default',\n full: 'acceptEdits',\n};\n\n/**\n * Outcome of a permission evaluation\n * - auto: proceed without prompting\n * - approve: prompt user for approval\n * - deny: block the action\n */\nexport type TPermissionDecision = 'auto' | 'approve' | 'deny';\n","/**\n * Permission mode definitions for Robota CLI\n *\n * Matches Claude Code-compatible permission modes:\n * - plan: read-only tools only (Read, Glob, Grep, WebFetch, WebSearch auto; Write, Edit, Bash denied)\n * - default: safe reads auto, writes and bash need approval\n * - acceptEdits: reads + writes auto, bash needs approval\n * - bypassPermissions: all tools auto\n */\n\nimport type { TPermissionMode, TPermissionDecision } from './types.js';\n\n/**\n * Tool names known to the permission system\n */\nexport type TKnownToolName =\n | 'Bash'\n | 'Read'\n | 'Write'\n | 'Edit'\n | 'Glob'\n | 'Grep'\n | 'WebFetch'\n | 'WebSearch';\n\n/**\n * Permission mode → tool policy matrix\n * Maps each mode to a decision for each known tool.\n */\nexport const MODE_POLICY: Record<TPermissionMode, Record<TKnownToolName, TPermissionDecision>> = {\n plan: {\n Bash: 'deny',\n Read: 'auto',\n Write: 'deny',\n Edit: 'deny',\n Glob: 'auto',\n Grep: 'auto',\n WebFetch: 'auto',\n WebSearch: 'auto',\n },\n default: {\n Bash: 'approve',\n Read: 'auto',\n Write: 'approve',\n Edit: 'approve',\n Glob: 'auto',\n Grep: 'auto',\n WebFetch: 'auto',\n WebSearch: 'auto',\n },\n acceptEdits: {\n Bash: 'approve',\n Read: 'auto',\n Write: 'auto',\n Edit: 'auto',\n Glob: 'auto',\n Grep: 'auto',\n WebFetch: 'auto',\n WebSearch: 'auto',\n },\n bypassPermissions: {\n Bash: 'auto',\n Read: 'auto',\n Write: 'auto',\n Edit: 'auto',\n Glob: 'auto',\n Grep: 'auto',\n WebFetch: 'auto',\n WebSearch: 'auto',\n },\n};\n\n/**\n * Fallback decision when a tool name is not in the policy matrix.\n * Unknown tools are treated as requiring approval (fail-safe).\n */\nexport const UNKNOWN_TOOL_FALLBACK: Record<TPermissionMode, TPermissionDecision> = {\n plan: 'deny',\n default: 'approve',\n acceptEdits: 'approve',\n bypassPermissions: 'auto',\n};\n","/**\n * Permission gate — evaluates whether a tool call is auto-approved, needs user approval, or denied.\n *\n * Three-step deterministic policy (in order of precedence):\n * 1. Deny list match → deny\n * 2. Allow list match → auto\n * 3. Mode policy lookup\n *\n * Pattern syntax (same as Claude Code):\n * - `Bash(pnpm *)` — Bash tool whose command starts with \"pnpm \"\n * - `Read(/src/**)` — Read tool whose filePath is under /src/\n * - `Write(*)` — Write tool with any argument\n * - `ToolName` — match any invocation of that tool\n */\n\nimport type { TPermissionMode, TPermissionDecision } from './types.js';\nimport { MODE_POLICY, UNKNOWN_TOOL_FALLBACK } from './permission-mode.js';\n\n/**\n * Tool arguments passed from the LLM invocation.\n * The values relevant to permission matching are strings.\n */\nexport type TToolArgs = Record<string, string | number | boolean | object>;\n\n/**\n * Permission list entries (allow / deny).\n * Each entry is a pattern string such as \"Bash(pnpm *)\" or \"Read(/src/**)\".\n */\nexport interface IPermissionLists {\n allow?: string[];\n deny?: string[];\n}\n\n/**\n * Convert a glob-style wildcard pattern to a RegExp.\n * Only `*` and `**` wildcards are supported (same semantics as minimatch lite).\n */\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // escape regex specials except * ?\n .replace(/\\*\\*/g, '.+') // ** → one-or-more any char\n .replace(/\\*/g, '.*'); // * → zero-or-more any char (shell-style, not path-segment restricted)\n return new RegExp(`^${escaped}$`);\n}\n\n/**\n * Parse a permission pattern entry into tool name and optional argument pattern.\n *\n * Examples:\n * - \"Bash\" → { toolName: \"Bash\", argPattern: undefined }\n * - \"Bash(pnpm *)\" → { toolName: \"Bash\", argPattern: \"pnpm *\" }\n * - \"Read(/src/**)\" → { toolName: \"Read\", argPattern: \"/src/**\" }\n */\nfunction parsePattern(pattern: string): { toolName: string; argPattern: string | undefined } {\n const parenIdx = pattern.indexOf('(');\n if (parenIdx === -1) {\n return { toolName: pattern.trim(), argPattern: undefined };\n }\n\n const toolName = pattern.slice(0, parenIdx).trim();\n const argPattern = pattern.slice(parenIdx + 1, pattern.lastIndexOf(')')).trim();\n return { toolName, argPattern };\n}\n\n/**\n * Return the \"primary\" argument value for a tool to match against argument patterns.\n * The matching argument depends on the tool:\n * Bash → args.command\n * Read → args.filePath\n * Write → args.filePath\n * Edit → args.filePath\n * Glob → args.pattern\n * Grep → args.pattern\n */\nfunction primaryArg(toolName: string, args: TToolArgs): string | undefined {\n switch (toolName) {\n case 'Bash':\n return typeof args['command'] === 'string' ? args['command'] : undefined;\n case 'Read':\n case 'Write':\n case 'Edit':\n return typeof args['filePath'] === 'string' ? args['filePath'] : undefined;\n case 'Glob':\n case 'Grep':\n return typeof args['pattern'] === 'string' ? args['pattern'] : undefined;\n default:\n return undefined;\n }\n}\n\n/**\n * Test whether a tool invocation matches a permission pattern entry.\n */\nfunction matchesPattern(toolName: string, args: TToolArgs, pattern: string): boolean {\n const parsed = parsePattern(pattern);\n\n // Tool name must match (case-sensitive)\n if (parsed.toolName !== toolName) {\n return false;\n }\n\n // No argument constraint → matches any invocation of that tool\n if (parsed.argPattern === undefined) {\n return true;\n }\n\n const primary = primaryArg(toolName, args);\n if (primary === undefined) {\n return false;\n }\n\n return globToRegex(parsed.argPattern).test(primary);\n}\n\n/**\n * Evaluate whether a tool invocation should be auto-approved, require user approval, or be denied.\n *\n * @param toolName Name of the tool being invoked (e.g. \"Bash\", \"Write\")\n * @param toolArgs Arguments provided by the LLM\n * @param mode Active permission mode\n * @param permissions Optional allow/deny lists from config\n */\nexport function evaluatePermission(\n toolName: string,\n toolArgs: TToolArgs,\n mode: TPermissionMode,\n permissions: IPermissionLists = {},\n): TPermissionDecision {\n const { allow = [], deny = [] } = permissions;\n\n // Step 1: deny list — if any deny pattern matches, block immediately\n for (const pattern of deny) {\n if (matchesPattern(toolName, toolArgs, pattern)) {\n return 'deny';\n }\n }\n\n // Step 2: allow list — if any allow pattern matches, auto-approve\n for (const pattern of allow) {\n if (matchesPattern(toolName, toolArgs, pattern)) {\n return 'auto';\n }\n }\n\n // Step 3: mode policy lookup\n const modePolicy = MODE_POLICY[mode];\n const knownDecision = modePolicy[toolName as keyof typeof modePolicy];\n if (knownDecision !== undefined) {\n return knownDecision;\n }\n\n // Unknown tool — use fail-safe fallback per mode\n return UNKNOWN_TOOL_FALLBACK[mode];\n}\n","/**\n * Command hook executor — executes shell commands with JSON input on stdin.\n *\n * Exit codes:\n * - 0: allow/proceed\n * - 2: block/deny (stderr contains reason)\n * - other: proceed (logged as warning)\n */\n\nimport { spawn } from 'node:child_process';\nimport type {\n ICommandHookDefinition,\n IHookInput,\n IHookResult,\n IHookTypeExecutor,\n} from '../types.js';\n\n/** Default timeout in seconds — matches Claude Code's 600s default */\nconst DEFAULT_TIMEOUT_SECONDS = 600;\n\nexport class CommandExecutor implements IHookTypeExecutor {\n readonly type = 'command' as const;\n\n execute(definition: ICommandHookDefinition, input: IHookInput): Promise<IHookResult> {\n const timeoutSeconds = definition.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n const timeoutMs = timeoutSeconds * 1000;\n const inputJson = JSON.stringify(input);\n\n return new Promise<IHookResult>((resolve) => {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n let settled = false;\n\n const child = spawn('sh', ['-c', definition.command], {\n cwd: input.cwd,\n env: { ...process.env, ...input.env },\n });\n\n child.stdout.on('data', (chunk: Buffer) => stdoutChunks.push(chunk));\n child.stderr.on('data', (chunk: Buffer) => stderrChunks.push(chunk));\n\n child.stdin.on('error', () => {\n // EPIPE: child closed stdin before we finished writing — safe to ignore\n });\n child.stdin.write(inputJson);\n child.stdin.end();\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n child.kill('SIGTERM');\n resolve({ exitCode: 1, stdout: '', stderr: 'Hook timed out' });\n }\n }, timeoutMs);\n\n child.on('close', (code: number | null) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({\n exitCode: code ?? 1,\n stdout: Buffer.concat(stdoutChunks).toString('utf8'),\n stderr: Buffer.concat(stderrChunks).toString('utf8'),\n });\n });\n\n child.on('error', (err: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ exitCode: 1, stdout: '', stderr: err.message });\n });\n });\n }\n}\n","/**\n * HTTP hook executor — POSTs hook input as JSON to a URL.\n *\n * Response format: { ok: boolean, reason?: string }\n * - ok: true → exit code 0\n * - ok: false → exit code 2 (blocked), reason in stderr\n *\n * Supports env var interpolation in headers: $VAR_NAME\n */\n\nimport type { IHttpHookDefinition, IHookInput, IHookResult, IHookTypeExecutor } from '../types.js';\n\n/** Default timeout in seconds */\nconst DEFAULT_TIMEOUT_SECONDS = 10;\n\n/** Interpolate $VAR_NAME references in a string with process.env values. */\nfunction interpolateEnvVars(value: string): string {\n return value.replace(/\\$([A-Za-z_][A-Za-z0-9_]*)/g, (_match, varName: string) => {\n const envValue = process.env[varName];\n return envValue !== undefined ? envValue : _match;\n });\n}\n\nexport class HttpExecutor implements IHookTypeExecutor {\n readonly type = 'http' as const;\n\n async execute(definition: IHttpHookDefinition, input: IHookInput): Promise<IHookResult> {\n const timeoutSeconds = definition.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n const timeoutMs = timeoutSeconds * 1000;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (definition.headers) {\n for (const [key, value] of Object.entries(definition.headers)) {\n headers[key] = interpolateEnvVars(value);\n }\n }\n\n try {\n const response = await fetch(definition.url, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n signal: AbortSignal.timeout(timeoutMs),\n });\n\n if (!response.ok) {\n return {\n exitCode: 1,\n stdout: '',\n stderr: `HTTP ${response.status} ${response.statusText}`,\n };\n }\n\n const body = (await response.json()) as { ok: boolean; reason?: string };\n\n if (!body.ok) {\n return {\n exitCode: 2,\n stdout: '',\n stderr: body.reason ?? 'Blocked by HTTP hook',\n };\n }\n\n return { exitCode: 0, stdout: JSON.stringify(body), stderr: '' };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { exitCode: 1, stdout: '', stderr: message };\n }\n }\n}\n","/**\n * Hook runner — executes hooks for lifecycle events using the strategy pattern.\n *\n * Dispatches to registered IHookTypeExecutor implementations by definition type.\n * Default executors: CommandExecutor (shell), HttpExecutor (HTTP POST).\n *\n * Exit code semantics:\n * - 0: allow/proceed\n * - 2: block/deny (stderr contains reason)\n * - other: proceed (logged as warning)\n *\n * stdout JSON semantics (Claude Code compatible):\n * - { continue: false } → block, regardless of exit code\n * - PreToolUse: { hookSpecificOutput: { permissionDecision, updatedInput } }\n * - UserPromptSubmit: { decision: \"block\" } → block; hookSpecificOutput.additionalContext → injected into stdout\n */\n\nimport type {\n THookEvent,\n THooksConfig,\n IHookGroup,\n IHookInput,\n IHookTypeExecutor,\n} from './types.js';\nimport { CommandExecutor } from './executors/command-executor.js';\nimport { HttpExecutor } from './executors/http-executor.js';\n\n/** Default set of hook type executors */\nfunction createDefaultExecutors(): IHookTypeExecutor[] {\n return [new CommandExecutor(), new HttpExecutor()];\n}\n\n/** Permission decision priority: deny=3 > defer=2 > ask=1 > allow=0 */\nconst PERMISSION_PRIORITY: Record<string, number> = { deny: 3, defer: 2, ask: 1, allow: 0 };\n\n/** Parse hook stdout as JSON if it starts with '{', otherwise return null. */\nfunction parseHookJson(stdout: string): Record<string, unknown> | null {\n const trimmed = stdout.trim();\n if (!trimmed.startsWith('{')) return null;\n try {\n return JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n // allow-fallback: hook stdout may be plain text; malformed JSON means raw stdout\n return null;\n }\n}\n\n/** Check if a tool name matches a hook group's matcher pattern. */\nfunction matchesGroup(group: IHookGroup, matcherTarget: string | undefined): boolean {\n // Empty matcher = match everything\n if (!group.matcher) return true;\n if (!matcherTarget) return false;\n try {\n return new RegExp(group.matcher).test(matcherTarget);\n } catch {\n // allow-fallback: invalid regex → fall back to exact string match\n return group.matcher === matcherTarget;\n }\n}\n\nfunction getMatcherTarget(input: IHookInput): string | undefined {\n if (input.tool_name) return input.tool_name;\n if (input.hook_event_name === 'SubagentStart' || input.hook_event_name === 'SubagentStop') {\n return input.agent_type ?? input.agent_id;\n }\n if (input.hook_event_name === 'SessionEnd') return input.reason;\n return undefined;\n}\n\n/** Result of running hooks for an event. */\nexport interface IRunHooksResult {\n blocked: boolean;\n reason?: string;\n /** Collected stdout from all successful hooks (exit code 0). */\n stdout: string;\n /** Parsed updatedInput from PreToolUse hookSpecificOutput (PreToolUse only). */\n updatedInput?: Record<string, unknown>;\n /** Highest-priority permissionDecision from PreToolUse hooks (PreToolUse only). */\n permissionDecision?: 'allow' | 'deny' | 'ask' | 'defer';\n}\n\n/**\n * Run all hooks for a given event.\n *\n * For PreToolUse: if any hook returns exit code 2 or JSON deny, the tool call is blocked.\n * JSON stdout responses are parsed and applied per Claude Code spec.\n * Returns { blocked: true, reason } if blocked, otherwise { blocked: false, stdout }.\n *\n * @param config - Hooks configuration mapping events to hook groups\n * @param event - The lifecycle event being fired\n * @param input - Hook input data passed to executors\n * @param executors - Optional array of hook type executors (defaults to command + http)\n */\nexport async function runHooks(\n config: THooksConfig | undefined,\n event: THookEvent,\n input: IHookInput,\n executors?: IHookTypeExecutor[],\n): Promise<IRunHooksResult> {\n if (!config) return { blocked: false, stdout: '' };\n\n const groups = config[event];\n if (!groups || groups.length === 0) return { blocked: false, stdout: '' };\n\n const resolvedExecutors = executors ?? createDefaultExecutors();\n const executorMap = new Map<string, IHookTypeExecutor>();\n for (const executor of resolvedExecutors) {\n executorMap.set(executor.type, executor);\n }\n\n const stdoutParts: string[] = [];\n const matcherTarget = getMatcherTarget(input);\n\n // PreToolUse multi-hook priority tracking\n let highestPermissionPriority = -1;\n let highestPermissionDecision: 'allow' | 'deny' | 'ask' | 'defer' | undefined;\n let lastUpdatedInput: Record<string, unknown> | undefined;\n\n for (const group of groups) {\n if (!matchesGroup(group, matcherTarget)) continue;\n\n // Merge group-level env vars into hook input\n const groupInput = group.env ? { ...input, env: { ...input.env, ...group.env } } : input;\n\n for (const hook of group.hooks) {\n const executor = executorMap.get(hook.type);\n if (!executor) {\n // Unknown hook type — skip with warning\n continue;\n }\n\n const result = await executor.execute(hook, groupInput);\n\n // Exit code 2 = block/deny (exit early)\n if (result.exitCode === 2) {\n return {\n blocked: true,\n reason: result.stderr || 'Blocked by hook',\n stdout: stdoutParts.join('\\n'),\n };\n }\n\n // Only parse stdout for exit code 0 responses\n if (result.exitCode !== 0) continue;\n\n const json = parseHookJson(result.stdout);\n\n if (json !== null) {\n // Common: continue: false → block\n if (json['continue'] === false) {\n const stopReason =\n typeof json['stopReason'] === 'string'\n ? json['stopReason']\n : 'Blocked by hook (continue: false)';\n return {\n blocked: true,\n reason: stopReason,\n stdout: stdoutParts.join('\\n'),\n };\n }\n\n // UserPromptSubmit: decision: \"block\" → block\n if (event === 'UserPromptSubmit' && json['decision'] === 'block') {\n const hookSpecific = json['hookSpecificOutput'];\n const additionalContext =\n hookSpecific !== null &&\n typeof hookSpecific === 'object' &&\n 'additionalContext' in (hookSpecific as object)\n ? String((hookSpecific as Record<string, unknown>)['additionalContext'])\n : undefined;\n return {\n blocked: true,\n reason: 'Blocked by hook (decision: block)',\n stdout: additionalContext\n ? [...stdoutParts, additionalContext].join('\\n')\n : stdoutParts.join('\\n'),\n };\n }\n\n // UserPromptSubmit: additionalContext without block → inject into stdout\n if (event === 'UserPromptSubmit') {\n const hookSpecific = json['hookSpecificOutput'];\n if (\n hookSpecific !== null &&\n typeof hookSpecific === 'object' &&\n 'additionalContext' in (hookSpecific as object)\n ) {\n const ctx = String((hookSpecific as Record<string, unknown>)['additionalContext']);\n if (ctx) stdoutParts.push(ctx);\n }\n }\n\n // PreToolUse: parse permissionDecision and updatedInput\n if (event === 'PreToolUse') {\n const hookSpecific = json['hookSpecificOutput'];\n if (hookSpecific !== null && typeof hookSpecific === 'object') {\n const specific = hookSpecific as Record<string, unknown>;\n const decision = specific['permissionDecision'];\n if (typeof decision === 'string' && decision in PERMISSION_PRIORITY) {\n const priority = PERMISSION_PRIORITY[decision];\n if (priority > highestPermissionPriority) {\n highestPermissionPriority = priority;\n highestPermissionDecision = decision as 'allow' | 'deny' | 'ask' | 'defer';\n }\n // deny → immediate block\n if (decision === 'deny') {\n return {\n blocked: true,\n reason: 'Blocked by hook (permissionDecision: deny)',\n stdout: stdoutParts.join('\\n'),\n permissionDecision: 'deny',\n };\n }\n // Track updatedInput from the highest-priority decision\n if (priority >= highestPermissionPriority && specific['updatedInput'] !== undefined) {\n lastUpdatedInput = specific['updatedInput'] as Record<string, unknown>;\n }\n }\n }\n }\n\n // systemMessage → inject into stdout for AI context\n if (typeof json['systemMessage'] === 'string' && json['systemMessage']) {\n stdoutParts.push(json['systemMessage']);\n }\n } else if (result.stdout.trim()) {\n // Raw text stdout (non-JSON)\n stdoutParts.push(result.stdout.trim());\n }\n }\n }\n\n const finalResult: IRunHooksResult = {\n blocked: false,\n stdout: stdoutParts.join('\\n'),\n };\n\n if (highestPermissionDecision !== undefined) {\n finalResult.permissionDecision = highestPermissionDecision;\n }\n if (lastUpdatedInput !== undefined) {\n finalResult.updatedInput = lastUpdatedInput;\n }\n\n return finalResult;\n}\n"],"mappings":"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"}