@iworkforces/tracelattice 2.2.0 → 2.3.0

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.
Files changed (38) hide show
  1. package/README.md +31 -8
  2. package/dist/ServerConfig.d.ts +9 -5
  3. package/dist/ServerConfig.d.ts.map +1 -1
  4. package/dist/ServerConfig.js.map +1 -1
  5. package/dist/cli.js +6 -5
  6. package/dist/config/ConfigLoader.d.ts +20 -7
  7. package/dist/config/ConfigLoader.d.ts.map +1 -1
  8. package/dist/config/ConfigLoader.js.map +1 -1
  9. package/dist/core/HistoryManager.d.ts +6 -1
  10. package/dist/core/HistoryManager.d.ts.map +1 -1
  11. package/dist/core/HistoryManager.js +38 -6
  12. package/dist/core/HistoryManager.js.map +1 -1
  13. package/dist/core/IHistoryManager.d.ts +2 -0
  14. package/dist/core/IHistoryManager.d.ts.map +1 -1
  15. package/dist/core/SessionErrors.d.ts +4 -0
  16. package/dist/core/SessionErrors.d.ts.map +1 -1
  17. package/dist/core/SessionErrors.js +9 -1
  18. package/dist/core/SessionErrors.js.map +1 -1
  19. package/dist/core/SessionResetCoordinator.d.ts +4 -0
  20. package/dist/core/SessionResetCoordinator.d.ts.map +1 -1
  21. package/dist/core/SessionResetCoordinator.js +6 -0
  22. package/dist/core/SessionResetCoordinator.js.map +1 -1
  23. package/dist/core/ThoughtProcessor.d.ts.map +1 -1
  24. package/dist/core/ThoughtProcessor.js +5 -4
  25. package/dist/core/ThoughtProcessor.js.map +1 -1
  26. package/dist/errors.d.ts +1 -0
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +1 -0
  29. package/dist/errors.js.map +1 -1
  30. package/dist/metrics/metrics.impl.d.ts.map +1 -1
  31. package/dist/metrics/metrics.impl.js +19 -7
  32. package/dist/metrics/metrics.impl.js.map +1 -1
  33. package/dist/persistence/FileSnapshotV2.d.ts +6 -6
  34. package/dist/schema.d.ts +3 -3
  35. package/dist/schema.d.ts.map +1 -1
  36. package/dist/schema.js +5 -5
  37. package/dist/schema.js.map +1 -1
  38. package/package.json +13 -13
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sources":["../src/errors.ts"],"sourcesContent":["/**\n * Custom error types for the TraceLattice server.\n *\n * This module defines a hierarchy of error classes for handling various\n * error conditions that can occur in the sequential thinking server.\n * All errors extend the base `SequentialThinkingError` class with\n * specific error codes for programmatic handling.\n *\n * @example\n * ```typescript\n * import { ToolNotFoundError, SkillDiscoveryError } from './errors.js';\n *\n * // Throw a tool not found error\n * throw new ToolNotFoundError('my-tool');\n *\n * // Catch and handle specific errors\n * try {\n * await discoverSkills(dir);\n * } catch (error) {\n * if (error instanceof SkillDiscoveryError) {\n * console.error(`Failed to discover skills: ${error.message}`);\n * console.error(`Error code: ${error.code}`);\n * }\n * }\n * ```\n * @module errors\n */\n\n/**\n * All known error codes as a const object for exhaustive switching.\n */\nexport const ERROR_CODES = {\n\tCONFIGURATION_ERROR: 'CONFIGURATION_ERROR',\n\tTOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n\tSKILL_NOT_FOUND: 'SKILL_NOT_FOUND',\n\tINVALID_THOUGHT: 'INVALID_THOUGHT',\n\tSKILL_DISCOVERY_FAILED: 'SKILL_DISCOVERY_FAILED',\n\tHISTORY_LIMIT_EXCEEDED: 'HISTORY_LIMIT_EXCEEDED',\n\tDUPLICATE_SKILL: 'DUPLICATE_SKILL',\n\tINVALID_SKILL: 'INVALID_SKILL',\n\tDUPLICATE_TOOL: 'DUPLICATE_TOOL',\n\tINVALID_TOOL: 'INVALID_TOOL',\n\tSESSION_NOT_ACTIVE: 'SESSION_NOT_ACTIVE',\n\tSESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n\tMAX_SESSIONS_REACHED: 'MAX_SESSIONS_REACHED',\n\tPOOL_TERMINATED: 'POOL_TERMINATED',\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_EDGE: 'INVALID_EDGE',\n\tCYCLE_DETECTED: 'CYCLE_DETECTED',\n\tSUSPENSION_NOT_FOUND: 'SUSPENSION_NOT_FOUND',\n\tSUSPENSION_EXPIRED: 'SUSPENSION_EXPIRED',\n\tINVALID_TOOL_CALL: 'INVALID_TOOL_CALL',\n\tINVALID_BACKTRACK: 'INVALID_BACKTRACK',\n\tDUPLICATE_SUMMARY: 'DUPLICATE_SUMMARY',\n\tUNKNOWN_TOOL: 'UNKNOWN_TOOL',\n\tLOCK_TIMEOUT: 'LOCK_TIMEOUT',\n\tCLI_SHUTDOWN_TIMEOUT: 'CLI_SHUTDOWN_TIMEOUT',\n\tSESSION_ACCESS_DENIED: 'SESSION_ACCESS_DENIED',\n\tSESSION_LIFECYCLE_CLOSED: 'SESSION_LIFECYCLE_CLOSED',\n\tPERSISTENCE_OWNERSHIP: 'PERSISTENCE_OWNERSHIP',\n\tPERSISTENCE_CORRUPTION: 'PERSISTENCE_CORRUPTION',\n\tPERSISTENCE_PUBLICATION: 'PERSISTENCE_PUBLICATION',\n\tPERSISTENCE_CLOSED: 'PERSISTENCE_CLOSED',\n\tPERSISTENCE_DRAIN: 'PERSISTENCE_DRAIN',\n\tPERSISTENCE_SESSION_ADMISSION_CLOSED: 'PERSISTENCE_SESSION_ADMISSION_CLOSED',\n\tPERSISTENCE_SESSION_BARRIER_REENTRANCY: 'PERSISTENCE_SESSION_BARRIER_REENTRANCY',\n\tPERSISTENCE_SCOPE_MISMATCH: 'PERSISTENCE_SCOPE_MISMATCH',\n\tPERSISTENCE_UNAVAILABLE: 'PERSISTENCE_UNAVAILABLE',\n\tPERSISTENCE_COMPATIBILITY: 'PERSISTENCE_COMPATIBILITY',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * All known warning codes as a const object.\n * Warnings are non-fatal advisory signals returned alongside successful results.\n */\nexport const WARNING_CODES = {\n\tTOTAL_THOUGHTS_ADJUSTED: 'TOTAL_THOUGHTS_ADJUSTED',\n} as const;\n\nexport type WarningCode = (typeof WARNING_CODES)[keyof typeof WARNING_CODES];\n\n/**\n * Base error class for all Sequential Thinking server errors.\n *\n * This error extends the native `Error` class and adds a `code` property\n * for programmatic error identification and handling. All specific error\n * types in the system extend this base class.\n *\n * @remarks\n * **Error Codes:**\n * - `TOOL_NOT_FOUND` - A requested tool was not found\n * - `SKILL_NOT_FOUND` - A requested skill was not found\n * - `INVALID_THOUGHT` - Thought validation failed\n * - `SKILL_DISCOVERY_FAILED` - Skill discovery operation failed\n * - `HISTORY_LIMIT_EXCEEDED` - History size limit was exceeded\n * - `INVALID_EDGE` - An invalid edge operation was attempted\n *\n * @example\n * ```typescript\n * // Throw a custom sequential thinking error\n * throw new SequentialThinkingError('Custom error message', 'CUSTOM_CODE');\n *\n * // Check if an error is a SequentialThinkingError\n * if (error instanceof SequentialThinkingError) {\n * console.error(`Error [${error.code}]: ${error.message}`);\n * }\n * ```\n */\nexport class SequentialThinkingError extends Error {\n\t/** The error code for programmatic identification. */\n\tpublic readonly code: ErrorCode;\n\n\t/**\n\t * Creates a new SequentialThinkingError.\n\t *\n\t * @param message - Human-readable error message\n\t * @param code - Error code for programmatic handling\n\t *\n\t * @example\n\t * ```typescript\n\t * const error = new SequentialThinkingError(\n\t * 'Something went wrong',\n\t * 'CUSTOM_ERROR'\n\t * );\n\t * console.log(error.code); // 'CUSTOM_ERROR'\n\t * ```\n\t */\n\tconstructor(message: string, code: ErrorCode) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t\tthis.name = 'SequentialThinkingError';\n\t\tError.captureStackTrace(this, this.constructor);\n\t}\n}\n\nexport class ConfigurationError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.CONFIGURATION_ERROR);\n\t\tthis.name = 'ConfigurationError';\n\t}\n}\n\n/**\n * Error thrown when a requested tool is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a tool that doesn't exist in the tool registry.\n *\n * @example\n * ```typescript\n * const tool = registry.get('non-existent-tool');\n * if (!tool) {\n * throw new ToolNotFoundError('non-existent-tool');\n * }\n * ```\n */\nexport class ToolNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new ToolNotFoundError.\n\t *\n\t * @param toolName - The name of the tool that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new ToolNotFoundError('my-custom-tool');\n\t * // Error: tool 'my-custom-tool' not found\n\t *\n\t * throw new ToolNotFoundError('my-custom-tool', 'remove');\n\t * // Error: tool 'my-custom-tool' not found, cannot remove\n\t * // Code: TOOL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(toolName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Tool '${toolName}' not found, cannot ${action}`\n\t\t\t: `Tool '${toolName}' not found`;\n\t\tsuper(message, ERROR_CODES.TOOL_NOT_FOUND);\n\t\tthis.name = 'ToolNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a requested skill is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a skill that doesn't exist in the skill registry.\n *\n * @example\n * ```typescript\n * const skill = registry.get('non-existent-skill');\n * if (!skill) {\n * throw new SkillNotFoundError('non-existent-skill');\n * }\n * ```\n */\nexport class SkillNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SkillNotFoundError.\n\t *\n\t * @param skillName - The name of the skill that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SkillNotFoundError('my-custom-skill');\n\t * // Error: skill 'my-custom-skill' not found\n\t *\n\t * throw new SkillNotFoundError('my-custom-skill', 'remove');\n\t * // Error: skill 'my-custom-skill' not found, cannot remove\n\t * // Code: SKILL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(skillName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Skill '${skillName}' not found, cannot ${action}`\n\t\t\t: `Skill '${skillName}' not found`;\n\t\tsuper(message, ERROR_CODES.SKILL_NOT_FOUND);\n\t\tthis.name = 'SkillNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when thought validation fails.\n *\n * This error is thrown when a thought fails validation, typically due to\n * invalid values, missing required fields, or constraint violations.\n *\n * @example\n * ```typescript\n * // Validate thought number\n * if (thought.thought_number < 1) {\n * throw new InvalidThoughtError(thought.thought_number, 'thought_number must be >= 1');\n * }\n * ```\n */\nexport class InvalidThoughtError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidThoughtError.\n\t *\n\t * @param thoughtNumber - The thought number that failed validation\n\t * @param reason - Human-readable explanation of why validation failed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidThoughtError(5, 'thought_number exceeds total_thoughts');\n\t * // Error: Invalid thought 5: thought_number exceeds total_thoughts\n\t * // Code: INVALID_THOUGHT\n\t * ```\n\t */\n\tconstructor(thoughtNumber: number, reason: string) {\n\t\tsuper(`Invalid thought ${thoughtNumber}: ${reason}`, ERROR_CODES.INVALID_THOUGHT);\n\t\tthis.name = 'InvalidThoughtError';\n\t}\n}\n\n/**\n * Error thrown when skill discovery fails.\n *\n * This error is thrown when the skill discovery process encounters an issue,\n * such as filesystem errors, invalid skill files, or parsing failures.\n *\n * @remarks\n * The original error that caused the discovery failure is preserved in the\n * `cause` property for debugging purposes.\n *\n * @example\n * ```typescript\n * try {\n * await discoverSkills('./skills');\n * } catch (error) {\n * throw new SkillDiscoveryError('./skills', error as Error);\n * }\n * ```\n */\nexport class SkillDiscoveryError extends SequentialThinkingError {\n\t/** The underlying error that caused the discovery failure. */\n\tpublic override readonly cause: Error;\n\n\t/**\n\t * Creates a new SkillDiscoveryError.\n\t *\n\t * @param directory - The directory where discovery failed\n\t * @param cause - The underlying error that caused the failure\n\t *\n\t * @example\n\t * ```typescript\n\t * try {\n\t * const skills = await loadSkills('./invalid-directory');\n\t * } catch (error) {\n\t * throw new SkillDiscoveryError('./invalid-directory', error as Error);\n\t * }\n\t * ```\n\t */\n\tconstructor(directory: string, cause: Error) {\n\t\tsuper(\n\t\t\t`Failed to discover skills in ${directory}: ${cause.message}`,\n\t\t\tERROR_CODES.SKILL_DISCOVERY_FAILED\n\t\t);\n\t\tthis.name = 'SkillDiscoveryError';\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Error thrown when history size exceeds the configured limit.\n *\n * This error is thrown when an operation would cause the history size\n * to exceed the maximum configured size limit.\n *\n * @example\n * ```typescript\n * if (history.length >= maxSize) {\n * throw new HistoryLimitExceededError(history.length, maxSize);\n * }\n * ```\n */\nexport class HistoryLimitExceededError extends SequentialThinkingError {\n\t/**\n\t * Creates a new HistoryLimitExceededError.\n\t *\n\t * @param currentSize - The current history size\n\t * @param maxSize - The maximum allowed size\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new HistoryLimitExceededError(1500, 1000);\n\t * // Error: History size 1500 exceeds limit 1000\n\t * // Code: HISTORY_LIMIT_EXCEEDED\n\t * ```\n\t */\n\tconstructor(currentSize: number, maxSize: number) {\n\t\tsuper(\n\t\t\t`History size ${currentSize} exceeds limit ${maxSize}`,\n\t\t\tERROR_CODES.HISTORY_LIMIT_EXCEEDED\n\t\t);\n\t\tthis.name = 'HistoryLimitExceededError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a skill that already exists.\n *\n * This error is thrown when trying to register a skill with a name that\n * is already present in the skill registry.\n *\n * @example\n * ```typescript\n * if (registry.has(skill.name)) {\n * throw new DuplicateSkillError(skill.name);\n * }\n * ```\n */\nexport class DuplicateSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateSkillError.\n\t *\n\t * @param skillName - The name of the duplicate skill\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateSkillError('my-skill');\n\t * // Error: skill 'my-skill' already exists\n\t * // Code: DUPLICATE_SKILL\n\t * ```\n\t */\n\tconstructor(skillName: string) {\n\t\tsuper(`skill '${skillName}' already exists`, ERROR_CODES.DUPLICATE_SKILL);\n\t\tthis.name = 'DuplicateSkillError';\n\t}\n}\n\n/**\n * Error thrown when a skill has invalid data.\n *\n * This error is thrown when a skill fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!skill.name) {\n * throw new InvalidSkillError('Skill must have a valid name');\n * }\n * ```\n */\nexport class InvalidSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidSkillError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidSkillError('Skill must have a valid name');\n\t * // Error: Invalid skill: Skill must have a valid name\n\t * // Code: INVALID_SKILL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid skill: ${reason}`, ERROR_CODES.INVALID_SKILL);\n\t\tthis.name = 'InvalidSkillError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a tool that already exists.\n *\n * This error is thrown when trying to register a tool with a name that\n * is already present in the tool registry.\n *\n * @example\n * ```typescript\n * if (registry.has(tool.name)) {\n * throw new DuplicateToolError(tool.name);\n * }\n * ```\n */\nexport class DuplicateToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateToolError.\n\t *\n\t * @param toolName - The name of the duplicate tool\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateToolError('my-tool');\n\t * // Error: tool 'my-tool' already exists\n\t * // Code: DUPLICATE_TOOL\n\t * ```\n\t */\n\tconstructor(toolName: string) {\n\t\tsuper(`tool '${toolName}' already exists`, ERROR_CODES.DUPLICATE_TOOL);\n\t\tthis.name = 'DuplicateToolError';\n\t}\n}\n\n/**\n * Error thrown when a tool has invalid data.\n *\n * This error is thrown when a tool fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!tool.name) {\n * throw new InvalidToolError('Tool must have a valid name');\n * }\n * ```\n */\nexport class InvalidToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidToolError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidToolError('Tool must have a valid name');\n\t * // Error: Invalid tool: Tool must have a valid name\n\t * // Code: INVALID_TOOL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid tool: ${reason}`, ERROR_CODES.INVALID_TOOL);\n\t\tthis.name = 'InvalidToolError';\n\t}\n}\n\n/**\n * Error thrown when the maximum number of sessions has been reached.\n *\n * This error is thrown when trying to create a new session when the\n * pool has reached its configured maximum session limit.\n *\n * @example\n * ```typescript\n * if (pool.sessionCount >= pool.maxSessions) {\n * throw new MaxSessionsReachedError(pool.maxSessions);\n * }\n * ```\n */\nexport class MaxSessionsReachedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new MaxSessionsReachedError.\n\t *\n\t * @param maxSessions - The maximum number of sessions allowed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new MaxSessionsReachedError(100);\n\t * // Error: Max sessions (100) reached. Wait for a session to close or increase maxSessions.\n\t * // Code: MAX_SESSIONS_REACHED\n\t * ```\n\t */\n\tconstructor(maxSessions: number) {\n\t\tsuper(\n\t\t\t`Max sessions (${maxSessions}) reached. Wait for a session to close or increase maxSessions.`,\n\t\t\tERROR_CODES.MAX_SESSIONS_REACHED\n\t\t);\n\t\tthis.name = 'MaxSessionsReachedError';\n\t}\n}\n\n/**\n * Error thrown when attempting to use a terminated connection pool.\n *\n * This error is thrown when trying to create sessions or process requests\n * after the connection pool has been terminated.\n *\n * @example\n * ```typescript\n * if (pool.isTerminated) {\n * throw new PoolTerminatedError();\n * }\n * ```\n */\nexport class PoolTerminatedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new PoolTerminatedError.\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new PoolTerminatedError();\n\t * // Error: ConnectionPool has been terminated\n\t * // Code: POOL_TERMINATED\n\t * ```\n\t */\n\tconstructor() {\n\t\tsuper('ConnectionPool has been terminated', ERROR_CODES.POOL_TERMINATED);\n\t\tthis.name = 'PoolTerminatedError';\n\t}\n}\n\n/**\n * Error thrown when input validation fails due to invalid or malicious data.\n *\n * This error is thrown when user input fails security or format validation,\n * such as path traversal attempts or invalid identifier formats.\n *\n * @example\n * ```typescript\n * if (!BRANCH_ID_PATTERN.test(branchId)) {\n * throw new ValidationError('branchId', 'Invalid format');\n * }\n * ```\n */\nexport class ValidationError extends SequentialThinkingError {\n\t/** The field that failed validation. */\n\tpublic readonly field: string;\n\n\tconstructor(field: string, reason: string) {\n\t\tsuper(`Validation failed for '${field}': ${reason}`, ERROR_CODES.VALIDATION_ERROR);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t}\n}\n\n/**\n * Error thrown when an invalid edge operation is attempted.\n *\n * This error is thrown when attempting to add an edge that violates\n * structural invariants of the thought DAG, such as a self-edge\n * (where `from` and `to` reference the same thought).\n *\n * @example\n * ```typescript\n * if (edge.from === edge.to) {\n * throw new InvalidEdgeError(\n * `Self-edge not allowed: from and to are the same (${edge.from})`\n * );\n * }\n * ```\n */\nexport class InvalidEdgeError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidEdgeError.\n\t *\n\t * @param message - Human-readable explanation of the invalid edge\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidEdgeError('Self-edge not allowed: from and to are the same (t1)');\n\t * // Code: INVALID_EDGE\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_EDGE);\n\t\tthis.name = 'InvalidEdgeError';\n\t}\n}\n\n/**\n * Error thrown when a cycle is detected during graph traversal.\n *\n * This error is thrown by graph algorithms (such as topological sort)\n * when the thought DAG contains a cycle, violating the acyclic invariant.\n *\n * @example\n * ```typescript\n * try {\n * const order = graphView.topological(sessionId);\n * } catch (error) {\n * if (error instanceof CycleDetectedError) {\n * console.error('Cycle in thought graph:', error.message);\n * }\n * }\n * ```\n */\nexport class CycleDetectedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new CycleDetectedError.\n\t *\n\t * @param message - Human-readable explanation of the cycle\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new CycleDetectedError('Cycle detected in session s1');\n\t * // Code: CYCLE_DETECTED\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.CYCLE_DETECTED);\n\t\tthis.name = 'CycleDetectedError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record is not found.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension that does not exist in the suspension store.\n */\nexport class SuspensionNotFoundError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.SUSPENSION_NOT_FOUND);\n\t\tthis.name = 'SuspensionNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record has expired.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension whose TTL has elapsed.\n */\nexport class SuspensionExpiredError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.SUSPENSION_EXPIRED);\n\t\tthis.name = 'SuspensionExpiredError';\n\t}\n}\n\n/**\n * Error thrown when a tool call payload is invalid.\n *\n * This error is thrown when a tool interleave invocation has malformed\n * arguments, missing identifiers, or otherwise fails validation.\n */\nexport class InvalidToolCallError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_TOOL_CALL);\n\t\tthis.name = 'InvalidToolCallError';\n\t}\n}\n\n/**\n * Error thrown when a backtrack operation is invalid.\n *\n * This error is thrown when an attempt to backtrack the reasoning\n * chain references an unreachable thought or violates DAG invariants.\n */\nexport class InvalidBacktrackError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_BACKTRACK);\n\t\tthis.name = 'InvalidBacktrackError';\n\t}\n}\n\n/**\n * Error thrown when a tool_call references a tool not registered with the server.\n *\n * Acts as an allowlist gate: only tools registered in the ToolRegistry may be\n * invoked through tool interleave. Prevents arbitrary tool name injection.\n */\nexport class UnknownToolError extends SequentialThinkingError {\n\tpublic readonly toolName: string;\n\n\tconstructor(toolName: string, message?: string) {\n\t\tsuper(\n\t\t\tmessage ?? `Unknown tool '${toolName}': not registered with the server`,\n\t\t\tERROR_CODES.UNKNOWN_TOOL\n\t\t);\n\t\tthis.name = 'UnknownToolError';\n\t\tthis.toolName = toolName;\n\t}\n}\n\n/** Error thrown when the CLI's complete shutdown exceeds its outer deadline. */\nexport class CliShutdownTimeoutError extends SequentialThinkingError {\n\tpublic readonly timeoutMs: number;\n\n\tconstructor(timeoutMs: number) {\n\t\tsuper(`CLI shutdown timed out after ${timeoutMs}ms`, ERROR_CODES.CLI_SHUTDOWN_TIMEOUT);\n\t\tthis.name = 'CliShutdownTimeoutError';\n\t\tthis.timeoutMs = timeoutMs;\n\t}\n}\n\nexport class PersistenceOwnershipError extends SequentialThinkingError {\n\tpublic readonly canonicalDataDir: string;\n\tpublic readonly lockPath: string;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(canonicalDataDir: string, lockPath: string, cause: unknown) {\n\t\tsuper(\n\t\t\t`Persistence directory '${canonicalDataDir}' already has an active writer`,\n\t\t\tERROR_CODES.PERSISTENCE_OWNERSHIP\n\t\t);\n\t\tthis.name = 'PersistenceOwnershipError';\n\t\tthis.canonicalDataDir = canonicalDataDir;\n\t\tthis.lockPath = lockPath;\n\t\tthis.cause = cause;\n\t}\n}\n\nexport class PersistenceCorruptionError extends SequentialThinkingError {\n\tpublic readonly path: string;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(path: string, cause: unknown) {\n\t\tsuper(\n\t\t\t`Persisted data at '${path}' is corrupt or incompatible`,\n\t\t\tERROR_CODES.PERSISTENCE_CORRUPTION\n\t\t);\n\t\tthis.name = 'PersistenceCorruptionError';\n\t\tthis.path = path;\n\t\tthis.cause = cause;\n\t}\n}\n\n/** Error raised when startup cannot read from an unhealthy persistence backend. */\nexport class PersistenceUnavailableError extends SequentialThinkingError {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'Persistence backend is unavailable during startup restore',\n\t\t\tERROR_CODES.PERSISTENCE_UNAVAILABLE\n\t\t);\n\t\tthis.name = 'PersistenceUnavailableError';\n\t}\n}\n\nexport type PersistencePublicationStage = 'temporary-write' | 'atomic-replacement' | 'cleanup';\n\nexport class PersistencePublicationError extends SequentialThinkingError {\n\tpublic readonly path: string;\n\tpublic readonly stage: PersistencePublicationStage;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(path: string, stage: PersistencePublicationStage, cause: unknown) {\n\t\tsuper(\n\t\t\t`Failed persistence publication for '${path}' during ${stage}`,\n\t\t\tERROR_CODES.PERSISTENCE_PUBLICATION\n\t\t);\n\t\tthis.name = 'PersistencePublicationError';\n\t\tthis.path = path;\n\t\tthis.stage = stage;\n\t\tthis.cause = cause;\n\t}\n}\n\nexport class PersistenceClosedError extends SequentialThinkingError {\n\tpublic readonly dataDir: string;\n\n\tconstructor(dataDir: string) {\n\t\tsuper(`Persistence writer for '${dataDir}' is closed`, ERROR_CODES.PERSISTENCE_CLOSED);\n\t\tthis.name = 'PersistenceClosedError';\n\t\tthis.dataDir = dataDir;\n\t}\n}\n\n/** Error raised for well-formed but unsupported or drifted persisted data. */\nexport class PersistenceCompatibilityError extends SequentialThinkingError {\n\tpublic readonly sourcePath: string;\n\tpublic readonly detail: string;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(sourcePath: string, detail: string, cause?: unknown) {\n\t\tsuper(\n\t\t\t`Persisted data at '${sourcePath}' is incompatible: ${detail}`,\n\t\t\tERROR_CODES.PERSISTENCE_COMPATIBILITY\n\t\t);\n\t\tthis.name = 'PersistenceCompatibilityError';\n\t\tthis.sourcePath = sourcePath;\n\t\tthis.detail = detail;\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Type guard to check if an error has a specific error code.\n */\nexport function isErrorCode<C extends ErrorCode>(\n\terr: unknown,\n\tcode: C\n): err is SequentialThinkingError & { readonly code: C } {\n\treturn err instanceof SequentialThinkingError && err.code === code;\n}\n\n/**\n * Extract a human-readable message from an unknown error value.\n *\n * Standardizes the common `error instanceof Error ? error.message : String(error)`\n * pattern used in catch blocks across the codebase.\n *\n * @param error - The unknown error value to extract a message from\n * @returns The error message string\n *\n * @example\n * ```typescript\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error('Failed', { error: getErrorMessage(error) });\n * }\n * ```\n */\nexport function getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],"names":["ERROR_CODES","WARNING_CODES","SequentialThinkingError","Error","message","code","ConfigurationError","ToolNotFoundError","toolName","action","SkillNotFoundError","skillName","InvalidThoughtError","thoughtNumber","reason","SkillDiscoveryError","directory","cause","HistoryLimitExceededError","currentSize","maxSize","DuplicateSkillError","InvalidSkillError","DuplicateToolError","InvalidToolError","MaxSessionsReachedError","maxSessions","PoolTerminatedError","ValidationError","field","InvalidEdgeError","CycleDetectedError","SuspensionNotFoundError","SuspensionExpiredError","InvalidToolCallError","InvalidBacktrackError","UnknownToolError","CliShutdownTimeoutError","timeoutMs","PersistenceOwnershipError","canonicalDataDir","lockPath","PersistenceCorruptionError","path","PersistenceUnavailableError","PersistencePublicationError","stage","PersistenceClosedError","dataDir","PersistenceCompatibilityError","sourcePath","detail","isErrorCode","err","getErrorMessage","error","String"],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sources":["../src/errors.ts"],"sourcesContent":["/**\n * Custom error types for the TraceLattice server.\n *\n * This module defines a hierarchy of error classes for handling various\n * error conditions that can occur in the sequential thinking server.\n * All errors extend the base `SequentialThinkingError` class with\n * specific error codes for programmatic handling.\n *\n * @example\n * ```typescript\n * import { ToolNotFoundError, SkillDiscoveryError } from './errors.js';\n *\n * // Throw a tool not found error\n * throw new ToolNotFoundError('my-tool');\n *\n * // Catch and handle specific errors\n * try {\n * await discoverSkills(dir);\n * } catch (error) {\n * if (error instanceof SkillDiscoveryError) {\n * console.error(`Failed to discover skills: ${error.message}`);\n * console.error(`Error code: ${error.code}`);\n * }\n * }\n * ```\n * @module errors\n */\n\n/**\n * All known error codes as a const object for exhaustive switching.\n */\nexport const ERROR_CODES = {\n\tCONFIGURATION_ERROR: 'CONFIGURATION_ERROR',\n\tTOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n\tSKILL_NOT_FOUND: 'SKILL_NOT_FOUND',\n\tINVALID_THOUGHT: 'INVALID_THOUGHT',\n\tSKILL_DISCOVERY_FAILED: 'SKILL_DISCOVERY_FAILED',\n\tHISTORY_LIMIT_EXCEEDED: 'HISTORY_LIMIT_EXCEEDED',\n\tDUPLICATE_SKILL: 'DUPLICATE_SKILL',\n\tINVALID_SKILL: 'INVALID_SKILL',\n\tDUPLICATE_TOOL: 'DUPLICATE_TOOL',\n\tINVALID_TOOL: 'INVALID_TOOL',\n\tSESSION_NOT_ACTIVE: 'SESSION_NOT_ACTIVE',\n\tSESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n\tMAX_SESSIONS_REACHED: 'MAX_SESSIONS_REACHED',\n\tPOOL_TERMINATED: 'POOL_TERMINATED',\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_EDGE: 'INVALID_EDGE',\n\tCYCLE_DETECTED: 'CYCLE_DETECTED',\n\tSUSPENSION_NOT_FOUND: 'SUSPENSION_NOT_FOUND',\n\tSUSPENSION_EXPIRED: 'SUSPENSION_EXPIRED',\n\tINVALID_TOOL_CALL: 'INVALID_TOOL_CALL',\n\tINVALID_BACKTRACK: 'INVALID_BACKTRACK',\n\tDUPLICATE_SUMMARY: 'DUPLICATE_SUMMARY',\n\tUNKNOWN_TOOL: 'UNKNOWN_TOOL',\n\tLOCK_TIMEOUT: 'LOCK_TIMEOUT',\n\tCLI_SHUTDOWN_TIMEOUT: 'CLI_SHUTDOWN_TIMEOUT',\n\tSESSION_ACCESS_DENIED: 'SESSION_ACCESS_DENIED',\n\tSESSION_EXPIRED: 'SESSION_EXPIRED',\n\tSESSION_LIFECYCLE_CLOSED: 'SESSION_LIFECYCLE_CLOSED',\n\tPERSISTENCE_OWNERSHIP: 'PERSISTENCE_OWNERSHIP',\n\tPERSISTENCE_CORRUPTION: 'PERSISTENCE_CORRUPTION',\n\tPERSISTENCE_PUBLICATION: 'PERSISTENCE_PUBLICATION',\n\tPERSISTENCE_CLOSED: 'PERSISTENCE_CLOSED',\n\tPERSISTENCE_DRAIN: 'PERSISTENCE_DRAIN',\n\tPERSISTENCE_SESSION_ADMISSION_CLOSED: 'PERSISTENCE_SESSION_ADMISSION_CLOSED',\n\tPERSISTENCE_SESSION_BARRIER_REENTRANCY: 'PERSISTENCE_SESSION_BARRIER_REENTRANCY',\n\tPERSISTENCE_SCOPE_MISMATCH: 'PERSISTENCE_SCOPE_MISMATCH',\n\tPERSISTENCE_UNAVAILABLE: 'PERSISTENCE_UNAVAILABLE',\n\tPERSISTENCE_COMPATIBILITY: 'PERSISTENCE_COMPATIBILITY',\n} as const;\n\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\n/**\n * All known warning codes as a const object.\n * Warnings are non-fatal advisory signals returned alongside successful results.\n */\nexport const WARNING_CODES = {\n\tTOTAL_THOUGHTS_ADJUSTED: 'TOTAL_THOUGHTS_ADJUSTED',\n} as const;\n\nexport type WarningCode = (typeof WARNING_CODES)[keyof typeof WARNING_CODES];\n\n/**\n * Base error class for all Sequential Thinking server errors.\n *\n * This error extends the native `Error` class and adds a `code` property\n * for programmatic error identification and handling. All specific error\n * types in the system extend this base class.\n *\n * @remarks\n * **Error Codes:**\n * - `TOOL_NOT_FOUND` - A requested tool was not found\n * - `SKILL_NOT_FOUND` - A requested skill was not found\n * - `INVALID_THOUGHT` - Thought validation failed\n * - `SKILL_DISCOVERY_FAILED` - Skill discovery operation failed\n * - `HISTORY_LIMIT_EXCEEDED` - History size limit was exceeded\n * - `INVALID_EDGE` - An invalid edge operation was attempted\n *\n * @example\n * ```typescript\n * // Throw a custom sequential thinking error\n * throw new SequentialThinkingError('Custom error message', 'CUSTOM_CODE');\n *\n * // Check if an error is a SequentialThinkingError\n * if (error instanceof SequentialThinkingError) {\n * console.error(`Error [${error.code}]: ${error.message}`);\n * }\n * ```\n */\nexport class SequentialThinkingError extends Error {\n\t/** The error code for programmatic identification. */\n\tpublic readonly code: ErrorCode;\n\n\t/**\n\t * Creates a new SequentialThinkingError.\n\t *\n\t * @param message - Human-readable error message\n\t * @param code - Error code for programmatic handling\n\t *\n\t * @example\n\t * ```typescript\n\t * const error = new SequentialThinkingError(\n\t * 'Something went wrong',\n\t * 'CUSTOM_ERROR'\n\t * );\n\t * console.log(error.code); // 'CUSTOM_ERROR'\n\t * ```\n\t */\n\tconstructor(message: string, code: ErrorCode) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t\tthis.name = 'SequentialThinkingError';\n\t\tError.captureStackTrace(this, this.constructor);\n\t}\n}\n\nexport class ConfigurationError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.CONFIGURATION_ERROR);\n\t\tthis.name = 'ConfigurationError';\n\t}\n}\n\n/**\n * Error thrown when a requested tool is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a tool that doesn't exist in the tool registry.\n *\n * @example\n * ```typescript\n * const tool = registry.get('non-existent-tool');\n * if (!tool) {\n * throw new ToolNotFoundError('non-existent-tool');\n * }\n * ```\n */\nexport class ToolNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new ToolNotFoundError.\n\t *\n\t * @param toolName - The name of the tool that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new ToolNotFoundError('my-custom-tool');\n\t * // Error: tool 'my-custom-tool' not found\n\t *\n\t * throw new ToolNotFoundError('my-custom-tool', 'remove');\n\t * // Error: tool 'my-custom-tool' not found, cannot remove\n\t * // Code: TOOL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(toolName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Tool '${toolName}' not found, cannot ${action}`\n\t\t\t: `Tool '${toolName}' not found`;\n\t\tsuper(message, ERROR_CODES.TOOL_NOT_FOUND);\n\t\tthis.name = 'ToolNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a requested skill is not found in the registry.\n *\n * This error is thrown when attempting to retrieve, update, or delete\n * a skill that doesn't exist in the skill registry.\n *\n * @example\n * ```typescript\n * const skill = registry.get('non-existent-skill');\n * if (!skill) {\n * throw new SkillNotFoundError('non-existent-skill');\n * }\n * ```\n */\nexport class SkillNotFoundError extends SequentialThinkingError {\n\t/**\n\t * Creates a new SkillNotFoundError.\n\t *\n\t * @param skillName - The name of the skill that was not found\n\t * @param action - Optional action being performed (e.g., 'remove', 'update')\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new SkillNotFoundError('my-custom-skill');\n\t * // Error: skill 'my-custom-skill' not found\n\t *\n\t * throw new SkillNotFoundError('my-custom-skill', 'remove');\n\t * // Error: skill 'my-custom-skill' not found, cannot remove\n\t * // Code: SKILL_NOT_FOUND\n\t * ```\n\t */\n\tconstructor(skillName: string, action?: string) {\n\t\tconst message = action\n\t\t\t? `Skill '${skillName}' not found, cannot ${action}`\n\t\t\t: `Skill '${skillName}' not found`;\n\t\tsuper(message, ERROR_CODES.SKILL_NOT_FOUND);\n\t\tthis.name = 'SkillNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when thought validation fails.\n *\n * This error is thrown when a thought fails validation, typically due to\n * invalid values, missing required fields, or constraint violations.\n *\n * @example\n * ```typescript\n * // Validate thought number\n * if (thought.thought_number < 1) {\n * throw new InvalidThoughtError(thought.thought_number, 'thought_number must be >= 1');\n * }\n * ```\n */\nexport class InvalidThoughtError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidThoughtError.\n\t *\n\t * @param thoughtNumber - The thought number that failed validation\n\t * @param reason - Human-readable explanation of why validation failed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidThoughtError(5, 'thought_number exceeds total_thoughts');\n\t * // Error: Invalid thought 5: thought_number exceeds total_thoughts\n\t * // Code: INVALID_THOUGHT\n\t * ```\n\t */\n\tconstructor(thoughtNumber: number, reason: string) {\n\t\tsuper(`Invalid thought ${thoughtNumber}: ${reason}`, ERROR_CODES.INVALID_THOUGHT);\n\t\tthis.name = 'InvalidThoughtError';\n\t}\n}\n\n/**\n * Error thrown when skill discovery fails.\n *\n * This error is thrown when the skill discovery process encounters an issue,\n * such as filesystem errors, invalid skill files, or parsing failures.\n *\n * @remarks\n * The original error that caused the discovery failure is preserved in the\n * `cause` property for debugging purposes.\n *\n * @example\n * ```typescript\n * try {\n * await discoverSkills('./skills');\n * } catch (error) {\n * throw new SkillDiscoveryError('./skills', error as Error);\n * }\n * ```\n */\nexport class SkillDiscoveryError extends SequentialThinkingError {\n\t/** The underlying error that caused the discovery failure. */\n\tpublic override readonly cause: Error;\n\n\t/**\n\t * Creates a new SkillDiscoveryError.\n\t *\n\t * @param directory - The directory where discovery failed\n\t * @param cause - The underlying error that caused the failure\n\t *\n\t * @example\n\t * ```typescript\n\t * try {\n\t * const skills = await loadSkills('./invalid-directory');\n\t * } catch (error) {\n\t * throw new SkillDiscoveryError('./invalid-directory', error as Error);\n\t * }\n\t * ```\n\t */\n\tconstructor(directory: string, cause: Error) {\n\t\tsuper(\n\t\t\t`Failed to discover skills in ${directory}: ${cause.message}`,\n\t\t\tERROR_CODES.SKILL_DISCOVERY_FAILED\n\t\t);\n\t\tthis.name = 'SkillDiscoveryError';\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Error thrown when history size exceeds the configured limit.\n *\n * This error is thrown when an operation would cause the history size\n * to exceed the maximum configured size limit.\n *\n * @example\n * ```typescript\n * if (history.length >= maxSize) {\n * throw new HistoryLimitExceededError(history.length, maxSize);\n * }\n * ```\n */\nexport class HistoryLimitExceededError extends SequentialThinkingError {\n\t/**\n\t * Creates a new HistoryLimitExceededError.\n\t *\n\t * @param currentSize - The current history size\n\t * @param maxSize - The maximum allowed size\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new HistoryLimitExceededError(1500, 1000);\n\t * // Error: History size 1500 exceeds limit 1000\n\t * // Code: HISTORY_LIMIT_EXCEEDED\n\t * ```\n\t */\n\tconstructor(currentSize: number, maxSize: number) {\n\t\tsuper(\n\t\t\t`History size ${currentSize} exceeds limit ${maxSize}`,\n\t\t\tERROR_CODES.HISTORY_LIMIT_EXCEEDED\n\t\t);\n\t\tthis.name = 'HistoryLimitExceededError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a skill that already exists.\n *\n * This error is thrown when trying to register a skill with a name that\n * is already present in the skill registry.\n *\n * @example\n * ```typescript\n * if (registry.has(skill.name)) {\n * throw new DuplicateSkillError(skill.name);\n * }\n * ```\n */\nexport class DuplicateSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateSkillError.\n\t *\n\t * @param skillName - The name of the duplicate skill\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateSkillError('my-skill');\n\t * // Error: skill 'my-skill' already exists\n\t * // Code: DUPLICATE_SKILL\n\t * ```\n\t */\n\tconstructor(skillName: string) {\n\t\tsuper(`skill '${skillName}' already exists`, ERROR_CODES.DUPLICATE_SKILL);\n\t\tthis.name = 'DuplicateSkillError';\n\t}\n}\n\n/**\n * Error thrown when a skill has invalid data.\n *\n * This error is thrown when a skill fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!skill.name) {\n * throw new InvalidSkillError('Skill must have a valid name');\n * }\n * ```\n */\nexport class InvalidSkillError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidSkillError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidSkillError('Skill must have a valid name');\n\t * // Error: Invalid skill: Skill must have a valid name\n\t * // Code: INVALID_SKILL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid skill: ${reason}`, ERROR_CODES.INVALID_SKILL);\n\t\tthis.name = 'InvalidSkillError';\n\t}\n}\n\n/**\n * Error thrown when attempting to add a tool that already exists.\n *\n * This error is thrown when trying to register a tool with a name that\n * is already present in the tool registry.\n *\n * @example\n * ```typescript\n * if (registry.has(tool.name)) {\n * throw new DuplicateToolError(tool.name);\n * }\n * ```\n */\nexport class DuplicateToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new DuplicateToolError.\n\t *\n\t * @param toolName - The name of the duplicate tool\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new DuplicateToolError('my-tool');\n\t * // Error: tool 'my-tool' already exists\n\t * // Code: DUPLICATE_TOOL\n\t * ```\n\t */\n\tconstructor(toolName: string) {\n\t\tsuper(`tool '${toolName}' already exists`, ERROR_CODES.DUPLICATE_TOOL);\n\t\tthis.name = 'DuplicateToolError';\n\t}\n}\n\n/**\n * Error thrown when a tool has invalid data.\n *\n * This error is thrown when a tool fails validation, typically due to\n * missing required fields or invalid values.\n *\n * @example\n * ```typescript\n * if (!tool.name) {\n * throw new InvalidToolError('Tool must have a valid name');\n * }\n * ```\n */\nexport class InvalidToolError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidToolError.\n\t *\n\t * @param reason - The reason for the validation failure\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidToolError('Tool must have a valid name');\n\t * // Error: Invalid tool: Tool must have a valid name\n\t * // Code: INVALID_TOOL\n\t * ```\n\t */\n\tconstructor(reason: string) {\n\t\tsuper(`Invalid tool: ${reason}`, ERROR_CODES.INVALID_TOOL);\n\t\tthis.name = 'InvalidToolError';\n\t}\n}\n\n/**\n * Error thrown when the maximum number of sessions has been reached.\n *\n * This error is thrown when trying to create a new session when the\n * pool has reached its configured maximum session limit.\n *\n * @example\n * ```typescript\n * if (pool.sessionCount >= pool.maxSessions) {\n * throw new MaxSessionsReachedError(pool.maxSessions);\n * }\n * ```\n */\nexport class MaxSessionsReachedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new MaxSessionsReachedError.\n\t *\n\t * @param maxSessions - The maximum number of sessions allowed\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new MaxSessionsReachedError(100);\n\t * // Error: Max sessions (100) reached. Wait for a session to close or increase maxSessions.\n\t * // Code: MAX_SESSIONS_REACHED\n\t * ```\n\t */\n\tconstructor(maxSessions: number) {\n\t\tsuper(\n\t\t\t`Max sessions (${maxSessions}) reached. Wait for a session to close or increase maxSessions.`,\n\t\t\tERROR_CODES.MAX_SESSIONS_REACHED\n\t\t);\n\t\tthis.name = 'MaxSessionsReachedError';\n\t}\n}\n\n/**\n * Error thrown when attempting to use a terminated connection pool.\n *\n * This error is thrown when trying to create sessions or process requests\n * after the connection pool has been terminated.\n *\n * @example\n * ```typescript\n * if (pool.isTerminated) {\n * throw new PoolTerminatedError();\n * }\n * ```\n */\nexport class PoolTerminatedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new PoolTerminatedError.\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new PoolTerminatedError();\n\t * // Error: ConnectionPool has been terminated\n\t * // Code: POOL_TERMINATED\n\t * ```\n\t */\n\tconstructor() {\n\t\tsuper('ConnectionPool has been terminated', ERROR_CODES.POOL_TERMINATED);\n\t\tthis.name = 'PoolTerminatedError';\n\t}\n}\n\n/**\n * Error thrown when input validation fails due to invalid or malicious data.\n *\n * This error is thrown when user input fails security or format validation,\n * such as path traversal attempts or invalid identifier formats.\n *\n * @example\n * ```typescript\n * if (!BRANCH_ID_PATTERN.test(branchId)) {\n * throw new ValidationError('branchId', 'Invalid format');\n * }\n * ```\n */\nexport class ValidationError extends SequentialThinkingError {\n\t/** The field that failed validation. */\n\tpublic readonly field: string;\n\n\tconstructor(field: string, reason: string) {\n\t\tsuper(`Validation failed for '${field}': ${reason}`, ERROR_CODES.VALIDATION_ERROR);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t}\n}\n\n/**\n * Error thrown when an invalid edge operation is attempted.\n *\n * This error is thrown when attempting to add an edge that violates\n * structural invariants of the thought DAG, such as a self-edge\n * (where `from` and `to` reference the same thought).\n *\n * @example\n * ```typescript\n * if (edge.from === edge.to) {\n * throw new InvalidEdgeError(\n * `Self-edge not allowed: from and to are the same (${edge.from})`\n * );\n * }\n * ```\n */\nexport class InvalidEdgeError extends SequentialThinkingError {\n\t/**\n\t * Creates a new InvalidEdgeError.\n\t *\n\t * @param message - Human-readable explanation of the invalid edge\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new InvalidEdgeError('Self-edge not allowed: from and to are the same (t1)');\n\t * // Code: INVALID_EDGE\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_EDGE);\n\t\tthis.name = 'InvalidEdgeError';\n\t}\n}\n\n/**\n * Error thrown when a cycle is detected during graph traversal.\n *\n * This error is thrown by graph algorithms (such as topological sort)\n * when the thought DAG contains a cycle, violating the acyclic invariant.\n *\n * @example\n * ```typescript\n * try {\n * const order = graphView.topological(sessionId);\n * } catch (error) {\n * if (error instanceof CycleDetectedError) {\n * console.error('Cycle in thought graph:', error.message);\n * }\n * }\n * ```\n */\nexport class CycleDetectedError extends SequentialThinkingError {\n\t/**\n\t * Creates a new CycleDetectedError.\n\t *\n\t * @param message - Human-readable explanation of the cycle\n\t *\n\t * @example\n\t * ```typescript\n\t * throw new CycleDetectedError('Cycle detected in session s1');\n\t * // Code: CYCLE_DETECTED\n\t * ```\n\t */\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.CYCLE_DETECTED);\n\t\tthis.name = 'CycleDetectedError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record is not found.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension that does not exist in the suspension store.\n */\nexport class SuspensionNotFoundError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.SUSPENSION_NOT_FOUND);\n\t\tthis.name = 'SuspensionNotFoundError';\n\t}\n}\n\n/**\n * Error thrown when a suspension record has expired.\n *\n * This error is thrown when attempting to resume a tool interleave\n * suspension whose TTL has elapsed.\n */\nexport class SuspensionExpiredError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.SUSPENSION_EXPIRED);\n\t\tthis.name = 'SuspensionExpiredError';\n\t}\n}\n\n/**\n * Error thrown when a tool call payload is invalid.\n *\n * This error is thrown when a tool interleave invocation has malformed\n * arguments, missing identifiers, or otherwise fails validation.\n */\nexport class InvalidToolCallError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_TOOL_CALL);\n\t\tthis.name = 'InvalidToolCallError';\n\t}\n}\n\n/**\n * Error thrown when a backtrack operation is invalid.\n *\n * This error is thrown when an attempt to backtrack the reasoning\n * chain references an unreachable thought or violates DAG invariants.\n */\nexport class InvalidBacktrackError extends SequentialThinkingError {\n\tconstructor(message: string) {\n\t\tsuper(message, ERROR_CODES.INVALID_BACKTRACK);\n\t\tthis.name = 'InvalidBacktrackError';\n\t}\n}\n\n/**\n * Error thrown when a tool_call references a tool not registered with the server.\n *\n * Acts as an allowlist gate: only tools registered in the ToolRegistry may be\n * invoked through tool interleave. Prevents arbitrary tool name injection.\n */\nexport class UnknownToolError extends SequentialThinkingError {\n\tpublic readonly toolName: string;\n\n\tconstructor(toolName: string, message?: string) {\n\t\tsuper(\n\t\t\tmessage ?? `Unknown tool '${toolName}': not registered with the server`,\n\t\t\tERROR_CODES.UNKNOWN_TOOL\n\t\t);\n\t\tthis.name = 'UnknownToolError';\n\t\tthis.toolName = toolName;\n\t}\n}\n\n/** Error thrown when the CLI's complete shutdown exceeds its outer deadline. */\nexport class CliShutdownTimeoutError extends SequentialThinkingError {\n\tpublic readonly timeoutMs: number;\n\n\tconstructor(timeoutMs: number) {\n\t\tsuper(`CLI shutdown timed out after ${timeoutMs}ms`, ERROR_CODES.CLI_SHUTDOWN_TIMEOUT);\n\t\tthis.name = 'CliShutdownTimeoutError';\n\t\tthis.timeoutMs = timeoutMs;\n\t}\n}\n\nexport class PersistenceOwnershipError extends SequentialThinkingError {\n\tpublic readonly canonicalDataDir: string;\n\tpublic readonly lockPath: string;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(canonicalDataDir: string, lockPath: string, cause: unknown) {\n\t\tsuper(\n\t\t\t`Persistence directory '${canonicalDataDir}' already has an active writer`,\n\t\t\tERROR_CODES.PERSISTENCE_OWNERSHIP\n\t\t);\n\t\tthis.name = 'PersistenceOwnershipError';\n\t\tthis.canonicalDataDir = canonicalDataDir;\n\t\tthis.lockPath = lockPath;\n\t\tthis.cause = cause;\n\t}\n}\n\nexport class PersistenceCorruptionError extends SequentialThinkingError {\n\tpublic readonly path: string;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(path: string, cause: unknown) {\n\t\tsuper(\n\t\t\t`Persisted data at '${path}' is corrupt or incompatible`,\n\t\t\tERROR_CODES.PERSISTENCE_CORRUPTION\n\t\t);\n\t\tthis.name = 'PersistenceCorruptionError';\n\t\tthis.path = path;\n\t\tthis.cause = cause;\n\t}\n}\n\n/** Error raised when startup cannot read from an unhealthy persistence backend. */\nexport class PersistenceUnavailableError extends SequentialThinkingError {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'Persistence backend is unavailable during startup restore',\n\t\t\tERROR_CODES.PERSISTENCE_UNAVAILABLE\n\t\t);\n\t\tthis.name = 'PersistenceUnavailableError';\n\t}\n}\n\nexport type PersistencePublicationStage = 'temporary-write' | 'atomic-replacement' | 'cleanup';\n\nexport class PersistencePublicationError extends SequentialThinkingError {\n\tpublic readonly path: string;\n\tpublic readonly stage: PersistencePublicationStage;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(path: string, stage: PersistencePublicationStage, cause: unknown) {\n\t\tsuper(\n\t\t\t`Failed persistence publication for '${path}' during ${stage}`,\n\t\t\tERROR_CODES.PERSISTENCE_PUBLICATION\n\t\t);\n\t\tthis.name = 'PersistencePublicationError';\n\t\tthis.path = path;\n\t\tthis.stage = stage;\n\t\tthis.cause = cause;\n\t}\n}\n\nexport class PersistenceClosedError extends SequentialThinkingError {\n\tpublic readonly dataDir: string;\n\n\tconstructor(dataDir: string) {\n\t\tsuper(`Persistence writer for '${dataDir}' is closed`, ERROR_CODES.PERSISTENCE_CLOSED);\n\t\tthis.name = 'PersistenceClosedError';\n\t\tthis.dataDir = dataDir;\n\t}\n}\n\n/** Error raised for well-formed but unsupported or drifted persisted data. */\nexport class PersistenceCompatibilityError extends SequentialThinkingError {\n\tpublic readonly sourcePath: string;\n\tpublic readonly detail: string;\n\tpublic override readonly cause: unknown;\n\n\tconstructor(sourcePath: string, detail: string, cause?: unknown) {\n\t\tsuper(\n\t\t\t`Persisted data at '${sourcePath}' is incompatible: ${detail}`,\n\t\t\tERROR_CODES.PERSISTENCE_COMPATIBILITY\n\t\t);\n\t\tthis.name = 'PersistenceCompatibilityError';\n\t\tthis.sourcePath = sourcePath;\n\t\tthis.detail = detail;\n\t\tthis.cause = cause;\n\t}\n}\n\n/**\n * Type guard to check if an error has a specific error code.\n */\nexport function isErrorCode<C extends ErrorCode>(\n\terr: unknown,\n\tcode: C\n): err is SequentialThinkingError & { readonly code: C } {\n\treturn err instanceof SequentialThinkingError && err.code === code;\n}\n\n/**\n * Extract a human-readable message from an unknown error value.\n *\n * Standardizes the common `error instanceof Error ? error.message : String(error)`\n * pattern used in catch blocks across the codebase.\n *\n * @param error - The unknown error value to extract a message from\n * @returns The error message string\n *\n * @example\n * ```typescript\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error('Failed', { error: getErrorMessage(error) });\n * }\n * ```\n */\nexport function getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n"],"names":["ERROR_CODES","WARNING_CODES","SequentialThinkingError","Error","message","code","ConfigurationError","ToolNotFoundError","toolName","action","SkillNotFoundError","skillName","InvalidThoughtError","thoughtNumber","reason","SkillDiscoveryError","directory","cause","HistoryLimitExceededError","currentSize","maxSize","DuplicateSkillError","InvalidSkillError","DuplicateToolError","InvalidToolError","MaxSessionsReachedError","maxSessions","PoolTerminatedError","ValidationError","field","InvalidEdgeError","CycleDetectedError","SuspensionNotFoundError","SuspensionExpiredError","InvalidToolCallError","InvalidBacktrackError","UnknownToolError","CliShutdownTimeoutError","timeoutMs","PersistenceOwnershipError","canonicalDataDir","lockPath","PersistenceCorruptionError","path","PersistenceUnavailableError","PersistencePublicationError","stage","PersistenceClosedError","dataDir","PersistenceCompatibilityError","sourcePath","detail","isErrorCode","err","getErrorMessage","error","String"],"mappings":"AA+BO,MAAMA,cAAc;IAC1B,qBAAqB;IACrB,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,wBAAwB;IACxB,wBAAwB;IACxB,iBAAiB;IACjB,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,oBAAoB;IACpB,mBAAmB;IACnB,sBAAsB;IACtB,iBAAiB;IACjB,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,sBAAsB;IACtB,oBAAoB;IACpB,mBAAmB;IACnB,mBAAmB;IACnB,mBAAmB;IACnB,cAAc;IACd,cAAc;IACd,sBAAsB;IACtB,uBAAuB;IACvB,iBAAiB;IACjB,0BAA0B;IAC1B,uBAAuB;IACvB,wBAAwB;IACxB,yBAAyB;IACzB,oBAAoB;IACpB,mBAAmB;IACnB,sCAAsC;IACtC,wCAAwC;IACxC,4BAA4B;IAC5B,yBAAyB;IACzB,2BAA2B;AAC5B;AAQO,MAAMC,gBAAgB;IAC5B,yBAAyB;AAC1B;AA+BO,MAAMC,gCAAgCC;IAE5B,KAAgB;IAiBhC,YAAYC,OAAe,EAAEC,IAAe,CAAE;QAC7C,KAAK,CAACD;QACN,IAAI,CAAC,IAAI,GAAGC;QACZ,IAAI,CAAC,IAAI,GAAG;QACZF,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW;IAC/C;AACD;AAEO,MAAMG,2BAA2BJ;IACvC,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,mBAAmB;QAC9C,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAgBO,MAAMO,0BAA0BL;IAiBtC,YAAYM,QAAgB,EAAEC,MAAe,CAAE;QAC9C,MAAML,UAAUK,SACb,CAAC,MAAM,EAAED,SAAS,oBAAoB,EAAEC,QAAQ,GAChD,CAAC,MAAM,EAAED,SAAS,WAAW,CAAC;QACjC,KAAK,CAACJ,SAASJ,YAAY,cAAc;QACzC,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAgBO,MAAMU,2BAA2BR;IAiBvC,YAAYS,SAAiB,EAAEF,MAAe,CAAE;QAC/C,MAAML,UAAUK,SACb,CAAC,OAAO,EAAEE,UAAU,oBAAoB,EAAEF,QAAQ,GAClD,CAAC,OAAO,EAAEE,UAAU,WAAW,CAAC;QACnC,KAAK,CAACP,SAASJ,YAAY,eAAe;QAC1C,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAgBO,MAAMY,4BAA4BV;IAcxC,YAAYW,aAAqB,EAAEC,MAAc,CAAE;QAClD,KAAK,CAAC,CAAC,gBAAgB,EAAED,cAAc,EAAE,EAAEC,QAAQ,EAAEd,YAAY,eAAe;QAChF,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAqBO,MAAMe,4BAA4Bb;IAEf,MAAa;IAiBtC,YAAYc,SAAiB,EAAEC,KAAY,CAAE;QAC5C,KAAK,CACJ,CAAC,6BAA6B,EAAED,UAAU,EAAE,EAAEC,MAAM,OAAO,EAAE,EAC7DjB,YAAY,sBAAsB;QAEnC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,KAAK,GAAGiB;IACd;AACD;AAeO,MAAMC,kCAAkChB;IAc9C,YAAYiB,WAAmB,EAAEC,OAAe,CAAE;QACjD,KAAK,CACJ,CAAC,aAAa,EAAED,YAAY,eAAe,EAAEC,SAAS,EACtDpB,YAAY,sBAAsB;QAEnC,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAMqB,4BAA4BnB;IAaxC,YAAYS,SAAiB,CAAE;QAC9B,KAAK,CAAC,CAAC,OAAO,EAAEA,UAAU,gBAAgB,CAAC,EAAEX,YAAY,eAAe;QACxE,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAMsB,0BAA0BpB;IAatC,YAAYY,MAAc,CAAE;QAC3B,KAAK,CAAC,CAAC,eAAe,EAAEA,QAAQ,EAAEd,YAAY,aAAa;QAC3D,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAMuB,2BAA2BrB;IAavC,YAAYM,QAAgB,CAAE;QAC7B,KAAK,CAAC,CAAC,MAAM,EAAEA,SAAS,gBAAgB,CAAC,EAAER,YAAY,cAAc;QACrE,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAMwB,yBAAyBtB;IAarC,YAAYY,MAAc,CAAE;QAC3B,KAAK,CAAC,CAAC,cAAc,EAAEA,QAAQ,EAAEd,YAAY,YAAY;QACzD,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAMyB,gCAAgCvB;IAa5C,YAAYwB,WAAmB,CAAE;QAChC,KAAK,CACJ,CAAC,cAAc,EAAEA,YAAY,+DAA+D,CAAC,EAC7F1B,YAAY,oBAAoB;QAEjC,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAM2B,4BAA4BzB;IAWxC,aAAc;QACb,KAAK,CAAC,sCAAsCF,YAAY,eAAe;QACvE,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAeO,MAAM4B,wBAAwB1B;IAEpB,MAAc;IAE9B,YAAY2B,KAAa,EAAEf,MAAc,CAAE;QAC1C,KAAK,CAAC,CAAC,uBAAuB,EAAEe,MAAM,GAAG,EAAEf,QAAQ,EAAEd,YAAY,gBAAgB;QACjF,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,KAAK,GAAG6B;IACd;AACD;AAkBO,MAAMC,yBAAyB5B;IAYrC,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,YAAY;QACvC,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAmBO,MAAM+B,2BAA2B7B;IAYvC,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,cAAc;QACzC,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAQO,MAAMgC,gCAAgC9B;IAC5C,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,oBAAoB;QAC/C,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAQO,MAAMiC,+BAA+B/B;IAC3C,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,kBAAkB;QAC7C,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAQO,MAAMkC,6BAA6BhC;IACzC,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,iBAAiB;QAC5C,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAQO,MAAMmC,8BAA8BjC;IAC1C,YAAYE,OAAe,CAAE;QAC5B,KAAK,CAACA,SAASJ,YAAY,iBAAiB;QAC5C,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAQO,MAAMoC,yBAAyBlC;IACrB,SAAiB;IAEjC,YAAYM,QAAgB,EAAEJ,OAAgB,CAAE;QAC/C,KAAK,CACJA,WAAW,CAAC,cAAc,EAAEI,SAAS,iCAAiC,CAAC,EACvER,YAAY,YAAY;QAEzB,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,QAAQ,GAAGQ;IACjB;AACD;AAGO,MAAM6B,gCAAgCnC;IAC5B,UAAkB;IAElC,YAAYoC,SAAiB,CAAE;QAC9B,KAAK,CAAC,CAAC,6BAA6B,EAAEA,UAAU,EAAE,CAAC,EAAEtC,YAAY,oBAAoB;QACrF,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,SAAS,GAAGsC;IAClB;AACD;AAEO,MAAMC,kCAAkCrC;IAC9B,iBAAyB;IACzB,SAAiB;IACR,MAAe;IAExC,YAAYsC,gBAAwB,EAAEC,QAAgB,EAAExB,KAAc,CAAE;QACvE,KAAK,CACJ,CAAC,uBAAuB,EAAEuB,iBAAiB,8BAA8B,CAAC,EAC1ExC,YAAY,qBAAqB;QAElC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,gBAAgB,GAAGwC;QACxB,IAAI,CAAC,QAAQ,GAAGC;QAChB,IAAI,CAAC,KAAK,GAAGxB;IACd;AACD;AAEO,MAAMyB,mCAAmCxC;IAC/B,KAAa;IACJ,MAAe;IAExC,YAAYyC,IAAY,EAAE1B,KAAc,CAAE;QACzC,KAAK,CACJ,CAAC,mBAAmB,EAAE0B,KAAK,4BAA4B,CAAC,EACxD3C,YAAY,sBAAsB;QAEnC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,IAAI,GAAG2C;QACZ,IAAI,CAAC,KAAK,GAAG1B;IACd;AACD;AAGO,MAAM2B,oCAAoC1C;IAChD,aAAc;QACb,KAAK,CACJ,6DACAF,YAAY,uBAAuB;QAEpC,IAAI,CAAC,IAAI,GAAG;IACb;AACD;AAIO,MAAM6C,oCAAoC3C;IAChC,KAAa;IACb,MAAmC;IAC1B,MAAe;IAExC,YAAYyC,IAAY,EAAEG,KAAkC,EAAE7B,KAAc,CAAE;QAC7E,KAAK,CACJ,CAAC,oCAAoC,EAAE0B,KAAK,SAAS,EAAEG,OAAO,EAC9D9C,YAAY,uBAAuB;QAEpC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,IAAI,GAAG2C;QACZ,IAAI,CAAC,KAAK,GAAGG;QACb,IAAI,CAAC,KAAK,GAAG7B;IACd;AACD;AAEO,MAAM8B,+BAA+B7C;IAC3B,QAAgB;IAEhC,YAAY8C,OAAe,CAAE;QAC5B,KAAK,CAAC,CAAC,wBAAwB,EAAEA,QAAQ,WAAW,CAAC,EAAEhD,YAAY,kBAAkB;QACrF,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,OAAO,GAAGgD;IAChB;AACD;AAGO,MAAMC,sCAAsC/C;IAClC,WAAmB;IACnB,OAAe;IACN,MAAe;IAExC,YAAYgD,UAAkB,EAAEC,MAAc,EAAElC,KAAe,CAAE;QAChE,KAAK,CACJ,CAAC,mBAAmB,EAAEiC,WAAW,mBAAmB,EAAEC,QAAQ,EAC9DnD,YAAY,yBAAyB;QAEtC,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,UAAU,GAAGkD;QAClB,IAAI,CAAC,MAAM,GAAGC;QACd,IAAI,CAAC,KAAK,GAAGlC;IACd;AACD;AAKO,SAASmC,YACfC,GAAY,EACZhD,IAAO;IAEP,OAAOgD,eAAenD,2BAA2BmD,IAAI,IAAI,KAAKhD;AAC/D;AAoBO,SAASiD,gBAAgBC,KAAc;IAC7C,OAAOA,iBAAiBpD,QAAQoD,MAAM,OAAO,GAAGC,OAAOD;AACxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.impl.d.ts","sourceRoot":"","sources":["../../src/metrics/metrics.impl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,oBAAY,UAAU;IACrB,wDAAwD;IACxD,OAAO,YAAY;IAEnB,+CAA+C;IAC/C,KAAK,UAAU;IAEf,qDAAqD;IACrD,SAAS,cAAc;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACtB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IAEb,iDAAiD;IACjD,IAAI,EAAE,UAAU,CAAC;IAEjB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IAEd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,qBAAa,OAAO;IACnB,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAsB;IAEtC,wBAAwB;IACxB,OAAO,CAAC,WAAW,CAA+B;IAElD,kCAAkC;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,6CAA6C;IAC7C,OAAO,CAAC,cAAc,CAAyB;IAE/C,+CAA+C;IAC/C,OAAO,CAAC,kBAAkB,CAAa;IAEvC;;;;;;;;;OASG;gBACS,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAO;IAOrF;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAI,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAuB1F;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAe5F;;;;;;;;;;;;;;OAcG;IACH,SAAS,CACR,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACnC,OAAO,WAAkB,GACvB,IAAI;IAkCP;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,GAAG,SAAS;IAO1E;;;;;;;;;;OAUG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAIxD;;;;;;;;;;OAUG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAKxD;;;;;;;;OAQG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;;;;;OAUG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;;;;;;;;;;;;;OAcG;IACH,MAAM,IAAI,MAAM;IA8DhB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IASjB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,iBAAiB;CAGzB"}
1
+ {"version":3,"file":"metrics.impl.d.ts","sourceRoot":"","sources":["../../src/metrics/metrics.impl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,oBAAY,UAAU;IACrB,wDAAwD;IACxD,OAAO,YAAY;IAEnB,+CAA+C;IAC/C,KAAK,UAAU;IAEf,qDAAqD;IACrD,SAAS,cAAc;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACtB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IAEb,iDAAiD;IACjD,IAAI,EAAE,UAAU,CAAC;IAEjB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IAEd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/B,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,qBAAa,OAAO;IACnB,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAsB;IAEtC,wBAAwB;IACxB,OAAO,CAAC,WAAW,CAA+B;IAElD,kCAAkC;IAClC,OAAO,CAAC,OAAO,CAAS;IAExB,6CAA6C;IAC7C,OAAO,CAAC,cAAc,CAAyB;IAE/C,+CAA+C;IAC/C,OAAO,CAAC,kBAAkB,CAAa;IAEvC;;;;;;;;;OASG;gBACS,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAO;IAOrF;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAI,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAuB1F;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAe5F;;;;;;;;;;;;;;OAcG;IACH,SAAS,CACR,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACnC,OAAO,WAAkB,GACvB,IAAI;IA6CP;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAAG,MAAM,GAAG,SAAS;IAO1E;;;;;;;;;;OAUG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAIxD;;;;;;;;;;OAUG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAKxD;;;;;;;;OAQG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;;;;;OAUG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;;;;;;;;;;;;;OAcG;IACH,MAAM,IAAI,MAAM;IA+DhB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IASjB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,iBAAiB;CAGzB"}
@@ -80,12 +80,16 @@ class Metrics {
80
80
  };
81
81
  const key = this._metricKey(fullName, allLabels);
82
82
  const histogram = this._histograms.get(key);
83
+ let previousBoundary = -1 / 0;
84
+ for (const boundary of buckets){
85
+ if (!Number.isFinite(boundary) || boundary <= previousBoundary) throw new RangeError('Histogram boundaries must be finite and strictly increasing');
86
+ previousBoundary = boundary;
87
+ }
88
+ if (histogram && (histogram.boundaries.length !== buckets.length || histogram.boundaries.some((boundary, index)=>boundary !== buckets[index]))) throw new RangeError('Histogram bucket layout differs from the existing series');
83
89
  if (histogram) {
84
90
  histogram.sum += value;
85
91
  histogram.count += 1;
86
- for (const boundary of buckets)if (value <= boundary) histogram.buckets.set(boundary, (histogram.buckets.get(boundary) ?? 0) + 1);
87
- else histogram.buckets.set(boundary, histogram.buckets.get(boundary) ?? 0);
88
- histogram.buckets.set(1 / 0, (histogram.buckets.get(1 / 0) ?? 0) + 1);
92
+ for (const boundary of histogram.boundaries)if (value <= boundary) histogram.buckets.set(boundary, (histogram.buckets.get(boundary) ?? 0) + 1);
89
93
  } else {
90
94
  const histogramData = {
91
95
  name: fullName,
@@ -94,10 +98,12 @@ class Metrics {
94
98
  },
95
99
  sum: value,
96
100
  count: 1,
101
+ boundaries: [
102
+ ...buckets
103
+ ],
97
104
  buckets: new Map()
98
105
  };
99
106
  for (const boundary of buckets)histogramData.buckets.set(boundary, value <= boundary ? 1 : 0);
100
- histogramData.buckets.set(1 / 0, 1);
101
107
  this._histograms.set(key, histogramData);
102
108
  }
103
109
  this._operationsCounter++;
@@ -135,7 +141,7 @@ class Metrics {
135
141
  for (const metric of metrics){
136
142
  if (!helpEntries.has(metric.name)) {
137
143
  const helpText = metric.help ?? `${metric.name} metric`;
138
- lines.push(`# HELP ${metric.name} ${helpText}`);
144
+ lines.push(`# HELP ${metric.name} ${helpText.replaceAll('\\', '\\\\').replaceAll('\n', '\\n')}`);
139
145
  helpEntries.set(metric.name, helpText);
140
146
  }
141
147
  if (!typeEntries.has(metric.name)) {
@@ -159,14 +165,20 @@ class Metrics {
159
165
  };
160
166
  lines.push(formatMetricLine('_sum', histogram.sum));
161
167
  lines.push(formatMetricLine('_count', histogram.count));
162
- for (const [boundary, count] of histogram.buckets.entries()){
163
- const boundaryLabel = 1 / 0 === boundary ? '+Inf' : Number.isFinite(boundary) ? String(boundary) : String(boundary);
168
+ for (const boundary of histogram.boundaries){
169
+ const count = histogram.buckets.get(boundary);
170
+ const boundaryLabel = String(boundary);
164
171
  const boundaryLabelStr = this._formatLabels({
165
172
  le: boundaryLabel
166
173
  });
167
174
  const bucketLabels = 0 === labelStr.length ? boundaryLabelStr : `${labelStr},${boundaryLabelStr}`;
168
175
  lines.push(`${fullName}_bucket{${bucketLabels}} ${count}`);
169
176
  }
177
+ const infLabelStr = this._formatLabels({
178
+ le: '+Inf'
179
+ });
180
+ const infLabels = 0 === labelStr.length ? infLabelStr : `${labelStr},${infLabelStr}`;
181
+ lines.push(`${fullName}_bucket{${infLabels}} ${histogram.count}`);
170
182
  }
171
183
  }
172
184
  return lines.join('\n');
@@ -1 +1 @@
1
- {"version":3,"file":"metrics/metrics.impl.js","sources":["../../src/metrics/metrics.impl.ts"],"sourcesContent":["/**\n * Prometheus-compatible metrics collection.\n *\n * This module provides metrics collection and export in Prometheus text format.\n * Supports counters, gauges, and histograms for observability.\n *\n * @module metrics\n */\n\n/**\n * Metric types supported by the metrics collector.\n */\nexport enum MetricType {\n\t/** Counter - a cumulative metric that only increases */\n\tCounter = 'counter',\n\n\t/** Gauge - a metric that can go up and down */\n\tGauge = 'gauge',\n\n\t/** Histogram - a metric for sampling observations */\n\tHistogram = 'histogram',\n}\n\n/**\n * A collected metric with its value and labels.\n */\nexport interface Metric {\n\t/** Name of the metric */\n\tname: string;\n\n\t/** Type of metric (counter, gauge, histogram) */\n\ttype: MetricType;\n\n\t/** Current value */\n\tvalue: number;\n\n\t/** Labels for the metric */\n\tlabels: Record<string, string>;\n\n\t/** Help text describing the metric */\n\thelp?: string;\n\n\t/** Timestamp when metric was recorded (Unix epoch) */\n\ttimestamp?: number;\n}\n\ninterface HistogramMetric {\n\tname: string;\n\tlabels: Record<string, string>;\n\tsum: number;\n\tcount: number;\n\tbuckets: Map<number, number>;\n}\n\n/**\n * Histogram bucket boundaries for latency tracking.\n */\nconst DEFAULT_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];\n\n/**\n * Prometheus-compatible metrics collector.\n *\n * Collects and exports metrics in Prometheus text format for scraping.\n * Thread-safe and supports counters, gauges, and histograms.\n *\n * @remarks\n * **Metric Types:**\n * - **Counter**: Cumulative value that only increases (e.g., request counts)\n * - **Gauge**: Value that can go up or down (e.g., active connections)\n * - **Histogram**: Sampling observations (e.g., request latency)\n *\n * **Labels:**\n * Metrics can have labels for dimensional data:\n * ```typescript\n * counter('http_requests_total', { method: 'GET', status: '200' });\n * ```\n *\n * **Export Format:**\n * Metrics are exported in Prometheus text format:\n * ```\n * # HELP http_requests_total Total HTTP requests\n * # TYPE http_requests_total counter\n * http_requests_total{method=\"GET\",status=\"200\"} 1234\n * ```\n *\n * @example\n * ```typescript\n * const metrics = new Metrics({ prefix: 'mcp_server' });\n *\n * // Count requests\n * metrics.counter('requests_total', { method: 'GET' }).inc();\n *\n * // Track active connections\n * const activeConnections = metrics.gauge('active_connections');\n * activeConnections.set(5);\n * activeConnections.dec();\n *\n * // Record latency\n * metrics.histogram('request_duration_seconds').observe(0.023);\n *\n * // Export for Prometheus\n * const prometheusText = metrics.export();\n * ```\n */\nexport class Metrics {\n\t/** Metrics storage indexed by name and label hash */\n\tprivate _metrics: Map<string, Metric>;\n\n\t/** Histogram samples */\n\tprivate _histograms: Map<string, HistogramMetric>;\n\n\t/** Prefix for all metric names */\n\tprivate _prefix: string;\n\n\t/** Default labels to apply to all metrics */\n\tprivate _defaultLabels: Record<string, string>;\n\n\t/** Counter for metric collection operations */\n\tprivate _operationsCounter: number = 0;\n\n\t/**\n\t * Creates a new Metrics instance.\n\t *\n\t * @param options - Configuration options\n\t *\n\t * @example\n\t * ```typescript\n\t * const metrics = new Metrics({ prefix: 'mcp_server' });\n\t * ```\n\t */\n\tconstructor(options: { prefix?: string; defaultLabels?: Record<string, string> } = {}) {\n\t\tthis._metrics = new Map();\n\t\tthis._histograms = new Map();\n\t\tthis._prefix = options.prefix ?? '';\n\t\tthis._defaultLabels = { ...options.defaultLabels };\n\t}\n\n\t/**\n\t * Creates a counter metric.\n\t *\n\t * @param name - Metric name\n\t * @param value - Increment value (default: 1)\n\t * @param labels - Optional labels\n\t * @param help - Help text\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.counter('requests_total', 1, { method: 'GET' });\n\t * metrics.counter('errors_total', 1, { type: 'timeout' });\n\t * ```\n\t */\n\tcounter(name: string, value = 1, labels: Record<string, string> = {}, help?: string): void {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\tconst existing = this._metrics.get(key);\n\n\t\tif (existing) {\n\t\t\texisting.value += value;\n\t\t\tif (help && !existing.help) {\n\t\t\t\texisting.help = help;\n\t\t\t}\n\t\t} else {\n\t\t\tthis._metrics.set(key, {\n\t\t\t\tname: fullName,\n\t\t\t\ttype: MetricType.Counter,\n\t\t\t\tvalue,\n\t\t\t\tlabels: { ...allLabels },\n\t\t\t\thelp,\n\t\t\t});\n\t\t}\n\t\tthis._operationsCounter++;\n\t}\n\n\t/**\n\t * Creates a gauge metric.\n\t *\n\t * @param name - Metric name\n\t * @param value - Current value\n\t * @param labels - Optional labels\n\t * @param help - Help text\n\t *\n\t * @example\n\t * ```typescript\n\t * const activeConnections = metrics.gauge('active_connections');\n\t * activeConnections.set(5);\n\t * activeConnections.dec();\n\t * ```\n\t */\n\tgauge(name: string, value: number, labels: Record<string, string> = {}, help?: string): void {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\tconst existing = this._metrics.get(key);\n\t\tthis._metrics.set(key, {\n\t\t\tname: fullName,\n\t\t\ttype: MetricType.Gauge,\n\t\t\tvalue,\n\t\t\tlabels: { ...allLabels },\n\t\t\thelp: help ?? existing?.help,\n\t\t});\n\t\tthis._operationsCounter++;\n\t}\n\n\t/**\n\t * Records a histogram observation.\n\t *\n\t * @param name - Histogram name\n\t * @param value - Observed value\n\t * @param labels - Optional labels\n\t * @param help - Help text\n\t * @param buckets - Custom bucket boundaries\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.histogram('request_duration_seconds').observe(0.023);\n\t * metrics.histogram('thought_processing_ms').observe(45);\n\t * ```\n\t */\n\thistogram(\n\t\tname: string,\n\t\tvalue: number,\n\t\tlabels: Record<string, string> = {},\n\t\tbuckets = DEFAULT_BUCKETS\n\t): void {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\tconst histogram = this._histograms.get(key);\n\n\t\tif (histogram) {\n\t\t\thistogram.sum += value;\n\t\t\thistogram.count += 1;\n\t\t\tfor (const boundary of buckets) {\n\t\t\t\tif (value <= boundary) {\n\t\t\t\t\thistogram.buckets.set(boundary, (histogram.buckets.get(boundary) ?? 0) + 1);\n\t\t\t\t} else {\n\t\t\t\t\thistogram.buckets.set(boundary, histogram.buckets.get(boundary) ?? 0);\n\t\t\t\t}\n\t\t\t}\n\t\t\thistogram.buckets.set(Infinity, (histogram.buckets.get(Infinity) ?? 0) + 1);\n\t\t} else {\n\t\t\tconst histogramData = {\n\t\t\t\tname: fullName,\n\t\t\t\tlabels: { ...allLabels },\n\t\t\t\tsum: value,\n\t\t\t\tcount: 1,\n\t\t\t\tbuckets: new Map<number, number>(),\n\t\t\t};\n\t\t\tfor (const boundary of buckets) {\n\t\t\t\thistogramData.buckets.set(boundary, value <= boundary ? 1 : 0);\n\t\t\t}\n\t\t\thistogramData.buckets.set(Infinity, 1);\n\t\t\tthis._histograms.set(key, histogramData);\n\t\t}\n\t\tthis._operationsCounter++;\n\t}\n\n\t/**\n\t * Gets the current value of a metric.\n\t *\n\t * @param name - Metric name\n\t * @param labels - Labels\n\t * @returns Current value or undefined if not found\n\t *\n\t * @example\n\t * ```typescript\n\t * const count = metrics.get('requests_total', { method: 'GET' });\n\t * ```\n\t */\n\tget(name: string, labels: Record<string, string> = {}): number | undefined {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\treturn this._metrics.get(key)?.value;\n\t}\n\n\t/**\n\t * Increments a counter by 1.\n\t *\n\t * @param name - Metric name\n\t * @param labels - Optional labels\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.inc('requests_total', { method: 'GET' });\n\t * ```\n\t */\n\tinc(name: string, labels?: Record<string, string>): void {\n\t\tthis.counter(name, 1, labels);\n\t}\n\n\t/**\n\t * Decrements a gauge by 1.\n\t *\n\t * @param name - Metric name\n\t * @param labels - Optional labels\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.dec('active_connections');\n\t * ```\n\t */\n\tdec(name: string, labels?: Record<string, string>): void {\n\t\tconst value = this.get(name, labels) ?? 0;\n\t\tthis.gauge(name, value - 1, labels);\n\t}\n\n\t/**\n\t * Resets all metrics to zero.\n\t * Useful for testing or on server restart.\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.reset();\n\t * ```\n\t */\n\treset(): void {\n\t\tthis._metrics.clear();\n\t\tthis._histograms.clear();\n\t\tthis._operationsCounter = 0;\n\t}\n\n\t/**\n\t * Gets the number of metric operations performed.\n\t * Useful for testing.\n\t *\n\t * @returns Operation count\n\t *\n\t * @example\n\t * ```typescript\n\t * const ops = metrics.getOperationCount();\n\t * ```\n\t */\n\tgetOperationCount(): number {\n\t\treturn this._operationsCounter;\n\t}\n\n\t/**\n\t * Exports metrics in Prometheus text format.\n\t *\n\t * @returns Prometheus text format string\n\t *\n\t * @example\n\t * ```typescript\n\t * const prometheusText = metrics.export();\n\t * console.log(prometheusText);\n\t * // Output:\n\t * // # HELP http_requests_total Total HTTP requests\n\t * // # TYPE http_requests_total counter\n\t * // http_requests_total{method=\"GET\",status=\"200\"} 1234\n\t * ```\n\t */\n\texport(): string {\n\t\tconst lines: string[] = [];\n\n\t\tconst metrics = Array.from(this._metrics.values());\n\t\tconst histograms = Array.from(this._histograms.values());\n\n\t\tconst helpEntries = new Map<string, string>();\n\t\tconst typeEntries = new Map<string, MetricType>();\n\n\t\tfor (const metric of metrics) {\n\t\t\tif (!helpEntries.has(metric.name)) {\n\t\t\t\tconst helpText = metric.help ?? `${metric.name} metric`;\n\t\t\t\tlines.push(`# HELP ${metric.name} ${helpText}`);\n\t\t\t\thelpEntries.set(metric.name, helpText);\n\t\t\t}\n\t\t\tif (!typeEntries.has(metric.name)) {\n\t\t\t\tlines.push(`# TYPE ${metric.name} ${metric.type}`);\n\t\t\t\ttypeEntries.set(metric.name, metric.type);\n\t\t\t}\n\n\t\t\tconst labelStr = this._formatLabels(metric.labels);\n\t\t\tlines.push(`${metric.name}{${labelStr}} ${metric.value}`);\n\t\t}\n\n\t\tfor (const histogram of histograms) {\n\t\t\tconst { name: fullName, labels } = histogram;\n\t\t\tif (histogram.count > 0) {\n\t\t\t\tif (!typeEntries.has(fullName)) {\n\t\t\t\t\tlines.push(`# TYPE ${fullName} histogram`);\n\t\t\t\t\ttypeEntries.set(fullName, MetricType.Histogram);\n\t\t\t\t}\n\n\t\t\t\tconst labelStr = this._formatLabels(labels);\n\t\t\t\tconst formatMetricLine = (suffix: string, value: number): string => {\n\t\t\t\t\tif (labelStr.length === 0) {\n\t\t\t\t\t\treturn `${fullName}${suffix} ${value}`;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn `${fullName}${suffix}{${labelStr}} ${value}`;\n\t\t\t\t};\n\n\t\t\t\tlines.push(formatMetricLine('_sum', histogram.sum));\n\t\t\t\tlines.push(formatMetricLine('_count', histogram.count));\n\n\t\t\t\tfor (const [boundary, count] of histogram.buckets.entries()) {\n\t\t\t\t\tconst boundaryLabel =\n\t\t\t\t\t\tboundary === Infinity\n\t\t\t\t\t\t\t? '+Inf'\n\t\t\t\t\t\t\t: Number.isFinite(boundary)\n\t\t\t\t\t\t\t\t? String(boundary)\n\t\t\t\t\t\t\t\t: String(boundary);\n\t\t\t\t\tconst boundaryLabelStr = this._formatLabels({ le: boundaryLabel });\n\t\t\t\t\tconst bucketLabels =\n\t\t\t\t\t\tlabelStr.length === 0 ? boundaryLabelStr : `${labelStr},${boundaryLabelStr}`;\n\t\t\t\t\tlines.push(`${fullName}_bucket{${bucketLabels}} ${count}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn lines.join('\\n');\n\t}\n\n\t/**\n\t * Gets metric name with prefix.\n\t * @param name - Metric name\n\t * @returns Full metric name\n\t * @private\n\t */\n\tprivate _fullName(name: string): string {\n\t\tif (!this._prefix) {\n\t\t\treturn name;\n\t\t}\n\n\t\tconst prefix = `${this._prefix}_`;\n\t\treturn name.startsWith(prefix) ? name : `${prefix}${name}`;\n\t}\n\n\t/**\n\t * Creates a unique key for a metric with labels.\n\t * @param name - Metric name\n\t * @param labels - Labels\n\t * @returns Unique key\n\t * @private\n\t */\n\tprivate _metricKey(name: string, labels: Record<string, string>): string {\n\t\tconst sortedLabels = Object.entries(labels).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n\t\treturn JSON.stringify([name, sortedLabels]);\n\t}\n\n\tprivate _formatLabels(labels: Record<string, string>): string {\n\t\treturn Object.entries(labels)\n\t\t\t.map(([key, value]) => `${key}=\"${this._escapeLabelValue(value)}\"`)\n\t\t\t.join(',');\n\t}\n\n\tprivate _escapeLabelValue(value: string): string {\n\t\treturn value.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"').replaceAll('\\n', '\\\\n');\n\t}\n}\n"],"names":["MetricType","DEFAULT_BUCKETS","Metrics","options","Map","name","value","labels","help","fullName","allLabels","key","existing","buckets","histogram","boundary","Infinity","histogramData","lines","metrics","Array","histograms","helpEntries","typeEntries","metric","helpText","labelStr","formatMetricLine","suffix","count","boundaryLabel","Number","String","boundaryLabelStr","bucketLabels","prefix","sortedLabels","Object","a","b","JSON"],"mappings":"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"}
1
+ {"version":3,"file":"metrics/metrics.impl.js","sources":["../../src/metrics/metrics.impl.ts"],"sourcesContent":["/**\n * Prometheus-compatible metrics collection.\n *\n * This module provides metrics collection and export in Prometheus text format.\n * Supports counters, gauges, and histograms for observability.\n *\n * @module metrics\n */\n\n/**\n * Metric types supported by the metrics collector.\n */\nexport enum MetricType {\n\t/** Counter - a cumulative metric that only increases */\n\tCounter = 'counter',\n\n\t/** Gauge - a metric that can go up and down */\n\tGauge = 'gauge',\n\n\t/** Histogram - a metric for sampling observations */\n\tHistogram = 'histogram',\n}\n\n/**\n * A collected metric with its value and labels.\n */\nexport interface Metric {\n\t/** Name of the metric */\n\tname: string;\n\n\t/** Type of metric (counter, gauge, histogram) */\n\ttype: MetricType;\n\n\t/** Current value */\n\tvalue: number;\n\n\t/** Labels for the metric */\n\tlabels: Record<string, string>;\n\n\t/** Help text describing the metric */\n\thelp?: string;\n\n\t/** Timestamp when metric was recorded (Unix epoch) */\n\ttimestamp?: number;\n}\n\ninterface HistogramMetric {\n\tname: string;\n\tlabels: Record<string, string>;\n\tsum: number;\n\tcount: number;\n\tboundaries: readonly number[];\n\tbuckets: Map<number, number>;\n}\n\n/**\n * Histogram bucket boundaries for latency tracking.\n */\nconst DEFAULT_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];\n\n/**\n * Prometheus-compatible metrics collector.\n *\n * Collects and exports metrics in Prometheus text format for scraping.\n * Thread-safe and supports counters, gauges, and histograms.\n *\n * @remarks\n * **Metric Types:**\n * - **Counter**: Cumulative value that only increases (e.g., request counts)\n * - **Gauge**: Value that can go up or down (e.g., active connections)\n * - **Histogram**: Sampling observations (e.g., request latency)\n *\n * **Labels:**\n * Metrics can have labels for dimensional data:\n * ```typescript\n * counter('http_requests_total', { method: 'GET', status: '200' });\n * ```\n *\n * **Export Format:**\n * Metrics are exported in Prometheus text format:\n * ```\n * # HELP http_requests_total Total HTTP requests\n * # TYPE http_requests_total counter\n * http_requests_total{method=\"GET\",status=\"200\"} 1234\n * ```\n *\n * @example\n * ```typescript\n * const metrics = new Metrics({ prefix: 'mcp_server' });\n *\n * // Count requests\n * metrics.counter('requests_total', { method: 'GET' }).inc();\n *\n * // Track active connections\n * const activeConnections = metrics.gauge('active_connections');\n * activeConnections.set(5);\n * activeConnections.dec();\n *\n * // Record latency\n * metrics.histogram('request_duration_seconds').observe(0.023);\n *\n * // Export for Prometheus\n * const prometheusText = metrics.export();\n * ```\n */\nexport class Metrics {\n\t/** Metrics storage indexed by name and label hash */\n\tprivate _metrics: Map<string, Metric>;\n\n\t/** Histogram samples */\n\tprivate _histograms: Map<string, HistogramMetric>;\n\n\t/** Prefix for all metric names */\n\tprivate _prefix: string;\n\n\t/** Default labels to apply to all metrics */\n\tprivate _defaultLabels: Record<string, string>;\n\n\t/** Counter for metric collection operations */\n\tprivate _operationsCounter: number = 0;\n\n\t/**\n\t * Creates a new Metrics instance.\n\t *\n\t * @param options - Configuration options\n\t *\n\t * @example\n\t * ```typescript\n\t * const metrics = new Metrics({ prefix: 'mcp_server' });\n\t * ```\n\t */\n\tconstructor(options: { prefix?: string; defaultLabels?: Record<string, string> } = {}) {\n\t\tthis._metrics = new Map();\n\t\tthis._histograms = new Map();\n\t\tthis._prefix = options.prefix ?? '';\n\t\tthis._defaultLabels = { ...options.defaultLabels };\n\t}\n\n\t/**\n\t * Creates a counter metric.\n\t *\n\t * @param name - Metric name\n\t * @param value - Increment value (default: 1)\n\t * @param labels - Optional labels\n\t * @param help - Help text\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.counter('requests_total', 1, { method: 'GET' });\n\t * metrics.counter('errors_total', 1, { type: 'timeout' });\n\t * ```\n\t */\n\tcounter(name: string, value = 1, labels: Record<string, string> = {}, help?: string): void {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\tconst existing = this._metrics.get(key);\n\n\t\tif (existing) {\n\t\t\texisting.value += value;\n\t\t\tif (help && !existing.help) {\n\t\t\t\texisting.help = help;\n\t\t\t}\n\t\t} else {\n\t\t\tthis._metrics.set(key, {\n\t\t\t\tname: fullName,\n\t\t\t\ttype: MetricType.Counter,\n\t\t\t\tvalue,\n\t\t\t\tlabels: { ...allLabels },\n\t\t\t\thelp,\n\t\t\t});\n\t\t}\n\t\tthis._operationsCounter++;\n\t}\n\n\t/**\n\t * Creates a gauge metric.\n\t *\n\t * @param name - Metric name\n\t * @param value - Current value\n\t * @param labels - Optional labels\n\t * @param help - Help text\n\t *\n\t * @example\n\t * ```typescript\n\t * const activeConnections = metrics.gauge('active_connections');\n\t * activeConnections.set(5);\n\t * activeConnections.dec();\n\t * ```\n\t */\n\tgauge(name: string, value: number, labels: Record<string, string> = {}, help?: string): void {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\tconst existing = this._metrics.get(key);\n\t\tthis._metrics.set(key, {\n\t\t\tname: fullName,\n\t\t\ttype: MetricType.Gauge,\n\t\t\tvalue,\n\t\t\tlabels: { ...allLabels },\n\t\t\thelp: help ?? existing?.help,\n\t\t});\n\t\tthis._operationsCounter++;\n\t}\n\n\t/**\n\t * Records a histogram observation.\n\t *\n\t * @param name - Histogram name\n\t * @param value - Observed value\n\t * @param labels - Optional labels\n\t * @param help - Help text\n\t * @param buckets - Custom bucket boundaries\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.histogram('request_duration_seconds').observe(0.023);\n\t * metrics.histogram('thought_processing_ms').observe(45);\n\t * ```\n\t */\n\thistogram(\n\t\tname: string,\n\t\tvalue: number,\n\t\tlabels: Record<string, string> = {},\n\t\tbuckets = DEFAULT_BUCKETS\n\t): void {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\tconst histogram = this._histograms.get(key);\n\t\tlet previousBoundary = -Infinity;\n\t\tfor (const boundary of buckets) {\n\t\t\tif (!Number.isFinite(boundary) || boundary <= previousBoundary) {\n\t\t\t\tthrow new RangeError('Histogram boundaries must be finite and strictly increasing');\n\t\t\t}\n\t\t\tpreviousBoundary = boundary;\n\t\t}\n\t\tif (\n\t\t\thistogram &&\n\t\t\t(histogram.boundaries.length !== buckets.length ||\n\t\t\t\thistogram.boundaries.some((boundary, index) => boundary !== buckets[index]))\n\t\t) {\n\t\t\tthrow new RangeError('Histogram bucket layout differs from the existing series');\n\t\t}\n\n\t\tif (histogram) {\n\t\t\thistogram.sum += value;\n\t\t\thistogram.count += 1;\n\t\t\tfor (const boundary of histogram.boundaries) {\n\t\t\t\tif (value <= boundary) {\n\t\t\t\t\thistogram.buckets.set(boundary, (histogram.buckets.get(boundary) ?? 0) + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst histogramData = {\n\t\t\t\tname: fullName,\n\t\t\t\tlabels: { ...allLabels },\n\t\t\t\tsum: value,\n\t\t\t\tcount: 1,\n\t\t\t\tboundaries: [...buckets],\n\t\t\t\tbuckets: new Map<number, number>(),\n\t\t\t};\n\t\t\tfor (const boundary of buckets) {\n\t\t\t\thistogramData.buckets.set(boundary, value <= boundary ? 1 : 0);\n\t\t\t}\n\t\t\tthis._histograms.set(key, histogramData);\n\t\t}\n\t\tthis._operationsCounter++;\n\t}\n\n\t/**\n\t * Gets the current value of a metric.\n\t *\n\t * @param name - Metric name\n\t * @param labels - Labels\n\t * @returns Current value or undefined if not found\n\t *\n\t * @example\n\t * ```typescript\n\t * const count = metrics.get('requests_total', { method: 'GET' });\n\t * ```\n\t */\n\tget(name: string, labels: Record<string, string> = {}): number | undefined {\n\t\tconst fullName = this._fullName(name);\n\t\tconst allLabels = { ...this._defaultLabels, ...labels };\n\t\tconst key = this._metricKey(fullName, allLabels);\n\t\treturn this._metrics.get(key)?.value;\n\t}\n\n\t/**\n\t * Increments a counter by 1.\n\t *\n\t * @param name - Metric name\n\t * @param labels - Optional labels\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.inc('requests_total', { method: 'GET' });\n\t * ```\n\t */\n\tinc(name: string, labels?: Record<string, string>): void {\n\t\tthis.counter(name, 1, labels);\n\t}\n\n\t/**\n\t * Decrements a gauge by 1.\n\t *\n\t * @param name - Metric name\n\t * @param labels - Optional labels\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.dec('active_connections');\n\t * ```\n\t */\n\tdec(name: string, labels?: Record<string, string>): void {\n\t\tconst value = this.get(name, labels) ?? 0;\n\t\tthis.gauge(name, value - 1, labels);\n\t}\n\n\t/**\n\t * Resets all metrics to zero.\n\t * Useful for testing or on server restart.\n\t *\n\t * @example\n\t * ```typescript\n\t * metrics.reset();\n\t * ```\n\t */\n\treset(): void {\n\t\tthis._metrics.clear();\n\t\tthis._histograms.clear();\n\t\tthis._operationsCounter = 0;\n\t}\n\n\t/**\n\t * Gets the number of metric operations performed.\n\t * Useful for testing.\n\t *\n\t * @returns Operation count\n\t *\n\t * @example\n\t * ```typescript\n\t * const ops = metrics.getOperationCount();\n\t * ```\n\t */\n\tgetOperationCount(): number {\n\t\treturn this._operationsCounter;\n\t}\n\n\t/**\n\t * Exports metrics in Prometheus text format.\n\t *\n\t * @returns Prometheus text format string\n\t *\n\t * @example\n\t * ```typescript\n\t * const prometheusText = metrics.export();\n\t * console.log(prometheusText);\n\t * // Output:\n\t * // # HELP http_requests_total Total HTTP requests\n\t * // # TYPE http_requests_total counter\n\t * // http_requests_total{method=\"GET\",status=\"200\"} 1234\n\t * ```\n\t */\n\texport(): string {\n\t\tconst lines: string[] = [];\n\n\t\tconst metrics = Array.from(this._metrics.values());\n\t\tconst histograms = Array.from(this._histograms.values());\n\n\t\tconst helpEntries = new Map<string, string>();\n\t\tconst typeEntries = new Map<string, MetricType>();\n\n\t\tfor (const metric of metrics) {\n\t\t\tif (!helpEntries.has(metric.name)) {\n\t\t\t\tconst helpText = metric.help ?? `${metric.name} metric`;\n\t\t\t\tlines.push(\n\t\t\t\t\t`# HELP ${metric.name} ${helpText.replaceAll('\\\\', '\\\\\\\\').replaceAll('\\n', '\\\\n')}`\n\t\t\t\t);\n\t\t\t\thelpEntries.set(metric.name, helpText);\n\t\t\t}\n\t\t\tif (!typeEntries.has(metric.name)) {\n\t\t\t\tlines.push(`# TYPE ${metric.name} ${metric.type}`);\n\t\t\t\ttypeEntries.set(metric.name, metric.type);\n\t\t\t}\n\n\t\t\tconst labelStr = this._formatLabels(metric.labels);\n\t\t\tlines.push(`${metric.name}{${labelStr}} ${metric.value}`);\n\t\t}\n\n\t\tfor (const histogram of histograms) {\n\t\t\tconst { name: fullName, labels } = histogram;\n\t\t\tif (histogram.count > 0) {\n\t\t\t\tif (!typeEntries.has(fullName)) {\n\t\t\t\t\tlines.push(`# TYPE ${fullName} histogram`);\n\t\t\t\t\ttypeEntries.set(fullName, MetricType.Histogram);\n\t\t\t\t}\n\n\t\t\t\tconst labelStr = this._formatLabels(labels);\n\t\t\t\tconst formatMetricLine = (suffix: string, value: number): string => {\n\t\t\t\t\tif (labelStr.length === 0) {\n\t\t\t\t\t\treturn `${fullName}${suffix} ${value}`;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn `${fullName}${suffix}{${labelStr}} ${value}`;\n\t\t\t\t};\n\n\t\t\t\tlines.push(formatMetricLine('_sum', histogram.sum));\n\t\t\t\tlines.push(formatMetricLine('_count', histogram.count));\n\n\t\t\t\tfor (const boundary of histogram.boundaries) {\n\t\t\t\t\tconst count = histogram.buckets.get(boundary);\n\t\t\t\t\tconst boundaryLabel = String(boundary);\n\t\t\t\t\tconst boundaryLabelStr = this._formatLabels({ le: boundaryLabel });\n\t\t\t\t\tconst bucketLabels =\n\t\t\t\t\t\tlabelStr.length === 0 ? boundaryLabelStr : `${labelStr},${boundaryLabelStr}`;\n\t\t\t\t\tlines.push(`${fullName}_bucket{${bucketLabels}} ${count}`);\n\t\t\t\t}\n\t\t\t\tconst infLabelStr = this._formatLabels({ le: '+Inf' });\n\t\t\t\tconst infLabels = labelStr.length === 0 ? infLabelStr : `${labelStr},${infLabelStr}`;\n\t\t\t\tlines.push(`${fullName}_bucket{${infLabels}} ${histogram.count}`);\n\t\t\t}\n\t\t}\n\n\t\treturn lines.join('\\n');\n\t}\n\n\t/**\n\t * Gets metric name with prefix.\n\t * @param name - Metric name\n\t * @returns Full metric name\n\t * @private\n\t */\n\tprivate _fullName(name: string): string {\n\t\tif (!this._prefix) {\n\t\t\treturn name;\n\t\t}\n\n\t\tconst prefix = `${this._prefix}_`;\n\t\treturn name.startsWith(prefix) ? name : `${prefix}${name}`;\n\t}\n\n\t/**\n\t * Creates a unique key for a metric with labels.\n\t * @param name - Metric name\n\t * @param labels - Labels\n\t * @returns Unique key\n\t * @private\n\t */\n\tprivate _metricKey(name: string, labels: Record<string, string>): string {\n\t\tconst sortedLabels = Object.entries(labels).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n\t\treturn JSON.stringify([name, sortedLabels]);\n\t}\n\n\tprivate _formatLabels(labels: Record<string, string>): string {\n\t\treturn Object.entries(labels)\n\t\t\t.map(([key, value]) => `${key}=\"${this._escapeLabelValue(value)}\"`)\n\t\t\t.join(',');\n\t}\n\n\tprivate _escapeLabelValue(value: string): string {\n\t\treturn value.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"').replaceAll('\\n', '\\\\n');\n\t}\n}\n"],"names":["MetricType","DEFAULT_BUCKETS","Metrics","options","Map","name","value","labels","help","fullName","allLabels","key","existing","buckets","histogram","previousBoundary","boundary","Number","RangeError","index","histogramData","lines","metrics","Array","histograms","helpEntries","typeEntries","metric","helpText","labelStr","formatMetricLine","suffix","count","boundaryLabel","String","boundaryLabelStr","bucketLabels","infLabelStr","infLabels","prefix","sortedLabels","Object","a","b","JSON"],"mappings":"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"}
@@ -153,15 +153,15 @@ export declare const FileSnapshotV2Schema: v.StrictObjectSchema<{
153
153
  readonly quality_score: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "Self-assessed quality score (0-1)">]>, undefined>;
154
154
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "Explicit confidence in correctness (0-1)">]>, undefined>;
155
155
  readonly hypothesis_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Hypothesis ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 50, undefined>, v.DescriptionAction<string, "Identifier linking hypothesis to verification thoughts">]>, undefined>;
156
- readonly verification_target: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "Thought number being verified or critiqued">]>, undefined>;
156
+ readonly verification_target: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "Uniquely retained thought number being verified or critiqued; ambiguous numeric targets fail even though branch/revision number reuse is legal">]>, undefined>;
157
157
  readonly verification_result: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnionSchema<[v.LiteralSchema<0, undefined>, v.LiteralSchema<1, undefined>], undefined>, v.DescriptionAction<0 | 1, "Exact verification outcome label: 0 for incorrect, 1 for correct">]>, undefined>;
158
158
  readonly synthesis_sources: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>, v.DescriptionAction<number[], "Thought numbers being synthesized">]>, undefined>;
159
159
  readonly merge_from_thoughts: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>, v.DescriptionAction<number[], "Thought numbers from other branches being merged (DAG)">]>, undefined>;
160
160
  readonly merge_branch_ids: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>, v.MaxLengthAction<string, 50, undefined>]>, undefined>, v.DescriptionAction<string[], "Branch IDs being merged into current context">]>, undefined>;
161
161
  readonly meta_observation: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Metacognitive observation about reasoning process">]>, undefined>;
162
162
  readonly reasoning_depth: v.OptionalSchema<v.SchemaWithPipe<readonly [v.PicklistSchema<["shallow", "moderate", "deep"], undefined>, v.DescriptionAction<"shallow" | "moderate" | "deep", "Effort signal: how deep reasoning should go">]>, undefined>;
163
- readonly session_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Session ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 100, undefined>, v.NotValueAction<string, "__global__", "Session ID '__global__' is retired; use an explicit named session">, v.DescriptionAction<string, "Required session identifier for state isolation. Thought history, branches, and statistics are scoped to this explicit named session.">]>;
164
- readonly reset_state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.BooleanSchema<undefined>, v.DescriptionAction<boolean, "When true, clears all state for the target session before processing this thought. The thought is then processed as the first in a fresh session.">]>, undefined>;
163
+ readonly session_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Session ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 100, undefined>, v.NotValueAction<string, "__global__", "Session ID '__global__' is retired; use an explicit named session">, v.DescriptionAction<string, "Required named session for state isolation. SESSION_EXPIRED after runtime eviction requires an authorized reset_state fresh chain or a new session_id; ordinary continuation cannot recreate it.">]>;
164
+ readonly reset_state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.BooleanSchema<undefined>, v.DescriptionAction<boolean, "Authorized fresh-chain replacement, deleting target-session durable data and preserving its former owner. Recovers SESSION_EXPIRED only on successful reset; invalid or failed reset does not reopen it.">]>, undefined>;
165
165
  readonly tool_name: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.DescriptionAction<string, "Name of the tool being invoked (for tool_call thoughts)">]>, undefined>;
166
166
  readonly tool_arguments: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
167
167
  [x: string]: unknown;
@@ -323,15 +323,15 @@ export declare const FileSnapshotV2Schema: v.StrictObjectSchema<{
323
323
  readonly quality_score: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "Self-assessed quality score (0-1)">]>, undefined>;
324
324
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "Explicit confidence in correctness (0-1)">]>, undefined>;
325
325
  readonly hypothesis_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Hypothesis ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 50, undefined>, v.DescriptionAction<string, "Identifier linking hypothesis to verification thoughts">]>, undefined>;
326
- readonly verification_target: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "Thought number being verified or critiqued">]>, undefined>;
326
+ readonly verification_target: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "Uniquely retained thought number being verified or critiqued; ambiguous numeric targets fail even though branch/revision number reuse is legal">]>, undefined>;
327
327
  readonly verification_result: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnionSchema<[v.LiteralSchema<0, undefined>, v.LiteralSchema<1, undefined>], undefined>, v.DescriptionAction<0 | 1, "Exact verification outcome label: 0 for incorrect, 1 for correct">]>, undefined>;
328
328
  readonly synthesis_sources: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>, v.DescriptionAction<number[], "Thought numbers being synthesized">]>, undefined>;
329
329
  readonly merge_from_thoughts: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>, v.DescriptionAction<number[], "Thought numbers from other branches being merged (DAG)">]>, undefined>;
330
330
  readonly merge_branch_ids: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>, v.MaxLengthAction<string, 50, undefined>]>, undefined>, v.DescriptionAction<string[], "Branch IDs being merged into current context">]>, undefined>;
331
331
  readonly meta_observation: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Metacognitive observation about reasoning process">]>, undefined>;
332
332
  readonly reasoning_depth: v.OptionalSchema<v.SchemaWithPipe<readonly [v.PicklistSchema<["shallow", "moderate", "deep"], undefined>, v.DescriptionAction<"shallow" | "moderate" | "deep", "Effort signal: how deep reasoning should go">]>, undefined>;
333
- readonly session_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Session ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 100, undefined>, v.NotValueAction<string, "__global__", "Session ID '__global__' is retired; use an explicit named session">, v.DescriptionAction<string, "Required session identifier for state isolation. Thought history, branches, and statistics are scoped to this explicit named session.">]>;
334
- readonly reset_state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.BooleanSchema<undefined>, v.DescriptionAction<boolean, "When true, clears all state for the target session before processing this thought. The thought is then processed as the first in a fresh session.">]>, undefined>;
333
+ readonly session_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Session ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 100, undefined>, v.NotValueAction<string, "__global__", "Session ID '__global__' is retired; use an explicit named session">, v.DescriptionAction<string, "Required named session for state isolation. SESSION_EXPIRED after runtime eviction requires an authorized reset_state fresh chain or a new session_id; ordinary continuation cannot recreate it.">]>;
334
+ readonly reset_state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.BooleanSchema<undefined>, v.DescriptionAction<boolean, "Authorized fresh-chain replacement, deleting target-session durable data and preserving its former owner. Recovers SESSION_EXPIRED only on successful reset; invalid or failed reset does not reopen it.">]>, undefined>;
335
335
  readonly tool_name: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.DescriptionAction<string, "Name of the tool being invoked (for tool_call thoughts)">]>, undefined>;
336
336
  readonly tool_arguments: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
337
337
  [x: string]: unknown;
package/dist/schema.d.ts CHANGED
@@ -473,15 +473,15 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
473
473
  readonly quality_score: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "Self-assessed quality score (0-1)">]>, undefined>;
474
474
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "Explicit confidence in correctness (0-1)">]>, undefined>;
475
475
  readonly hypothesis_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Hypothesis ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 50, undefined>, v.DescriptionAction<string, "Identifier linking hypothesis to verification thoughts">]>, undefined>;
476
- readonly verification_target: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "Thought number being verified or critiqued">]>, undefined>;
476
+ readonly verification_target: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.DescriptionAction<number, "Uniquely retained thought number being verified or critiqued; ambiguous numeric targets fail even though branch/revision number reuse is legal">]>, undefined>;
477
477
  readonly verification_result: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnionSchema<[v.LiteralSchema<0, undefined>, v.LiteralSchema<1, undefined>], undefined>, v.DescriptionAction<0 | 1, "Exact verification outcome label: 0 for incorrect, 1 for correct">]>, undefined>;
478
478
  readonly synthesis_sources: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>, v.DescriptionAction<number[], "Thought numbers being synthesized">]>, undefined>;
479
479
  readonly merge_from_thoughts: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>, v.DescriptionAction<number[], "Thought numbers from other branches being merged (DAG)">]>, undefined>;
480
480
  readonly merge_branch_ids: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>, v.MaxLengthAction<string, 50, undefined>]>, undefined>, v.DescriptionAction<string[], "Branch IDs being merged into current context">]>, undefined>;
481
481
  readonly meta_observation: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Metacognitive observation about reasoning process">]>, undefined>;
482
482
  readonly reasoning_depth: v.OptionalSchema<v.SchemaWithPipe<readonly [v.PicklistSchema<["shallow", "moderate", "deep"], undefined>, v.DescriptionAction<"shallow" | "moderate" | "deep", "Effort signal: how deep reasoning should go">]>, undefined>;
483
- readonly session_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Session ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 100, undefined>, v.NotValueAction<string, "__global__", "Session ID '__global__' is retired; use an explicit named session">, v.DescriptionAction<string, "Required session identifier for state isolation. Thought history, branches, and statistics are scoped to this explicit named session.">]>;
484
- readonly reset_state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.BooleanSchema<undefined>, v.DescriptionAction<boolean, "When true, clears all state for the target session before processing this thought. The thought is then processed as the first in a fresh session.">]>, undefined>;
483
+ readonly session_id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "Session ID must contain only letters, numbers, hyphens, and underscores">, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 100, undefined>, v.NotValueAction<string, "__global__", "Session ID '__global__' is retired; use an explicit named session">, v.DescriptionAction<string, "Required named session for state isolation. SESSION_EXPIRED after runtime eviction requires an authorized reset_state fresh chain or a new session_id; ordinary continuation cannot recreate it.">]>;
484
+ readonly reset_state: v.OptionalSchema<v.SchemaWithPipe<readonly [v.BooleanSchema<undefined>, v.DescriptionAction<boolean, "Authorized fresh-chain replacement, deleting target-session durable data and preserving its former owner. Recovers SESSION_EXPIRED only on successful reset; invalid or failed reset does not reopen it.">]>, undefined>;
485
485
  readonly tool_name: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.DescriptionAction<string, "Name of the tool being invoked (for tool_call thoughts)">]>, undefined>;
486
486
  readonly tool_arguments: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
487
487
  [x: string]: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAoH5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;aAqBnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;aAgCpC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAanC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;aA6B1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAe1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA0OnC,CAAC;AAEH,6FAA6F;AAC7F,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,EAAE,IAItC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB;;;;;;;aAmB/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,kWASW,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;aAetB,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAoH5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;aAqBnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;aAgCpC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAanC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;aA6B1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAe1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAgPnC,CAAC;AAEH,6FAA6F;AAC7F,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,EAAE,IAItC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB;;;;;;;aAmB/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,kWASW,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;aAetB,CAAC"}
package/dist/schema.js CHANGED
@@ -66,7 +66,7 @@ Reasoning Enhancement Parameters:
66
66
  - quality_score: Self-assessed quality of this thought (0-1)
67
67
  - confidence: Confidence in this thought's correctness (0-1)
68
68
  - hypothesis_id: Links hypothesis to verification (alphanumeric, hyphens, underscores)
69
- - verification_target: For 'verification'/'critique' types, the thought_number being evaluated
69
+ - verification_target: For 'verification'/'critique', the thought_number of a uniquely retained identity. Branch/revision number reuse is legal, but ambiguous numeric targets fail. Result-bearing verification requires a non-retracted target with confidence.
70
70
  - verification_result: Optional exact outcome label (0 = incorrect, 1 = correct) for a verification_target; only has outcome semantics on thought_type='verification'
71
71
  - synthesis_sources: For 'synthesis' type, the thought_numbers being combined
72
72
  - merge_from_thoughts: Thought numbers from other branches merged (graph reasoning)
@@ -74,7 +74,7 @@ Reasoning Enhancement Parameters:
74
74
  - meta_observation: Observation about reasoning process (with thought_type 'meta')
75
75
  - reasoning_depth: How deep to reason: 'shallow' (quick), 'moderate' (default), 'deep' (thorough)
76
76
  - session_id: Required unique identifier that scopes thought history, branches, and statistics to an explicit session. Format: alphanumeric, hyphens, underscores, 1-100 chars; the retired value __global__ is rejected.
77
- - reset_state: (Optional) When true, clears all state for the required session_id before processing the current thought. Use this to start a fresh reasoning chain without accumulated state from previous chains.
77
+ - reset_state: (Optional) Authorized fresh-chain replacement for session_id, deleting its durable data and preserving its former owner. SESSION_EXPIRED requires this explicit recovery or a new session_id; invalid or failed reset does not reopen the expired scope.
78
78
 
79
79
  Response Enrichment:
80
80
  - When reasoning fields are set, response includes confidence_signals (depth, revision/branch count, type distribution, avg confidence, structural_quality, quality_components) and reasoning_stats (hypothesis tracking)
@@ -187,7 +187,7 @@ const SequentialThinkingSchema = __rspack_external_valibot.object({
187
187
  quality_score: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(0), __rspack_external_valibot.maxValue(1), __rspack_external_valibot.description('Self-assessed quality score (0-1)'))),
188
188
  confidence: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(0), __rspack_external_valibot.maxValue(1), __rspack_external_valibot.description('Explicit confidence in correctness (0-1)'))),
189
189
  hypothesis_id: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.regex(/^[a-zA-Z0-9_-]+$/, 'Hypothesis ID must contain only letters, numbers, hyphens, and underscores'), __rspack_external_valibot.minLength(1), __rspack_external_valibot.maxLength(50), __rspack_external_valibot.description('Identifier linking hypothesis to verification thoughts'))),
190
- verification_target: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(1), __rspack_external_valibot.description('Thought number being verified or critiqued'))),
190
+ verification_target: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(1), __rspack_external_valibot.description('Uniquely retained thought number being verified or critiqued; ambiguous numeric targets fail even though branch/revision number reuse is legal'))),
191
191
  verification_result: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.union([
192
192
  __rspack_external_valibot.literal(0),
193
193
  __rspack_external_valibot.literal(1)
@@ -201,8 +201,8 @@ const SequentialThinkingSchema = __rspack_external_valibot.object({
201
201
  'moderate',
202
202
  'deep'
203
203
  ]), __rspack_external_valibot.description('Effort signal: how deep reasoning should go'))),
204
- session_id: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.regex(/^[a-zA-Z0-9_-]+$/, 'Session ID must contain only letters, numbers, hyphens, and underscores'), __rspack_external_valibot.minLength(1), __rspack_external_valibot.maxLength(100), __rspack_external_valibot.notValue('__global__', "Session ID '__global__' is retired; use an explicit named session"), __rspack_external_valibot.description('Required session identifier for state isolation. Thought history, branches, and statistics are scoped to this explicit named session.')),
205
- reset_state: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.boolean(), __rspack_external_valibot.description('When true, clears all state for the target session before processing this thought. The thought is then processed as the first in a fresh session.'))),
204
+ session_id: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.regex(/^[a-zA-Z0-9_-]+$/, 'Session ID must contain only letters, numbers, hyphens, and underscores'), __rspack_external_valibot.minLength(1), __rspack_external_valibot.maxLength(100), __rspack_external_valibot.notValue('__global__', "Session ID '__global__' is retired; use an explicit named session"), __rspack_external_valibot.description('Required named session for state isolation. SESSION_EXPIRED after runtime eviction requires an authorized reset_state fresh chain or a new session_id; ordinary continuation cannot recreate it.')),
205
+ reset_state: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.boolean(), __rspack_external_valibot.description('Authorized fresh-chain replacement, deleting target-session durable data and preserving its former owner. Recovers SESSION_EXPIRED only on successful reset; invalid or failed reset does not reopen it.'))),
206
206
  tool_name: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.minLength(1), __rspack_external_valibot.description('Name of the tool being invoked (for tool_call thoughts)'))),
207
207
  tool_arguments: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.record(__rspack_external_valibot.string(), __rspack_external_valibot.unknown()), __rspack_external_valibot.description('Arguments passed to the tool (for tool_call thoughts)'))),
208
208
  tool_result: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.unknown(), __rspack_external_valibot.description('Result returned by the tool (for tool_observation thoughts)'))),