fix: refactor 5 additional aliased output.args mutations + strengthen audit test
Address Oracle review feedback: refactor 4 aliased mutations via argsObject in plugin/tool-execute-before.ts and 1 via toolOutput in atlas/tool-execute-before.ts. Strengthen audit test regex to catch Output.args mutations regardless of the variable name prefix (toolOutput, argsObject aliases). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { log } from "../../shared/logger"
|
import { log } from "../../shared/logger"
|
||||||
|
import { replaceToolArgs } from "../../shared/replace-tool-args"
|
||||||
import { SYSTEM_DIRECTIVE_PREFIX } from "../../shared/system-directive"
|
import { SYSTEM_DIRECTIVE_PREFIX } from "../../shared/system-directive"
|
||||||
import { isCallerOrchestrator } from "../../shared/session-utils"
|
import { isCallerOrchestrator } from "../../shared/session-utils"
|
||||||
import type { PluginInput } from "@opencode-ai/plugin"
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
@@ -179,7 +180,7 @@ export function createToolExecuteBeforeHandler(input: {
|
|||||||
|
|
||||||
const prompt = toolOutput.args.prompt as string | undefined
|
const prompt = toolOutput.args.prompt as string | undefined
|
||||||
if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
|
if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
|
||||||
toolOutput.args.prompt = `<system-reminder>${SINGLE_TASK_DIRECTIVE}</system-reminder>\n` + prompt
|
replaceToolArgs(toolOutput, { prompt: `<system-reminder>${SINGLE_TASK_DIRECTIVE}</system-reminder>\n` + prompt })
|
||||||
log(`[${HOOK_NAME}] Injected single-task directive to task`, {
|
log(`[${HOOK_NAME}] Injected single-task directive to task`, {
|
||||||
sessionID: toolInput.sessionID,
|
sessionID: toolInput.sessionID,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -100,21 +100,20 @@ export function createToolExecuteBeforeHandler(args: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (input.tool === "task") {
|
if (input.tool === "task") {
|
||||||
const argsObject = output.args
|
const category = typeof output.args.category === "string" ? output.args.category : undefined
|
||||||
const category = typeof argsObject.category === "string" ? argsObject.category : undefined
|
const subagentType = typeof output.args.subagent_type === "string" ? output.args.subagent_type : undefined
|
||||||
const subagentType = typeof argsObject.subagent_type === "string" ? argsObject.subagent_type : undefined
|
const taskId = typeof output.args.task_id === "string" ? output.args.task_id : undefined
|
||||||
const taskId = typeof argsObject.task_id === "string" ? argsObject.task_id : undefined
|
|
||||||
|
|
||||||
if (category) {
|
if (category) {
|
||||||
argsObject.subagent_type = "sisyphus-junior"
|
replaceToolArgs(output, { subagent_type: "sisyphus-junior" })
|
||||||
} else if (!subagentType && taskId) {
|
} else if (!subagentType && taskId) {
|
||||||
const resolvedAgent = await resolveSessionAgent(ctx.client, taskId)
|
const resolvedAgent = await resolveSessionAgent(ctx.client, taskId)
|
||||||
argsObject.subagent_type = resolvedAgent ?? "continue"
|
replaceToolArgs(output, { subagent_type: resolvedAgent ?? "continue" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const normalizedSubagentType =
|
const normalizedSubagentType =
|
||||||
typeof argsObject.subagent_type === "string" ? stripInvisibleAgentCharacters(argsObject.subagent_type) : undefined
|
typeof output.args.subagent_type === "string" ? stripInvisibleAgentCharacters(output.args.subagent_type) : undefined
|
||||||
const prompt = typeof argsObject.prompt === "string" ? argsObject.prompt : ""
|
const prompt = typeof output.args.prompt === "string" ? output.args.prompt : ""
|
||||||
const loopState = typeof ctx.directory === "string" ? readState(ctx.directory) : null
|
const loopState = typeof ctx.directory === "string" ? readState(ctx.directory) : null
|
||||||
const shouldInjectOracleVerification =
|
const shouldInjectOracleVerification =
|
||||||
normalizedSubagentType === "oracle"
|
normalizedSubagentType === "oracle"
|
||||||
@@ -136,12 +135,14 @@ export function createToolExecuteBeforeHandler(args: {
|
|||||||
verification_attempt_id: verificationAttemptId,
|
verification_attempt_id: verificationAttemptId,
|
||||||
verification_session_id: undefined,
|
verification_session_id: undefined,
|
||||||
})
|
})
|
||||||
argsObject.run_in_background = false
|
replaceToolArgs(output, {
|
||||||
argsObject.prompt = buildUltraworkOracleVerificationPrompt(
|
run_in_background: false,
|
||||||
prompt,
|
prompt: buildUltraworkOracleVerificationPrompt(
|
||||||
loopState.prompt,
|
prompt,
|
||||||
verificationAttemptId,
|
loopState.prompt,
|
||||||
)
|
verificationAttemptId,
|
||||||
|
),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ async function collectTsFiles(dir: string): Promise<string[]> {
|
|||||||
|
|
||||||
const HELPER_FILE = "shared/replace-tool-args.ts"
|
const HELPER_FILE = "shared/replace-tool-args.ts"
|
||||||
|
|
||||||
const DIRECT_MUTATION_PATTERN = /output\.args\.\w+\s*=[^=]/g
|
// Matches direct mutations like `output.args.foo =` or `toolOutput.args.foo =`
|
||||||
const OBJECT_ASSIGN_PATTERN = /Object\.assign\(\s*output\.args/g
|
// but excludes comparisons (===, !==, ==)
|
||||||
|
const DIRECT_MUTATION_PATTERN = /\w*[Oo]utput\.args\.\w+\s*=[^=]/g
|
||||||
|
const OBJECT_ASSIGN_PATTERN = /Object\.assign\(\s*\w*[Oo]utput\.args/g
|
||||||
|
|
||||||
describe("replace-tool-args audit", () => {
|
describe("replace-tool-args audit", () => {
|
||||||
it("#given src/**/*.ts files #when scanning for direct output.args mutation #then no matches found outside the helper", async () => {
|
it("#given src/**/*.ts files #when scanning for direct output.args mutation #then no matches found outside the helper", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user