feat: extend operational investigation workflows
Generic Container CI/CD / test-build-publish (push) Successful in 3m53s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 3m52s

This commit is contained in:
2026-10-30 17:30:19 +08:00
parent 63af998045
commit 05183aff93
82 changed files with 4644 additions and 330 deletions
+20 -6
View File
@@ -203,7 +203,11 @@ class McpQueryApplication:
return None
schema = tool.model.model_json_schema()
if tool.computation or tool.mutating:
schema["properties"]["timeout_seconds"]["maximum"] = self.settings.max_calculation_timeout_seconds
schema["properties"]["timeout_seconds"]["maximum"] = self.settings.max_request_timeout_seconds
schema["properties"]["timeout_seconds"]["default"] = min(
self.settings.query_timeout_seconds,
self.settings.max_request_timeout_seconds,
)
return schema
async def list_tools(self, ctx, params):
@@ -213,6 +217,10 @@ class McpQueryApplication:
for name in sorted(TOOLS):
tool = TOOLS[name].protocol_tool()
tool.input_schema.update(self.tool_input_schema(name))
tool.meta = {**(tool.meta or {}), "io.tjwater/request-timeout": {
"defaultSeconds": self.settings.query_timeout_seconds,
"maxSeconds": self.settings.max_request_timeout_seconds,
}}
tools.append(tool)
return types.ListToolsResult(
tools=tools,
@@ -291,11 +299,13 @@ class McpQueryApplication:
return tool_error(
"INVALID_QUERY", "Query parameters do not match the tool schema"
)
if (tool.computation or tool.mutating) and "timeout_seconds" not in args.model_fields_set:
args.timeout_seconds = min(self.settings.query_timeout_seconds, self.settings.max_request_timeout_seconds)
timeout_seconds = (
args.timeout_seconds if tool.computation or tool.mutating else self.settings.query_timeout_seconds
)
if (tool.computation or tool.mutating) and timeout_seconds > self.settings.max_calculation_timeout_seconds:
return tool_error("INVALID_QUERY", "Calculation timeout exceeds the server limit")
if (tool.computation or tool.mutating) and timeout_seconds > self.settings.max_request_timeout_seconds:
return tool_error("INVALID_QUERY", "HTTP request timeout exceeds the server limit")
request = ctx.request
project = request.headers.get("x-project-id", "") if request else ""
meta = ctx.meta or {}
@@ -349,7 +359,10 @@ class McpQueryApplication:
else:
from app.mcp.calculation_jobs import should_queue, submit_calculation
if should_queue(tool, args):
result = await submit_calculation(scope, binding, tool, args, call_id)
result = await submit_calculation(
scope, binding, tool, args, call_id,
job_timeout_seconds=self.settings.max_calculation_timeout_seconds,
)
else:
result = (
await self.executor(
@@ -463,6 +476,7 @@ class McpQueryApplication:
403: "QUERY_CONTEXT_DENIED",
404: "NOT_FOUND",
409: "QUERY_CONTEXT_STALE",
410: "RESULT_EXPIRED",
413: "RESULT_TOO_LARGE",
422: "INVALID_QUERY",
503: "SOURCE_UNAVAILABLE",
@@ -471,7 +485,7 @@ class McpQueryApplication:
codes.get(exc.status_code, "QUERY_FAILED"),
str(exc.detail)
if isinstance(exc.detail, str)
and exc.status_code in {403, 404, 409, 413, 422}
and exc.status_code in {403, 404, 409, 410, 413, 422}
else "Query is unavailable",
)
except (UndefinedTable, InvalidSchemaName):
@@ -480,7 +494,7 @@ class McpQueryApplication:
"MCP project storage has not been provisioned",
)
except TimeoutError:
return tool_error("QUERY_TIMEOUT", "Query execution timed out")
return tool_error("QUERY_TIMEOUT", "HTTP request timed out")
except ValueError:
return tool_error(
"INVALID_QUERY", "Invalid query value or incompatible source data"