import { callQiaoqiaoAgentApi, callQiaoqiaoBackendApi, unwrapQiaoqiaoApiPayload, } from "../tools-common/qiaoqiao-api.js"; import type { ResolvedQiaoqiaoAccount } from "../types.js"; import type { QiaoqiaoMemoryParams } from "./schemas.js"; type BehaviorLogsResponse = { logs?: unknown[]; hasMore?: boolean; total?: number; }; function buildMemoryPath(path: string): string { return path.startsWith("/") ? path : `/${path}`; } function withQuery(path: string, query: URLSearchParams): string { const suffix = query.toString(); return suffix ? `${path}?${suffix}` : path; } export async function runMemoryAction( account: ResolvedQiaoqiaoAccount, params: QiaoqiaoMemoryParams, ): Promise { const accountConfig = account.config as { apiBase?: string }; const apiBase = accountConfig.apiBase; if (params.action === "list") { const query = new URLSearchParams(); if (params.category && params.category !== "all") { query.set("category", params.category); } const data = await callQiaoqiaoAgentApi({ method: "GET", path: withQuery(buildMemoryPath("/memories/me"), query), appId: account.appId!, appSecret: account.appSecret!, apiBase, }); return { ok: true, action: "list", total: data.length, memories: data }; } if (params.action === "behavior_logs") { const query = new URLSearchParams(); if (params.from?.trim()) query.set("from", params.from.trim()); if (params.to?.trim()) query.set("to", params.to.trim()); if (Number.isFinite(params.limit)) query.set("limit", String(params.limit)); const data = await callQiaoqiaoAgentApi({ method: "GET", path: withQuery(buildMemoryPath("/memories/me/behavior-logs"), query), appId: account.appId!, appSecret: account.appSecret!, apiBase, }); return { ok: true, action: "behavior_logs", total: Number(data.total ?? (Array.isArray(data.logs) ? data.logs.length : 0)), hasMore: Boolean(data.hasMore), logs: data.logs ?? [], }; } if (params.action === "create") { const content = String(params.content || "").trim(); if (!params.category || !content) { throw new Error("category and content are required for create"); } const data = await callQiaoqiaoAgentApi({ method: "POST", path: "/memories/me", appId: account.appId!, appSecret: account.appSecret!, apiBase, body: { category: params.category, content, title: params.title, isPrivate: params.isPrivate, status: params.status, isTemporary: params.isTemporary, temporaryDays: params.temporaryDays, expiresAt: params.expiresAt, }, }); return { ok: true, action: "create", memory: data }; } if (params.action === "update") { const memoryId = String(params.memoryId || "").trim(); if (!memoryId) { throw new Error("memoryId is required for update"); } const payload: Record = {}; if (params.title !== undefined) payload.title = params.title; if (params.category !== undefined) payload.category = params.category; if (params.content !== undefined) payload.content = params.content; if (params.isPrivate !== undefined) payload.isPrivate = params.isPrivate; if (params.status !== undefined) payload.status = params.status; if (params.expiresAt !== undefined) payload.expiresAt = params.expiresAt; // Agent-specific memories routes do not expose update/delete yet. // Reuse the shared memory endpoints, which still honor X-App-ID/X-App-Secret // and map `me` to the bound parent user. const data = unwrapQiaoqiaoApiPayload(await callQiaoqiaoBackendApi({ method: "PUT", path: `/memories/me/${memoryId}`, appId: account.appId!, appSecret: account.appSecret!, apiBase, body: payload, })); return { ok: true, action: "update", memory: data }; } if (params.action === "accept") { const memoryId = String(params.memoryId || "").trim(); if (!memoryId) { throw new Error("memoryId is required for accept"); } const payload: Record = {}; if (params.title !== undefined) payload.title = params.title; if (params.category !== undefined) payload.category = params.category; if (params.content !== undefined) payload.content = params.content; if (params.isPrivate !== undefined) payload.isPrivate = params.isPrivate; const memory = unwrapQiaoqiaoApiPayload(await callQiaoqiaoBackendApi({ method: "POST", path: `/memories/me/${memoryId}/accept`, appId: account.appId!, appSecret: account.appSecret!, apiBase, body: payload, })); return { ok: true, action: "accept", memory }; } if (params.action === "reject") { const memoryId = String(params.memoryId || "").trim(); if (!memoryId) { throw new Error("memoryId is required for reject"); } const memory = unwrapQiaoqiaoApiPayload(await callQiaoqiaoBackendApi({ method: "POST", path: `/memories/me/${memoryId}/reject`, appId: account.appId!, appSecret: account.appSecret!, apiBase, })); return { ok: true, action: "reject", memory }; } const memoryId = String(params.memoryId || "").trim(); if (!memoryId) { throw new Error("memoryId is required for delete"); } const data = unwrapQiaoqiaoApiPayload(await callQiaoqiaoBackendApi({ method: "DELETE", path: `/memories/me/${memoryId}`, appId: account.appId!, appSecret: account.appSecret!, apiBase, })); return { ok: true, action: "delete", data }; }