@templmf/temp-solf-lmf 0.0.55 → 0.0.56

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.
Files changed (87) hide show
  1. package/package.json +1 -1
  2. package//345/242/236/351/207/217/351/234/200/346/261/202prompt +72 -0
  3. package/guanwang/README.md +0 -95
  4. package/guanwang/docs/changelog.md +0 -145
  5. package/guanwang/docs/doc-maintenance.md +0 -229
  6. package/guanwang/docs/product.md +0 -181
  7. package/guanwang/docs/test-cases.md +0 -395
  8. package/guanwang/docs/usage.md +0 -291
  9. package/guanwang/env.example +0 -27
  10. package/guanwang/index.html +0 -13
  11. package/guanwang/package-lock.json +0 -3825
  12. package/guanwang/package.json +0 -32
  13. package/guanwang/public/favicon.svg +0 -4
  14. package/guanwang/public/react-runtime/babel.min.js +0 -4
  15. package/guanwang/public/react-runtime/react-dom.min.js +0 -267
  16. package/guanwang/public/react-runtime/react.min.js +0 -31
  17. package/guanwang/public/vue-repl-assets/compiler-sfc.esm-browser.js +0 -50795
  18. package/guanwang/public/vue-repl-assets/runtime-dom.esm-browser.js +0 -12758
  19. package/guanwang/public/vue-repl-assets/server-renderer.esm-browser.js +0 -8600
  20. package/guanwang/public/vue-repl-assets/vue.esm-browser.js +0 -18672
  21. package/guanwang/src/App.vue +0 -61
  22. package/guanwang/src/chat-sdk/core/components/ChatBox.vue +0 -305
  23. package/guanwang/src/chat-sdk/core/components/ChatSidebar.vue +0 -84
  24. package/guanwang/src/chat-sdk/core/components/InputBar.vue +0 -354
  25. package/guanwang/src/chat-sdk/core/components/MessageBubble.vue +0 -703
  26. package/guanwang/src/chat-sdk/core/useTheme.js +0 -31
  27. package/guanwang/src/chat-sdk/features/artifact/ArtifactCard.vue +0 -172
  28. package/guanwang/src/chat-sdk/features/artifact/ArtifactPanel.vue +0 -963
  29. package/guanwang/src/chat-sdk/features/artifact/index.js +0 -13
  30. package/guanwang/src/chat-sdk/features/artifact/useArtifactStore.js +0 -275
  31. package/guanwang/src/chat-sdk/features/codepreview/CodePreview.vue +0 -523
  32. package/guanwang/src/chat-sdk/features/codepreview/index.js +0 -7
  33. package/guanwang/src/chat-sdk/features/markdown/index.js +0 -13
  34. package/guanwang/src/chat-sdk/features/markdown/useMarkdown.js +0 -724
  35. package/guanwang/src/chat-sdk/features/mermaid/MermaidZoom.vue +0 -254
  36. package/guanwang/src/chat-sdk/features/upload/FileAttachment.vue +0 -142
  37. package/guanwang/src/chat-sdk/features/upload/index.js +0 -17
  38. package/guanwang/src/chat-sdk/features/upload/useFileHandler.js +0 -336
  39. package/guanwang/src/chat-sdk/headless/api/adapters/openai.js +0 -76
  40. package/guanwang/src/chat-sdk/headless/api/chatApi.js +0 -126
  41. package/guanwang/src/chat-sdk/headless/buildSystemPrompt.js +0 -351
  42. package/guanwang/src/chat-sdk/headless/index.js +0 -15
  43. package/guanwang/src/chat-sdk/headless/useChat.js +0 -77
  44. package/guanwang/src/chat-sdk/headless/useChatDB.js +0 -147
  45. package/guanwang/src/chat-sdk/headless/useChatStore.js +0 -529
  46. package/guanwang/src/chat-sdk/index.js +0 -79
  47. package/guanwang/src/chat-sdk/modes/architect.js +0 -27
  48. package/guanwang/src/chat-sdk/modes/ask.js +0 -26
  49. package/guanwang/src/chat-sdk/modes/code.js +0 -25
  50. package/guanwang/src/chat-sdk/modes/index.js +0 -36
  51. package/guanwang/src/chat-sdk/modes/requirements.js +0 -175
  52. package/guanwang/src/chat-sdk/settings/SettingsPanel.vue +0 -170
  53. package/guanwang/src/chat-sdk/settings/index.js +0 -9
  54. package/guanwang/src/chat-sdk/settings/useSettings.js +0 -122
  55. package/guanwang/src/chat-sdk/tools/defaults.js +0 -89
  56. package/guanwang/src/chat-sdk/tools/index.js +0 -16
  57. package/guanwang/src/chat-sdk/tools/parser.js +0 -116
  58. package/guanwang/src/components/CustomCursor.vue +0 -69
  59. package/guanwang/src/components/Footer.vue +0 -24
  60. package/guanwang/src/components/LoginModal.vue +0 -109
  61. package/guanwang/src/components/Navbar.vue +0 -193
  62. package/guanwang/src/components/ThemeToggle.vue +0 -25
  63. package/guanwang/src/composables/useArtifactStore.js +0 -253
  64. package/guanwang/src/composables/useAuth.js +0 -88
  65. package/guanwang/src/composables/useChatDB.js +0 -147
  66. package/guanwang/src/composables/useCountUp.js +0 -24
  67. package/guanwang/src/composables/useFileHandler.js +0 -345
  68. package/guanwang/src/composables/useTheme.js +0 -31
  69. package/guanwang/src/config/api.js +0 -71
  70. package/guanwang/src/main.js +0 -23
  71. package/guanwang/src/router/index.js +0 -23
  72. package/guanwang/src/services/authApi.js +0 -27
  73. package/guanwang/src/services/chatApi.js +0 -66
  74. package/guanwang/src/styles/global.css +0 -478
  75. package/guanwang/src/tracker/analyze.js +0 -73
  76. package/guanwang/src/tracker/config.js +0 -82
  77. package/guanwang/src/tracker/index.js +0 -18
  78. package/guanwang/src/tracker/service.js +0 -102
  79. package/guanwang/src/tracker/useChatTracker.js +0 -179
  80. package/guanwang/src/tracker/useTracker.js +0 -45
  81. package/guanwang/src/views/ChatView.vue +0 -65
  82. package/guanwang/src/views/HomeView.vue +0 -156
  83. package/guanwang/src/views/MarketView.vue +0 -143
  84. package/guanwang/src/views/PracticesView.vue +0 -190
  85. package/guanwang/src/views/SkillsView.vue +0 -129
  86. package/guanwang/temp +0 -19
  87. package/guanwang/vite.config.js +0 -6
@@ -1,36 +0,0 @@
1
- /**
2
- * modes/ — 模式 prompt 配置
3
- *
4
- * 每个模式导出:
5
- * id 模式唯一标识
6
- * name 显示名称
7
- * icon 图标(lucide 图标名)
8
- * rolePrompt 角色定义段落(注入 system prompt 开头)
9
- * description 在模式列表里的简短说明
10
- *
11
- * 按 config.modes 数组按需导入,未声明的模式不打进 bundle
12
- */
13
-
14
- const MODE_MAP = {
15
- code: () => import('./code.js'),
16
- ask: () => import('./ask.js'),
17
- architect: () => import('./architect.js'),
18
- requirements: () => import('./requirements.js'),
19
- }
20
-
21
- /**
22
- * 按配置的 modes 列表加载对应模式定义
23
- * @param {string[]} modeIds
24
- * @returns {Promise<Record<string, ModeConfig>>}
25
- */
26
- export async function loadModes(modeIds) {
27
- const entries = await Promise.all(
28
- modeIds
29
- .filter(id => MODE_MAP[id])
30
- .map(async id => {
31
- const mod = await MODE_MAP[id]()
32
- return [id, mod.default]
33
- })
34
- )
35
- return Object.fromEntries(entries)
36
- }
@@ -1,175 +0,0 @@
1
- /**
2
- * modes/requirements.js — 需求创造者模式
3
- * 角色:需求分析师,通过假设+确认方式引导用户完善需求,
4
- * 输出用户故事 + 功能拆解列表(细到接口/交互级别),
5
- * 同时关注系统间能力与相互调用关系
6
- */
7
- export default {
8
- id: 'requirements',
9
- name: '需求',
10
- icon: 'FileText',
11
- description: '引导用户梳理需求,输出用户故事与功能拆解列表',
12
-
13
- rolePrompt: `你是一名资深需求分析师,擅长将模糊的业务想法转化为结构清晰、可直接落地的需求文档。你的工作方式是:先理解用户意图,提出合理假设补全细节,然后让用户确认或修正,而不是一开始就追问大量问题。
14
-
15
- 你当前处于需求模式,职责是:
16
- - 理解并丰富用户描述的业务需求
17
- - 引导用户厘清需求边界和关键决策点
18
- - 识别系统间的能力依赖与调用关系
19
- - 输出标准格式的需求文档
20
-
21
- ====
22
-
23
- 【核心原则:先问后写】
24
-
25
- 在输出任何需求文档之前,你 MUST 完成"信息充分性评估":
26
-
27
- 判断当前信息是否足以填充需求文档的每个必填项。以下任何一项信息缺失或模糊,均视为"信息不足",禁止直接输出文档:
28
-
29
- - 背景不清晰(为什么要做这个需求、触发原因是什么)
30
- - 目标用户不明确(谁在用、在什么场景下用)
31
- - 核心业务流程不完整(关键步骤、分支路径不清楚)
32
- - 涉及系统/依赖方不明确
33
- - 优先级未知
34
-
35
- 信息不足时,MUST 进入引导式问答流程,不得直接输出文档。
36
-
37
- ====
38
-
39
- 工作流程(MUST 按此流程执行,不得跳步):
40
-
41
- 【第一步:快速理解 + 信息充分性评估】
42
-
43
- 收到用户需求描述后:
44
- 1. 用 2-3 句话复述你理解的核心业务目标
45
- 2. 立即执行信息充分性评估
46
- 3. 根据评估结果走不同分支:
47
- - 信息不足 → 进入第二步(引导式问答)
48
- - 信息充分 → 进入第三步(假设补全)
49
-
50
- 【第二步:引导式问答(信息不足时执行)】
51
-
52
- MUST 遵守以下规则:
53
- - 每轮最多提 2-3 个问题,不得一次抛出所有问题
54
- - 问题按优先级排序:先问影响整体方向的,再问细节
55
- - 每轮问完后等用户回答,再决定是否继续追问或推进到下一步
56
- - 用友好、对话式的语气,而非表单式罗列
57
-
58
- 问题选取优先级(从高到低):
59
- ① 业务背景与目标(不清楚时必问)
60
- ② 目标用户与使用场景(不清楚时必问)
61
- ③ 核心业务流程与关键节点
62
- ④ 涉及的系统与外部依赖
63
- ⑤ 优先级与上线时间要求
64
-
65
- 示例引导语风格(参考,不得照抄):
66
- "我先理解一下背景——这个功能是为了解决什么问题触发的?目前用户是怎么处理这个事情的?"
67
- "用这个功能的主要是哪类用户?他们在什么场景下会触发这个操作?"
68
-
69
- 【第三步:假设补全】
70
-
71
- 当核心信息已经充分后,对剩余模糊点给出合理假设,让用户轻量确认:
72
-
73
- 【我的假设,请确认或修正】
74
- ✓ 假设1:[具体假设内容]
75
- ✓ 假设2:[具体假设内容]
76
- ✗ 待确认:[真正不确定、影响方案设计的关键决策点]
77
-
78
- 【第四步:系统边界识别】
79
-
80
- 明确本次需求涉及哪些系统/模块及其调用关系:
81
- - 哪些能力由本系统提供
82
- - 哪些能力依赖外部系统(第三方服务、其他内部系统)
83
- - 关键的数据流转路径
84
-
85
- 【第五步:输出交付物】
86
-
87
- 假设确认后,将完整需求文档以 markdown 代码块的形式输出,即用 \`\`\`markdown ... \`\`\` 包裹整个文档内容,严格遵守以下模板:
88
-
89
- ====
90
-
91
- 交付物格式(MUST 严格遵守):
92
-
93
- # [功能名称] 需求文档
94
-
95
- ## 1 概述
96
-
97
- ### 1.1 背景
98
- [说明需求产生的业务背景、触发原因、现有痛点]
99
-
100
- ### 1.2 业务目标
101
- [1-2句话说明此功能解决什么业务问题,期望达成什么结果]
102
-
103
- ### 1.3 术语
104
-
105
- | 术语名称 | 术语解释 |
106
- |---|---|
107
- | [术语] | [解释] |
108
-
109
- ### 1.4 整体方案
110
- [用 3-5 句话描述整体解决思路,包括主要功能模块的关系与实现路径]
111
-
112
- ---
113
-
114
- ## 2 功能性需求分析
115
-
116
- ### 2.1 需求场景分析
117
-
118
- | 产品/模块 | 场景 | 描述 | 优先级 |
119
- |---|---|---|---|
120
- | [产品名] | [场景名] | [场景简述] | P0/P1/P2 |
121
-
122
- ### 2.2 需求场景明细
123
-
124
- #### 2.2.1 [场景功能标题]
125
-
126
- **业务场景描述:**
127
- - [场景的整体业务背景与触发条件]
128
- - [主要操作流程与关键节点]
129
- - [异常分支或边界情况]
130
-
131
- **用户故事:**
132
-
133
- - As a [用户角色], I want [功能], so that [业务价值]
134
- - 验收标准:
135
- - [ ] [可验收的具体条件1]
136
- - [ ] [可验收的具体条件2]
137
- - [ ] [可验收的具体条件3]
138
-
139
- (每个场景可包含多个用户故事,覆盖主流程、异常流程、边界情况)
140
-
141
- **涉及系统:**
142
-
143
- | 系统/模块 | 角色 | 说明 |
144
- |---|---|---|
145
- | 本系统 | 主体 | ... |
146
- | [外部系统] | 依赖方 | 提供[具体能力] |
147
-
148
- ---
149
-
150
- ## 3 非功能性需求分析
151
-
152
- ### 3.1 性能需求
153
-
154
- 说明:根据实际需求初步评估涉及的性能场景,供 PM 参考进行最终性能评估。若不涉及或无需求,填写"无"。
155
-
156
- - [涉及的性能场景名称及初步评估]
157
-
158
- ---
159
-
160
- ## 待确认事项
161
- - [ ] [需要产品/业务进一步确认的问题]
162
-
163
- ====
164
-
165
- 你在需求模式下的行为准则:
166
- 1. MUST 在信息充分后才输出文档,信息不足时 MUST 进入引导式问答,禁止用"我假设..."填充关键空白后直接输出
167
- 2. MUST 按"快速理解 → 引导问答(如需)→ 假设补全 → 系统边界 → 输出交付物"五步执行,不得跳步
168
- 3. 引导式问答 MUST 每轮最多 2-3 个问题,按优先级排序,用对话式语气
169
- 4. 假设补全 MUST 区分"合理假设(可直接列出)"和"关键决策点(必须用户确认)"
170
- 5. 用户故事的验收标准 MUST 具体可测,覆盖正常流程、异常流程和边界情况,不得写泛化描述
171
- 6. 涉及外部系统时 MUST 在"涉及系统"表格中明确标注依赖方及其提供的具体能力
172
- 7. 输出需求文档时 MUST 用 \`\`\`markdown ... \`\`\` 代码块包裹整个文档,不得裸输出 Markdown 文本
173
- 8. NEVER 主动切换到 Code 或 Architect 模式,需求确认后告知用户可切换到对应模式继续
174
- 9. 若用户描述的需求跨越多个独立功能模块,MUST 引导用户优先聚焦一个模块,逐个推进`,
175
- }
@@ -1,170 +0,0 @@
1
- <template>
2
- <div class="settings-panel">
3
- <div class="settings-section">
4
- <p class="settings-label">模型</p>
5
- <!-- 模型选择 -->
6
- <div v-if="showModelSelector" class="model-list">
7
- <button
8
- v-for="m in availableModels"
9
- :key="m.id"
10
- class="model-item"
11
- :class="{ active: selectedModelId === m.id }"
12
- @click="emit('select-model', m.id)"
13
- >
14
- <span class="model-item__name">{{ m.name }}</span>
15
- <span v-if="m.vision" class="model-item__badge">视觉</span>
16
- <span v-if="selectedModelId === m.id" class="model-item__check">✓</span>
17
- </button>
18
- </div>
19
- </div>
20
-
21
- <div v-if="controllableKeys.length" class="settings-section">
22
- <p class="settings-label">功能开关</p>
23
- <div class="toggle-list">
24
- <div
25
- v-for="key in controllableKeys"
26
- :key="key"
27
- class="toggle-item"
28
- >
29
- <span class="toggle-item__name">{{ FEATURE_LABELS[key] || key }}</span>
30
- <button
31
- class="toggle-btn"
32
- :class="{ on: runtimeToggles[key] }"
33
- @click="emit('toggle', key)"
34
- :aria-label="runtimeToggles[key] ? '关闭' : '开启'"
35
- >
36
- <span class="toggle-btn__knob" />
37
- </button>
38
- </div>
39
- </div>
40
- </div>
41
-
42
- <div class="settings-section settings-section--footer">
43
- <button class="reset-btn" @click="emit('reset')">恢复默认设置</button>
44
- </div>
45
- </div>
46
- </template>
47
-
48
- <script setup>
49
- const FEATURE_LABELS = {
50
- artifact: '代码文件生成',
51
- upload: '文件上传',
52
- markdown: 'Markdown 渲染',
53
- mermaid: 'Mermaid 图表',
54
- codepreview: '代码预览',
55
- modelSelector: '模型选择器',
56
- }
57
-
58
- defineProps({
59
- availableModels: { type: Array, default: () => [] },
60
- selectedModelId: { type: String, default: '' },
61
- controllableKeys: { type: Array, default: () => [] },
62
- runtimeToggles: { type: Object, default: () => ({}) },
63
- showModelSelector: { type: Boolean, default: true },
64
- })
65
-
66
- const emit = defineEmits(['select-model', 'toggle', 'reset'])
67
- </script>
68
-
69
- <style scoped>
70
- .settings-panel {
71
- display: flex;
72
- flex-direction: column;
73
- gap: 0;
74
- min-width: 220px;
75
- }
76
-
77
- .settings-section {
78
- padding: 10px 0;
79
- border-bottom: 1px solid var(--border-subtle);
80
- }
81
- .settings-section:last-child { border-bottom: none; }
82
- .settings-section--footer { padding-top: 8px; }
83
-
84
- .settings-label {
85
- font-size: 11px;
86
- color: var(--text-muted);
87
- font-family: 'Cascadia Code', 'Consolas', monospace;
88
- margin: 0 0 6px;
89
- padding: 0 14px;
90
- text-transform: uppercase;
91
- letter-spacing: 0.06em;
92
- }
93
-
94
- /* 模型列表 */
95
- .model-list { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
96
- .model-item {
97
- display: flex;
98
- align-items: center;
99
- gap: 8px;
100
- padding: 7px 10px;
101
- border-radius: 7px;
102
- border: none;
103
- background: transparent;
104
- cursor: pointer;
105
- font-size: 13px;
106
- color: var(--text-secondary);
107
- font-family: Inter, 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
108
- transition: background 0.12s;
109
- text-align: left;
110
- }
111
- .model-item:hover { background: var(--border-subtle); color: var(--text-primary); }
112
- .model-item.active { color: var(--text-primary); }
113
- .model-item__name { flex: 1; font-family: 'Cascadia Code', 'Consolas', monospace; font-size: 12px; }
114
- .model-item__badge {
115
- font-size: 10px; padding: 1px 6px; border-radius: 4px;
116
- background: var(--tag-bg); color: var(--tag-color); border: 1px solid var(--tag-border);
117
- }
118
- .model-item__check { color: var(--brand-400); font-size: 13px; }
119
-
120
- /* 功能开关列表 */
121
- .toggle-list { display: flex; flex-direction: column; gap: 2px; padding: 0 8px; }
122
- .toggle-item {
123
- display: flex; align-items: center; justify-content: space-between;
124
- padding: 7px 10px;
125
- }
126
- .toggle-item__name {
127
- font-size: 13px;
128
- color: var(--text-secondary);
129
- font-family: Inter, 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
130
- }
131
-
132
- /* 开关按钮 */
133
- .toggle-btn {
134
- position: relative;
135
- width: 32px; height: 18px;
136
- border-radius: 9px;
137
- border: none;
138
- background: var(--border-default);
139
- cursor: pointer;
140
- transition: background 0.18s;
141
- flex-shrink: 0;
142
- }
143
- .toggle-btn.on { background: var(--brand-500); }
144
- .toggle-btn__knob {
145
- position: absolute;
146
- top: 2px; left: 2px;
147
- width: 14px; height: 14px;
148
- border-radius: 50%;
149
- background: white;
150
- transition: transform 0.18s;
151
- display: block;
152
- }
153
- .toggle-btn.on .toggle-btn__knob { transform: translateX(14px); }
154
-
155
- /* 重置按钮 */
156
- .reset-btn {
157
- width: 100%;
158
- padding: 7px 14px;
159
- border: none;
160
- background: transparent;
161
- color: var(--text-muted);
162
- font-size: 12px;
163
- font-family: Inter, 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
164
- cursor: pointer;
165
- border-radius: 6px;
166
- transition: background 0.12s, color 0.12s;
167
- text-align: center;
168
- }
169
- .reset-btn:hover { background: var(--border-subtle); color: var(--text-secondary); }
170
- </style>
@@ -1,9 +0,0 @@
1
- /**
2
- * settings/ — 运行时配置管理
3
- *
4
- * useSettings.js 读写 localStorage,管理运行时开关状态
5
- * SettingsPanel.vue 设置面板 UI(仅 createAIChat 使用)
6
- */
7
-
8
- export { useSettings } from './useSettings.js'
9
- export const SettingsPanel = () => import('./SettingsPanel.vue')
@@ -1,122 +0,0 @@
1
- /**
2
- * settings/useSettings.js
3
- *
4
- * 管理运行时用户可控开关,持久化到 localStorage。
5
- * 只存储 userControls 里声明的开关,features 层由初始化配置控制。
6
- */
7
- import { ref, watch, computed } from 'vue'
8
-
9
- const STORAGE_KEY = 'ai-chat-sdk:settings'
10
-
11
- /**
12
- * @param {object} initConfig
13
- * @param {object} initConfig.features 初始化层能力配置(控制代码加载)
14
- * @param {object} initConfig.userControls 用户可控开关声明
15
- * @param {string[]} initConfig.models 可用模型列表
16
- * @param {string} initConfig.defaultModel 默认模型 id
17
- */
18
- export function useSettings(initConfig = {}) {
19
- const { features = {}, userControls = {}, models = [], defaultModel = '' } = initConfig
20
-
21
- // ── 从 localStorage 读取上次的用户设置 ───────────────────────────
22
- function loadStored() {
23
- try {
24
- const raw = localStorage.getItem(STORAGE_KEY)
25
- return raw ? JSON.parse(raw) : {}
26
- } catch {
27
- return {}
28
- }
29
- }
30
-
31
- const stored = loadStored()
32
-
33
- // ── 运行时开关状态 ───────────────────────────────────────────────
34
- // 规则:
35
- // userControls[key] = true → 默认开启,用户可关
36
- // userControls[key] = false → 默认关闭,用户可开
37
- // key 不在 userControls → 强制开启,不暴露给用户
38
- // features[key] = false → 代码未加载,开关无效
39
-
40
- const runtimeToggles = ref({})
41
-
42
- for (const [key, defaultVal] of Object.entries(userControls)) {
43
- // localStorage 有历史值则用历史值,否则用 userControls 声明的默认值
44
- runtimeToggles.value[key] = key in stored ? stored[key] : defaultVal
45
- }
46
-
47
- // ── 当前选中模型 ─────────────────────────────────────────────────
48
- const selectedModelId = ref(
49
- stored.selectedModel && models.find(m => m.id === stored.selectedModel)
50
- ? stored.selectedModel
51
- : defaultModel
52
- )
53
-
54
- // ── 自动持久化 ───────────────────────────────────────────────────
55
- watch(
56
- [runtimeToggles, selectedModelId],
57
- () => {
58
- try {
59
- localStorage.setItem(STORAGE_KEY, JSON.stringify({
60
- ...runtimeToggles.value,
61
- selectedModel: selectedModelId.value,
62
- }))
63
- } catch { /* storage 写入失败静默处理 */ }
64
- },
65
- { deep: true }
66
- )
67
-
68
- // ── 对外暴露 ─────────────────────────────────────────────────────
69
-
70
- /**
71
- * 判断某个 feature 是否实际可用
72
- * 需要同时满足:features 里已加载 + 运行时开关为 true(或未在 userControls 中声明)
73
- */
74
- function isEnabled(key) {
75
- if (!features[key]) return false // 代码未加载
76
- if (key in userControls) return runtimeToggles.value[key] // 用户可控
77
- return true // 强制开启
78
- }
79
-
80
- /**
81
- * 某个开关是否应该在设置面板里显示
82
- * 条件:features 已加载 + 在 userControls 里声明
83
- */
84
- function isControllable(key) {
85
- return !!(features[key] && key in userControls)
86
- }
87
-
88
- function toggle(key) {
89
- if (!isControllable(key)) return
90
- runtimeToggles.value[key] = !runtimeToggles.value[key]
91
- }
92
-
93
- function setToggle(key, val) {
94
- if (!isControllable(key)) return
95
- runtimeToggles.value[key] = !!val
96
- }
97
-
98
- /**
99
- * 所有可在设置面板显示的开关列表(用于 SettingsPanel.vue 渲染)
100
- */
101
- const controllableKeys = computed(() =>
102
- Object.keys(userControls).filter(k => features[k])
103
- )
104
-
105
- function reset() {
106
- for (const [key, defaultVal] of Object.entries(userControls)) {
107
- runtimeToggles.value[key] = defaultVal
108
- }
109
- selectedModelId.value = defaultModel
110
- }
111
-
112
- return {
113
- runtimeToggles,
114
- selectedModelId,
115
- controllableKeys,
116
- isEnabled,
117
- isControllable,
118
- toggle,
119
- setToggle,
120
- reset,
121
- }
122
- }
@@ -1,89 +0,0 @@
1
- /**
2
- * tools/defaults.js
3
- * 每个工具的默认处理逻辑
4
- *
5
- * 消费方可通过 onToolCall(toolName, handler) 覆盖任意工具的默认行为
6
- * 覆盖时 handler 接收 { params, resolve, reject } 并负责调用 resolve/reject
7
- */
8
-
9
- /**
10
- * 内置默认工具处理器
11
- * key = 工具名
12
- * value = async ({ params, resolve, reject, context }) => void
13
- *
14
- * context 包含:
15
- * switchMode(modeId) 切换模式
16
- * appendMessage(msg) 向消息列表追加一条消息
17
- * markComplete() 标记当前任务完成
18
- * requestInput(question) 弹出输入框等待用户输入(返回 Promise<string>)
19
- */
20
- export const defaultToolHandlers = {
21
-
22
- /**
23
- * ask_followup_question
24
- * 默认行为:把问题和选项作为一条特殊 AI 消息追加到消息列表
25
- * 用户点选后,把选项文字作为新的 user 消息发送
26
- */
27
- ask_followup_question: async ({ params, resolve, context }) => {
28
- // 通知 UI 层渲染选项消息气泡
29
- // UI 层监听到 type: 'followup' 的消息后,渲染选项按钮
30
- // 用户点选后调用 resolve(selectedText)
31
- context.appendFollowup({
32
- question: params.question || '',
33
- suggests: params.suggests || [],
34
- onSelect: resolve,
35
- })
36
- },
37
-
38
- /**
39
- * attempt_completion
40
- * 默认行为:标记当前轮次完成,UI 层可据此做视觉区分
41
- */
42
- attempt_completion: async ({ params, resolve, context }) => {
43
- context.markComplete(params.result || '')
44
- resolve()
45
- },
46
-
47
- /**
48
- * switch_mode
49
- * 默认行为:直接切换到目标模式,追加一条系统提示消息
50
- */
51
- switch_mode: async ({ params, resolve, context }) => {
52
- const targetMode = params.mode_slug
53
- const reason = params.reason || ''
54
- if (targetMode) {
55
- context.appendSystemTip(`切换到 ${targetMode} 模式${reason ? ':' + reason : ''}`)
56
- context.switchMode(targetMode)
57
- }
58
- resolve()
59
- },
60
-
61
- /**
62
- * render_artifact
63
- * 默认行为:交给 artifact feature 处理(注册 artifact,触发面板展示)
64
- * 若 artifact feature 未启用,降级为普通代码块展示
65
- */
66
- render_artifact: async ({ params, resolve, context }) => {
67
- if (context.artifactEnabled) {
68
- context.registerArtifact({
69
- fileName: params.file_name || 'artifact',
70
- lang: params.lang || 'text',
71
- code: params.content || '',
72
- })
73
- }
74
- resolve()
75
- },
76
-
77
- /**
78
- * request_context
79
- * 默认行为:追加一条系统提示消息,引导用户粘贴代码或上传文件
80
- * 用户完成后,其下一条消息自动作为上下文继续对话
81
- */
82
- request_context: async ({ params, resolve, context }) => {
83
- const hint = params.hint || '请提供相关代码或文件内容,以便继续分析'
84
- context.appendSystemTip(hint, 'context-request')
85
- // request_context 不需要等待用户响应就 resolve
86
- // 用户的下一条消息自然携带上下文
87
- resolve()
88
- },
89
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * tools/ — tool-use 解析器
3
- *
4
- * parser.js XML 工具调用解析
5
- * ask-followup.js ask_followup_question 默认行为
6
- * attempt-completion.js attempt_completion 默认行为
7
- * switch-mode.js switch_mode 默认行为
8
- * render-artifact.js render_artifact 默认行为(依赖 artifact feature)
9
- * request-context.js request_context 默认行为(依赖 upload feature)
10
- *
11
- * 每个 tool 内置默认处理逻辑,消费方可按 tool 名覆盖:
12
- * onToolCall('ask_followup_question', (tool) => { ... })
13
- */
14
-
15
- export { parseToolCall, extractAllToolCalls } from './parser.js'
16
- export { defaultToolHandlers } from './defaults.js'