Compare commits

...
Author SHA1 Message Date
weichen 4abf13d33d Mirror the prompt module contract and add the library API
Why: the backend prompt library ships new contract shapes and an
endpoint; the frontend mirror and api binding keep the TS side in sync
for upcoming management UI.

Evidence: tsc + vite build green as part of composite make test.

Impact: contracts.ts gains PromptModule/Trigger and
AgentProfile.promptModules; api gains listPromptModules. No UI change
yet.

Refs: feature/prompt-library task card.
2026-09-30 10:35:13 +00:00
weichen 0eb9066510 Merge pull request 'feature/chat-live-quality: live streaming bubble, markdown spacing, document-task quality' (#9) from feature/chat-live-quality into main 2026-09-30 09:59:24 +00:00
2 changed files with 23 additions and 1 deletions
+2 -1
View File
@@ -3,7 +3,7 @@
import { auth } from './auth' import { auth } from './auth'
import type { import type {
Project, Conversation, Message, Run, Artifact, HITLCard, HITLResponse, Project, Conversation, Message, Run, Artifact, HITLCard, HITLResponse,
AgentProfile, SettingDesc, StreamEvent, PlanSnapshot, TodoList, UploadInfo, AgentProfile, SettingDesc, StreamEvent, PlanSnapshot, TodoList, UploadInfo, PromptModule,
ActivityCard, ActivityCard,
} from './contracts' } from './contracts'
@@ -67,6 +67,7 @@ export const api = {
getTodos: (convId: string) => auth.fetch(`${BASE}/api/conversations/${convId}/todos`).then(r => r.ok ? r.json() : null) as Promise<TodoList | null>, getTodos: (convId: string) => auth.fetch(`${BASE}/api/conversations/${convId}/todos`).then(r => r.ok ? r.json() : null) as Promise<TodoList | null>,
listProfiles: () => auth.fetch(`${BASE}/api/profiles`).then(r => json<AgentProfile[]>(r)), listProfiles: () => auth.fetch(`${BASE}/api/profiles`).then(r => json<AgentProfile[]>(r)),
listPromptModules: () => auth.fetch(`${BASE}/api/prompts`).then(r => json<PromptModule[]>(r)),
saveProfile: (p: AgentProfile) => auth.fetch(`${BASE}/api/profiles`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(p) }).then(r => { if (!r.ok) throw new Error(r.statusText); return r.json() }), saveProfile: (p: AgentProfile) => auth.fetch(`${BASE}/api/profiles`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(p) }).then(r => { if (!r.ok) throw new Error(r.statusText); return r.json() }),
deleteProfile: (id: string) => auth.fetch(`${BASE}/api/profiles/${id}`, { method: 'DELETE' }), deleteProfile: (id: string) => auth.fetch(`${BASE}/api/profiles/${id}`, { method: 'DELETE' }),
+21
View File
@@ -192,11 +192,32 @@ export interface UIField {
options?: string[]; required?: boolean; placeholder?: string; help?: string; default?: string; options?: string[]; required?: boolean; placeholder?: string; help?: string; default?: string;
} }
// ---- 提示词库(prompt-library)----
export interface PromptTrigger {
kind: 'intent' | 'command' | 'attachment' | 'manual';
keywords?: string[]; command?: string;
}
export interface PromptModule {
id: string; layer: 'base' | 'env' | 'task' | 'agent' | 'tool' | 'aux' | 'style';
version: number; title: string; description?: string; priority?: number;
triggers?: PromptTrigger[]; requiresAttachments?: boolean;
body: string; outputContract?: string;
source?: 'builtin' | 'plugin' | 'user'; owner?: string;
basedOnVersion?: number; drifted?: boolean; disabled?: boolean;
}
export interface PromptBlock { moduleId: string; version: number; layer: string; body: string; }
export interface PromptHitRecord { moduleId: string; layer: string; reason: string; injected: boolean; }
// ---- 画像 / 设置 ---- // ---- 画像 / 设置 ----
export interface AgentProfile { export interface AgentProfile {
id: string; owner?: string; name: string; description?: string; builtin?: boolean; source?: string; id: string; owner?: string; name: string; description?: string; builtin?: boolean; source?: string;
systemPrompt: string; systemPrompt: string;
/** 提示词库模块引用(有序;空 = 默认 base+env 全集)。 */
promptModules?: string[];
model: { chat?: string; lightweight?: string; embedding?: string; rerank?: string }; model: { chat?: string; lightweight?: string; embedding?: string; rerank?: string };
tools: { allow: string[]; deny?: string[]; confirm?: string[] }; tools: { allow: string[]; deny?: string[]; confirm?: string[] };
context: { context: {