代码提交

This commit is contained in:
董宏凯 committed 2026-05-15 14:08:01 +08:00
1 parent b81f64a253
commit 050b1ad78e
45 files changed
+5011 -2694

No files matched your search

@@ -0,0 +1 @@
export { getAPIClient } from "@/core/api";
@@ -0,0 +1,37 @@
import { apiFetch } from "@/core/api";
import { getBackendBaseURL } from "@/core/config";
import type { CanvasModel } from "../types/model";
interface BackendModel {
name: string;
display_name?: string;
provider?: string;
is_local?: boolean;
supports_vision?: boolean;
supports_thinking?: boolean;
supports_reasoning_effort?: boolean;
supports_tool_calling?: boolean;
}
export async function loadCanvasModels(): Promise<CanvasModel[]> {
const res = await apiFetch(`${getBackendBaseURL()}/api/models`);
const data = (await res.json()) as { models?: BackendModel[] };
return (data.models ?? []).map(
(m): CanvasModel => ({
name: m.name,
display_name: m.display_name ?? m.name,
provider: m.provider,
is_local: m.is_local,
supports_vision: m.supports_vision,
supports_thinking: m.supports_thinking,
supports_reasoning_effort: m.supports_reasoning_effort,
supports_tool_calling: m.supports_tool_calling ?? true,
supports_canvas_generation: true,
supports_canvas_rewrite: true,
supports_canvas_code_edit: true,
supports_streaming_text: true,
supports_streaming_tool_calls: m.supports_tool_calling ?? true,
}),
);
}
+62
View File
@@ -0,0 +1,62 @@
import { getAPIClient } from "@/core/api";
import { CANVAS_AGENT_ID } from "../constants";
import type { CanvasArtifact } from "../types/artifact";
import type { CanvasMessage } from "../types/thread";
export type CanvasRunInput = {
messages: Array<{ type: string; content: string }>;
canvas_mode?: "text" | "code";
highlighted_text?: string;
highlighted_code?: string;
quick_action_id?: string;
};
export type CanvasStreamCallbacks = {
onMessage?: (msg: CanvasMessage) => void;
onArtifact?: (artifact: CanvasArtifact) => void;
onDone?: () => void;
onError?: (err: unknown) => void;
};
export async function streamCanvasRun(
threadId: string,
input: CanvasRunInput,
callbacks: CanvasStreamCallbacks,
): Promise<void> {
const client = getAPIClient();
try {
const stream = client.runs.stream(threadId, CANVAS_AGENT_ID, {
input,
streamMode: ["values", "messages-tuple"],
});
for await (const chunk of stream) {
// Cast to string: SDK typings only list a subset of event names
const event = chunk.event as string;
const data = (chunk as { event: string; data: unknown }).data;
if (event === "values") {
const state = data as Record<string, unknown>;
if (state.artifact) {
callbacks.onArtifact?.(state.artifact as CanvasArtifact);
}
} else if (event === "messages/tuple") {
const [msg] = data as [CanvasMessage];
if (msg) {
callbacks.onMessage?.(msg);
}
}
}
callbacks.onDone?.();
} catch (err) {
callbacks.onError?.(err);
}
}
export async function stopCanvasRun(
threadId: string,
runId: string,
): Promise<void> {
const client = getAPIClient();
await client.runs.cancel(threadId, runId);
}
@@ -0,0 +1,35 @@
import { getAPIClient } from "@/core/api";
import { CANVAS_THREAD_METADATA } from "../constants";
import type { CanvasThreadMetadata, CanvasThreadValues } from "../types/thread";
export async function createCanvasThread(
metadata?: Partial<CanvasThreadMetadata>,
): Promise<string> {
const client = getAPIClient();
const thread = await client.threads.create({
metadata: { ...CANVAS_THREAD_METADATA, ...metadata },
});
return thread.thread_id;
}
export async function getCanvasThread(
threadId: string,
): Promise<CanvasThreadValues | null> {
const client = getAPIClient();
try {
const state =
await client.threads.getState<CanvasThreadValues>(threadId);
return (state.values as CanvasThreadValues) ?? null;
} catch {
return null;
}
}
export async function updateCanvasThreadState(
threadId: string,
values: Partial<CanvasThreadValues>,
): Promise<void> {
const client = getAPIClient();
await client.threads.updateState(threadId, { values });
}