fix(athena): address 11 audit findings (H2,H3,H5,M1-M4,M8-M11)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -140,13 +140,13 @@ describe("hasCouncilResponseTag", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given assistant message contains the response tag", () => {
|
||||
describe("#given assistant message contains a complete council response", () => {
|
||||
it("#then should return true", () => {
|
||||
//#given
|
||||
const messages = [
|
||||
{
|
||||
info: { role: "assistant" },
|
||||
parts: [{ type: "text", text: "My analysis </COUNCIL_MEMBER_RESPONSE>" }],
|
||||
parts: [{ type: "text", text: "<COUNCIL_MEMBER_RESPONSE>This is a comprehensive analysis of the council member findings. The investigation reveals multiple significant patterns across the entire codebase that require careful refactoring.</COUNCIL_MEMBER_RESPONSE>" }],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -170,7 +170,7 @@ describe("hasCouncilResponseTag", () => {
|
||||
},
|
||||
{
|
||||
info: { role: "assistant" },
|
||||
parts: [{ type: "text", text: "final answer </COUNCIL_MEMBER_RESPONSE>" }],
|
||||
parts: [{ type: "text", text: "<COUNCIL_MEMBER_RESPONSE>This is a comprehensive analysis of the council member findings. The investigation reveals multiple significant patterns across the entire codebase that require careful refactoring.</COUNCIL_MEMBER_RESPONSE>" }],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -6,12 +6,11 @@ import {
|
||||
createInternalAgentTextPart,
|
||||
} from "../../shared"
|
||||
import { setSessionTools } from "../../shared/session-tools-store"
|
||||
import { extractCouncilResponse } from "../../tools/council-archive/council-response-extractor"
|
||||
import { COUNCIL_MEMBER_KEY_PREFIX } from "../../agents/builtin-agents/council-member-agents"
|
||||
|
||||
type OpencodeClient = PluginInput["client"]
|
||||
|
||||
const COUNCIL_RESPONSE_TAG = "</COUNCIL_MEMBER_RESPONSE>"
|
||||
|
||||
const CONTINUATION_PROMPT =
|
||||
"You have not yet produced your final <COUNCIL_MEMBER_RESPONSE>. Continue your analysis and wrap your findings in <COUNCIL_MEMBER_RESPONSE> tags. If you are waiting for background tasks, use background_wait to block until they complete, then produce your response."
|
||||
|
||||
@@ -28,17 +27,18 @@ export function resetCouncilNudgeCount(taskId: string): void {
|
||||
}
|
||||
|
||||
export function hasCouncilResponseTag(sessionMessages: Array<{ info?: { role?: string }; parts?: Array<{ type?: string; text?: string }> }>): boolean {
|
||||
for (let i = sessionMessages.length - 1; i >= 0; i--) {
|
||||
const msg = sessionMessages[i]
|
||||
const assistantTexts: string[] = []
|
||||
for (const msg of sessionMessages) {
|
||||
if (msg.info?.role !== "assistant") continue
|
||||
const parts = msg.parts ?? []
|
||||
for (const part of parts) {
|
||||
if (part.type === "text" && part.text?.includes(COUNCIL_RESPONSE_TAG)) {
|
||||
return true
|
||||
for (const part of msg.parts ?? []) {
|
||||
if (part.type === "text" && part.text) {
|
||||
assistantTexts.push(part.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
if (assistantTexts.length === 0) return false
|
||||
const extraction = extractCouncilResponse(assistantTexts.join("\n"))
|
||||
return extraction.has_response && extraction.response_complete
|
||||
}
|
||||
|
||||
export function sendCouncilContinuationNudge(
|
||||
|
||||
@@ -13,13 +13,13 @@ function createMockClient(
|
||||
}
|
||||
|
||||
describe("sessionHasCouncilResponse", () => {
|
||||
describe("#given assistant message with closing council tag", () => {
|
||||
describe("#given assistant message with complete council response", () => {
|
||||
it("#when tag is in text part #then should return true", async () => {
|
||||
//#given
|
||||
const client = createMockClient([
|
||||
{
|
||||
info: { role: "assistant" },
|
||||
parts: [{ type: "text", text: "Some response</COUNCIL_MEMBER_RESPONSE>" }],
|
||||
parts: [{ type: "text", text: "<COUNCIL_MEMBER_RESPONSE>This is a comprehensive analysis of the council member findings. The investigation reveals multiple significant patterns across the entire codebase that require careful refactoring.</COUNCIL_MEMBER_RESPONSE>" }],
|
||||
},
|
||||
])
|
||||
|
||||
@@ -102,7 +102,7 @@ describe("sessionHasCouncilResponse", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given assistant message with tag buried in longer text", () => {
|
||||
describe("#given assistant message with complete council response in longer text", () => {
|
||||
it("#when tag appears mid-text #then should return true", async () => {
|
||||
//#given
|
||||
const client = createMockClient([
|
||||
@@ -111,7 +111,7 @@ describe("sessionHasCouncilResponse", () => {
|
||||
parts: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Here is my analysis of the situation.\n\nLong content here.\n\n</COUNCIL_MEMBER_RESPONSE>\n\nMore text after.",
|
||||
text: "Here is my analysis. <COUNCIL_MEMBER_RESPONSE>This is a comprehensive analysis of the council member findings. The investigation reveals multiple significant patterns across the entire codebase that require careful refactoring.</COUNCIL_MEMBER_RESPONSE> More text after.",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import { log, normalizeSDKResponse } from "../../shared"
|
||||
import { hasCouncilResponseTag } from "./council-continuation-enforcer"
|
||||
|
||||
type OpencodeClient = PluginInput["client"]
|
||||
|
||||
const COUNCIL_RESPONSE_TAG = "</COUNCIL_MEMBER_RESPONSE>"
|
||||
|
||||
export async function sessionHasCouncilResponse(
|
||||
client: OpencodeClient,
|
||||
sessionID: string,
|
||||
@@ -20,18 +19,7 @@ export async function sessionHasCouncilResponse(
|
||||
{ preferResponseOnMissingData: true },
|
||||
)
|
||||
|
||||
for (let i = messages.length - 1; i >= 0; i--) {
|
||||
const msg = messages[i]
|
||||
if (msg.info?.role !== "assistant") continue
|
||||
const parts = msg.parts ?? []
|
||||
for (const part of parts) {
|
||||
if (part.type === "text" && part.text?.includes(COUNCIL_RESPONSE_TAG)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return hasCouncilResponseTag(messages)
|
||||
} catch (error) {
|
||||
log("[council-response-checker] Error checking session for response tag:", {
|
||||
sessionID,
|
||||
|
||||
Reference in New Issue
Block a user