fix(ai-context): include local tasks in prompt injection

This commit is contained in:
2026-04-07 00:56:50 +08:00
parent 1564d2dd30
commit 45b149ad58
5 changed files with 299 additions and 39 deletions
+22 -1
View File
@@ -17,6 +17,7 @@ import {
type WebAiBindingSummary,
type WebAiBindingsResponse,
type WebAiChannel,
type WebAiLocalTaskContextItem,
WebAiApiError
} from "@/services/ai-api";
import {
@@ -25,6 +26,7 @@ import {
saveLocalAiChatSession,
type LocalAiChatMessageRecord
} from "@/services/local-ai-chat-repo";
import { listLocalTasksByUser } from "@/services/local-task-repo";
import type { WebSession } from "@/services/session-storage";
import { CHANNEL_META, CHANNEL_ORDER } from "@/components/ai/ai-shared";
@@ -64,6 +66,23 @@ function appendMessage(
};
}
function buildLocalTaskContext(
items: Awaited<ReturnType<typeof listLocalTasksByUser>>
): WebAiLocalTaskContextItem[] {
return items
.filter((item) => item.status === "TODO" || item.status === "IN_PROGRESS")
.slice(0, 20)
.map((item) => ({
id: item.id,
title: item.title,
priority: item.priority,
status: item.status,
ddlAt: item.ddlAt,
contentText: item.contentText,
updatedAt: item.updatedAt
}));
}
export function AiChatPage({ session }: AiChatPageProps) {
const navigate = useNavigate();
const [bindingsResponse, setBindingsResponse] = useState<WebAiBindingsResponse | null>(null);
@@ -224,10 +243,12 @@ export function AiChatPage({ session }: AiChatPageProps) {
);
try {
const localTasks = buildLocalTaskContext(await listLocalTasksByUser(session.user.id));
const response = await chatWithAi(session, {
channel,
message,
sessionId: sessionIds[channel]
sessionId: sessionIds[channel],
localTasks
});
setSessionIds((current) => ({
+12 -2
View File
@@ -56,6 +56,16 @@ export type WebAiChatResponse = {
attempts: WebAiRouteAttempt[];
};
export type WebAiLocalTaskContextItem = {
id: string;
title: string;
priority: "LOW" | "MEDIUM" | "HIGH" | "URGENT";
status: "TODO" | "IN_PROGRESS" | "DONE" | "ARCHIVED";
ddlAt: number | null;
contentText: string | null;
updatedAt: number;
};
export class WebAiApiError extends Error {
attempts: WebAiRouteAttempt[] | null;
@@ -92,7 +102,7 @@ async function createApiError(response: Response): Promise<WebAiApiError> {
attempts?: WebAiRouteAttempt[];
};
const message = Array.isArray(body.message)
? body.message.join("")
? body.message.join("")
: typeof body.message === "string" && body.message.trim().length > 0
? body.message
: `请求失败(${response.status}`;
@@ -101,7 +111,6 @@ async function createApiError(response: Response): Promise<WebAiApiError> {
return new WebAiApiError(`请求失败(${response.status}`);
}
}
export async function listAiBindings(session: WebSession): Promise<WebAiBindingsResponse> {
const response = await fetch(`${resolveApiBaseUrl()}/ai/bindings`, {
method: "GET",
@@ -138,6 +147,7 @@ export async function chatWithAi(
channel: WebAiChannel;
message: string;
sessionId?: string;
localTasks?: WebAiLocalTaskContextItem[];
}
): Promise<WebAiChatResponse> {
const response = await fetch(`${resolveApiBaseUrl()}/ai/chat`, {