import { Session } from "@/session/session"
import { SessionID, MessageID, PartID } from "./schema"
import { Effect } from "effect"
import * as Log from "@opencode-ai/core/util/log"
import { KNOWLEDGE_TOOL_ID } from "@/tool/oh_knowledge.ts"
const log = Log.create({service: "knowledge"})
type OhKnowledgeResult = {
title: string
output: string
metadata: Record<string, any>
}
type OhKnowledgeState = {
result: OhKnowledgeResult | null
callID: string | null
userInput: string
pending: boolean
}
const state: OhKnowledgeState = {
result: null,
callID: null,
userInput: "",
pending: false,
}
export namespace OhKnowledgeAsync {
export function trigger(
userInput: string,
callId: string,
execute: () => Promise<OhKnowledgeResult>
): void {
state.result = null
state.callID = callId
state.userInput = userInput
state.pending = true
execute()
.then((result) => {
if (result?.output && result.output.trim() && result.output !== "No answer found for question") {
state.result = result
}
state.pending = false
})
.catch((err) => {
log.error("oh_knowledge async error:", { err })
state.pending = false
})
}
export function inject(
sessions: Session.Interface,
sessionID: SessionID,
messageID: MessageID
): Effect.Effect<void> {
return Effect.gen(function* () {
if (!state.result || !state.callID || state.result.output === "No answer found for question") return
log.info("knowledge inject start success")
yield* sessions.updatePart({
id: PartID.ascending(),
sessionID,
messageID,
type: "tool",
tool: KNOWLEDGE_TOOL_ID,
callID: state.callID,
state: {
status: "completed",
input: { question: state.userInput },
output: state.result.output,
title: state.result.title,
metadata: state.result.metadata,
time: {
start: Date.now(),
end: Date.now(),
},
},
})
state.result = null
state.callID = null
state.pending = false
})
}
export function reset(): void {
state.result = null
state.callID = null
state.userInput = ""
state.pending = false
}
}