nolo-cli 0.1.9 → 0.1.11

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 (240) hide show
  1. package/README.md +0 -32
  2. package/agentRuntimeCommands.ts +3 -3
  3. package/commandRegistry.ts +2 -2
  4. package/machineCommands.ts +31 -6
  5. package/package.json +6 -8
  6. package/ai/agent/_executeModel.ts +0 -118
  7. package/ai/agent/agentSlice.ts +0 -525
  8. package/ai/agent/appWorkingMemory.ts +0 -126
  9. package/ai/agent/avatarUtils.ts +0 -24
  10. package/ai/agent/buildEditingContext.ts +0 -373
  11. package/ai/agent/buildSystemPrompt.ts +0 -532
  12. package/ai/agent/cleanAgentMessages.ts +0 -140
  13. package/ai/agent/cliChatClient.ts +0 -119
  14. package/ai/agent/cliExecutor.ts +0 -733
  15. package/ai/agent/cliPrompt.ts +0 -10
  16. package/ai/agent/contextCompiler.ts +0 -107
  17. package/ai/agent/contextLayerContract.ts +0 -44
  18. package/ai/agent/createAgentSchema.ts +0 -234
  19. package/ai/agent/executeToolCall.ts +0 -58
  20. package/ai/agent/fetchAgentContexts.ts +0 -42
  21. package/ai/agent/generatePrompt.ts +0 -3
  22. package/ai/agent/getFullChatContextKeys.ts +0 -168
  23. package/ai/agent/hooks/fetchPublicAgents.ts +0 -133
  24. package/ai/agent/hooks/useAgentConfig.ts +0 -61
  25. package/ai/agent/hooks/useAgentDialog.ts +0 -35
  26. package/ai/agent/hooks/useAgentFormValidation.ts +0 -202
  27. package/ai/agent/hooks/usePublicAgents.ts +0 -473
  28. package/ai/agent/machineRunPermissions.ts +0 -95
  29. package/ai/agent/persistMessageWithFixedId.ts +0 -37
  30. package/ai/agent/planSlice.ts +0 -259
  31. package/ai/agent/referenceUtils.ts +0 -229
  32. package/ai/agent/runAgentBackground.ts +0 -238
  33. package/ai/agent/runAgentClientLoop.ts +0 -138
  34. package/ai/agent/runtimeGuidance.ts +0 -97
  35. package/ai/agent/runtimeServerBase.ts +0 -37
  36. package/ai/agent/server/fetchPublicAgents.ts +0 -128
  37. package/ai/agent/startParallelAgentStreams.ts +0 -424
  38. package/ai/agent/startupProtocol.ts +0 -53
  39. package/ai/agent/streamAgentChatTurn.ts +0 -1278
  40. package/ai/agent/streamAgentChatTurnUtils.ts +0 -738
  41. package/ai/agent/types.ts +0 -71
  42. package/ai/agent/utils/imageOutput.ts +0 -33
  43. package/ai/agent/utils/sortUtils.ts +0 -250
  44. package/ai/agent/web/referencePickerUtils.ts +0 -146
  45. package/ai/ai.locale.ts +0 -1075
  46. package/ai/chat/accumulateToolCallChunks.ts +0 -95
  47. package/ai/chat/fetchUtils.native.ts +0 -276
  48. package/ai/chat/fetchUtils.ts +0 -153
  49. package/ai/chat/parseApiError.ts +0 -64
  50. package/ai/chat/parseMultilineSSE.ts +0 -95
  51. package/ai/chat/sendOpenAICompletionsRequest.native.ts +0 -682
  52. package/ai/chat/sendOpenAICompletionsRequest.ts +0 -703
  53. package/ai/chat/sendOpenAIResponseRequest.ts +0 -491
  54. package/ai/chat/shouldUseServerProxy.ts +0 -18
  55. package/ai/chat/sseClient.native.ts +0 -91
  56. package/ai/chat/sseClient.ts +0 -67
  57. package/ai/chat/streamReader.native.ts +0 -31
  58. package/ai/chat/streamReader.ts +0 -62
  59. package/ai/chat/updateTotalUsage.ts +0 -72
  60. package/ai/context/buildReferenceContext.ts +0 -437
  61. package/ai/context/calculateContextUsage.ts +0 -133
  62. package/ai/context/retention.ts +0 -165
  63. package/ai/context/tokenUtils.ts +0 -78
  64. package/ai/index.ts +0 -1
  65. package/ai/llm/calculateGeminiImageTokens.ts +0 -57
  66. package/ai/llm/deepinfra.ts +0 -28
  67. package/ai/llm/fireworks.ts +0 -50
  68. package/ai/llm/generateRequestBody.ts +0 -165
  69. package/ai/llm/getModelContextWindow.ts +0 -84
  70. package/ai/llm/getNoloKey.ts +0 -31
  71. package/ai/llm/getPricing.ts +0 -199
  72. package/ai/llm/hooks/useModelPricing.ts +0 -75
  73. package/ai/llm/imagePricing.ts +0 -40
  74. package/ai/llm/isResponseAPIModel.ts +0 -13
  75. package/ai/llm/mimo.ts +0 -71
  76. package/ai/llm/mistral.ts +0 -22
  77. package/ai/llm/modelAvatar.ts +0 -427
  78. package/ai/llm/models.ts +0 -45
  79. package/ai/llm/openrouterModels.ts +0 -269
  80. package/ai/llm/providers.ts +0 -306
  81. package/ai/llm/reasoningModels.ts +0 -28
  82. package/ai/llm/types.ts +0 -59
  83. package/ai/llm/usageRequestOptions.ts +0 -59
  84. package/ai/memory/capture.ts +0 -148
  85. package/ai/memory/consolidate.ts +0 -104
  86. package/ai/memory/delete.ts +0 -147
  87. package/ai/memory/overlay.ts +0 -84
  88. package/ai/memory/query.ts +0 -38
  89. package/ai/memory/queryShared.ts +0 -160
  90. package/ai/memory/rank.ts +0 -105
  91. package/ai/memory/recentRelationshipRecap.ts +0 -249
  92. package/ai/memory/remember.ts +0 -167
  93. package/ai/memory/runtime.ts +0 -76
  94. package/ai/memory/store.ts +0 -20
  95. package/ai/memory/storeShared.ts +0 -76
  96. package/ai/memory/types.ts +0 -46
  97. package/ai/memory/understanding.ts +0 -349
  98. package/ai/memory/understandingGreeting.ts +0 -264
  99. package/ai/messages/type.ts +0 -20
  100. package/ai/policy/personalizationDialog.ts +0 -333
  101. package/ai/policy/runtimePolicy.ts +0 -440
  102. package/ai/policy/selfUpdateFields.ts +0 -48
  103. package/ai/policy/types.ts +0 -64
  104. package/ai/skills/referenceRuntime.ts +0 -274
  105. package/ai/skills/skillDiagnostics.ts +0 -251
  106. package/ai/skills/skillDocBuilder.ts +0 -139
  107. package/ai/skills/skillDocProtocol.ts +0 -434
  108. package/ai/skills/skillReferenceSummary.ts +0 -63
  109. package/ai/skills/skillSummaryMarker.ts +0 -26
  110. package/ai/token/calculatePrice.ts +0 -544
  111. package/ai/token/db.ts +0 -98
  112. package/ai/token/externalToolCost.ts +0 -330
  113. package/ai/token/hooks/useRecords.ts +0 -65
  114. package/ai/token/missingUsageEstimate.ts +0 -42
  115. package/ai/token/modelUsageQuery.ts +0 -252
  116. package/ai/token/normalizeUsage.ts +0 -84
  117. package/ai/token/openaiImageGenerationUsage.ts +0 -56
  118. package/ai/token/prepareTokenUsageData.ts +0 -88
  119. package/ai/token/query.ts +0 -88
  120. package/ai/token/queryUserTokens.ts +0 -59
  121. package/ai/token/resolveBillingTarget.ts +0 -52
  122. package/ai/token/saveTokenRecord.ts +0 -53
  123. package/ai/token/serverDialogProjection.ts +0 -78
  124. package/ai/token/serverTokenWriter.ts +0 -143
  125. package/ai/token/stats.ts +0 -21
  126. package/ai/token/tokenThunks.ts +0 -24
  127. package/ai/token/types.ts +0 -93
  128. package/ai/tools/agent/agentTools.ts +0 -176
  129. package/ai/tools/agent/agentUpdateShared.ts +0 -311
  130. package/ai/tools/agent/callAgentTool.ts +0 -139
  131. package/ai/tools/agent/createAgentTool.ts +0 -512
  132. package/ai/tools/agent/createDialogTool.ts +0 -69
  133. package/ai/tools/agent/createSkillAgentTool.ts +0 -62
  134. package/ai/tools/agent/parallelBudget.ts +0 -221
  135. package/ai/tools/agent/presets/appBuilderPreset.ts +0 -145
  136. package/ai/tools/agent/runLlmTool.ts +0 -96
  137. package/ai/tools/agent/runStreamingAgentTool.ts +0 -73
  138. package/ai/tools/agent/skillAgentArgs.ts +0 -106
  139. package/ai/tools/agent/skillAgentPreset.ts +0 -89
  140. package/ai/tools/agent/streamParallelAgentsTool.ts +0 -122
  141. package/ai/tools/agent/updateAgentTool.ts +0 -96
  142. package/ai/tools/agent/updateSelfTool.ts +0 -113
  143. package/ai/tools/amazonProductScraperTool.ts +0 -86
  144. package/ai/tools/apifyActorClient.ts +0 -45
  145. package/ai/tools/appEditGuard.ts +0 -372
  146. package/ai/tools/appReadSnapshot.ts +0 -153
  147. package/ai/tools/appTools.ts +0 -1549
  148. package/ai/tools/applyEditTool.ts +0 -256
  149. package/ai/tools/applyLineEditsTool.ts +0 -312
  150. package/ai/tools/browserTools/click.ts +0 -33
  151. package/ai/tools/browserTools/closeSession.ts +0 -29
  152. package/ai/tools/browserTools/common.ts +0 -27
  153. package/ai/tools/browserTools/openSession.ts +0 -48
  154. package/ai/tools/browserTools/readContent.ts +0 -38
  155. package/ai/tools/browserTools/selectOption.ts +0 -46
  156. package/ai/tools/browserTools/typeText.ts +0 -42
  157. package/ai/tools/category/createCategoryTool.ts +0 -66
  158. package/ai/tools/category/queryContentsByCategoryTool.ts +0 -69
  159. package/ai/tools/category/updateContentCategoryTool.ts +0 -75
  160. package/ai/tools/cfBrowserTools.ts +0 -319
  161. package/ai/tools/cfSpeechToTextTool.ts +0 -49
  162. package/ai/tools/checkEnvTool.ts +0 -65
  163. package/ai/tools/cloudflareCrawlTool.ts +0 -289
  164. package/ai/tools/codeSearchTool.ts +0 -111
  165. package/ai/tools/codeTools.ts +0 -101
  166. package/ai/tools/createDocTool.ts +0 -132
  167. package/ai/tools/createPlanTool.ts +0 -999
  168. package/ai/tools/createSkillDocTool.ts +0 -155
  169. package/ai/tools/createWorkflowTool.ts +0 -154
  170. package/ai/tools/deepseekOcrTool.ts +0 -34
  171. package/ai/tools/delayTool.ts +0 -31
  172. package/ai/tools/deleteSpacesTool.ts +0 -325
  173. package/ai/tools/deleteSpacesToolModel.ts +0 -159
  174. package/ai/tools/devReloadUtils.ts +0 -29
  175. package/ai/tools/dialogMessageSearch.ts +0 -137
  176. package/ai/tools/doctorSkillTool.ts +0 -72
  177. package/ai/tools/ecommerceScraperTool.ts +0 -86
  178. package/ai/tools/emailTools.ts +0 -549
  179. package/ai/tools/evalSkillTool.ts +0 -92
  180. package/ai/tools/exaSearchTool.ts +0 -64
  181. package/ai/tools/execBashTool.ts +0 -379
  182. package/ai/tools/executeSqlTool.ts +0 -192
  183. package/ai/tools/fetchWebpageSupport.ts +0 -309
  184. package/ai/tools/fetchWebpageTool.ts +0 -84
  185. package/ai/tools/geminiImagePreviewTool.ts +0 -361
  186. package/ai/tools/generateDocxTool.ts +0 -215
  187. package/ai/tools/googleSearchScraperTool.ts +0 -106
  188. package/ai/tools/importDataTool.ts +0 -133
  189. package/ai/tools/importSkillTool.ts +0 -162
  190. package/ai/tools/index.ts +0 -1858
  191. package/ai/tools/listFilesTool.ts +0 -82
  192. package/ai/tools/listUserSpacesTool.ts +0 -113
  193. package/ai/tools/modelUsageTools.ts +0 -142
  194. package/ai/tools/olmOcrTool.ts +0 -34
  195. package/ai/tools/openaiImageTool.ts +0 -218
  196. package/ai/tools/paddleOcrTool.ts +0 -34
  197. package/ai/tools/prepareTools.ts +0 -23
  198. package/ai/tools/readDocTool.ts +0 -84
  199. package/ai/tools/readFileTool.ts +0 -211
  200. package/ai/tools/readTool.ts +0 -163
  201. package/ai/tools/readXPostTool.ts +0 -233
  202. package/ai/tools/rememberMemoryTool.ts +0 -84
  203. package/ai/tools/remotionVideoTool.ts +0 -151
  204. package/ai/tools/searchDialogMessagesTool.ts +0 -222
  205. package/ai/tools/searchRepoTool.ts +0 -115
  206. package/ai/tools/searchWorkspaceTool.ts +0 -259
  207. package/ai/tools/skillFollowup.ts +0 -86
  208. package/ai/tools/surfWeatherTool.ts +0 -169
  209. package/ai/tools/table/addTableRowTool.ts +0 -217
  210. package/ai/tools/table/createTableTool.ts +0 -315
  211. package/ai/tools/table/rowTools.ts +0 -366
  212. package/ai/tools/table/schemaTools.ts +0 -244
  213. package/ai/tools/table/shareTableTool.ts +0 -148
  214. package/ai/tools/table/toolShared.ts +0 -129
  215. package/ai/tools/toolApiClient.ts +0 -198
  216. package/ai/tools/toolNameAliases.ts +0 -57
  217. package/ai/tools/toolResultError.ts +0 -42
  218. package/ai/tools/toolRunSlice.ts +0 -303
  219. package/ai/tools/toolSchemaCompatibility.ts +0 -53
  220. package/ai/tools/toolVisibility.ts +0 -4
  221. package/ai/tools/types.ts +0 -20
  222. package/ai/tools/uiAskChoiceTool.ts +0 -104
  223. package/ai/tools/updateContentTitleTool.ts +0 -84
  224. package/ai/tools/updateDocTool.ts +0 -105
  225. package/ai/tools/updateUserPreferenceProfileTool.ts +0 -145
  226. package/ai/tools/whisperTool.ts +0 -77
  227. package/ai/tools/writeFileTool.ts +0 -210
  228. package/ai/tools/youtubeScraperTool.ts +0 -116
  229. package/ai/tools/ziweiChartTool.ts +0 -678
  230. package/ai/types.ts +0 -55
  231. package/ai/workflow/workflowExecutor.ts +0 -323
  232. package/ai/workflow/workflowSlice.ts +0 -73
  233. package/ai/workflow/workflowTypes.ts +0 -106
  234. package/client/compactDialog.ts +0 -222
  235. package/connector-experimental/capabilities.ts +0 -73
  236. package/connector-experimental/codexBinary.ts +0 -41
  237. package/connector-experimental/heartbeatLoop.ts +0 -22
  238. package/connector-experimental/index.ts +0 -5
  239. package/connector-experimental/machineInfo.ts +0 -46
  240. package/connector-experimental/protocol.ts +0 -54
@@ -1,264 +0,0 @@
1
- import { chooseMemoryOwners, loadMemoryCandidatesFromDb } from "./queryShared";
2
- import type { MemoryFacet, MemoryItem } from "./types";
3
-
4
- export interface UnderstandingGreetingResolution {
5
- item: MemoryItem | null;
6
- anchorItems: MemoryItem[];
7
- followUpItem: MemoryItem | null;
8
- }
9
-
10
- const UNDERSTANDING_TAG = "understanding-memory";
11
-
12
- const facetPriority: Record<MemoryFacet, number> = {
13
- unfinished: 5,
14
- tension: 4,
15
- preference: 3,
16
- style: 2,
17
- goal: 1,
18
- };
19
-
20
- const anchorFacetPriority: Record<MemoryFacet, number> = {
21
- preference: 3,
22
- style: 2,
23
- goal: 1,
24
- tension: 0,
25
- unfinished: 0,
26
- };
27
-
28
- const normalizeText = (value: string): string =>
29
- value.trim().replace(/[。!?!?]+$/u, "").trim();
30
-
31
- const stripPrefix = (text: string, prefix: string): string =>
32
- text.startsWith(prefix) ? text.slice(prefix.length).trim() : text;
33
-
34
- const toTimestamp = (item: MemoryItem): number => {
35
- const parsed = Date.parse(item.lastActivatedAt || item.createdAt);
36
- return Number.isFinite(parsed) ? parsed : 0;
37
- };
38
-
39
- const isUnderstandingItem = (item: MemoryItem): boolean =>
40
- Array.isArray(item.tags) && item.tags.includes(UNDERSTANDING_TAG);
41
-
42
- const sortByKindAndTime = (left: MemoryItem, right: MemoryItem): number => {
43
- if (left.kind !== right.kind) return left.kind === "semantic" ? -1 : 1;
44
- return toTimestamp(right) - toTimestamp(left);
45
- };
46
-
47
- const sameNormalizedContent = (left: string, right: string): boolean =>
48
- normalizeText(left).toLowerCase() === normalizeText(right).toLowerCase();
49
-
50
- const pickAnchorItems = (items: MemoryItem[]): MemoryItem[] => {
51
- const ranked = [...items]
52
- .filter((item) => (item.facet ? anchorFacetPriority[item.facet] > 0 : false))
53
- .sort((left, right) => {
54
- const leftFacet = left.facet ? anchorFacetPriority[left.facet] ?? 0 : 0;
55
- const rightFacet = right.facet ? anchorFacetPriority[right.facet] ?? 0 : 0;
56
- if (leftFacet !== rightFacet) return rightFacet - leftFacet;
57
- if (left.kind !== right.kind) return left.kind === "semantic" ? -1 : 1;
58
- if (left.content.length !== right.content.length) {
59
- return left.content.length - right.content.length;
60
- }
61
- return toTimestamp(right) - toTimestamp(left);
62
- });
63
-
64
- const selected: MemoryItem[] = [];
65
- for (const item of ranked) {
66
- if (
67
- selected.some((existing) =>
68
- sameNormalizedContent(existing.content, item.content) ||
69
- (existing.facet && item.facet && existing.facet === item.facet)
70
- )
71
- ) {
72
- continue;
73
- }
74
- selected.push(item);
75
- if (selected.length >= 2) break;
76
- }
77
- return selected;
78
- };
79
-
80
- const pickFollowUpItem = (items: MemoryItem[]): MemoryItem | null =>
81
- [...items]
82
- .filter((item) => item.facet === "unfinished" || item.facet === "tension")
83
- .sort((left, right) => {
84
- const leftFacet = left.facet ? facetPriority[left.facet] ?? 0 : 0;
85
- const rightFacet = right.facet ? facetPriority[right.facet] ?? 0 : 0;
86
- if (leftFacet !== rightFacet) return rightFacet - leftFacet;
87
- return sortByKindAndTime(left, right);
88
- })[0] ?? null;
89
-
90
- export const resolveUnderstandingGreetingMemory = async (input: {
91
- db: any;
92
- userId?: string | null;
93
- spaceId?: string | null;
94
- agentKey: string;
95
- }): Promise<UnderstandingGreetingResolution> => {
96
- const owners = chooseMemoryOwners({
97
- userId: input.userId,
98
- spaceId: input.spaceId,
99
- });
100
- if (owners.length === 0) {
101
- return { item: null, anchorItems: [], followUpItem: null };
102
- }
103
-
104
- const items = await loadMemoryCandidatesFromDb(input.db, {
105
- owners,
106
- subjects: [{ subjectType: "agent", subjectId: input.agentKey }],
107
- kinds: ["semantic", "episodic"],
108
- ownerLimit: 40,
109
- });
110
-
111
- const understandingItems = items.filter(isUnderstandingItem);
112
- if (understandingItems.length === 0) {
113
- return { item: null, anchorItems: [], followUpItem: null };
114
- }
115
-
116
- const ranked = [...understandingItems].sort((left, right) => {
117
- const leftFacet = left.facet ? facetPriority[left.facet] ?? 0 : 0;
118
- const rightFacet = right.facet ? facetPriority[right.facet] ?? 0 : 0;
119
- if (leftFacet !== rightFacet) return rightFacet - leftFacet;
120
- return sortByKindAndTime(left, right);
121
- });
122
-
123
- const anchorItems = pickAnchorItems(understandingItems);
124
- const followUpItem = pickFollowUpItem(understandingItems);
125
- const item = followUpItem ?? anchorItems[0] ?? ranked[0] ?? null;
126
-
127
- return {
128
- item,
129
- anchorItems,
130
- followUpItem,
131
- };
132
- };
133
-
134
- const renderLeadClause = (item: MemoryItem): string => {
135
- const content = normalizeText(item.content);
136
- switch (item.facet) {
137
- case "unfinished":
138
- return `我记得你上次还没定下来:${stripPrefix(content, "还没决定")}`;
139
- case "tension":
140
- return `我记得你上次还在权衡${stripPrefix(content, "在权衡")}`;
141
- case "style":
142
- case "preference":
143
- return `我记得你上次${content}`;
144
- case "goal":
145
- return `我记得你上次想推进的是${content}`;
146
- default:
147
- return `我记得你上次提过${content}`;
148
- }
149
- };
150
-
151
- const renderAnchorFragment = (item: MemoryItem): string => {
152
- const content = normalizeText(item.content);
153
- switch (item.facet) {
154
- case "preference":
155
- if (content.startsWith("更在意")) {
156
- return `更在意的是${stripPrefix(content, "更在意")}`;
157
- }
158
- if (content.startsWith("更关心")) {
159
- return `更关心的是${stripPrefix(content, "更关心")}`;
160
- }
161
- if (content.startsWith("更怕")) {
162
- return `更怕${stripPrefix(content, "更怕")}`;
163
- }
164
- if (content.startsWith("不想")) {
165
- return `不想${stripPrefix(content, "不想")}`;
166
- }
167
- if (content.startsWith("不希望")) {
168
- return `不希望${stripPrefix(content, "不希望")}`;
169
- }
170
- return content;
171
- case "style":
172
- if (content.startsWith("不喜欢")) {
173
- return `不太喜欢${stripPrefix(content, "不喜欢")}`;
174
- }
175
- if (content.startsWith("更喜欢")) {
176
- return `更喜欢${stripPrefix(content, "更喜欢")}`;
177
- }
178
- return content;
179
- case "goal":
180
- if (content.startsWith("想先")) {
181
- return `想先${stripPrefix(content, "想先")}`;
182
- }
183
- return `想推进的是${content}`;
184
- default:
185
- return content;
186
- }
187
- };
188
-
189
- const renderAnchorSentence = (items: MemoryItem[]): string | null => {
190
- if (items.length === 0) return null;
191
- const fragments = items
192
- .map(renderAnchorFragment)
193
- .map((fragment) => fragment.trim())
194
- .filter(Boolean);
195
- if (fragments.length === 0) return null;
196
- if (fragments.length === 1) {
197
- return `我记得你上次${fragments[0]}。`;
198
- }
199
- return `我记得你上次${fragments[0]},也${fragments[1]}。`;
200
- };
201
-
202
- const splitTradeoff = (value: string): [string, string] | null => {
203
- const normalized = normalizeText(value)
204
- .replace(/^在权衡/u, "")
205
- .replace(/^还没决定/u, "")
206
- .replace(/^还不确定/u, "")
207
- .replace(/^还没想好/u, "")
208
- .trim();
209
- if (!normalized.includes("还是")) return null;
210
-
211
- const [left, right] = normalized.split(/\s*还是/u, 2);
212
- const normalizedLeft = normalizeText((left ?? "").replace(/[,,::]+$/u, "").trim());
213
- const normalizedRight = normalizeText((right ?? "").trim());
214
- if (!normalizedLeft || !normalizedRight) return null;
215
- return [normalizedLeft, normalizedRight];
216
- };
217
-
218
- const renderFollowUpLine = (item: MemoryItem | null): string => {
219
- if (!item) {
220
- return "如果你想,我们可以接着上次那个点;如果今天是新问题,也直接说。";
221
- }
222
-
223
- const tradeoff = splitTradeoff(item.content);
224
- if (tradeoff) {
225
- return `如果你愿意,我们可以接着看:${tradeoff[0]},还是${tradeoff[1]}。如果今天是新问题,也直接说。`;
226
- }
227
-
228
- const content = normalizeText(item.content);
229
- switch (item.facet) {
230
- case "unfinished":
231
- return `如果你愿意,我们可以接着把${stripPrefix(content, "还没决定")}定下来;如果今天是新问题,也直接说。`;
232
- case "tension":
233
- return `如果你愿意,我们可以接着看${stripPrefix(content, "在权衡")};如果今天是新问题,也直接说。`;
234
- case "goal":
235
- return `如果你愿意,我们可以继续推进${stripPrefix(content, "想先")};如果今天是新问题,也直接说。`;
236
- default:
237
- return "如果你想,我们可以接着上次那个点;如果今天是新问题,也直接说。";
238
- }
239
- };
240
-
241
- export const mergeGreetingWithUnderstandingMemory = (input: {
242
- greetingText?: string;
243
- resolution?: UnderstandingGreetingResolution | null;
244
- item?: MemoryItem | null;
245
- }): string | null => {
246
- const greetingText = typeof input.greetingText === "string"
247
- ? input.greetingText.trim()
248
- : "";
249
- const resolution = input.resolution ?? null;
250
- const item = input.item ?? resolution?.item ?? null;
251
- if (!greetingText && !item) return null;
252
- if (!item) return greetingText || null;
253
-
254
- const anchorItems = resolution?.anchorItems ?? [];
255
- const followUpItem = resolution?.followUpItem ?? item;
256
- const leadLine = renderAnchorSentence(anchorItems) ?? `${renderLeadClause(item)}。`;
257
- const suffix = renderFollowUpLine(followUpItem);
258
- const memoryBlock = `欢迎回来。${leadLine}\n${suffix}`;
259
-
260
- if (!greetingText) {
261
- return memoryBlock;
262
- }
263
- return `${greetingText}\n\n${memoryBlock}`;
264
- };
@@ -1,20 +0,0 @@
1
- import { ClaudeContent } from "integrations/anthropic/type";
2
-
3
- export interface InputMessage {
4
- content:
5
- | Array<{
6
- text?: string;
7
- type: string;
8
- image_url?: {
9
- url: string;
10
- };
11
- }>
12
- | string;
13
- role: string;
14
- }
15
-
16
- export interface OutputMessage {
17
- role: string;
18
- content: string | ClaudeContent;
19
- images: string[];
20
- }
@@ -1,333 +0,0 @@
1
- import { noloAgentId } from "core/init";
2
- import { createDialog, initDialog } from "chat/dialog/dialogSlice";
3
- import { buildDialogUrl } from "chat/dialog/dialogUrl";
4
- import { prepareAndPersistMessage } from "chat/messages/messageSlice";
5
- import {
6
- uiAskChoiceFunc,
7
- uiAskChoiceFunctionSchema,
8
- } from "ai/tools/uiAskChoiceTool";
9
- import type { AgentRuntimeOptions } from "ai/agent/types";
10
-
11
- export type PersonalizationDialogSource = "signup" | "home";
12
-
13
- /**
14
- * 当前阶段,这个入口只负责“对话式编辑 User Overlay Profile”。
15
- * 未来它可以演进成引导用户创建属于自己的一个或多个 AI,
16
- * 但那会把偏好采集和 agent 创建耦合在一起,所以现在明确不做。
17
- *
18
- * 这里刻意继续复用 nolo,而不是单独拆一个 personalization-agent、
19
- * 也不是把它建模成 skill / first-class mode:
20
- * - 用户感知上,这仍然是“nolo 帮我做个性化设置”,一致感比内部抽象更重要;
21
- * - 当前只有这一条特殊入口,单独引入 agent/skill/mode 只会把同一套约束换个名字再实现一遍;
22
- * - 真正变化的是这个 dialog 的目标、允许的工具和策略上下文,所以先用 dialog category 承载。
23
- *
24
- * 以后如果出现第二、第三个长期存在的“特殊流程对话”,再考虑把这类 category 升级成统一抽象。
25
- */
26
- export const PERSONALIZATION_DIALOG_CATEGORY = "user-overlay-profile";
27
- export const PERSONALIZATION_DIALOG_EXTRA_TOOLS = [
28
- "ui_ask_choice",
29
- "updateUserPreferenceProfile",
30
- ] as const;
31
-
32
- type SupportedCopyLocale = "en" | "zh-CN" | "zh-TW" | "ja";
33
-
34
- const resolveCopyLocale = (language?: string | null): SupportedCopyLocale => {
35
- const normalized = (language || "").toLowerCase();
36
-
37
- if (normalized.startsWith("zh-tw") || normalized.startsWith("zh-hk")) {
38
- return "zh-TW";
39
- }
40
-
41
- if (normalized.startsWith("zh")) {
42
- return "zh-CN";
43
- }
44
-
45
- if (normalized.startsWith("ja")) {
46
- return "ja";
47
- }
48
-
49
- return "en";
50
- };
51
-
52
- export const buildPersonalizationDialogTitle = (
53
- language?: string | null,
54
- source: PersonalizationDialogSource = "home"
55
- ): string => {
56
- const locale = resolveCopyLocale(language);
57
-
58
- const titles = {
59
- en:
60
- source === "signup" ? "Set Up Your AI Preferences" : "Adjust AI Preferences",
61
- "zh-CN": source === "signup" ? "开始设置你的 AI 偏好" : "调整 AI 偏好",
62
- "zh-TW": source === "signup" ? "開始設定你的 AI 偏好" : "調整 AI 偏好",
63
- ja:
64
- source === "signup" ? "AI の好みを設定する" : "AI の好みを調整する",
65
- } as const;
66
-
67
- return titles[locale];
68
- };
69
-
70
- export const buildPersonalizationStarterPrompt = (
71
- language?: string | null,
72
- source: PersonalizationDialogSource = "home"
73
- ): string => {
74
- const locale = resolveCopyLocale(language);
75
-
76
- if (locale === "zh-CN") {
77
- return source === "signup"
78
- ? "我刚完成注册。请你作为我的个性化 AI 偏好助手,用最多 3 个简短问题帮我确认这三件事:1. 我偏好的交流语气;2. 值得沉淀的结果应该如何处理;3. 回答问题时是否应该读取当前空间,以及读取到什么程度。请保持简洁、像真正的对话,不要一次把所有选项都堆给我。在我确认之前,不要创建文档,不要修改或创建任何 AI。最后请把建议整理成明确设置项,方便我确认或调整。"
79
- : "我想通过对话调整我的 AI 偏好。请你作为个性化 AI 偏好助手,用最多 3 个简短问题帮我重新确认:1. 我偏好的交流语气;2. 值得沉淀的结果应该如何处理;3. 回答问题时是否应该读取当前空间,以及读取到什么程度。请保持简洁、像真正的对话。在我确认之前,不要创建文档,不要修改或创建任何 AI。最后请把建议整理成明确设置项,方便我确认或调整。";
80
- }
81
-
82
- if (locale === "zh-TW") {
83
- return source === "signup"
84
- ? "我剛完成註冊。請你作為我的個人化 AI 偏好助手,用最多 3 個簡短問題幫我確認這三件事:1. 我偏好的交流語氣;2. 值得沉澱的結果應該如何處理;3. 回答問題時是否應該讀取目前空間,以及讀取到什麼程度。請保持簡潔、像真正的對話,不要一次把所有選項都丟給我。在我確認之前,不要建立文件,不要修改或建立任何 AI。最後請把建議整理成明確設定項,方便我確認或調整。"
85
- : "我想透過對話調整我的 AI 偏好。請你作為個人化 AI 偏好助手,用最多 3 個簡短問題幫我重新確認:1. 我偏好的交流語氣;2. 值得沉澱的結果應該如何處理;3. 回答問題時是否應該讀取目前空間,以及讀取到什麼程度。請保持簡潔、像真正的對話。在我確認之前,不要建立文件,不要修改或建立任何 AI。最後請把建議整理成明確設定項,方便我確認或調整。";
86
- }
87
-
88
- if (locale === "ja") {
89
- return source === "signup"
90
- ? "登録したばかりです。あなたは私の AI 設定アシスタントとして、最大 3 つの短い質問で次の 3 点を確認してください。1. 好みの話し方 2. 価値のある結果をどのように知識化するか 3. 回答時に現在のスペースを読むべきか、どの程度読むか。長い説明ではなく自然な対話で進めてください。私が確認する前に、ドキュメントを作成したり、AI を作成・更新したりしないでください。最後に、確認しやすい設定項目として整理してください。"
91
- : "会話しながら AI の好みを調整したいです。あなたは設定アシスタントとして、最大 3 つの短い質問で次の 3 点を再確認してください。1. 好みの話し方 2. 価値のある結果をどのように知識化するか 3. 回答時に現在のスペースを読むべきか、どの程度読むか。自然な対話で簡潔に進めてください。私が確認する前に、ドキュメントを作成したり、AI を作成・更新したりしないでください。最後に、確認しやすい設定項目として整理してください。";
92
- }
93
-
94
- return source === "signup"
95
- ? "I just signed up. Act as my AI personalization assistant and use at most three short questions to confirm three things: 1. the tone I prefer, 2. how reusable results should be captured, and 3. whether you should read the current space when answering, and how aggressively. Keep it concise and conversational. Do not create documents, and do not create or modify any AI before I confirm. End by summarizing the recommended settings so I can confirm or adjust them."
96
- : "I want to adjust my AI preferences through conversation. Act as my AI personalization assistant and use at most three short questions to reconfirm three things: 1. the tone I prefer, 2. how reusable results should be captured, and 3. whether you should read the current space when answering, and how aggressively. Keep it concise and conversational. Do not create documents, and do not create or modify any AI before I confirm. End by summarizing the recommended settings so I can confirm or adjust them.";
97
- };
98
-
99
- export const buildPersonalizationRuntimeOptions = (
100
- runtimeOptions?: AgentRuntimeOptions
101
- ): AgentRuntimeOptions => ({
102
- ...runtimeOptions,
103
- extraTools: Array.from(
104
- new Set([
105
- ...(runtimeOptions?.extraTools ?? []),
106
- ...PERSONALIZATION_DIALOG_EXTRA_TOOLS,
107
- ])
108
- ),
109
- });
110
-
111
- export const buildPersonalizationDialogPolicyContext = (): string =>
112
- [
113
- "当前对话是“用户个性化设置”模式,不是普通闲聊。",
114
- "你的目标是用简短对话帮助用户确认 tone、knowledge_capture、space_context 这三项偏好。",
115
- "如果用户先介绍自己、工作方式或长期沟通偏好,请把这些可复用信息整理成简洁的 globalPrompt 草案,并在用户确认后通过 updateUserPreferenceProfile 保存。",
116
- "优先一次只问一个问题;当存在清晰互斥选项时,优先调用 ui_ask_choice。",
117
- "收集到足够信息后,调用 updateUserPreferenceProfile 保存结果,然后用自然语言总结已保存的设置。",
118
- "保存完成后,要提醒用户:以后也可以在设置里修改 globalPrompt 和这些偏好,或者再次打开这个入口继续调整。",
119
- "个性化设置完成后,可顺手引导用户尝试 1 到 2 个相关功能,例如首页快捷对话、创建笔记、创建 AI,但不要一次推荐太多。",
120
- "除非用户明确要求,否则不要创建文档,不要创建或修改任何 agent。",
121
- ].join("\n");
122
-
123
- const buildPersonalizationOpeningChoice = (
124
- language?: string | null,
125
- source: PersonalizationDialogSource = "home"
126
- ) => {
127
- const locale = resolveCopyLocale(language);
128
-
129
- if (locale === "zh-CN") {
130
- return {
131
- question:
132
- source === "signup"
133
- ? [
134
- "你好,我会帮你完成 **AI 偏好设置确认**。",
135
- "",
136
- "你可以直接快速设置,也可以先做个自我介绍,我会顺手帮你整理成全局提示词。",
137
- "",
138
- "你想怎么开始?",
139
- ].join("\n")
140
- : [
141
- "我们来调整一下你的 **AI 偏好设置**。",
142
- "",
143
- "你可以直接快速设置,也可以先做个自我介绍,我会顺手帮你整理成全局提示词。",
144
- "",
145
- "你想怎么开始?",
146
- ].join("\n"),
147
- choices: [
148
- {
149
- id: "quick_setup",
150
- label: "直接快速设置",
151
- userMessage:
152
- "直接开始快速设置吧。请用最多三个简短问题帮我确定语气、知识沉淀和空间读取偏好。",
153
- },
154
- {
155
- id: "intro_first",
156
- label: "先做自我介绍",
157
- userMessage:
158
- "我想先做个自我介绍。请根据我的介绍帮我整理一段适合写进全局提示词的内容,在我确认后保存,然后继续完成语气、知识沉淀和空间读取设置。",
159
- },
160
- {
161
- id: "show_capabilities",
162
- label: "先看看你能做什么",
163
- userMessage:
164
- "先用很短的话告诉我 nolo 在这里还能帮我做什么,然后继续带我完成个性化设置。",
165
- },
166
- ],
167
- };
168
- }
169
-
170
- if (locale === "zh-TW") {
171
- return {
172
- question:
173
- source === "signup"
174
- ? [
175
- "你好,我會幫你完成 **AI 偏好設定確認**。",
176
- "",
177
- "你可以直接快速設定,也可以先做個自我介紹,我會順手幫你整理成全域提示詞。",
178
- "",
179
- "你想怎麼開始?",
180
- ].join("\n")
181
- : [
182
- "我們來調整一下你的 **AI 偏好設定**。",
183
- "",
184
- "你可以直接快速設定,也可以先做個自我介紹,我會順手幫你整理成全域提示詞。",
185
- "",
186
- "你想怎麼開始?",
187
- ].join("\n"),
188
- choices: [
189
- {
190
- id: "quick_setup",
191
- label: "直接快速設定",
192
- userMessage:
193
- "直接開始快速設定吧。請用最多三個簡短問題幫我確定語氣、知識沉澱與空間讀取偏好。",
194
- },
195
- {
196
- id: "intro_first",
197
- label: "先做自我介紹",
198
- userMessage:
199
- "我想先做個自我介紹。請根據我的介紹幫我整理一段適合寫進全域提示詞的內容,在我確認後保存,然後繼續完成語氣、知識沉澱與空間讀取設定。",
200
- },
201
- {
202
- id: "show_capabilities",
203
- label: "先看看你能做什麼",
204
- userMessage:
205
- "先用很短的話告訴我 nolo 在這裡還能幫我做什麼,然後繼續帶我完成個人化設定。",
206
- },
207
- ],
208
- };
209
- }
210
-
211
- if (locale === "ja") {
212
- return {
213
- question:
214
- source === "signup"
215
- ? "**AI の好み設定** を進めます。\n\nすぐに設定を始めることもできますし、先に自己紹介してもらえれば、その内容を global prompt にまとめられます。\n\nどう始めますか?"
216
- : "**AI の好み設定** を調整しましょう。\n\nすぐに設定を始めることもできますし、先に自己紹介してもらえれば、その内容を global prompt にまとめられます。\n\nどう始めますか?",
217
- choices: [
218
- {
219
- id: "quick_setup",
220
- label: "すぐに設定する",
221
- userMessage:
222
- "すぐに設定を始めたいです。最大3つの短い質問で、話し方、知識化、スペース読取の好みを確認してください。",
223
- },
224
- {
225
- id: "intro_first",
226
- label: "先に自己紹介する",
227
- userMessage:
228
- "先に自己紹介したいです。私の紹介をもとに global prompt に入れる短い文を作って、確認後に保存し、そのあと残りの設定も進めてください。",
229
- },
230
- {
231
- id: "show_capabilities",
232
- label: "何ができるか先に見る",
233
- userMessage:
234
- "先に nolo がここで何をしてくれるのかを短く教えてください。そのあと個人設定を続けてください。",
235
- },
236
- ],
237
- };
238
- }
239
-
240
- return {
241
- question:
242
- source === "signup"
243
- ? "Let's set up your **AI preferences**.\n\nWe can either start with a quick setup, or you can introduce yourself first and I'll turn that into a reusable global prompt.\n\nHow do you want to begin?"
244
- : "Let's adjust your **AI preferences**.\n\nWe can either start with a quick setup, or you can introduce yourself first and I'll turn that into a reusable global prompt.\n\nHow do you want to begin?",
245
- choices: [
246
- {
247
- id: "quick_setup",
248
- label: "Start quick setup",
249
- userMessage:
250
- "Start the quick setup. Ask me at most three short questions to confirm my tone, knowledge capture, and space-reading preferences.",
251
- },
252
- {
253
- id: "intro_first",
254
- label: "Let me introduce myself first",
255
- userMessage:
256
- "I want to introduce myself first. Please turn my introduction into a concise global prompt draft, save it after I confirm, and then continue the rest of the personalization setup.",
257
- },
258
- {
259
- id: "show_capabilities",
260
- label: "Show what nolo can do first",
261
- userMessage:
262
- "First, briefly show me what nolo can help me do here, then continue the personalization setup.",
263
- },
264
- ],
265
- };
266
- };
267
-
268
- export interface StartPersonalizationDialogParams {
269
- dispatch: any;
270
- navigate: (to: string, options?: { state?: Record<string, unknown> }) => void;
271
- language?: string | null;
272
- source?: PersonalizationDialogSource;
273
- }
274
-
275
- export const startPersonalizationDialog = async ({
276
- dispatch,
277
- navigate,
278
- language,
279
- source = "home",
280
- }: StartPersonalizationDialogParams): Promise<string> => {
281
- const result = await dispatch(
282
- createDialog({
283
- cybots: [noloAgentId],
284
- skipGreeting: true,
285
- title: buildPersonalizationDialogTitle(language, source),
286
- category: PERSONALIZATION_DIALOG_CATEGORY,
287
- })
288
- ).unwrap();
289
-
290
- const dialogKey = (result as { dbKey?: string } | undefined)?.dbKey ?? "";
291
- const dialogSpaceId =
292
- (result as { spaceId?: string | null } | undefined)?.spaceId ?? null;
293
-
294
- if (!dialogKey) {
295
- throw new Error("Personalization dialog key is missing.");
296
- }
297
-
298
- await dispatch(initDialog(dialogKey)).unwrap();
299
- const openingChoice = buildPersonalizationOpeningChoice(language, source);
300
- const toolResult = await uiAskChoiceFunc(
301
- {
302
- question: openingChoice.question,
303
- choices: openingChoice.choices,
304
- blocking: true,
305
- },
306
- { dispatch }
307
- );
308
-
309
- await dispatch(
310
- prepareAndPersistMessage({
311
- message: {
312
- role: "tool",
313
- toolName: uiAskChoiceFunctionSchema.name,
314
- cybotKey: noloAgentId,
315
- content: toolResult.rawData,
316
- displayData: toolResult.displayData,
317
- },
318
- dialogConfig: {
319
- id: dialogKey.split("-").at(-1),
320
- dbKey: dialogKey,
321
- },
322
- })
323
- );
324
-
325
- navigate(buildDialogUrl(dialogKey, dialogSpaceId), {
326
- state: {
327
- isNew: true,
328
- personalizationSource: source,
329
- },
330
- });
331
-
332
- return dialogKey;
333
- };