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.
- package/README.md +0 -32
- package/agentRuntimeCommands.ts +3 -3
- package/commandRegistry.ts +2 -2
- package/machineCommands.ts +31 -6
- package/package.json +6 -8
- package/ai/agent/_executeModel.ts +0 -118
- package/ai/agent/agentSlice.ts +0 -525
- package/ai/agent/appWorkingMemory.ts +0 -126
- package/ai/agent/avatarUtils.ts +0 -24
- package/ai/agent/buildEditingContext.ts +0 -373
- package/ai/agent/buildSystemPrompt.ts +0 -532
- package/ai/agent/cleanAgentMessages.ts +0 -140
- package/ai/agent/cliChatClient.ts +0 -119
- package/ai/agent/cliExecutor.ts +0 -733
- package/ai/agent/cliPrompt.ts +0 -10
- package/ai/agent/contextCompiler.ts +0 -107
- package/ai/agent/contextLayerContract.ts +0 -44
- package/ai/agent/createAgentSchema.ts +0 -234
- package/ai/agent/executeToolCall.ts +0 -58
- package/ai/agent/fetchAgentContexts.ts +0 -42
- package/ai/agent/generatePrompt.ts +0 -3
- package/ai/agent/getFullChatContextKeys.ts +0 -168
- package/ai/agent/hooks/fetchPublicAgents.ts +0 -133
- package/ai/agent/hooks/useAgentConfig.ts +0 -61
- package/ai/agent/hooks/useAgentDialog.ts +0 -35
- package/ai/agent/hooks/useAgentFormValidation.ts +0 -202
- package/ai/agent/hooks/usePublicAgents.ts +0 -473
- package/ai/agent/machineRunPermissions.ts +0 -95
- package/ai/agent/persistMessageWithFixedId.ts +0 -37
- package/ai/agent/planSlice.ts +0 -259
- package/ai/agent/referenceUtils.ts +0 -229
- package/ai/agent/runAgentBackground.ts +0 -238
- package/ai/agent/runAgentClientLoop.ts +0 -138
- package/ai/agent/runtimeGuidance.ts +0 -97
- package/ai/agent/runtimeServerBase.ts +0 -37
- package/ai/agent/server/fetchPublicAgents.ts +0 -128
- package/ai/agent/startParallelAgentStreams.ts +0 -424
- package/ai/agent/startupProtocol.ts +0 -53
- package/ai/agent/streamAgentChatTurn.ts +0 -1278
- package/ai/agent/streamAgentChatTurnUtils.ts +0 -738
- package/ai/agent/types.ts +0 -71
- package/ai/agent/utils/imageOutput.ts +0 -33
- package/ai/agent/utils/sortUtils.ts +0 -250
- package/ai/agent/web/referencePickerUtils.ts +0 -146
- package/ai/ai.locale.ts +0 -1075
- package/ai/chat/accumulateToolCallChunks.ts +0 -95
- package/ai/chat/fetchUtils.native.ts +0 -276
- package/ai/chat/fetchUtils.ts +0 -153
- package/ai/chat/parseApiError.ts +0 -64
- package/ai/chat/parseMultilineSSE.ts +0 -95
- package/ai/chat/sendOpenAICompletionsRequest.native.ts +0 -682
- package/ai/chat/sendOpenAICompletionsRequest.ts +0 -703
- package/ai/chat/sendOpenAIResponseRequest.ts +0 -491
- package/ai/chat/shouldUseServerProxy.ts +0 -18
- package/ai/chat/sseClient.native.ts +0 -91
- package/ai/chat/sseClient.ts +0 -67
- package/ai/chat/streamReader.native.ts +0 -31
- package/ai/chat/streamReader.ts +0 -62
- package/ai/chat/updateTotalUsage.ts +0 -72
- package/ai/context/buildReferenceContext.ts +0 -437
- package/ai/context/calculateContextUsage.ts +0 -133
- package/ai/context/retention.ts +0 -165
- package/ai/context/tokenUtils.ts +0 -78
- package/ai/index.ts +0 -1
- package/ai/llm/calculateGeminiImageTokens.ts +0 -57
- package/ai/llm/deepinfra.ts +0 -28
- package/ai/llm/fireworks.ts +0 -50
- package/ai/llm/generateRequestBody.ts +0 -165
- package/ai/llm/getModelContextWindow.ts +0 -84
- package/ai/llm/getNoloKey.ts +0 -31
- package/ai/llm/getPricing.ts +0 -199
- package/ai/llm/hooks/useModelPricing.ts +0 -75
- package/ai/llm/imagePricing.ts +0 -40
- package/ai/llm/isResponseAPIModel.ts +0 -13
- package/ai/llm/mimo.ts +0 -71
- package/ai/llm/mistral.ts +0 -22
- package/ai/llm/modelAvatar.ts +0 -427
- package/ai/llm/models.ts +0 -45
- package/ai/llm/openrouterModels.ts +0 -269
- package/ai/llm/providers.ts +0 -306
- package/ai/llm/reasoningModels.ts +0 -28
- package/ai/llm/types.ts +0 -59
- package/ai/llm/usageRequestOptions.ts +0 -59
- package/ai/memory/capture.ts +0 -148
- package/ai/memory/consolidate.ts +0 -104
- package/ai/memory/delete.ts +0 -147
- package/ai/memory/overlay.ts +0 -84
- package/ai/memory/query.ts +0 -38
- package/ai/memory/queryShared.ts +0 -160
- package/ai/memory/rank.ts +0 -105
- package/ai/memory/recentRelationshipRecap.ts +0 -249
- package/ai/memory/remember.ts +0 -167
- package/ai/memory/runtime.ts +0 -76
- package/ai/memory/store.ts +0 -20
- package/ai/memory/storeShared.ts +0 -76
- package/ai/memory/types.ts +0 -46
- package/ai/memory/understanding.ts +0 -349
- package/ai/memory/understandingGreeting.ts +0 -264
- package/ai/messages/type.ts +0 -20
- package/ai/policy/personalizationDialog.ts +0 -333
- package/ai/policy/runtimePolicy.ts +0 -440
- package/ai/policy/selfUpdateFields.ts +0 -48
- package/ai/policy/types.ts +0 -64
- package/ai/skills/referenceRuntime.ts +0 -274
- package/ai/skills/skillDiagnostics.ts +0 -251
- package/ai/skills/skillDocBuilder.ts +0 -139
- package/ai/skills/skillDocProtocol.ts +0 -434
- package/ai/skills/skillReferenceSummary.ts +0 -63
- package/ai/skills/skillSummaryMarker.ts +0 -26
- package/ai/token/calculatePrice.ts +0 -544
- package/ai/token/db.ts +0 -98
- package/ai/token/externalToolCost.ts +0 -330
- package/ai/token/hooks/useRecords.ts +0 -65
- package/ai/token/missingUsageEstimate.ts +0 -42
- package/ai/token/modelUsageQuery.ts +0 -252
- package/ai/token/normalizeUsage.ts +0 -84
- package/ai/token/openaiImageGenerationUsage.ts +0 -56
- package/ai/token/prepareTokenUsageData.ts +0 -88
- package/ai/token/query.ts +0 -88
- package/ai/token/queryUserTokens.ts +0 -59
- package/ai/token/resolveBillingTarget.ts +0 -52
- package/ai/token/saveTokenRecord.ts +0 -53
- package/ai/token/serverDialogProjection.ts +0 -78
- package/ai/token/serverTokenWriter.ts +0 -143
- package/ai/token/stats.ts +0 -21
- package/ai/token/tokenThunks.ts +0 -24
- package/ai/token/types.ts +0 -93
- package/ai/tools/agent/agentTools.ts +0 -176
- package/ai/tools/agent/agentUpdateShared.ts +0 -311
- package/ai/tools/agent/callAgentTool.ts +0 -139
- package/ai/tools/agent/createAgentTool.ts +0 -512
- package/ai/tools/agent/createDialogTool.ts +0 -69
- package/ai/tools/agent/createSkillAgentTool.ts +0 -62
- package/ai/tools/agent/parallelBudget.ts +0 -221
- package/ai/tools/agent/presets/appBuilderPreset.ts +0 -145
- package/ai/tools/agent/runLlmTool.ts +0 -96
- package/ai/tools/agent/runStreamingAgentTool.ts +0 -73
- package/ai/tools/agent/skillAgentArgs.ts +0 -106
- package/ai/tools/agent/skillAgentPreset.ts +0 -89
- package/ai/tools/agent/streamParallelAgentsTool.ts +0 -122
- package/ai/tools/agent/updateAgentTool.ts +0 -96
- package/ai/tools/agent/updateSelfTool.ts +0 -113
- package/ai/tools/amazonProductScraperTool.ts +0 -86
- package/ai/tools/apifyActorClient.ts +0 -45
- package/ai/tools/appEditGuard.ts +0 -372
- package/ai/tools/appReadSnapshot.ts +0 -153
- package/ai/tools/appTools.ts +0 -1549
- package/ai/tools/applyEditTool.ts +0 -256
- package/ai/tools/applyLineEditsTool.ts +0 -312
- package/ai/tools/browserTools/click.ts +0 -33
- package/ai/tools/browserTools/closeSession.ts +0 -29
- package/ai/tools/browserTools/common.ts +0 -27
- package/ai/tools/browserTools/openSession.ts +0 -48
- package/ai/tools/browserTools/readContent.ts +0 -38
- package/ai/tools/browserTools/selectOption.ts +0 -46
- package/ai/tools/browserTools/typeText.ts +0 -42
- package/ai/tools/category/createCategoryTool.ts +0 -66
- package/ai/tools/category/queryContentsByCategoryTool.ts +0 -69
- package/ai/tools/category/updateContentCategoryTool.ts +0 -75
- package/ai/tools/cfBrowserTools.ts +0 -319
- package/ai/tools/cfSpeechToTextTool.ts +0 -49
- package/ai/tools/checkEnvTool.ts +0 -65
- package/ai/tools/cloudflareCrawlTool.ts +0 -289
- package/ai/tools/codeSearchTool.ts +0 -111
- package/ai/tools/codeTools.ts +0 -101
- package/ai/tools/createDocTool.ts +0 -132
- package/ai/tools/createPlanTool.ts +0 -999
- package/ai/tools/createSkillDocTool.ts +0 -155
- package/ai/tools/createWorkflowTool.ts +0 -154
- package/ai/tools/deepseekOcrTool.ts +0 -34
- package/ai/tools/delayTool.ts +0 -31
- package/ai/tools/deleteSpacesTool.ts +0 -325
- package/ai/tools/deleteSpacesToolModel.ts +0 -159
- package/ai/tools/devReloadUtils.ts +0 -29
- package/ai/tools/dialogMessageSearch.ts +0 -137
- package/ai/tools/doctorSkillTool.ts +0 -72
- package/ai/tools/ecommerceScraperTool.ts +0 -86
- package/ai/tools/emailTools.ts +0 -549
- package/ai/tools/evalSkillTool.ts +0 -92
- package/ai/tools/exaSearchTool.ts +0 -64
- package/ai/tools/execBashTool.ts +0 -379
- package/ai/tools/executeSqlTool.ts +0 -192
- package/ai/tools/fetchWebpageSupport.ts +0 -309
- package/ai/tools/fetchWebpageTool.ts +0 -84
- package/ai/tools/geminiImagePreviewTool.ts +0 -361
- package/ai/tools/generateDocxTool.ts +0 -215
- package/ai/tools/googleSearchScraperTool.ts +0 -106
- package/ai/tools/importDataTool.ts +0 -133
- package/ai/tools/importSkillTool.ts +0 -162
- package/ai/tools/index.ts +0 -1858
- package/ai/tools/listFilesTool.ts +0 -82
- package/ai/tools/listUserSpacesTool.ts +0 -113
- package/ai/tools/modelUsageTools.ts +0 -142
- package/ai/tools/olmOcrTool.ts +0 -34
- package/ai/tools/openaiImageTool.ts +0 -218
- package/ai/tools/paddleOcrTool.ts +0 -34
- package/ai/tools/prepareTools.ts +0 -23
- package/ai/tools/readDocTool.ts +0 -84
- package/ai/tools/readFileTool.ts +0 -211
- package/ai/tools/readTool.ts +0 -163
- package/ai/tools/readXPostTool.ts +0 -233
- package/ai/tools/rememberMemoryTool.ts +0 -84
- package/ai/tools/remotionVideoTool.ts +0 -151
- package/ai/tools/searchDialogMessagesTool.ts +0 -222
- package/ai/tools/searchRepoTool.ts +0 -115
- package/ai/tools/searchWorkspaceTool.ts +0 -259
- package/ai/tools/skillFollowup.ts +0 -86
- package/ai/tools/surfWeatherTool.ts +0 -169
- package/ai/tools/table/addTableRowTool.ts +0 -217
- package/ai/tools/table/createTableTool.ts +0 -315
- package/ai/tools/table/rowTools.ts +0 -366
- package/ai/tools/table/schemaTools.ts +0 -244
- package/ai/tools/table/shareTableTool.ts +0 -148
- package/ai/tools/table/toolShared.ts +0 -129
- package/ai/tools/toolApiClient.ts +0 -198
- package/ai/tools/toolNameAliases.ts +0 -57
- package/ai/tools/toolResultError.ts +0 -42
- package/ai/tools/toolRunSlice.ts +0 -303
- package/ai/tools/toolSchemaCompatibility.ts +0 -53
- package/ai/tools/toolVisibility.ts +0 -4
- package/ai/tools/types.ts +0 -20
- package/ai/tools/uiAskChoiceTool.ts +0 -104
- package/ai/tools/updateContentTitleTool.ts +0 -84
- package/ai/tools/updateDocTool.ts +0 -105
- package/ai/tools/updateUserPreferenceProfileTool.ts +0 -145
- package/ai/tools/whisperTool.ts +0 -77
- package/ai/tools/writeFileTool.ts +0 -210
- package/ai/tools/youtubeScraperTool.ts +0 -116
- package/ai/tools/ziweiChartTool.ts +0 -678
- package/ai/types.ts +0 -55
- package/ai/workflow/workflowExecutor.ts +0 -323
- package/ai/workflow/workflowSlice.ts +0 -73
- package/ai/workflow/workflowTypes.ts +0 -106
- package/client/compactDialog.ts +0 -222
- package/connector-experimental/capabilities.ts +0 -73
- package/connector-experimental/codexBinary.ts +0 -41
- package/connector-experimental/heartbeatLoop.ts +0 -22
- package/connector-experimental/index.ts +0 -5
- package/connector-experimental/machineInfo.ts +0 -46
- package/connector-experimental/protocol.ts +0 -54
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// 文件路径: ai/tools/agent/callAgentTool.ts
|
|
2
|
-
|
|
3
|
-
import type { RootState } from "app/store";
|
|
4
|
-
import { runAgent } from "ai/agent/agentSlice";
|
|
5
|
-
import { runAgentBackground } from "ai/agent/runAgentBackground";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* callAgent 工具 Schema
|
|
10
|
-
*
|
|
11
|
-
* 用于开展一个子对话(sub-dialog),只关心执行结果。支持两种执行模式:
|
|
12
|
-
* - "server"(默认):通过服务端 agent run 接口后台异步执行,结果写回 DB 并通过 SSE 回传,
|
|
13
|
-
* 适合大多数子任务,也能复用服务端 runtime auto-routing。
|
|
14
|
-
* - "client":客户端同步执行,在当前 Redux 上下文中直接调用 runAgent,
|
|
15
|
-
* 适合确认只需本地轻量执行的子任务。
|
|
16
|
-
*
|
|
17
|
-
* 若需要用户立刻看到流式回复,请改用 runStreamingAgent。
|
|
18
|
-
*/
|
|
19
|
-
export const callAgentFunctionSchema = {
|
|
20
|
-
name: "callAgent",
|
|
21
|
-
description:
|
|
22
|
-
"调用一个指定的 Agent 执行一次子任务并返回结果。" +
|
|
23
|
-
"通常用于:将复杂子问题委托给其他 Agent,例如自动评测、多 Agent 对比、抓取结果的结构化处理等。",
|
|
24
|
-
parameters: {
|
|
25
|
-
type: "object",
|
|
26
|
-
properties: {
|
|
27
|
-
agentKey: {
|
|
28
|
-
type: "string",
|
|
29
|
-
description:
|
|
30
|
-
"要调用的 Agent 的唯一 ID。",
|
|
31
|
-
},
|
|
32
|
-
task: {
|
|
33
|
-
type: "string",
|
|
34
|
-
description:
|
|
35
|
-
"委托给该 Agent 的子任务描述(自然语言)。建议在此包含必要的上下文说明(例如当前表结构、题库说明等)。",
|
|
36
|
-
},
|
|
37
|
-
input: {
|
|
38
|
-
description:
|
|
39
|
-
"可选。JSON 或字符串,将作为本次子任务的附加输入。通常用于传递抓取到的原始数据、题库、上下文片段等。",
|
|
40
|
-
},
|
|
41
|
-
mode: {
|
|
42
|
-
type: "string",
|
|
43
|
-
enum: ["client", "server"],
|
|
44
|
-
description:
|
|
45
|
-
"执行模式:'server'(默认)为服务端后台异步执行,能复用 runtime auto-routing;" +
|
|
46
|
-
"'client' 为客户端同步执行,适合明确只需本地轻量完成的任务。",
|
|
47
|
-
default: "server",
|
|
48
|
-
},
|
|
49
|
-
serverBase: {
|
|
50
|
-
type: "string",
|
|
51
|
-
description:
|
|
52
|
-
"可选。目标 Agent 所在的 nolo server origin,例如 Windows 机器通过 Cloudflare 暴露的 https://win.example.com。" +
|
|
53
|
-
"仅 server 模式使用;跨域目标必须由服务端 AGENT_TOOL_ALLOWED_SERVER_BASES 明确放行。" +
|
|
54
|
-
"如果目标 Agent 记录声明了 delegation.serverBase / runtimeServerBase,服务端会在未显式传入时自动路由。",
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
required: ["agentKey", "task"],
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
interface CallAgentArgs {
|
|
62
|
-
agentKey: string;
|
|
63
|
-
task: string;
|
|
64
|
-
input?: any;
|
|
65
|
-
mode?: "client" | "server";
|
|
66
|
-
serverBase?: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* callAgent 工具执行函数
|
|
71
|
-
* @param args - { agentKey, task, input, mode }
|
|
72
|
-
* @param thunkApi - Redux thunkApi
|
|
73
|
-
* @param context - { parentMessageId },用于关联父消息
|
|
74
|
-
*/
|
|
75
|
-
export async function callAgentFunc(
|
|
76
|
-
args: CallAgentArgs,
|
|
77
|
-
thunkApi: any,
|
|
78
|
-
context?: { parentMessageId: string }
|
|
79
|
-
): Promise<{ rawData: any; displayData?: string }> {
|
|
80
|
-
const { agentKey, task, input, mode = "server", serverBase } = args;
|
|
81
|
-
const { dispatch, getState } = thunkApi;
|
|
82
|
-
const state = getState() as RootState;
|
|
83
|
-
|
|
84
|
-
if (!agentKey) {
|
|
85
|
-
throw new Error("callAgent: 缺少 agentKey 参数。");
|
|
86
|
-
}
|
|
87
|
-
if (!task || typeof task !== "string") {
|
|
88
|
-
throw new Error("callAgent: 缺少有效的 task 文本描述。");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// 组装 content:统一用「指令 + 输入」的简单文本协议
|
|
92
|
-
let content: string;
|
|
93
|
-
if (input === undefined || input === null) {
|
|
94
|
-
content = task;
|
|
95
|
-
} else if (typeof input === "string") {
|
|
96
|
-
content = `${task}\n\n--- INPUT (text) ---\n${input}`;
|
|
97
|
-
} else {
|
|
98
|
-
const jsonStr = JSON.stringify(input, null, 2);
|
|
99
|
-
content = `${task}\n\n--- INPUT (json) ---\n${jsonStr}`;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const parentMessageId = context?.parentMessageId;
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
if (mode === "server") {
|
|
106
|
-
// 服务端后台执行:适合耗时/计算密集型任务
|
|
107
|
-
// 通过 /api/agent/run?background=true 派发到服务端,SSE 监听结果
|
|
108
|
-
const result = await dispatch(
|
|
109
|
-
runAgentBackground({
|
|
110
|
-
agentKey,
|
|
111
|
-
userInput: content,
|
|
112
|
-
...(serverBase ? { serverBase } : {}),
|
|
113
|
-
})
|
|
114
|
-
).unwrap();
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
rawData: result.content ?? result,
|
|
118
|
-
displayData: `✅ callAgent(服务端) 执行完成,dialogId: ${result.dialogId}`,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// client 模式(默认):客户端同步执行,结果直接返回给调用方
|
|
123
|
-
const result = await dispatch(
|
|
124
|
-
runAgent({
|
|
125
|
-
agentKey,
|
|
126
|
-
content,
|
|
127
|
-
parentMessageId,
|
|
128
|
-
})
|
|
129
|
-
).unwrap();
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
rawData: result,
|
|
133
|
-
displayData: "✅ callAgent(客户端) 子任务执行完成。",
|
|
134
|
-
};
|
|
135
|
-
} catch (e: any) {
|
|
136
|
-
const msg = e?.message || String(e);
|
|
137
|
-
throw new Error(`callAgent 调用 Agent [${agentKey}] 时出错: ${msg}`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
@@ -1,512 +0,0 @@
|
|
|
1
|
-
// 文件路径: ai/tools/agent/createAgentTool.ts
|
|
2
|
-
|
|
3
|
-
import type { RootState } from "app/store";
|
|
4
|
-
import type { Agent } from "app/types";
|
|
5
|
-
import { createAgent } from "ai/agent/agentSlice";
|
|
6
|
-
import { selectAllMemberSpaces, addContentToSpace } from "create/space/spaceSlice";
|
|
7
|
-
import { ContentType } from "app/types";
|
|
8
|
-
import { createAgentKey, } from "database/keys";
|
|
9
|
-
import type { FormData as AgentFormData } from "ai/agent/createAgentSchema";
|
|
10
|
-
import { selectCurrentUserBalance, selectUserId } from "auth/authSlice";
|
|
11
|
-
import type { ModelWithProvider } from "ai/llm/models";
|
|
12
|
-
import i18n from "app/i18n";
|
|
13
|
-
|
|
14
|
-
type ReasoningEffort = "low" | "medium" | "high";
|
|
15
|
-
|
|
16
|
-
type ReferenceArg = {
|
|
17
|
-
dbKey: string;
|
|
18
|
-
title?: string;
|
|
19
|
-
type?: "knowledge" | "instruction" | "page";
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
// 与 GreetingMenuEditor / greetingMenuItemSchema 对齐
|
|
23
|
-
export type GreetingMenuItemArg = {
|
|
24
|
-
id: string;
|
|
25
|
-
label: string;
|
|
26
|
-
userMessage?: string;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type GreetingConfigArg = {
|
|
30
|
-
text?: string;
|
|
31
|
-
menu?: GreetingMenuItemArg[];
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export type CreateAgentToolArgs = {
|
|
35
|
-
name: string;
|
|
36
|
-
model: string;
|
|
37
|
-
provider: string; // 必填
|
|
38
|
-
prompt?: string;
|
|
39
|
-
introduction?: string;
|
|
40
|
-
greeting?: string | GreetingConfigArg; // 支持纯文本或带 menu 的对象
|
|
41
|
-
isPublic?: boolean;
|
|
42
|
-
tags?: string[] | string;
|
|
43
|
-
tools?: string[];
|
|
44
|
-
references?: ReferenceArg[];
|
|
45
|
-
linkedSpaces?: string[];
|
|
46
|
-
temperature?: number;
|
|
47
|
-
top_p?: number;
|
|
48
|
-
frequency_penalty?: number;
|
|
49
|
-
presence_penalty?: number;
|
|
50
|
-
max_tokens?: number;
|
|
51
|
-
reasoning_effort?: ReasoningEffort;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const toTrimmed = (v: unknown): string =>
|
|
55
|
-
typeof v === "string"
|
|
56
|
-
? v.trim()
|
|
57
|
-
: v == null
|
|
58
|
-
? ""
|
|
59
|
-
: String(v).trim();
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 根据 model + 可选 provider 找到唯一的模型配置
|
|
63
|
-
*
|
|
64
|
-
* 规则:
|
|
65
|
-
* - 如果传了 provider,则优先按 (name, provider) 精确匹配;
|
|
66
|
-
* - 否则按 name 匹配:
|
|
67
|
-
* - 找到 1 个 => 返回
|
|
68
|
-
* - 找到 0 或 >1 个 => 返回 null(>1 说明有歧义)
|
|
69
|
-
*/
|
|
70
|
-
const findModelConfig = async (
|
|
71
|
-
modelName: string,
|
|
72
|
-
provider?: string
|
|
73
|
-
): Promise<ModelWithProvider | null> => {
|
|
74
|
-
const { ALL_MODELS } = await import("ai/llm/models");
|
|
75
|
-
const name = toTrimmed(modelName);
|
|
76
|
-
const prov = toTrimmed(provider ?? "");
|
|
77
|
-
if (!name) return null;
|
|
78
|
-
|
|
79
|
-
if (prov) {
|
|
80
|
-
const exact = ALL_MODELS.find(
|
|
81
|
-
(m) => m.name === name && m.provider === prov
|
|
82
|
-
);
|
|
83
|
-
if (exact) return exact;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const matches = ALL_MODELS.filter((m) => m.name === name);
|
|
87
|
-
if (matches.length === 1) return matches[0];
|
|
88
|
-
|
|
89
|
-
if (matches.length > 1 && !prov) {
|
|
90
|
-
console.warn(
|
|
91
|
-
"[createAgentTool] findModelConfig: duplicate model names without provider",
|
|
92
|
-
{
|
|
93
|
-
modelName: name,
|
|
94
|
-
providers: matches.map((m) => m.provider),
|
|
95
|
-
}
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return null;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* [Schema] createAgent 工具定义:供 LLM 规划时调用
|
|
104
|
-
* - name / model / provider 必填:保证创建出来的 Agent 配置完整且无歧义
|
|
105
|
-
* - 其余字段可选:用于进一步定制 Agent 行为
|
|
106
|
-
*/
|
|
107
|
-
export const createAgentToolFunctionSchema = {
|
|
108
|
-
name: "createAgent",
|
|
109
|
-
description: i18n.t("tools.createAgent.description"),
|
|
110
|
-
parameters: {
|
|
111
|
-
type: "object",
|
|
112
|
-
properties: {
|
|
113
|
-
name: {
|
|
114
|
-
type: "string",
|
|
115
|
-
description: i18n.t("tools.createAgent.params.name"),
|
|
116
|
-
},
|
|
117
|
-
model: {
|
|
118
|
-
type: "string",
|
|
119
|
-
description: i18n.t("tools.createAgent.params.model"),
|
|
120
|
-
},
|
|
121
|
-
provider: {
|
|
122
|
-
type: "string",
|
|
123
|
-
description: i18n.t("tools.createAgent.params.provider"),
|
|
124
|
-
},
|
|
125
|
-
prompt: {
|
|
126
|
-
type: "string",
|
|
127
|
-
description: i18n.t("tools.createAgent.params.prompt"),
|
|
128
|
-
},
|
|
129
|
-
introduction: {
|
|
130
|
-
type: "string",
|
|
131
|
-
description: i18n.t("tools.createAgent.params.introduction"),
|
|
132
|
-
},
|
|
133
|
-
greeting: {
|
|
134
|
-
description: i18n.t("tools.createAgent.params.greeting.desc"),
|
|
135
|
-
anyOf: [
|
|
136
|
-
{
|
|
137
|
-
type: "string",
|
|
138
|
-
description: i18n.t(
|
|
139
|
-
"tools.createAgent.params.greeting.stringDesc"
|
|
140
|
-
),
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
type: "object",
|
|
144
|
-
description: i18n.t(
|
|
145
|
-
"tools.createAgent.params.greeting.objectDesc"
|
|
146
|
-
),
|
|
147
|
-
properties: {
|
|
148
|
-
text: {
|
|
149
|
-
type: "string",
|
|
150
|
-
description: i18n.t(
|
|
151
|
-
"tools.createAgent.params.greeting.texts.text"
|
|
152
|
-
),
|
|
153
|
-
},
|
|
154
|
-
menu: {
|
|
155
|
-
type: "array",
|
|
156
|
-
description: i18n.t(
|
|
157
|
-
"tools.createAgent.params.greeting.menu.desc"
|
|
158
|
-
),
|
|
159
|
-
items: {
|
|
160
|
-
type: "object",
|
|
161
|
-
properties: {
|
|
162
|
-
id: {
|
|
163
|
-
type: "string",
|
|
164
|
-
description: i18n.t(
|
|
165
|
-
"tools.createAgent.params.greeting.menu.id"
|
|
166
|
-
),
|
|
167
|
-
},
|
|
168
|
-
label: {
|
|
169
|
-
type: "string",
|
|
170
|
-
description: i18n.t(
|
|
171
|
-
"tools.createAgent.params.greeting.menu.label"
|
|
172
|
-
),
|
|
173
|
-
},
|
|
174
|
-
userMessage: {
|
|
175
|
-
type: "string",
|
|
176
|
-
description: i18n.t(
|
|
177
|
-
"tools.createAgent.params.greeting.menu.userMessage"
|
|
178
|
-
),
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
required: ["id", "label"],
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
],
|
|
187
|
-
},
|
|
188
|
-
isPublic: {
|
|
189
|
-
type: "boolean",
|
|
190
|
-
description: i18n.t("tools.createAgent.params.isPublic"),
|
|
191
|
-
},
|
|
192
|
-
tags: {
|
|
193
|
-
type: "array",
|
|
194
|
-
items: { type: "string" },
|
|
195
|
-
description: i18n.t("tools.createAgent.params.tags"),
|
|
196
|
-
},
|
|
197
|
-
tools: {
|
|
198
|
-
type: "array",
|
|
199
|
-
items: { type: "string" },
|
|
200
|
-
description: i18n.t("tools.createAgent.params.tools"),
|
|
201
|
-
},
|
|
202
|
-
references: {
|
|
203
|
-
type: "array",
|
|
204
|
-
description: i18n.t("tools.createAgent.params.references.desc"),
|
|
205
|
-
items: {
|
|
206
|
-
type: "object",
|
|
207
|
-
properties: {
|
|
208
|
-
dbKey: {
|
|
209
|
-
type: "string",
|
|
210
|
-
description: i18n.t(
|
|
211
|
-
"tools.createAgent.params.references.dbKey"
|
|
212
|
-
),
|
|
213
|
-
},
|
|
214
|
-
title: {
|
|
215
|
-
type: "string",
|
|
216
|
-
description: i18n.t(
|
|
217
|
-
"tools.createAgent.params.references.title"
|
|
218
|
-
),
|
|
219
|
-
},
|
|
220
|
-
type: {
|
|
221
|
-
type: "string",
|
|
222
|
-
enum: ["knowledge", "instruction", "page"],
|
|
223
|
-
description: i18n.t(
|
|
224
|
-
"tools.createAgent.params.references.type"
|
|
225
|
-
),
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
required: ["dbKey"],
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
linkedSpaces: {
|
|
232
|
-
type: "array",
|
|
233
|
-
items: { type: "string" },
|
|
234
|
-
description: i18n.t("tools.createAgent.params.linkedSpaces"),
|
|
235
|
-
},
|
|
236
|
-
temperature: {
|
|
237
|
-
type: "number",
|
|
238
|
-
description: i18n.t("tools.createAgent.params.temperature"),
|
|
239
|
-
},
|
|
240
|
-
top_p: {
|
|
241
|
-
type: "number",
|
|
242
|
-
description: i18n.t("tools.createAgent.params.top_p"),
|
|
243
|
-
},
|
|
244
|
-
frequency_penalty: {
|
|
245
|
-
type: "number",
|
|
246
|
-
description: i18n.t(
|
|
247
|
-
"tools.createAgent.params.frequency_penalty"
|
|
248
|
-
),
|
|
249
|
-
},
|
|
250
|
-
presence_penalty: {
|
|
251
|
-
type: "number",
|
|
252
|
-
description: i18n.t(
|
|
253
|
-
"tools.createAgent.params.presence_penalty"
|
|
254
|
-
),
|
|
255
|
-
},
|
|
256
|
-
max_tokens: {
|
|
257
|
-
type: "number",
|
|
258
|
-
description: i18n.t("tools.createAgent.params.max_tokens"),
|
|
259
|
-
},
|
|
260
|
-
reasoning_effort: {
|
|
261
|
-
type: "string",
|
|
262
|
-
enum: ["low", "medium", "high"],
|
|
263
|
-
description: i18n.t(
|
|
264
|
-
"tools.createAgent.params.reasoning_effort"
|
|
265
|
-
),
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
// provider 必填
|
|
269
|
-
required: ["name", "model", "provider"],
|
|
270
|
-
},
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
const normalizeTags = (tags?: string[] | string): string => {
|
|
274
|
-
if (!tags) return "";
|
|
275
|
-
if (Array.isArray(tags)) {
|
|
276
|
-
return tags
|
|
277
|
-
.map((t) => String(t || "").trim())
|
|
278
|
-
.filter(Boolean)
|
|
279
|
-
.join(", ");
|
|
280
|
-
}
|
|
281
|
-
return String(tags);
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* 将工具入参转换为 Agent 表单数据结构(AgentFormData)
|
|
286
|
-
* - 默认使用平台 API(apiSource: 'platform')
|
|
287
|
-
* - 不暴露自定义 API 字段(customProviderUrl / apiKey 等)
|
|
288
|
-
* - 根据 (model, provider) 自动补 hasVision 等能力字段
|
|
289
|
-
*/
|
|
290
|
-
const buildFormDataFromArgs = async (args: CreateAgentToolArgs): Promise<AgentFormData> => {
|
|
291
|
-
const {
|
|
292
|
-
name,
|
|
293
|
-
model,
|
|
294
|
-
provider,
|
|
295
|
-
prompt,
|
|
296
|
-
introduction,
|
|
297
|
-
greeting,
|
|
298
|
-
isPublic = false,
|
|
299
|
-
tags,
|
|
300
|
-
tools,
|
|
301
|
-
references,
|
|
302
|
-
linkedSpaces,
|
|
303
|
-
temperature,
|
|
304
|
-
top_p,
|
|
305
|
-
frequency_penalty,
|
|
306
|
-
presence_penalty,
|
|
307
|
-
max_tokens,
|
|
308
|
-
reasoning_effort,
|
|
309
|
-
} = args;
|
|
310
|
-
|
|
311
|
-
const trimmedName = toTrimmed(name);
|
|
312
|
-
const trimmedModel = toTrimmed(model);
|
|
313
|
-
const trimmedProvider = toTrimmed(provider);
|
|
314
|
-
|
|
315
|
-
// 用 (model, provider) 查模型元数据,顺便拿 hasVision 等能力
|
|
316
|
-
const modelConfig = await findModelConfig(trimmedModel, trimmedProvider);
|
|
317
|
-
const { getModelPricing } = await import("ai/llm/getPricing");
|
|
318
|
-
|
|
319
|
-
const formData: AgentFormData = {
|
|
320
|
-
name: trimmedName,
|
|
321
|
-
model: trimmedModel,
|
|
322
|
-
provider: modelConfig?.provider || trimmedProvider,
|
|
323
|
-
|
|
324
|
-
apiSource: "platform",
|
|
325
|
-
useServerProxy: true,
|
|
326
|
-
|
|
327
|
-
// 根据模型配置自动赋值 hasVision(支持图片 / 多模态)
|
|
328
|
-
hasVision: Boolean(modelConfig?.hasVision),
|
|
329
|
-
|
|
330
|
-
prompt: prompt ?? "",
|
|
331
|
-
introduction: introduction ?? "",
|
|
332
|
-
greeting, // 直接透传:string 或 { text, menu }
|
|
333
|
-
isPublic: !!isPublic,
|
|
334
|
-
tags: normalizeTags(tags),
|
|
335
|
-
|
|
336
|
-
tools: tools ?? [],
|
|
337
|
-
references: (references as any) ?? [],
|
|
338
|
-
linkedSpaces: linkedSpaces ?? [], // Leave raw inputs, resolve in executor
|
|
339
|
-
|
|
340
|
-
customProviderUrl: "",
|
|
341
|
-
apiKey: "",
|
|
342
|
-
|
|
343
|
-
// 从模型列表查真实价格,保证 AgentCard 和 useSendPermission 能正确显示
|
|
344
|
-
...(() => {
|
|
345
|
-
const pricing = getModelPricing(modelConfig?.provider || trimmedProvider, trimmedModel);
|
|
346
|
-
return {
|
|
347
|
-
inputPrice: pricing?.inputPrice ?? 0,
|
|
348
|
-
outputPrice: pricing?.outputPrice ?? 0,
|
|
349
|
-
};
|
|
350
|
-
})(),
|
|
351
|
-
|
|
352
|
-
temperature,
|
|
353
|
-
top_p,
|
|
354
|
-
frequency_penalty,
|
|
355
|
-
presence_penalty,
|
|
356
|
-
max_tokens,
|
|
357
|
-
reasoning_effort,
|
|
358
|
-
|
|
359
|
-
whitelist: [],
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
return formData;
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* [Helper] 根据 Space 名称或 ID 查找 Space
|
|
367
|
-
*/
|
|
368
|
-
const findSpaceConfig = (
|
|
369
|
-
nameOrId: string,
|
|
370
|
-
allSpaces: any[]
|
|
371
|
-
): { spaceId: string; name: string } | null => {
|
|
372
|
-
const query = toTrimmed(nameOrId).toLowerCase();
|
|
373
|
-
if (!query) return null;
|
|
374
|
-
|
|
375
|
-
// 1. 精确匹配 ID
|
|
376
|
-
const byId = allSpaces.find((s) => s.spaceId === nameOrId); // ID 区分大小写
|
|
377
|
-
if (byId) return { spaceId: byId.spaceId, name: byId.spaceName };
|
|
378
|
-
|
|
379
|
-
// 2. 匹配名称 (忽略大小写)
|
|
380
|
-
const byName = allSpaces.find(
|
|
381
|
-
(s) =>
|
|
382
|
-
(s.spaceName || "").toLowerCase() === query ||
|
|
383
|
-
(s.spaceId || "").toLowerCase() === query
|
|
384
|
-
);
|
|
385
|
-
if (byName) return { spaceId: byName.spaceId, name: byName.spaceName };
|
|
386
|
-
|
|
387
|
-
return null;
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* [Executor] createAgent 工具执行函数
|
|
392
|
-
*/
|
|
393
|
-
export async function createAgentToolFunc(
|
|
394
|
-
args: CreateAgentToolArgs,
|
|
395
|
-
thunkApi: any
|
|
396
|
-
): Promise<{ rawData: Agent; displayData: string }> {
|
|
397
|
-
const state = thunkApi.getState() as RootState;
|
|
398
|
-
const currentUserId = selectUserId(state);
|
|
399
|
-
const currentBalance = selectCurrentUserBalance(state);
|
|
400
|
-
|
|
401
|
-
// 获取当前用户的所有 Space (from create/space/spaceSlice)
|
|
402
|
-
const allSpaces = selectAllMemberSpaces(state);
|
|
403
|
-
|
|
404
|
-
if (!currentUserId) {
|
|
405
|
-
throw new Error("创建 Agent 失败:当前未登录或缺少 userId。");
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
const { name, model, provider, linkedSpaces } =
|
|
409
|
-
args || ({} as CreateAgentToolArgs);
|
|
410
|
-
|
|
411
|
-
if (!name || typeof name !== "string" || !name.trim()) {
|
|
412
|
-
throw new Error("创建 Agent 失败:必须提供非空的 name 字段。");
|
|
413
|
-
}
|
|
414
|
-
if (!model || typeof model !== "string" || !model.trim()) {
|
|
415
|
-
throw new Error("创建 Agent 失败:必须提供非空的 model 字段。");
|
|
416
|
-
}
|
|
417
|
-
if (!provider || typeof provider !== "string" || !provider.trim()) {
|
|
418
|
-
throw new Error("创建 Agent 失败:必须提供非空的 provider 字段。");
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// --- 处理 Space ID / Name 解析 ---
|
|
422
|
-
const resolvedLinkedSpaces: string[] = [];
|
|
423
|
-
if (Array.isArray(linkedSpaces) && linkedSpaces.length > 0) {
|
|
424
|
-
const notFound: string[] = [];
|
|
425
|
-
for (const input of linkedSpaces) {
|
|
426
|
-
const found = findSpaceConfig(input, allSpaces);
|
|
427
|
-
if (found) {
|
|
428
|
-
resolvedLinkedSpaces.push(found.spaceId);
|
|
429
|
-
} else {
|
|
430
|
-
notFound.push(input);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
if (notFound.length > 0) {
|
|
435
|
-
// 如果有找不到的 Space,生成详细错误提示,列出可用 Space
|
|
436
|
-
const availableList = allSpaces
|
|
437
|
-
.map((s) => `- ${s.spaceName} (ID: ${s.spaceId})`)
|
|
438
|
-
.join("\n");
|
|
439
|
-
throw new Error(
|
|
440
|
-
`无法找到以下 Space: ${notFound.join(", ")}。\n` +
|
|
441
|
-
`请检查名称拼写或使用 'listUserSpaces' 获取最新列表。\n` +
|
|
442
|
-
`当前可用 Space:\n${availableList}`
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
const formData = await buildFormDataFromArgs(args);
|
|
448
|
-
// 覆盖为解析后的 ID 列表
|
|
449
|
-
formData.linkedSpaces = resolvedLinkedSpaces;
|
|
450
|
-
|
|
451
|
-
try {
|
|
452
|
-
const agent: Agent = await thunkApi
|
|
453
|
-
.dispatch(
|
|
454
|
-
createAgent({
|
|
455
|
-
userId: currentUserId,
|
|
456
|
-
formData,
|
|
457
|
-
spaceId: state.space.currentSpaceId || undefined,
|
|
458
|
-
})
|
|
459
|
-
)
|
|
460
|
-
.unwrap();
|
|
461
|
-
|
|
462
|
-
// 自动添加到当前空间侧边栏
|
|
463
|
-
const currentSpaceId = state.space.currentSpaceId;
|
|
464
|
-
if (currentSpaceId) {
|
|
465
|
-
// 新创建的 Agent 统一使用 createAgentKey (agent- 前缀)
|
|
466
|
-
const agentDbKey = agent.isPublic
|
|
467
|
-
? createAgentKey.public(agent.id)
|
|
468
|
-
: createAgentKey.private(currentUserId, agent.id);
|
|
469
|
-
|
|
470
|
-
try {
|
|
471
|
-
await thunkApi.dispatch((addContentToSpace as any)({
|
|
472
|
-
spaceId: currentSpaceId,
|
|
473
|
-
title: agent.name || "未命名智能体",
|
|
474
|
-
type: ContentType.AGENT, // 统一使用 ContentType.AGENT
|
|
475
|
-
contentKey: agentDbKey,
|
|
476
|
-
})).unwrap();
|
|
477
|
-
} catch (err) {
|
|
478
|
-
console.error("[createAgentTool] Failed to add to space:", err);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
const lines: string[] = [
|
|
483
|
-
`✅ 已创建 Agent:${agent.name}`,
|
|
484
|
-
`- ID: ${agent.id}`,
|
|
485
|
-
`- 模型: ${agent.model || "(未指定)"}`,
|
|
486
|
-
`- Provider: ${agent.provider || "(未指定)"}`,
|
|
487
|
-
`- 是否公开: ${agent.isPublic ? "是" : "否"}`,
|
|
488
|
-
];
|
|
489
|
-
|
|
490
|
-
if (Array.isArray(agent.tags) && agent.tags.length > 0) {
|
|
491
|
-
lines.push(`- 标签: ${agent.tags.join(", ")}`);
|
|
492
|
-
}
|
|
493
|
-
if (Array.isArray(agent.tools) && agent.tools.length > 0) {
|
|
494
|
-
lines.push(`- 启用工具: ${agent.tools.join(", ")}`);
|
|
495
|
-
}
|
|
496
|
-
if (typeof agent.temperature === "number") {
|
|
497
|
-
lines.push(`- temperature: ${agent.temperature}`);
|
|
498
|
-
}
|
|
499
|
-
if (typeof currentBalance === "number") {
|
|
500
|
-
lines.push(`- 当前余额: ${currentBalance}`);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
return {
|
|
504
|
-
rawData: agent,
|
|
505
|
-
displayData: lines.join("\n"),
|
|
506
|
-
};
|
|
507
|
-
} catch (error: any) {
|
|
508
|
-
throw new Error(
|
|
509
|
-
`创建 Agent 失败:${error?.message || "未知错误,请稍后重试。"}`
|
|
510
|
-
);
|
|
511
|
-
}
|
|
512
|
-
}
|