feat: add SDK read paths for session-recovery parts/messages readers
This commit is contained in:
parent
1197f919af
commit
af8de2eaa2
@ -1,7 +1,9 @@
|
|||||||
export { generatePartId } from "./storage/part-id"
|
export { generatePartId } from "./storage/part-id"
|
||||||
export { getMessageDir } from "./storage/message-dir"
|
export { getMessageDir } from "./storage/message-dir"
|
||||||
export { readMessages } from "./storage/messages-reader"
|
export { readMessages } from "./storage/messages-reader"
|
||||||
|
export { readMessagesFromSDK } from "./storage/messages-reader"
|
||||||
export { readParts } from "./storage/parts-reader"
|
export { readParts } from "./storage/parts-reader"
|
||||||
|
export { readPartsFromSDK } from "./storage/parts-reader"
|
||||||
export { hasContent, messageHasContent } from "./storage/part-content"
|
export { hasContent, messageHasContent } from "./storage/part-content"
|
||||||
export { injectTextPart } from "./storage/text-part-injector"
|
export { injectTextPart } from "./storage/text-part-injector"
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,42 @@
|
|||||||
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
import type { StoredMessageMeta } from "../types"
|
import type { StoredMessageMeta } from "../types"
|
||||||
import { getMessageDir } from "./message-dir"
|
import { getMessageDir } from "./message-dir"
|
||||||
|
import { isSqliteBackend } from "../../../shared"
|
||||||
|
|
||||||
|
type OpencodeClient = PluginInput["client"]
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeSDKMessage(
|
||||||
|
sessionID: string,
|
||||||
|
value: unknown
|
||||||
|
): StoredMessageMeta | null {
|
||||||
|
if (!isRecord(value)) return null
|
||||||
|
if (typeof value.id !== "string") return null
|
||||||
|
|
||||||
|
const roleValue = value.role
|
||||||
|
const role: StoredMessageMeta["role"] = roleValue === "assistant" ? "assistant" : "user"
|
||||||
|
|
||||||
|
const created =
|
||||||
|
isRecord(value.time) && typeof value.time.created === "number"
|
||||||
|
? value.time.created
|
||||||
|
: 0
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: value.id,
|
||||||
|
sessionID,
|
||||||
|
role,
|
||||||
|
time: { created },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function readMessages(sessionID: string): StoredMessageMeta[] {
|
export function readMessages(sessionID: string): StoredMessageMeta[] {
|
||||||
|
if (isSqliteBackend()) return []
|
||||||
|
|
||||||
const messageDir = getMessageDir(sessionID)
|
const messageDir = getMessageDir(sessionID)
|
||||||
if (!messageDir || !existsSync(messageDir)) return []
|
if (!messageDir || !existsSync(messageDir)) return []
|
||||||
|
|
||||||
@ -25,3 +58,27 @@ export function readMessages(sessionID: string): StoredMessageMeta[] {
|
|||||||
return a.id.localeCompare(b.id)
|
return a.id.localeCompare(b.id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function readMessagesFromSDK(
|
||||||
|
client: OpencodeClient,
|
||||||
|
sessionID: string
|
||||||
|
): Promise<StoredMessageMeta[]> {
|
||||||
|
try {
|
||||||
|
const response = await client.session.messages({ path: { id: sessionID } })
|
||||||
|
const data: unknown = response.data
|
||||||
|
if (!Array.isArray(data)) return []
|
||||||
|
|
||||||
|
const messages = data
|
||||||
|
.map((msg): StoredMessageMeta | null => normalizeSDKMessage(sessionID, msg))
|
||||||
|
.filter((msg): msg is StoredMessageMeta => msg !== null)
|
||||||
|
|
||||||
|
return messages.sort((a, b) => {
|
||||||
|
const aTime = a.time?.created ?? 0
|
||||||
|
const bTime = b.time?.created ?? 0
|
||||||
|
if (aTime !== bTime) return aTime - bTime
|
||||||
|
return a.id.localeCompare(b.id)
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,29 @@
|
|||||||
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
import { PART_STORAGE } from "../constants"
|
import { PART_STORAGE } from "../constants"
|
||||||
import type { StoredPart } from "../types"
|
import type { StoredPart } from "../types"
|
||||||
|
import { isSqliteBackend } from "../../../shared"
|
||||||
|
|
||||||
|
type OpencodeClient = PluginInput["client"]
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null
|
||||||
|
}
|
||||||
|
|
||||||
|
function isStoredPart(value: unknown): value is StoredPart {
|
||||||
|
if (!isRecord(value)) return false
|
||||||
|
return (
|
||||||
|
typeof value.id === "string" &&
|
||||||
|
typeof value.sessionID === "string" &&
|
||||||
|
typeof value.messageID === "string" &&
|
||||||
|
typeof value.type === "string"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function readParts(messageID: string): StoredPart[] {
|
export function readParts(messageID: string): StoredPart[] {
|
||||||
|
if (isSqliteBackend()) return []
|
||||||
|
|
||||||
const partDir = join(PART_STORAGE, messageID)
|
const partDir = join(PART_STORAGE, messageID)
|
||||||
if (!existsSync(partDir)) return []
|
if (!existsSync(partDir)) return []
|
||||||
|
|
||||||
@ -20,3 +40,25 @@ export function readParts(messageID: string): StoredPart[] {
|
|||||||
|
|
||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function readPartsFromSDK(
|
||||||
|
client: OpencodeClient,
|
||||||
|
sessionID: string,
|
||||||
|
messageID: string
|
||||||
|
): Promise<StoredPart[]> {
|
||||||
|
try {
|
||||||
|
const response = await client.session.message({
|
||||||
|
path: { id: sessionID, messageID },
|
||||||
|
})
|
||||||
|
|
||||||
|
const data: unknown = response.data
|
||||||
|
if (!isRecord(data)) return []
|
||||||
|
|
||||||
|
const rawParts = data.parts
|
||||||
|
if (!Array.isArray(rawParts)) return []
|
||||||
|
|
||||||
|
return rawParts.filter(isStoredPart)
|
||||||
|
} catch {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user