dsh-prompt-refine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +93 -0
- package/cordis.patch.yml +8 -0
- package/lib/client.iife.js +518 -0
- package/lib/index.mjs +272 -0
- package/package.json +57 -0
- package/scripts/install.mjs +97 -0
- package/src/client.ts +387 -0
- package/src/dsh-prompt-refine.ts +24 -0
- package/src/host.ts +239 -0
- package/src/shared/prompt.ts +73 -0
- package/src/shared/types.ts +38 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// shared/prompt.ts —— 优化器 system prompt + JSON 提取
|
|
2
|
+
//
|
|
3
|
+
// MVP 阶段:用同一段提示词让 LLM 返回 3 条建议。系统提示明确要求
|
|
4
|
+
// 输出 JSON 格式。LLM 不总是严格遵守 → 我们做多策略解析兜底。
|
|
5
|
+
|
|
6
|
+
/** 优化器 system prompt —— 关键是要 LLM 返回可被 JSON.parse 的结构 */
|
|
7
|
+
export const SYSTEM_PROMPT = `你是一个提示词优化助手。用户给你:
|
|
8
|
+
1. 一段最近的对话历史(可能为空)
|
|
9
|
+
2. 用户即将发送的最新草稿
|
|
10
|
+
|
|
11
|
+
你的任务:分析草稿的不足,给出恰好 3 条改进建议。每条建议 = 一个「问题标签」+「问题描述」+「具体补丁」。
|
|
12
|
+
|
|
13
|
+
要求:
|
|
14
|
+
- 只输出合法 JSON,不要任何额外文字、不要 markdown 代码块标记
|
|
15
|
+
- patch 必须是可以直接追加到原草稿末尾或合适位置的一句话,长度 5-50 字
|
|
16
|
+
- 优先指出:范围不清、缺少输出格式、缺少约束条件、模糊指代
|
|
17
|
+
- 不要重写整个草稿,只补漏
|
|
18
|
+
- 如果草稿已经足够好,issue 里如实写「无需修改」,patch 留空
|
|
19
|
+
|
|
20
|
+
输出 schema(严格遵守):
|
|
21
|
+
{"suggestions": [{"tag": "scope|format|constraint|clarity|other", "issue": "一句话问题", "patch": "一句话补丁"}, ...共 3 条]}
|
|
22
|
+
` as const
|
|
23
|
+
|
|
24
|
+
/** 用户消息模板:把 history + draft 装进 user message */
|
|
25
|
+
export function buildUserMessage(history: readonly { role: string; content: string }[], draft: string): string {
|
|
26
|
+
const lines: string[] = []
|
|
27
|
+
if (history.length > 0) {
|
|
28
|
+
lines.push('【最近对话历史】')
|
|
29
|
+
for (const m of history) {
|
|
30
|
+
lines.push(`${m.role === 'user' ? '用户' : '助手'}: ${m.content}`)
|
|
31
|
+
}
|
|
32
|
+
lines.push('')
|
|
33
|
+
}
|
|
34
|
+
lines.push('【用户当前草稿】')
|
|
35
|
+
lines.push(draft)
|
|
36
|
+
lines.push('')
|
|
37
|
+
lines.push('请按 system 要求输出 JSON。')
|
|
38
|
+
return lines.join('\n')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 从 LLM 输出里提取 JSON。
|
|
43
|
+
* 策略:
|
|
44
|
+
* 1. 去掉可能的 markdown ```json``` 包裹
|
|
45
|
+
* 2. 找到第一个 { 到最后一个 } 的子串,parse
|
|
46
|
+
* 3. parse 失败抛错(调用方会回退)
|
|
47
|
+
*/
|
|
48
|
+
export function parseSuggestions(raw: string): { tag: string; issue: string; patch: string }[] {
|
|
49
|
+
// 去 markdown fence
|
|
50
|
+
let s = raw.trim()
|
|
51
|
+
s = s.replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/, '')
|
|
52
|
+
// 找 JSON 边界
|
|
53
|
+
const first = s.indexOf('{')
|
|
54
|
+
const last = s.lastIndexOf('}')
|
|
55
|
+
if (first < 0 || last <= first) {
|
|
56
|
+
throw new Error('LLM 输出不含 JSON 对象')
|
|
57
|
+
}
|
|
58
|
+
const json = s.slice(first, last + 1)
|
|
59
|
+
const obj = JSON.parse(json) as { suggestions?: unknown }
|
|
60
|
+
const arr = obj.suggestions
|
|
61
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
62
|
+
throw new Error('JSON 里没有 suggestions 数组')
|
|
63
|
+
}
|
|
64
|
+
// 规范化每条
|
|
65
|
+
return arr.slice(0, 3).map((raw, i) => {
|
|
66
|
+
const x = (raw && typeof raw === 'object' ? raw : {}) as Record<string, unknown>
|
|
67
|
+
return {
|
|
68
|
+
tag: typeof x.tag === 'string' ? x.tag : 'other',
|
|
69
|
+
issue: typeof x.issue === 'string' ? x.issue : `建议 #${i + 1}`,
|
|
70
|
+
patch: typeof x.patch === 'string' ? x.patch : '',
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// shared/types.ts —— client 和 host 共享的数据形状
|
|
2
|
+
|
|
3
|
+
/** 历史中的一条消息 */
|
|
4
|
+
export interface HistoryMessage {
|
|
5
|
+
role: 'user' | 'assistant'
|
|
6
|
+
content: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** 客户端 → 服务端的请求 */
|
|
10
|
+
export interface SuggestRequest {
|
|
11
|
+
/** 用户当前输入框里的草稿 */
|
|
12
|
+
draft: string
|
|
13
|
+
/** 最近 N 条历史(已截断) */
|
|
14
|
+
history: readonly HistoryMessage[]
|
|
15
|
+
/** 可选:模型 provider。缺省时由 host 读用户配置自动解析 */
|
|
16
|
+
provider?: string
|
|
17
|
+
/** 可选:模型 id。缺省时由 host 读用户配置自动解析 */
|
|
18
|
+
model?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 一条优化建议(对应 UI 里的 tag + issue + patch) */
|
|
22
|
+
export interface Suggestion {
|
|
23
|
+
/** 问题类型(scope / format / constraint / clarity / other) */
|
|
24
|
+
tag: string
|
|
25
|
+
/** 一句话说明问题 */
|
|
26
|
+
issue: string
|
|
27
|
+
/** 一句话补丁,追加到原草稿后面 */
|
|
28
|
+
patch: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 服务端 → 客户端的响应 */
|
|
32
|
+
export interface SuggestResponse {
|
|
33
|
+
ok: boolean
|
|
34
|
+
suggestions?: Suggestion[]
|
|
35
|
+
error?: string
|
|
36
|
+
/** 实际使用的模型(便于前端展示/排查) */
|
|
37
|
+
usedModel?: string
|
|
38
|
+
}
|