nolo-cli 0.1.41 → 0.1.43
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/README.md +27 -12
- package/agent-runtime/agentThread.ts +222 -0
- package/agent-runtime/agentThreadAdmission.ts +74 -0
- package/agent-runtime/dialogWritePlan.ts +42 -0
- package/agent-runtime/hostAdapter.ts +1 -0
- package/agent-runtime/index.ts +43 -0
- package/agent-runtime/localLoop.ts +31 -2
- package/agent-runtime/localToolPolicy.ts +1 -0
- package/agent-runtime/localWorkspaceTools.ts +1258 -78
- package/agent-runtime/noloWorkspaceTools.ts +20 -1
- package/agent-runtime/runtimeToolPolicy.ts +1 -5
- package/agent-runtime/runtimeToolSurface.ts +1 -0
- package/agentAliases.ts +29 -9
- package/agentInternalCommandEntries.ts +11 -3
- package/agentMachineCommands.ts +1 -0
- package/agentRecordCommands.ts +2 -2
- package/agentRecordHelpers.ts +59 -6
- package/agentRunCommand.ts +84 -19
- package/ai/agent/buildSystemPrompt.ts +14 -0
- package/ai/agent/cliExecutor.ts +202 -43
- package/ai/agent/createAgentSchema.ts +2 -2
- package/ai/agent/liveAudioModel.ts +1 -1
- package/ai/agent/streamAgentChatTurn.ts +154 -20
- package/ai/agent/streamAgentChatTurnUtils.ts +63 -0
- package/ai/ai.locale.ts +70 -0
- package/ai/chat/inlineImageUrlsForCustomProvider.ts +7 -2
- package/ai/chat/sendOpenAICompletionsRequest.ts +25 -1
- package/ai/llm/kimi.ts +0 -1
- package/ai/llm/openrouterModels.ts +27 -2
- package/ai/memory/policy.ts +49 -0
- package/ai/memory/queryShared.ts +10 -4
- package/ai/memory/recentRelationshipRecap.ts +4 -0
- package/ai/memory/remember.ts +48 -104
- package/ai/memory/scope.ts +74 -0
- package/ai/memory/types.ts +6 -0
- package/ai/memory/understanding.ts +10 -18
- package/ai/policy/runtimePolicy.ts +95 -23
- package/ai/tools/agent/agentTools.ts +0 -21
- package/ai/tools/agent/startAgentDialogTool.ts +2 -1
- package/ai/tools/index.ts +2 -20
- package/ai/tools/prepareTools.ts +171 -1
- package/ai/tools/readXhsProfileTool.ts +80 -69
- package/ai/tools/table/createTableTool.ts +11 -0
- package/ai/tools/toolPacks.ts +19 -0
- package/ai/types.ts +3 -0
- package/app/favorite/deletedFavoriteProjection.ts +31 -0
- package/app/hooks/deleteDbKey.ts +24 -3
- package/app/i18n/translations/interface.locale.ts +48 -16
- package/app/types/appSummary.ts +4 -0
- package/app/utils/desktopAgentRuntimeTurnClient.ts +2 -0
- package/auth/adminPermissions.ts +64 -4
- package/auth/routes.ts +5 -0
- package/chat/chat.locale.ts +4 -0
- package/chat/dialog/actions/handleSendMessageAction.ts +7 -2
- package/chat/dialog/dialogAttachmentCleanup.ts +135 -0
- package/chat/dialog/dialogSlice.ts +117 -4
- package/chat/messages/activityCompletion.ts +97 -0
- package/chat/messages/imagePayloadPersistence.ts +22 -0
- package/chat/messages/messageContent.ts +20 -16
- package/chat/messages/messageSlice.ts +20 -1
- package/chat/messages/toolThunks.ts +32 -11
- package/chat/messages/types.ts +8 -1
- package/chat/messages/web/toolDisplayName.ts +686 -0
- package/cli/agentAliases.ts +29 -9
- package/cli/agentInternalCommandEntries.ts +11 -3
- package/cli/agentMachineCommands.ts +1 -0
- package/cli/agentRecordCommands.ts +2 -2
- package/cli/agentRecordHelpers.ts +59 -6
- package/cli/agentRunCommand.ts +84 -19
- package/cli/client/agentRun.ts +65 -253
- package/cli/client/localRuntimeAdapter.ts +179 -53
- package/cli/commandRegistry.ts +7 -4
- package/cli/dialogAttachmentCleanup.ts +151 -0
- package/cli/dialogCommands.ts +163 -61
- package/cli/dialogInternalCommandEntries.ts +1 -1
- package/cli/docCreateCommands.ts +345 -0
- package/cli/docInternalCommandEntries.ts +11 -0
- package/cli/docPageHelpers.ts +80 -0
- package/cli/docSkillHelpers.ts +67 -0
- package/cli/docSpaceHelpers.ts +46 -0
- package/cli/internalCommandEntries.ts +4 -0
- package/cli/machineCommands.ts +18 -34
- package/cli/memoryCommands.ts +253 -0
- package/cli/memoryInternalCommandEntries.ts +9 -0
- package/cli/qoderUsageProbe.ts +252 -0
- package/cli/scriptCommandEntries.ts +0 -3
- package/cli/secretScan.ts +31 -0
- package/cli/tableCommands.ts +248 -13
- package/cli/workflowInternalCommandEntries.ts +2 -3
- package/client/agentRun.test.ts +68 -84
- package/client/agentRun.ts +65 -253
- package/client/localRuntimeAdapter.test.ts +505 -74
- package/client/localRuntimeAdapter.ts +179 -53
- package/commandRegistry.ts +7 -4
- package/connector-experimental/capabilities.ts +10 -9
- package/create/space/sidebarVisibleTypes.ts +19 -0
- package/dialogAttachmentCleanup.ts +151 -0
- package/dialogCommands.ts +163 -61
- package/dialogInternalCommandEntries.ts +1 -1
- package/docCreateCommands.ts +345 -0
- package/docInternalCommandEntries.ts +11 -0
- package/docPageHelpers.ts +80 -0
- package/docSkillHelpers.ts +67 -0
- package/docSpaceHelpers.ts +46 -0
- package/integrations/google/models.ts +4 -4
- package/integrations/openai/generateOpenAIRequestBody.ts +0 -3
- package/integrations/xhs-reader/types.ts +36 -3
- package/integrations/xhs-reader/url.ts +24 -1
- package/internalCommandEntries.ts +4 -0
- package/machineCommands.ts +18 -34
- package/memoryCommands.ts +253 -0
- package/memoryInternalCommandEntries.ts +9 -0
- package/package.json +141 -114
- package/qoderUsageProbe.ts +252 -0
- package/render/contentIcon/types.ts +167 -0
- package/render/page/docSlice.ts +30 -3
- package/render/page/types.ts +2 -0
- package/render/table/createTableAction.ts +4 -0
- package/render/table/tableSlice.ts +61 -0
- package/render/table/types.ts +10 -0
- package/scriptCommandEntries.ts +0 -3
- package/secretScan.ts +31 -0
- package/server/handlers/agentRun/types.ts +24 -23
- package/tableCommands.ts +248 -13
- package/workflowInternalCommandEntries.ts +2 -3
- package/ai/tools/agent/taskRunTool.ts +0 -112
- package/cli/client/taskRunPrompt.ts +0 -27
- package/cli/taskRunCommand.ts +0 -265
- package/client/taskRunPrompt.ts +0 -27
- package/integrations/xhs-reader/analyze/profileAnalyzer.ts +0 -205
- package/integrations/xhs-reader/backends/playwrightProfileCollector.ts +0 -624
- package/integrations/xhs-reader/bridge/readXhsProfileWithBridge.ts +0 -227
- package/integrations/xhs-reader/client/xhsWebApiClient.ts +0 -229
- package/integrations/xhs-reader/normalize.ts +0 -390
- package/integrations/xhs-reader/orchestrator.ts +0 -178
- package/taskRunCommand.ts +0 -265
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { serializeMessageContent } from "./messageContent";
|
|
2
|
+
import {
|
|
3
|
+
buildActivityTimeline,
|
|
4
|
+
type ToolActivityStatus,
|
|
5
|
+
} from "./web/toolDisplayName";
|
|
6
|
+
|
|
7
|
+
type ActivityMessage = Parameters<typeof buildActivityTimeline>[0][number];
|
|
8
|
+
|
|
9
|
+
type AssistantActivityCompletionInput = {
|
|
10
|
+
messages: ActivityMessage[];
|
|
11
|
+
finalContent: unknown;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type AssistantActivityCompletionMetadata = {
|
|
15
|
+
activity: {
|
|
16
|
+
phase: {
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
index?: number;
|
|
20
|
+
total?: number;
|
|
21
|
+
status: Extract<ToolActivityStatus, "success">;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const FINAL_DELIVERY_PHASE_PATTERNS = [
|
|
27
|
+
/汇报/,
|
|
28
|
+
/回复/,
|
|
29
|
+
/总结/,
|
|
30
|
+
/结果/,
|
|
31
|
+
/交付/,
|
|
32
|
+
/可视化/,
|
|
33
|
+
/图表/,
|
|
34
|
+
/report/i,
|
|
35
|
+
/deliver/i,
|
|
36
|
+
/result/i,
|
|
37
|
+
/summary/i,
|
|
38
|
+
/visual/i,
|
|
39
|
+
/chart/i,
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
const FAILED_FINAL_CONTENT_PATTERNS = [
|
|
43
|
+
/抱歉/,
|
|
44
|
+
/无法/,
|
|
45
|
+
/不能/,
|
|
46
|
+
/失败/,
|
|
47
|
+
/出错/,
|
|
48
|
+
/未完成/,
|
|
49
|
+
/cannot/i,
|
|
50
|
+
/can't/i,
|
|
51
|
+
/failed/i,
|
|
52
|
+
/error/i,
|
|
53
|
+
/unable/i,
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
function isLikelyFinalDeliveryPhase(title: string): boolean {
|
|
57
|
+
return FINAL_DELIVERY_PHASE_PATTERNS.some((pattern) => pattern.test(title));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function isLikelyFailedFinalContent(text: string): boolean {
|
|
61
|
+
return FAILED_FINAL_CONTENT_PATTERNS.some((pattern) => pattern.test(text));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function inferAssistantActivityCompletionMetadata({
|
|
65
|
+
messages,
|
|
66
|
+
finalContent,
|
|
67
|
+
}: AssistantActivityCompletionInput): AssistantActivityCompletionMetadata | undefined {
|
|
68
|
+
const finalText = serializeMessageContent(finalContent, "[图片]")?.trim();
|
|
69
|
+
if (!finalText || isLikelyFailedFinalContent(finalText)) return undefined;
|
|
70
|
+
|
|
71
|
+
const timeline = buildActivityTimeline(messages);
|
|
72
|
+
if (timeline.totalPhases <= 1 || timeline.completedPhases >= timeline.totalPhases) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const finalPhase = timeline.phases[timeline.phases.length - 1];
|
|
77
|
+
if (!finalPhase || finalPhase.status !== "pending") return undefined;
|
|
78
|
+
|
|
79
|
+
const priorPhases = timeline.phases.slice(0, -1);
|
|
80
|
+
if (priorPhases.length === 0 || priorPhases.some((phase) => phase.status !== "success")) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!isLikelyFinalDeliveryPhase(finalPhase.title)) return undefined;
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
activity: {
|
|
88
|
+
phase: {
|
|
89
|
+
id: finalPhase.id,
|
|
90
|
+
title: finalPhase.title,
|
|
91
|
+
...(finalPhase.index !== undefined ? { index: finalPhase.index } : {}),
|
|
92
|
+
...(finalPhase.total !== undefined ? { total: finalPhase.total } : {}),
|
|
93
|
+
status: "success",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type ImagePayloadPart = Record<string, any>;
|
|
2
|
+
|
|
3
|
+
export const stripDurableImageInlinePayload = <T extends ImagePayloadPart>(
|
|
4
|
+
part: T,
|
|
5
|
+
): T => {
|
|
6
|
+
if (!part || typeof part !== "object") return part;
|
|
7
|
+
|
|
8
|
+
const { original_data_url: _originalDataUrl, ...withoutOriginalDataUrl } =
|
|
9
|
+
part;
|
|
10
|
+
|
|
11
|
+
if (
|
|
12
|
+
withoutOriginalDataUrl.type !== "image_url" ||
|
|
13
|
+
!withoutOriginalDataUrl.google_native ||
|
|
14
|
+
typeof withoutOriginalDataUrl.google_native !== "object"
|
|
15
|
+
) {
|
|
16
|
+
return withoutOriginalDataUrl as T;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { google_native: _googleNative, ...durablePart } =
|
|
20
|
+
withoutOriginalDataUrl;
|
|
21
|
+
return durablePart as T;
|
|
22
|
+
};
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
import type { RootState } from "../../app/store";
|
|
11
11
|
import { upload } from "../../database/dbSlice";
|
|
12
12
|
import { getRuntimeServerContext } from "../../database/runtimeServerContext";
|
|
13
|
+
import { dataURLtoFile, waitForFileReady } from "../../app/utils/imageUtils";
|
|
13
14
|
import { buildMessageFileContentUrl } from "./fileUrl";
|
|
14
15
|
|
|
15
16
|
import { ContentType } from "../../app/types";
|
|
16
17
|
import { addContentAction } from "../../create/space/content/addContentAction";
|
|
18
|
+
import { stripDurableImageInlinePayload } from "./imagePayloadPersistence";
|
|
17
19
|
|
|
18
20
|
/** 判断 URL 是否为 data:image 开头的 dataURL */
|
|
19
21
|
const isDataUrlImage = (url: unknown): url is string =>
|
|
@@ -21,7 +23,7 @@ const isDataUrlImage = (url: unknown): url is string =>
|
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
25
|
* 将生成的 dataURL 图片上传为文件,并返回最终 URL。
|
|
24
|
-
*
|
|
26
|
+
* 失败时返回 null,避免把大 base64 图片持久化进 message。
|
|
25
27
|
*/
|
|
26
28
|
const uploadGeneratedImageDataUrl = async (
|
|
27
29
|
url: string,
|
|
@@ -31,16 +33,15 @@ const uploadGeneratedImageDataUrl = async (
|
|
|
31
33
|
dispatch: any,
|
|
32
34
|
getState: () => RootState,
|
|
33
35
|
options?: { spaceId?: string; agentName?: string }
|
|
34
|
-
): Promise<string> => {
|
|
36
|
+
): Promise<string | null> => {
|
|
35
37
|
const fileName = `generated-image-${dialogId}-${messageId}-${index}.png`;
|
|
36
|
-
const { dataURLtoFile, waitForFileReady } = await import("../../app/utils/imageUtils");
|
|
37
38
|
const file = dataURLtoFile(url, fileName);
|
|
38
39
|
|
|
39
40
|
if (!file) {
|
|
40
41
|
console.warn(
|
|
41
|
-
"[messageContent] dataURLtoFile failed,
|
|
42
|
+
"[messageContent] dataURLtoFile failed, drop generated image inline payload"
|
|
42
43
|
);
|
|
43
|
-
return
|
|
44
|
+
return null;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
const customKey = `generated-image-${dialogId}-${messageId}-${index}`;
|
|
@@ -50,10 +51,10 @@ const uploadGeneratedImageDataUrl = async (
|
|
|
50
51
|
metadata = await dispatch(upload({ file, customKey }) as any).unwrap();
|
|
51
52
|
} catch (err) {
|
|
52
53
|
console.warn(
|
|
53
|
-
"[messageContent] upload generated image failed,
|
|
54
|
+
"[messageContent] upload generated image failed, drop inline payload:",
|
|
54
55
|
err
|
|
55
56
|
);
|
|
56
|
-
return
|
|
57
|
+
return null;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
const state = getState() as RootState;
|
|
@@ -62,10 +63,10 @@ const uploadGeneratedImageDataUrl = async (
|
|
|
62
63
|
|
|
63
64
|
if (!currentServer || !fileId) {
|
|
64
65
|
console.warn(
|
|
65
|
-
"[messageContent] missing currentServer or fileId,
|
|
66
|
+
"[messageContent] missing currentServer or fileId, drop inline payload",
|
|
66
67
|
{ currentServer, fileId }
|
|
67
68
|
);
|
|
68
|
-
return
|
|
69
|
+
return null;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
// 如果提供了 spaceId,尝试保存到空间内容
|
|
@@ -89,16 +90,16 @@ const uploadGeneratedImageDataUrl = async (
|
|
|
89
90
|
|
|
90
91
|
const imageUrl = buildMessageFileContentUrl(currentServer, fileId);
|
|
91
92
|
if (!imageUrl) {
|
|
92
|
-
return
|
|
93
|
+
return null;
|
|
93
94
|
}
|
|
94
95
|
const ready = await waitForFileReady(imageUrl);
|
|
95
96
|
|
|
96
97
|
if (!ready) {
|
|
97
98
|
console.warn(
|
|
98
|
-
"[messageContent] uploaded generated image not ready,
|
|
99
|
+
"[messageContent] uploaded generated image not ready, drop inline payload:",
|
|
99
100
|
imageUrl
|
|
100
101
|
);
|
|
101
|
-
return
|
|
102
|
+
return null;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
return imageUrl;
|
|
@@ -144,17 +145,20 @@ export const normalizeAssistantContentBuffer = async (
|
|
|
144
145
|
options
|
|
145
146
|
);
|
|
146
147
|
|
|
147
|
-
if (newUrl
|
|
148
|
-
return
|
|
148
|
+
if (!newUrl) {
|
|
149
|
+
return {
|
|
150
|
+
type: "text",
|
|
151
|
+
text: "[图片保存失败,请重试生成图片]",
|
|
152
|
+
};
|
|
149
153
|
}
|
|
150
154
|
|
|
151
|
-
return {
|
|
155
|
+
return stripDurableImageInlinePayload({
|
|
152
156
|
...part,
|
|
153
157
|
image_url: {
|
|
154
158
|
...part.image_url,
|
|
155
159
|
url: newUrl,
|
|
156
160
|
},
|
|
157
|
-
};
|
|
161
|
+
});
|
|
158
162
|
})
|
|
159
163
|
);
|
|
160
164
|
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
appendSaveFailureToContent,
|
|
36
36
|
finalizeAssistantMessageContent,
|
|
37
37
|
} from "./messageContract";
|
|
38
|
+
import { inferAssistantActivityCompletionMetadata } from "./activityCompletion";
|
|
38
39
|
import { estimateMissingUsage } from "../../ai/token/missingUsageEstimate";
|
|
39
40
|
import {
|
|
40
41
|
countImageGenerationOutputsInContent,
|
|
@@ -837,6 +838,23 @@ export const messageSlice = createSliceWithThunks({
|
|
|
837
838
|
const agentName = rawName || undefined;
|
|
838
839
|
const { imageGenerationState: _transientImageGenerationState, ...persistedMessageMetadata } =
|
|
839
840
|
payload.messageMetadata ?? {};
|
|
841
|
+
const {
|
|
842
|
+
metadata: persistedMetadata,
|
|
843
|
+
...otherPersistedMessageMetadata
|
|
844
|
+
} = persistedMessageMetadata;
|
|
845
|
+
const shouldInferActivityCompletion =
|
|
846
|
+
!(persistedMetadata as Record<string, unknown> | undefined)?.activity &&
|
|
847
|
+
(!toolCalls || toolCalls.length === 0);
|
|
848
|
+
const inferredActivityCompletionMetadata = shouldInferActivityCompletion
|
|
849
|
+
? inferAssistantActivityCompletionMetadata({
|
|
850
|
+
messages: selectAllMsgs(getState() as RootState, dialogId),
|
|
851
|
+
finalContent: finalVisibleContent,
|
|
852
|
+
})
|
|
853
|
+
: undefined;
|
|
854
|
+
const finalMetadata =
|
|
855
|
+
inferredActivityCompletionMetadata
|
|
856
|
+
? { ...(persistedMetadata ?? {}), ...inferredActivityCompletionMetadata }
|
|
857
|
+
: persistedMetadata;
|
|
840
858
|
|
|
841
859
|
const finalMessage: Message = {
|
|
842
860
|
id: messageId,
|
|
@@ -848,7 +866,8 @@ export const messageSlice = createSliceWithThunks({
|
|
|
848
866
|
cybotKey: agentConfig.dbKey,
|
|
849
867
|
usage: finalUsageData,
|
|
850
868
|
isStreaming: false,
|
|
851
|
-
...
|
|
869
|
+
...otherPersistedMessageMetadata,
|
|
870
|
+
...(finalMetadata ? { metadata: finalMetadata } : {}),
|
|
852
871
|
...(agentName ? { agentName } : {}),
|
|
853
872
|
...(toolCalls && toolCalls.length > 0
|
|
854
873
|
? { tool_calls: toolCalls }
|
|
@@ -107,7 +107,23 @@ const processToolData = createAsyncThunk(
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
const
|
|
110
|
+
const activity =
|
|
111
|
+
toolArgs &&
|
|
112
|
+
typeof toolArgs === "object" &&
|
|
113
|
+
!Array.isArray(toolArgs) &&
|
|
114
|
+
toolArgs._activity &&
|
|
115
|
+
typeof toolArgs._activity === "object"
|
|
116
|
+
? toolArgs._activity
|
|
117
|
+
: undefined;
|
|
118
|
+
const executionToolArgs =
|
|
119
|
+
toolArgs &&
|
|
120
|
+
typeof toolArgs === "object" &&
|
|
121
|
+
!Array.isArray(toolArgs) &&
|
|
122
|
+
Object.prototype.hasOwnProperty.call(toolArgs, "_activity")
|
|
123
|
+
? (({ _activity: _ignored, ...rest }) => rest)(toolArgs)
|
|
124
|
+
: toolArgs;
|
|
125
|
+
|
|
126
|
+
const inputSummary = JSON.stringify(executionToolArgs).slice(0, 400);
|
|
111
127
|
|
|
112
128
|
dispatch(
|
|
113
129
|
toolRunStarted({
|
|
@@ -117,7 +133,7 @@ const processToolData = createAsyncThunk(
|
|
|
117
133
|
behavior,
|
|
118
134
|
inputSummary,
|
|
119
135
|
interaction,
|
|
120
|
-
input:
|
|
136
|
+
input: executionToolArgs,
|
|
121
137
|
})
|
|
122
138
|
);
|
|
123
139
|
|
|
@@ -128,7 +144,7 @@ const processToolData = createAsyncThunk(
|
|
|
128
144
|
|
|
129
145
|
const previewExecutor = def?.previewExecutor;
|
|
130
146
|
const previewResult = previewExecutor
|
|
131
|
-
? await previewExecutor(
|
|
147
|
+
? await previewExecutor(executionToolArgs, thunkApi, { parentMessageId })
|
|
132
148
|
: {
|
|
133
149
|
rawData: {
|
|
134
150
|
previewOnly: true,
|
|
@@ -149,10 +165,11 @@ const processToolData = createAsyncThunk(
|
|
|
149
165
|
const toolPayload: ToolPayload = {
|
|
150
166
|
toolName: canonicalName,
|
|
151
167
|
status: "pending",
|
|
152
|
-
input:
|
|
168
|
+
input: executionToolArgs,
|
|
153
169
|
rawToolCall: toolCall,
|
|
154
170
|
toolRunId,
|
|
155
171
|
summary,
|
|
172
|
+
...(activity ? { activity } : {}),
|
|
156
173
|
};
|
|
157
174
|
|
|
158
175
|
return {
|
|
@@ -191,11 +208,12 @@ const processToolData = createAsyncThunk(
|
|
|
191
208
|
const toolPayload: ToolPayload = {
|
|
192
209
|
toolName: canonicalName,
|
|
193
210
|
status: "failed",
|
|
194
|
-
input:
|
|
211
|
+
input: executionToolArgs,
|
|
195
212
|
rawToolCall: toolCall,
|
|
196
213
|
error: errorPayload,
|
|
197
214
|
toolRunId,
|
|
198
215
|
summary,
|
|
216
|
+
...(activity ? { activity } : {}),
|
|
199
217
|
};
|
|
200
218
|
|
|
201
219
|
return rejectWithValue({
|
|
@@ -212,7 +230,7 @@ const processToolData = createAsyncThunk(
|
|
|
212
230
|
|
|
213
231
|
// ========= 分支二:auto 工具(包括 ui_ask_choice / readFile / createPlan 等) =========
|
|
214
232
|
try {
|
|
215
|
-
const toolResult = await found.executor(
|
|
233
|
+
const toolResult = await found.executor(executionToolArgs, thunkApi, {
|
|
216
234
|
parentMessageId,
|
|
217
235
|
toolRunId,
|
|
218
236
|
});
|
|
@@ -239,18 +257,19 @@ const processToolData = createAsyncThunk(
|
|
|
239
257
|
const toolPayload: ToolPayload = {
|
|
240
258
|
toolName: canonicalName,
|
|
241
259
|
status: "succeeded",
|
|
242
|
-
input:
|
|
260
|
+
input: executionToolArgs,
|
|
243
261
|
rawToolCall: toolCall,
|
|
244
262
|
toolRunId,
|
|
245
263
|
summary,
|
|
246
264
|
...(llmContext ? { llmContext } : {}),
|
|
265
|
+
...(activity ? { activity } : {}),
|
|
247
266
|
};
|
|
248
267
|
|
|
249
268
|
// ✅ 关键:ui_ask_choice(blocking=true) 也视作“暂停点”
|
|
250
269
|
const isUiAskChoice = canonicalName === "ui_ask_choice";
|
|
251
270
|
const blocking =
|
|
252
|
-
typeof
|
|
253
|
-
?
|
|
271
|
+
typeof executionToolArgs?.blocking === "boolean"
|
|
272
|
+
? executionToolArgs.blocking
|
|
254
273
|
: true; // schema 默认 true
|
|
255
274
|
|
|
256
275
|
const hasPendingInteraction =
|
|
@@ -274,7 +293,7 @@ const processToolData = createAsyncThunk(
|
|
|
274
293
|
|
|
275
294
|
if (requiresConfirmation) {
|
|
276
295
|
const confirmedInput = {
|
|
277
|
-
...(
|
|
296
|
+
...(executionToolArgs ?? {}),
|
|
278
297
|
__confirmedSelfEvolution: true,
|
|
279
298
|
};
|
|
280
299
|
const summary =
|
|
@@ -302,6 +321,7 @@ const processToolData = createAsyncThunk(
|
|
|
302
321
|
rawToolCall: toolCall,
|
|
303
322
|
toolRunId,
|
|
304
323
|
summary,
|
|
324
|
+
...(activity ? { activity } : {}),
|
|
305
325
|
};
|
|
306
326
|
|
|
307
327
|
return {
|
|
@@ -342,11 +362,12 @@ const processToolData = createAsyncThunk(
|
|
|
342
362
|
const toolPayload: ToolPayload = {
|
|
343
363
|
toolName: canonicalName,
|
|
344
364
|
status: "failed",
|
|
345
|
-
input:
|
|
365
|
+
input: executionToolArgs,
|
|
346
366
|
rawToolCall: toolCall,
|
|
347
367
|
error: errorPayload,
|
|
348
368
|
toolRunId,
|
|
349
369
|
summary,
|
|
370
|
+
...(activity ? { activity } : {}),
|
|
350
371
|
};
|
|
351
372
|
|
|
352
373
|
return rejectWithValue({
|
package/chat/messages/types.ts
CHANGED
|
@@ -16,7 +16,7 @@ export interface OpenAIImageContent {
|
|
|
16
16
|
detail?: "low" | "high" | "auto";
|
|
17
17
|
};
|
|
18
18
|
google_native?: {
|
|
19
|
-
inlineData
|
|
19
|
+
inlineData?: {
|
|
20
20
|
mimeType: string;
|
|
21
21
|
data: string;
|
|
22
22
|
};
|
|
@@ -112,6 +112,12 @@ export interface ToolPayload {
|
|
|
112
112
|
*/
|
|
113
113
|
summary?: string;
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Human-readable tool activity hint for UI projection.
|
|
117
|
+
* Execution output remains in message.content; this is display metadata only.
|
|
118
|
+
*/
|
|
119
|
+
activity?: unknown;
|
|
120
|
+
|
|
115
121
|
/**
|
|
116
122
|
* 提供给下一轮 LLM 的结构化上下文补充。
|
|
117
123
|
* 典型场景:工具真实产物(如 fileId / 可复用 URL)不能只靠 summary 传达。
|
|
@@ -153,6 +159,7 @@ export interface Message {
|
|
|
153
159
|
imageGenerationState?: ImageGenerationState;
|
|
154
160
|
userId?: string;
|
|
155
161
|
usage?: any;
|
|
162
|
+
metadata?: Record<string, unknown>;
|
|
156
163
|
|
|
157
164
|
controller?: AbortController;
|
|
158
165
|
|