feat(coding-agent): added Auto QA tool and Python environment warmup for tool reliability

- Added Auto QA tool (`report_tool_issue`) for automated tracking of unexpected tool behavior with environment variable and setting support.
- Added Python tool environment warmup on first execution to ensure prelude helpers are available before use.
- Fixed Python prelude introspection to respect execution timeout and signal options, preventing hangs.
- Refactored prelude documentation caching and loading logic into reusable helper functions with test environment awareness.
- Enhanced kernel introspection with optional timeout and signal parameters for better execution control.
- Added system prompt guidance to encourage agents to report tool issues via Auto QA when available.
This commit is contained in:
can1357
2026-04-08 11:49:13 +02:00
parent 4058582a5a
commit 4c03bad90d
20 changed files with 385 additions and 141 deletions
+17 -3
View File
@@ -7,7 +7,7 @@ import { Markdown, Text } from "@oh-my-pi/pi-tui";
import { getProjectDir, prompt } from "@oh-my-pi/pi-utils";
import { type Static, Type } from "@sinclair/typebox";
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
import { executePython, getPreludeDocs, type PythonExecutorOptions } from "../ipy/executor";
import { executePython, getPreludeDocs, type PythonExecutorOptions, warmPythonEnvironment } from "../ipy/executor";
import type { PreludeHelper, PythonStatusEvent } from "../ipy/kernel";
import { truncateToVisualLines } from "../modes/components/visual-truncate";
import { getMarkdownTheme, type Theme } from "../modes/theme/theme";
@@ -145,7 +145,9 @@ export interface PythonToolOptions {
export class PythonTool implements AgentTool<typeof pythonSchema> {
readonly name = "python";
readonly label = "Python";
readonly description: string;
get description(): string {
return getPythonToolDescription();
}
readonly parameters = pythonSchema;
readonly concurrency = "exclusive";
readonly strict = true;
@@ -157,7 +159,6 @@ export class PythonTool implements AgentTool<typeof pythonSchema> {
options?: PythonToolOptions,
) {
this.#proxyExecutor = options?.proxyExecutor;
this.description = getPythonToolDescription();
}
async execute(
@@ -265,6 +266,19 @@ export class PythonTool implements AgentTool<typeof pythonSchema> {
},
});
const sessionId = sessionFile ? `session:${sessionFile}:cwd:${commandCwd}` : `cwd:${commandCwd}`;
if (getPreludeDocs().length === 0) {
const warmup = await warmPythonEnvironment(
commandCwd,
sessionId,
this.session.settings.get("python.sharedGateway"),
sessionFile ?? undefined,
);
if (!warmup.ok) {
throw new ToolError(warmup.reason ?? "Python prelude helpers unavailable");
}
}
const baseExecutorOptions: Omit<PythonExecutorOptions, "reset"> = {
cwd: commandCwd,
deadlineMs,