nolo-cli 0.1.22 → 0.1.26
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 +25 -3
- package/agent-runtime/agentRecordConfig.ts +4 -0
- package/agent-runtime/hostAdapter.ts +2 -0
- package/agent-runtime/hybridRecordStore.ts +30 -9
- package/agent-runtime/index.ts +7 -0
- package/agent-runtime/localLoop.ts +14 -4
- package/agent-runtime/localToolPolicy.ts +22 -10
- package/agent-runtime/localWorkspaceTools.ts +140 -374
- package/agent-runtime/platformChatProvider.ts +3 -0
- package/agent-runtime/runtimeToolPolicy.ts +133 -0
- package/agent-runtime/types.ts +47 -0
- package/agentAliases.ts +1 -1
- package/agentCommandSupport.ts +77 -0
- package/agentInternalCommandEntries.ts +34 -0
- package/agentListCommands.ts +123 -0
- package/agentListHelpers.ts +187 -0
- package/agentMachineCommands.ts +402 -0
- package/agentRecordCommands.ts +141 -0
- package/agentRecordHelpers.ts +395 -0
- package/agentRunCommand.ts +75 -3
- package/agentRuntimeCommands.ts +7 -773
- package/ai/agent/_executeModel.ts +29 -3
- package/ai/agent/buildSystemPrompt.ts +17 -0
- package/ai/agent/cliChatClient.ts +38 -4
- package/ai/agent/cliExecutor.ts +304 -25
- package/ai/agent/createAgentSchema.ts +2 -2
- package/ai/agent/guidedCreation/assistant.ts +82 -0
- package/ai/agent/guidedCreation/capabilities.ts +84 -0
- package/ai/agent/guidedCreation/draft.ts +62 -0
- package/ai/agent/guidedCreation/types.ts +38 -0
- package/ai/agent/machineRunPermissions.ts +21 -3
- package/ai/agent/runtimeGuidance.ts +1 -1
- package/ai/agent/server/fetchPublicAgents.ts +6 -1
- package/ai/agent/streamAgentChatTurn.ts +593 -36
- package/ai/agent/web/useGuidedAgentCreation.ts +217 -0
- package/ai/ai.locale.ts +14 -2
- package/ai/chat/fetchUtils.native.ts +2 -0
- package/ai/chat/fetchUtils.ts +2 -0
- package/ai/chat/sendOpenAICompletionsRequest.ts +82 -1
- package/ai/chat/sendOpenAIResponseRequest.ts +65 -0
- package/ai/llm/getPricing.ts +14 -0
- package/ai/llm/kimi.ts +4 -1
- package/ai/llm/modelAvatar.ts +1 -0
- package/ai/llm/providers.ts +4 -1
- package/ai/llm/reasoningModels.ts +1 -0
- package/ai/taskRun/taskRunProtocol.ts +25 -10
- package/ai/token/modelUsageQuery.ts +17 -0
- package/ai/tools/agent/agentTools.ts +38 -0
- package/ai/tools/agent/prepareAgentDraftTool.ts +159 -0
- package/ai/tools/agent/startAgentDialogTool.ts +53 -0
- package/ai/tools/checkEnvTool.ts +52 -20
- package/ai/tools/convertMarxistsBookTool.ts +103 -0
- package/ai/tools/{execBashTool.ts → execShellTool.ts} +44 -161
- package/ai/tools/index.ts +24 -14
- package/ai/tools/marxistsOfflineBook.ts +253 -0
- package/ai/tools/modelUsageTools.ts +9 -2
- package/ai/tools/readTool.ts +31 -0
- package/ai/tools/toolApiClient.ts +35 -1
- package/ai/tools/toolNameAliases.ts +13 -0
- package/cliCommandAdapters.ts +28 -0
- package/cliCommandDispatch.ts +66 -0
- package/cliCommandFactories.ts +34 -0
- package/cliCommandTypes.ts +49 -0
- package/cliEnvHelpers.ts +44 -0
- package/client/agentRun.test.ts +330 -24
- package/client/agentRun.ts +117 -35
- package/client/hybridRecordStore.test.ts +42 -0
- package/client/hybridRecordStore.ts +11 -0
- package/client/localRuntimeAdapter.test.ts +191 -21
- package/client/localRuntimeAdapter.ts +99 -10
- package/client/localRuntimeDryRun.test.ts +5 -2
- package/client/taskRunPrompt.ts +1 -0
- package/commandRegistry.ts +11 -61
- package/connector-experimental/capabilities.ts +1 -0
- package/database/actions/common.ts +4 -3
- package/database/config.ts +19 -0
- package/database/server/coreDataProxy.ts +43 -26
- package/index.ts +54 -191
- package/internalCommandEntries.ts +12 -0
- package/machineCommands.ts +688 -64
- package/offlineMarxistsAgentCommand.ts +314 -0
- package/package.json +22 -2
- package/render/canvas/canvasEditContext.ts +127 -0
- package/render/canvas/canvasRuntime.ts +57 -0
- package/render/canvas/canvasSnapshotParser.ts +76 -0
- package/render/canvas/canvasTree.ts +308 -0
- package/render/canvas/types.ts +46 -0
- package/render/layout/deleteBehavior.ts +52 -0
- package/render/layout/mainLayoutSidebar.ts +17 -0
- package/render/layout/mainLayoutViewMode.ts +56 -0
- package/render/layout/topbarUtils.ts +87 -0
- package/render/layout/useDevReloadPending.ts +30 -0
- package/render/page/createPageAction.ts +183 -0
- package/render/page/docSlice.ts +468 -0
- package/render/page/server/createPage.ts +174 -0
- package/render/page/server/handleCreatePage.ts +91 -0
- package/render/page/server/index.ts +4 -0
- package/render/page/types.ts +17 -0
- package/render/page/useKeyboardSave.ts +48 -0
- package/render/styles/zIndex.ts +12 -0
- package/render/surf/WeatherIconStyles.ts +17 -0
- package/render/surf/color.ts +9 -0
- package/render/surf/config.ts +46 -0
- package/render/surf/screens/style.ts +1 -0
- package/render/surf/styles/ToggleButtonStyles.ts +8 -0
- package/render/surf/utils/groupedWeatherData.ts +32 -0
- package/render/surf/weatherUtils.ts +50 -0
- package/render/table/activityColumns.ts +6 -0
- package/render/table/createTableAction.ts +270 -0
- package/render/table/deleteTableAction.ts +129 -0
- package/render/table/fetchAndCacheTableRows.ts +174 -0
- package/render/table/tableSlice.ts +1106 -0
- package/render/table/tableView.ts +289 -0
- package/render/table/toolValueUtils.ts +363 -0
- package/render/table/types.ts +252 -0
- package/render/table/useCreateTable.ts +72 -0
- package/render/table/useTable.ts +61 -0
- package/render/table/utils/tableSerialization.ts +50 -0
- package/render/web/elements/artifactPreviewCode.ts +43 -0
- package/render/web/elements/artifactRuntimePreload.ts +52 -0
- package/render/web/elements/codeBlockAutoPreview.ts +10 -0
- package/render/web/elements/mermaidPreview.ts +21 -0
- package/render/web/ui/useInlineEdit.ts +135 -0
- package/runtimeDoctorCommands.ts +118 -0
- package/scriptCommandEntries.ts +71 -0
- package/systemInternalCommandEntries.ts +71 -0
- package/tableCommands.ts +42 -5
- package/workflowInternalCommandEntries.ts +11 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { GuidedAgentDraft, GuidedAgentReferenceChoice } from "./types";
|
|
2
|
+
|
|
3
|
+
export const GUIDED_AGENT_CREATION_ASSISTANT_SYSTEM_PROMPT = `你是 Nolo 的 AI 创建助手。
|
|
4
|
+
|
|
5
|
+
目标:通过对话理解用户想创建的 AI,并输出结构化配置草稿。
|
|
6
|
+
|
|
7
|
+
规则:
|
|
8
|
+
- 只生成草稿,不要创建真实 Agent 记录。
|
|
9
|
+
- 不要告诉用户你已经创建了 Agent。
|
|
10
|
+
- 优先询问用途、目标用户、风格、边界、能力、资料来源、公开状态。
|
|
11
|
+
- 默认用能力语言沟通,不要要求用户理解 tool id。
|
|
12
|
+
- 如果用户提到资料、知识库或当前空间,只推荐 references,必须等待用户确认后才选择。
|
|
13
|
+
- 输出给系统的结构化草稿必须放在最后一个 JSON 代码块中。
|
|
14
|
+
- JSON 形状必须是 {"draft": {...}}。
|
|
15
|
+
- draft 字段包括 name, introduction, prompt, promptSummary, provider, model, isPublic, capabilityIds, toolIds, references, tags, unresolved。
|
|
16
|
+
- 如果信息不足,把缺失项写进 unresolved,并继续追问。
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const extractJsonBlocks = (content: string): string[] => {
|
|
20
|
+
const blocks: string[] = [];
|
|
21
|
+
const pattern = /```json\s*([\s\S]*?)```/g;
|
|
22
|
+
let match: RegExpExecArray | null;
|
|
23
|
+
while ((match = pattern.exec(content)) != null) {
|
|
24
|
+
blocks.push(match[1].trim());
|
|
25
|
+
}
|
|
26
|
+
return blocks;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const parseGuidedAgentAssistantDraft = (
|
|
30
|
+
content: string
|
|
31
|
+
): GuidedAgentDraft | null => {
|
|
32
|
+
const blocks = extractJsonBlocks(content);
|
|
33
|
+
const last = blocks[blocks.length - 1];
|
|
34
|
+
if (!last) return null;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(last);
|
|
38
|
+
const draft = parsed?.draft;
|
|
39
|
+
if (!draft || typeof draft !== "object") return null;
|
|
40
|
+
|
|
41
|
+
const sanitizeStringArray = (value: unknown): string[] =>
|
|
42
|
+
Array.isArray(value)
|
|
43
|
+
? value.filter((x): x is string => typeof x === "string")
|
|
44
|
+
: [];
|
|
45
|
+
|
|
46
|
+
const rawRefs = Array.isArray(draft.references) ? draft.references : [];
|
|
47
|
+
const sanitizedReferences: GuidedAgentReferenceChoice[] = rawRefs
|
|
48
|
+
.filter((ref): ref is Record<string, unknown> =>
|
|
49
|
+
ref !== null && typeof ref === "object"
|
|
50
|
+
)
|
|
51
|
+
.filter((r) => typeof r.dbKey === "string")
|
|
52
|
+
.map((r) => {
|
|
53
|
+
const choice: GuidedAgentReferenceChoice = {
|
|
54
|
+
dbKey: r.dbKey,
|
|
55
|
+
title: typeof r.title === "string" ? r.title : "",
|
|
56
|
+
type: r.type === "instruction" ? "instruction" : "knowledge",
|
|
57
|
+
selected: r.selected === true,
|
|
58
|
+
};
|
|
59
|
+
if (typeof r.reason === "string") {
|
|
60
|
+
choice.reason = r.reason;
|
|
61
|
+
}
|
|
62
|
+
return choice;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
name: String(draft.name || ""),
|
|
67
|
+
introduction: String(draft.introduction || ""),
|
|
68
|
+
prompt: String(draft.prompt || ""),
|
|
69
|
+
promptSummary: String(draft.promptSummary || ""),
|
|
70
|
+
provider: String(draft.provider || ""),
|
|
71
|
+
model: String(draft.model || ""),
|
|
72
|
+
isPublic: draft.isPublic === true,
|
|
73
|
+
capabilityIds: sanitizeStringArray(draft.capabilityIds),
|
|
74
|
+
toolIds: sanitizeStringArray(draft.toolIds),
|
|
75
|
+
references: sanitizedReferences,
|
|
76
|
+
tags: sanitizeStringArray(draft.tags),
|
|
77
|
+
unresolved: sanitizeStringArray(draft.unresolved),
|
|
78
|
+
};
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { GuidedAgentCapabilityId } from "./types";
|
|
2
|
+
|
|
3
|
+
type CapabilityDefinition = {
|
|
4
|
+
id: GuidedAgentCapabilityId;
|
|
5
|
+
label: {
|
|
6
|
+
zhCN: string;
|
|
7
|
+
en: string;
|
|
8
|
+
};
|
|
9
|
+
description: {
|
|
10
|
+
zhCN: string;
|
|
11
|
+
en: string;
|
|
12
|
+
};
|
|
13
|
+
toolIds: string[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const GUIDED_AGENT_CAPABILITIES: Record<
|
|
17
|
+
GuidedAgentCapabilityId,
|
|
18
|
+
CapabilityDefinition
|
|
19
|
+
> = {
|
|
20
|
+
webSearch: {
|
|
21
|
+
id: "webSearch",
|
|
22
|
+
label: { zhCN: "联网搜索", en: "Search the web" },
|
|
23
|
+
description: {
|
|
24
|
+
zhCN: "需要获取外部网页、资料或最新信息时使用。",
|
|
25
|
+
en: "Use when the agent needs external webpages, research, or current information.",
|
|
26
|
+
},
|
|
27
|
+
toolIds: ["exa_search", "fetchWebpage"],
|
|
28
|
+
},
|
|
29
|
+
docs: {
|
|
30
|
+
id: "docs",
|
|
31
|
+
label: { zhCN: "读写文档", en: "Read and write docs" },
|
|
32
|
+
description: {
|
|
33
|
+
zhCN: "需要读取、创建或更新知识页和文档时使用。",
|
|
34
|
+
en: "Use when the agent should read, create, or update docs.",
|
|
35
|
+
},
|
|
36
|
+
toolIds: ["createDoc", "updateDoc", "read"],
|
|
37
|
+
},
|
|
38
|
+
tables: {
|
|
39
|
+
id: "tables",
|
|
40
|
+
label: { zhCN: "处理表格", en: "Work with tables" },
|
|
41
|
+
description: {
|
|
42
|
+
zhCN: "需要创建表、追加记录或整理结构化数据时使用。",
|
|
43
|
+
en: "Use when the agent should create tables or manage structured rows.",
|
|
44
|
+
},
|
|
45
|
+
toolIds: ["createTable", "addTableRow", "addTableRows", "read"],
|
|
46
|
+
},
|
|
47
|
+
agents: {
|
|
48
|
+
id: "agents",
|
|
49
|
+
label: { zhCN: "调用其他 AI", en: "Call other AI agents" },
|
|
50
|
+
description: {
|
|
51
|
+
zhCN: "需要多 Agent 协作、评审或分工时使用。",
|
|
52
|
+
en: "Use when the agent should collaborate with other agents.",
|
|
53
|
+
},
|
|
54
|
+
toolIds: ["callAgent", "startAgentDialog"],
|
|
55
|
+
},
|
|
56
|
+
apps: {
|
|
57
|
+
id: "apps",
|
|
58
|
+
label: { zhCN: "创建应用或代码", en: "Create apps or code" },
|
|
59
|
+
description: {
|
|
60
|
+
zhCN: "需要生成应用、代码或使用 App Builder 能力时使用。",
|
|
61
|
+
en: "Use when the agent should build apps, code, or App Builder outputs.",
|
|
62
|
+
},
|
|
63
|
+
toolIds: ["appDeploy", "appList", "appRead"],
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const mapCapabilityIdsToToolIds = (
|
|
68
|
+
capabilityIds: GuidedAgentCapabilityId[]
|
|
69
|
+
): string[] => {
|
|
70
|
+
const seen = new Set<string>();
|
|
71
|
+
const result: string[] = [];
|
|
72
|
+
|
|
73
|
+
for (const id of capabilityIds) {
|
|
74
|
+
const definition = GUIDED_AGENT_CAPABILITIES[id];
|
|
75
|
+
if (!definition) continue;
|
|
76
|
+
for (const toolId of definition.toolIds) {
|
|
77
|
+
if (seen.has(toolId)) continue;
|
|
78
|
+
seen.add(toolId);
|
|
79
|
+
result.push(toolId);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FormData as AgentFormData } from "ai/agent/createAgentSchema";
|
|
2
|
+
import type { GuidedAgentDraft, GuidedAgentValidationResult } from "./types";
|
|
3
|
+
|
|
4
|
+
const trim = (value: unknown) =>
|
|
5
|
+
typeof value === "string" ? value.trim() : "";
|
|
6
|
+
|
|
7
|
+
export const validateGuidedAgentDraft = (
|
|
8
|
+
draft: GuidedAgentDraft
|
|
9
|
+
): GuidedAgentValidationResult => {
|
|
10
|
+
const missing: string[] = [];
|
|
11
|
+
|
|
12
|
+
if (!trim(draft.name)) missing.push("name");
|
|
13
|
+
if (!trim(draft.model)) missing.push("model");
|
|
14
|
+
if (!trim(draft.provider)) missing.push("provider");
|
|
15
|
+
if (!trim(draft.prompt)) missing.push("prompt");
|
|
16
|
+
if (!trim(draft.introduction)) missing.push("introduction");
|
|
17
|
+
|
|
18
|
+
return missing.length === 0 ? { ok: true } : { ok: false, missing };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const mergeGuidedAgentDraft = (
|
|
22
|
+
current: GuidedAgentDraft,
|
|
23
|
+
next: Partial<GuidedAgentDraft>
|
|
24
|
+
): GuidedAgentDraft => ({
|
|
25
|
+
...current,
|
|
26
|
+
...next,
|
|
27
|
+
capabilityIds: next.capabilityIds ?? current.capabilityIds,
|
|
28
|
+
toolIds: next.toolIds ?? current.toolIds,
|
|
29
|
+
references: next.references ?? current.references,
|
|
30
|
+
tags: next.tags ?? current.tags,
|
|
31
|
+
unresolved: next.unresolved ?? current.unresolved,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export const buildAgentFormDataFromGuidedDraft = (
|
|
35
|
+
draft: GuidedAgentDraft
|
|
36
|
+
): AgentFormData => ({
|
|
37
|
+
name: trim(draft.name),
|
|
38
|
+
model: trim(draft.model),
|
|
39
|
+
provider: trim(draft.provider),
|
|
40
|
+
apiSource: "platform",
|
|
41
|
+
useServerProxy: true,
|
|
42
|
+
hasVision: false,
|
|
43
|
+
prompt: trim(draft.prompt),
|
|
44
|
+
introduction: trim(draft.introduction),
|
|
45
|
+
greeting: `你好,我是${trim(draft.name) || "你的 AI 助手"}。你想先让我帮你做什么?`,
|
|
46
|
+
isPublic: draft.isPublic === true,
|
|
47
|
+
tags: draft.tags.map((tag) => trim(tag)).filter(Boolean).join(", "),
|
|
48
|
+
tools: Array.from(new Set(draft.toolIds.filter(Boolean))),
|
|
49
|
+
references: draft.references
|
|
50
|
+
.filter((reference) => reference.selected === true)
|
|
51
|
+
.map((reference) => ({
|
|
52
|
+
dbKey: reference.dbKey,
|
|
53
|
+
title: reference.title || "",
|
|
54
|
+
type: reference.type === "instruction" ? "instruction" : "knowledge",
|
|
55
|
+
})),
|
|
56
|
+
linkedSpaces: [],
|
|
57
|
+
customProviderUrl: "",
|
|
58
|
+
apiKey: "",
|
|
59
|
+
inputPrice: 0,
|
|
60
|
+
outputPrice: 0,
|
|
61
|
+
whitelist: [],
|
|
62
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReferenceItem } from "app/types";
|
|
2
|
+
|
|
3
|
+
export type GuidedAgentCapabilityId =
|
|
4
|
+
| "webSearch"
|
|
5
|
+
| "docs"
|
|
6
|
+
| "tables"
|
|
7
|
+
| "agents"
|
|
8
|
+
| "apps";
|
|
9
|
+
|
|
10
|
+
export type GuidedAgentReferenceChoice = ReferenceItem & {
|
|
11
|
+
selected: boolean;
|
|
12
|
+
reason?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type GuidedAgentDraft = {
|
|
16
|
+
name: string;
|
|
17
|
+
introduction: string;
|
|
18
|
+
prompt: string;
|
|
19
|
+
promptSummary: string;
|
|
20
|
+
provider: string;
|
|
21
|
+
model: string;
|
|
22
|
+
isPublic: boolean;
|
|
23
|
+
capabilityIds: GuidedAgentCapabilityId[];
|
|
24
|
+
toolIds: string[];
|
|
25
|
+
references: GuidedAgentReferenceChoice[];
|
|
26
|
+
tags: string[];
|
|
27
|
+
unresolved: string[];
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type GuidedAgentAssistantMessage = {
|
|
31
|
+
id: string;
|
|
32
|
+
role: "user" | "assistant";
|
|
33
|
+
content: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type GuidedAgentValidationResult =
|
|
37
|
+
| { ok: true }
|
|
38
|
+
| { ok: false; missing: string[] };
|
|
@@ -65,13 +65,31 @@ export function resolveMachineRunPermissionPolicy(agentConfig: any): MachineRunP
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const WRITE_INTENT_RE =
|
|
68
|
-
/\b(write|overwrite|edit|modify|delete|remove|rename|move|create|save|patch|apply patch|mkdir|touch|rm|rmdir|del|erase|copy-item|move-item|remove-item|set-content|add-content|new-item)\b|
|
|
68
|
+
/\b(write|overwrite|edit|modify|delete|remove|rename|move|create|save|patch|apply patch|mkdir|touch|rm|rmdir|del|erase|copy-item|move-item|remove-item|set-content|add-content|new-item)\b|(\u5199\u5165|\u5199\u6587\u4EF6|\u5220\u9664|\u79FB\u9664|\u91CD\u547D\u540D|\u79FB\u52A8|\u521B\u5EFA|\u65B0\u5EFA|\u4FDD\u5B58|\u4FEE\u6539|\u7F16\u8F91|\u6253\u8865\u4E01|\u5E94\u7528\u8865\u4E01)/i;
|
|
69
69
|
|
|
70
70
|
const SHELL_INTENT_RE =
|
|
71
|
-
/\b(run|execute|exec
|
|
71
|
+
/\b(run|execute|exec)\s+(?:a\s+)?(?:shell|command|terminal|powershell|pwsh|bash|zsh|cmd\.exe|npm|bun|node|python|git|curl|wget|ssh|scp|chmod|chown|sudo|tests?|test suite)\b|\b(open|start)\s+(?:a\s+)?(?:shell|terminal)\b|\b(powershell|pwsh|bash|zsh|cmd\.exe|ssh|sudo)\b|(\u8FD0\u884C\u547D\u4EE4|\u6267\u884C\u547D\u4EE4|\u547D\u4EE4\u884C|\u7EC8\u7AEF|\u63A7\u5236\u53F0)/i;
|
|
72
|
+
|
|
73
|
+
const NEGATION_RE =
|
|
74
|
+
/\b(do not|don't|dont|never|no need to|without|非目标|不要|不需要|禁止|无需)\b|[\u4E0D\u975E]/i;
|
|
75
|
+
|
|
76
|
+
function stripNegatedPolicySentences(task: string): string {
|
|
77
|
+
return task
|
|
78
|
+
.split(/([\n.;!?。;!?])/)
|
|
79
|
+
.reduce<string[]>((segments, part, index, parts) => {
|
|
80
|
+
if (index % 2 === 1) return segments;
|
|
81
|
+
const separator = parts[index + 1] ?? "";
|
|
82
|
+
const segment = `${part}${separator}`;
|
|
83
|
+
const mentionsRestrictedAction = WRITE_INTENT_RE.test(segment) || SHELL_INTENT_RE.test(segment);
|
|
84
|
+
if (mentionsRestrictedAction && NEGATION_RE.test(segment)) return segments;
|
|
85
|
+
segments.push(segment);
|
|
86
|
+
return segments;
|
|
87
|
+
}, [])
|
|
88
|
+
.join("");
|
|
89
|
+
}
|
|
72
90
|
|
|
73
91
|
export function assertMachineRunAllowed(userInput: string, policy: MachineRunPermissionPolicy) {
|
|
74
|
-
const task = String(userInput || "");
|
|
92
|
+
const task = stripNegatedPolicySentences(String(userInput || ""));
|
|
75
93
|
if (!policy.allowFilesystemWrite && WRITE_INTENT_RE.test(task)) {
|
|
76
94
|
throw new Error(WRITE_DENIED);
|
|
77
95
|
}
|
|
@@ -54,7 +54,7 @@ const buildWebResearchToolPolicyBlock = (
|
|
|
54
54
|
return [
|
|
55
55
|
"--- 生产环境网页研究工具策略 ---",
|
|
56
56
|
"生产环境网页研究优先使用 fetchWebpage、站点 Markdown / llms.txt、或专用浏览/搜索工具。",
|
|
57
|
-
"不要用 execShell
|
|
57
|
+
"不要用 execShell 调 curl、grep、sed 等命令抓网页或截取网页段落;生产环境通常会禁用 dev shell,反复尝试只会浪费回合。",
|
|
58
58
|
"如果网页内容过长或锚点段落没有被单独提取,先寻找该文档站提供的 Markdown 版本、独立页面、llms.txt 索引或更具体 URL,再继续回答。",
|
|
59
59
|
].join("\n");
|
|
60
60
|
};
|
|
@@ -150,7 +150,12 @@ export async function fetchPublicAgents(
|
|
|
150
150
|
|
|
151
151
|
if (searchName) {
|
|
152
152
|
const kw = searchName.toLowerCase();
|
|
153
|
-
list = list.filter((agent) =>
|
|
153
|
+
list = list.filter((agent) => {
|
|
154
|
+
const nameMatch = agent.name?.toLowerCase().includes(kw);
|
|
155
|
+
const introMatch = agent.introduction?.toLowerCase().includes(kw);
|
|
156
|
+
const tagMatch = agent.tags?.some((tag) => tag.toLowerCase().includes(kw));
|
|
157
|
+
return nameMatch || introMatch || tagMatch;
|
|
158
|
+
});
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
if (userId) {
|