Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-agents/src/lexigram/ai/agents/exceptions.py: 47%

86 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-25 07:19 +0800

1"""Agent-specific leaf exceptions for the Lexigram AI agents package. 

2 

3These exceptions are raised during agent construction, execution, tool 

4invocation, and strategy execution. Base exception classes (AgentError, 

5ToolError, StrategyError) are imported from 

6``lexigram.contracts.agents.exceptions``. 

7 

8This module is the canonical location for all agent leaf exceptions. 

9""" 

10 

11from __future__ import annotations 

12 

13from typing import Any 

14 

15from lexigram.contracts.ai.agents import ( 

16 AgentError, 

17 StrategyError, 

18 ToolError, 

19) 

20 

21 

22class AgentConfigurationError(AgentError): 

23 """Invalid agent configuration. 

24 

25 Raised when an agent is constructed with invalid parameters 

26 (no tools, no system prompt, invalid strategy, etc.). 

27 """ 

28 

29 _code: str = "LEX_ERR_AGT_004" 

30 

31 def __init__( 

32 self, 

33 message: str = "Agent configuration error", 

34 *, 

35 agent_name: str | None = None, 

36 **kwargs: Any, 

37 ) -> None: 

38 details = kwargs.pop("details", {}) 

39 if agent_name: 

40 details["agent"] = agent_name 

41 super().__init__(message=message, details=details, **kwargs) 

42 

43 

44class AgentExecutionError(AgentError): 

45 """Agent execution failed. 

46 

47 Raised when the agent's reasoning loop encounters an 

48 unrecoverable error (LLM failure, strategy crash, etc.). 

49 """ 

50 

51 _code: str = "LEX_ERR_AGT_005" 

52 

53 def __init__( 

54 self, 

55 message: str = "Agent execution failed", 

56 *, 

57 agent_name: str | None = None, 

58 step_number: int | None = None, 

59 **kwargs: Any, 

60 ) -> None: 

61 details = kwargs.pop("details", {}) 

62 if agent_name: 

63 details["agent"] = agent_name 

64 if step_number is not None: 

65 details["step"] = step_number 

66 super().__init__(message=message, details=details, **kwargs) 

67 

68 

69class ToolNotFoundError(ToolError): 

70 """Tool not found in registry. 

71 

72 Raised when the agent tries to call a tool that is not 

73 registered in the tool registry. 

74 """ 

75 

76 _code: str = "LEX_ERR_AGT_006" 

77 

78 def __init__( 

79 self, 

80 message: str = "Tool not found", 

81 *, 

82 tool_name: str | None = None, 

83 available_tools: list[str] | None = None, 

84 **kwargs: Any, 

85 ) -> None: 

86 if tool_name: 

87 message = f"{message}: {tool_name}" 

88 details = kwargs.pop("details", {}) 

89 if tool_name: 

90 details["tool"] = tool_name 

91 if available_tools: 

92 details["available"] = available_tools 

93 super().__init__(message=message, details=details, **kwargs) 

94 

95 

96class ToolExecutionError(ToolError): 

97 """Tool execution failed. 

98 

99 Raised when a tool raises an exception during execution. 

100 """ 

101 

102 _code: str = "LEX_ERR_AGT_007" 

103 

104 def __init__( 

105 self, 

106 message: str = "Tool execution failed", 

107 *, 

108 tool_name: str | None = None, 

109 arguments: dict[str, Any] | None = None, 

110 **kwargs: Any, 

111 ) -> None: 

112 if tool_name: 

113 message = f"{message}: {tool_name}" 

114 details = kwargs.pop("details", {}) 

115 if tool_name: 

116 details["tool"] = tool_name 

117 if arguments: 

118 details["arguments"] = arguments 

119 super().__init__(message=message, details=details, **kwargs) 

120 

121 

122class ToolAccessDeniedError(ToolError): 

123 """Agent does not have access to this tool. 

124 

125 Raised when module visibility controls prevent an agent 

126 from accessing a specific tool. 

127 """ 

128 

129 _code: str = "LEX_ERR_AGT_008" 

130 

131 def __init__( 

132 self, 

133 message: str = "Tool access denied", 

134 *, 

135 tool_name: str | None = None, 

136 agent_module: str | None = None, 

137 tool_module: str | None = None, 

138 **kwargs: Any, 

139 ) -> None: 

140 if tool_name: 

141 message = f"{message}: {tool_name}" 

142 details = kwargs.pop("details", {}) 

143 if tool_name: 

144 details["tool"] = tool_name 

145 if agent_module: 

146 details["agent_module"] = agent_module 

147 if tool_module: 

148 details["tool_module"] = tool_module 

149 super().__init__(message=message, details=details, **kwargs) 

150 

151 

152class MaxIterationsExceededError(StrategyError): 

153 """Agent exceeded maximum reasoning iterations. 

154 

155 Raised when the agent reaches max_iterations without 

156 producing a final response. 

157 """ 

158 

159 _code: str = "LEX_ERR_AGT_009" 

160 

161 def __init__( 

162 self, 

163 message: str = "Maximum iterations exceeded", 

164 *, 

165 max_iterations: int | None = None, 

166 current_iteration: int | None = None, 

167 **kwargs: Any, 

168 ) -> None: 

169 details = kwargs.pop("details", {}) 

170 if max_iterations is not None: 

171 details["max_iterations"] = max_iterations 

172 if current_iteration is not None: 

173 details["current_iteration"] = current_iteration 

174 super().__init__(message=message, details=details, **kwargs) 

175 

176 

177class BudgetExceededError(AgentError): 

178 """Agent exceeded its AI governance budget. 

179 

180 Raised when token usage or cost exceeds configured limits 

181 before the agent completes its task. 

182 """ 

183 

184 _code: str = "LEX_ERR_AGT_010" 

185 

186 def __init__( 

187 self, 

188 message: str = "Budget exceeded", 

189 *, 

190 budget_type: str | None = None, 

191 limit: float | None = None, 

192 used: float | None = None, 

193 **kwargs: Any, 

194 ) -> None: 

195 details = kwargs.pop("details", {}) 

196 if budget_type: 

197 details["budget_type"] = budget_type 

198 if limit is not None: 

199 details["limit"] = limit 

200 if used is not None: 

201 details["used"] = used 

202 super().__init__(message=message, details=details, **kwargs) 

203 

204 

205class ToolValidationError(ToolError): 

206 """Tool input validation failed. 

207 

208 Raised when the arguments provided to a tool fail schema 

209 validation before execution begins. 

210 """ 

211 

212 _code: str = "LEX_ERR_AGT_011" 

213 

214 def __init__( 

215 self, 

216 message: str = "Tool input validation failed", 

217 *, 

218 tool_name: str | None = None, 

219 field: str | None = None, 

220 **kwargs: Any, 

221 ) -> None: 

222 if tool_name: 

223 message = f"{message}: {tool_name}" 

224 details = kwargs.pop("details", {}) 

225 if tool_name: 

226 details["tool"] = tool_name 

227 if field: 

228 details["field"] = field 

229 super().__init__(message=message, details=details, **kwargs) 

230 

231 

232__all__ = [ 

233 "AgentConfigurationError", 

234 "AgentError", 

235 "AgentExecutionError", 

236 "BudgetExceededError", 

237 "MaxIterationsExceededError", 

238 "StrategyError", 

239 "ToolAccessDeniedError", 

240 "ToolError", 

241 "ToolExecutionError", 

242 "ToolNotFoundError", 

243 "ToolValidationError", 

244]