fix(plugin): harden metadata recovery and extraction

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-16 13:52:12 +09:00
parent 80d3339c4c
commit 4da3005797
7 changed files with 158 additions and 75 deletions
@@ -90,6 +90,17 @@ describe("extractSessionIdFromMetadata", () => {
expect(result).toBe("ses_plugin_abc123")
})
test("extracts legacy session aliases from tool metadata object", () => {
// given
const metadata = { sessionID: "ses_plugin_alias_123" }
// when
const result = extractSessionIdFromMetadata(metadata)
// then
expect(result).toBe("ses_plugin_alias_123")
})
test("returns undefined for metadata without sessionId", () => {
// given
const metadata = { title: "some task" }
+6 -16
View File
@@ -1,30 +1,20 @@
import type { PluginInput } from "@opencode-ai/plugin"
import { extractTaskLink } from "../../features/tool-metadata-store"
import { log } from "../../shared/logger"
import { isSessionInBoulderLineage } from "./boulder-session-lineage"
import { HOOK_NAME } from "./hook-name"
export function extractSessionIdFromMetadata(metadata: unknown): string | undefined {
if (metadata && typeof metadata === "object" && "sessionId" in metadata) {
const value = (metadata as Record<string, unknown>).sessionId
if (typeof value === "string" && value.startsWith("ses_")) {
return value
}
const sessionId = extractTaskLink(metadata, "").sessionId
if (typeof sessionId === "string" && sessionId.startsWith("ses_")) {
return sessionId
}
return undefined
}
export function extractSessionIdFromOutput(output: string): string | undefined {
const taskMetadataBlocks = [...output.matchAll(/<task_metadata>([\s\S]*?)<\/task_metadata>/gi)]
const lastTaskMetadataBlock = taskMetadataBlocks.at(-1)?.[1]
if (lastTaskMetadataBlock) {
const taskMetadataSessionMatch = lastTaskMetadataBlock.match(/session_id:\s*(ses_[a-zA-Z0-9_-]+)/i)
if (taskMetadataSessionMatch) {
return taskMetadataSessionMatch[1]
}
}
const explicitSessionMatches = [...output.matchAll(/Session ID:\s*(ses_[a-zA-Z0-9_-]+)/g)]
return explicitSessionMatches.at(-1)?.[1]
return extractTaskLink(undefined, output).sessionId
}
export async function validateSubagentSessionId(input: {