nolo-cli 0.1.32 → 0.1.33
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 -6
- package/agent-runtime/agentRecordConfig.ts +2 -0
- package/agent-runtime/hostAdapter.ts +1 -0
- package/agent-runtime/index.ts +0 -21
- package/agent-runtime/localToolPolicy.ts +6 -13
- package/agent-runtime/localWorkspaceTools.ts +30 -333
- package/agent-runtime/platformChatProvider.ts +1 -4
- package/agent-runtime/runtimeToolPolicy.ts +47 -32
- package/agentAliases.ts +14 -83
- package/agentCommandSupport.ts +3 -6
- package/agentInternalCommandEntries.ts +2 -13
- package/agentListCommands.ts +19 -28
- package/agentMachineCommands.ts +40 -336
- package/agentPullCommand.ts +36 -56
- package/agentRecordCommands.ts +3 -5
- package/agentRecordHelpers.ts +22 -189
- package/agentRunCommand.ts +438 -107
- package/agentRuntimeLocal.ts +0 -10
- package/ai/agent/cliExecutor.ts +19 -323
- package/authCommands.ts +2 -36
- package/cli/agentAliases.ts +14 -83
- package/cli/agentCommandSupport.ts +3 -6
- package/cli/agentInternalCommandEntries.ts +2 -13
- package/cli/agentListCommands.ts +19 -28
- package/cli/agentMachineCommands.ts +40 -336
- package/cli/agentPullCommand.ts +36 -56
- package/cli/agentRecordCommands.ts +3 -5
- package/cli/agentRecordHelpers.ts +22 -189
- package/cli/agentRunCommand.ts +438 -107
- package/cli/agentRuntimeLocal.ts +0 -10
- package/cli/authCommands.ts +2 -36
- package/cli/cliEnvHelpers.ts +21 -162
- package/cli/client/agentRun.ts +853 -57
- package/cli/client/localRuntimeAdapter.ts +22 -159
- package/cli/client/streamingOutput.ts +3 -1
- package/cli/client/taskRunPrompt.ts +24 -7
- package/cli/commandRegistry.ts +2 -3
- package/cli/connectorRunArtifact.ts +10 -34
- package/cli/connectorWebSocketTarget.ts +6 -10
- package/cli/internalCommandEntries.ts +0 -8
- package/cli/localRuntimeDb.ts +2 -39
- package/cli/machineCommands.ts +189 -190
- package/cli/machineDaemonCommands.ts +165 -9
- package/cli/machineHeartbeatCommands.ts +2 -1
- package/cli/machineStatusCommands.ts +13 -5
- package/cli/machineWatchCommands.ts +1 -1
- package/cli/machineWsRunDispatch.ts +14 -48
- package/cli/machineWsSession.ts +0 -2
- package/cli/offlineMarxistsAgentCommand.ts +314 -0
- package/cli/runtimeDoctorCommands.ts +69 -18
- package/cli/scriptCommandEntries.ts +45 -5
- package/cli/tableCommands.ts +133 -33
- package/cli/taskRunCommand.ts +211 -16
- package/cli/tui/session.ts +372 -43
- package/cli/workflowInternalCommandEntries.ts +0 -20
- package/cliEnvHelpers.ts +21 -162
- package/client/agentConfigResolver.test.ts +2 -0
- package/client/agentRun.test.ts +12 -208
- package/client/agentRun.ts +853 -57
- package/client/localRuntimeAdapter.test.ts +9 -168
- package/client/localRuntimeAdapter.ts +22 -159
- package/client/localToolPolicy.test.ts +4 -28
- package/client/streamingOutput.ts +3 -1
- package/client/taskRunPrompt.ts +24 -7
- package/commandRegistry.ts +2 -3
- package/connectorRunArtifact.ts +10 -34
- package/connectorWebSocketTarget.ts +6 -10
- package/database/server/db.ts +34 -15
- package/internalCommandEntries.ts +0 -8
- package/localRuntimeDb.ts +2 -39
- package/machineCommands.ts +189 -190
- package/machineDaemonCommands.ts +165 -9
- package/machineHeartbeatCommands.ts +2 -1
- package/machineStatusCommands.ts +13 -5
- package/machineWatchCommands.ts +1 -1
- package/machineWsRunDispatch.ts +14 -48
- package/machineWsSession.ts +0 -2
- package/offlineMarxistsAgentCommand.ts +314 -0
- package/package.json +49 -193
- package/runtimeDoctorCommands.ts +69 -18
- package/scriptCommandEntries.ts +45 -5
- package/tableCommands.ts +133 -33
- package/taskRunCommand.ts +211 -16
- package/tui/session.ts +372 -43
- package/workflowInternalCommandEntries.ts +0 -20
- package/agent-runtime/dialogStatus.ts +0 -139
- package/agent-runtime/hostRuntimeConfig.ts +0 -86
- package/agentCreateCustomCommands.ts +0 -278
- package/agentDialogsCommands.ts +0 -227
- package/agentDoctorCommands.ts +0 -203
- package/agentRunLocalWorkspace.ts +0 -182
- package/agentRunParsing.ts +0 -298
- package/agentSuperviseCommands.ts +0 -8
- package/agentUnpublishCommands.ts +0 -113
- package/ai/agent/agentRunDialogLineage.ts +0 -56
- package/ai/policy/types.ts +0 -64
- package/ai/skills/skillSummaryMarker.ts +0 -26
- package/app/types.ts +0 -358
- package/build.ts +0 -16
- package/buildPublish.ts +0 -138
- package/buildPublishArtifactAssembly.ts +0 -724
- package/buildPublishImportAnalysis.ts +0 -242
- package/chat/messages/fetchMessages.ts +0 -84
- package/chat/messages/types.ts +0 -185
- package/cli/agentCreateCustomCommands.ts +0 -278
- package/cli/agentDialogsCommands.ts +0 -227
- package/cli/agentDoctorCommands.ts +0 -203
- package/cli/agentRunLocalWorkspace.ts +0 -182
- package/cli/agentRunParsing.ts +0 -298
- package/cli/agentSuperviseCommands.ts +0 -8
- package/cli/agentUnpublishCommands.ts +0 -113
- package/cli/buildPublish.ts +0 -138
- package/cli/buildPublishArtifactAssembly.ts +0 -724
- package/cli/buildPublishImportAnalysis.ts +0 -242
- package/cli/cliIoTypes.ts +0 -3
- package/cli/cliRuntimeDoctorReport.ts +0 -193
- package/cli/client/agentRunInput.ts +0 -10
- package/cli/client/agentRunLocalExecution.ts +0 -124
- package/cli/client/agentRunLocalExecutor.ts +0 -179
- package/cli/client/agentRunRuntimeSelection.ts +0 -145
- package/cli/client/agentRunServerTransport.ts +0 -397
- package/cli/client/agentRunTaskRunRecorder.ts +0 -176
- package/cli/customCodingAgentFlow.ts +0 -208
- package/cli/customCodingAgentRecord.ts +0 -179
- package/cli/dialogDataAccess.ts +0 -186
- package/cli/dialogInternalCommandEntries.ts +0 -11
- package/cli/dialogReadCommands.ts +0 -180
- package/cli/dialogReadHelpers.ts +0 -226
- package/cli/dialogStatusCommands.ts +0 -123
- package/cli/docInternalCommandEntries.ts +0 -20
- package/cli/hybridReadHelpers.ts +0 -109
- package/cli/machineCommandPrompts.ts +0 -79
- package/cli/machineCommandResolution.ts +0 -43
- package/cli/noloReadBridgePrompt.ts +0 -16
- package/cli/pageCreateCommands.ts +0 -219
- package/cli/pageDeleteCommands.ts +0 -167
- package/cli/pageReadCommands.ts +0 -151
- package/cli/pageUpdateCommands.ts +0 -249
- package/cli/pageWriteHelpers.ts +0 -209
- package/cli/publishPackage.ts +0 -36
- package/cli/runtimeInternalCommandEntries.ts +0 -15
- package/cli/runtimePassthroughCommands.ts +0 -22
- package/cli/scriptPassthroughHelpers.ts +0 -28
- package/cli/secretScanHelpers.ts +0 -31
- package/cli/spaceAttachCommands.ts +0 -134
- package/cli/spaceCategoryCommands.ts +0 -263
- package/cli/spaceCommands.ts +0 -295
- package/cli/spaceDeleteCommands.ts +0 -312
- package/cli/spaceInternalCommandEntries.ts +0 -21
- package/cli/spaceMutationHelpers.ts +0 -135
- package/cli/spaceReadCommands.ts +0 -323
- package/cli/tableDataOutput.ts +0 -41
- package/cli/tableDataSafety.ts +0 -26
- package/cli/tableMetaCommands.ts +0 -307
- package/cli/tableMutationCommands.ts +0 -266
- package/cli/tableQueryParsing.ts +0 -90
- package/cli/tableQueryRequest.ts +0 -53
- package/cli/taskRunActions.ts +0 -122
- package/cli/taskRunParsing.ts +0 -86
- package/cli/taskRunPromptShared.ts +0 -55
- package/cli/tui/tuiCatalog.ts +0 -22
- package/cli/tui/tuiCommandInterpreter.ts +0 -253
- package/cli/tui/tuiPresentation.ts +0 -146
- package/cliIoTypes.ts +0 -3
- package/cliRuntimeDoctorReport.ts +0 -193
- package/client/agentRunInput.ts +0 -10
- package/client/agentRunLocalExecution.test.ts +0 -123
- package/client/agentRunLocalExecution.ts +0 -124
- package/client/agentRunLocalExecutor.ts +0 -179
- package/client/agentRunRuntimeSelection.test.ts +0 -159
- package/client/agentRunRuntimeSelection.ts +0 -145
- package/client/agentRunServerTransport.ts +0 -397
- package/client/agentRunTaskRunRecorder.ts +0 -176
- package/connector-experimental/daemonLauncher.ts +0 -223
- package/create/space/spaceKeys.ts +0 -65
- package/create/types.ts +0 -21
- package/customCodingAgentFlow.ts +0 -208
- package/customCodingAgentRecord.ts +0 -179
- package/database/keys.ts +0 -765
- package/database/server/authorityStoreTypes.ts +0 -31
- package/database/server/legacyServerDb.ts +0 -58
- package/database/server/levelAuthorityStore.ts +0 -75
- package/database/server/memoryAuthorityStore.ts +0 -133
- package/database/server/serverStoreFactory.ts +0 -124
- package/database/tombstones.ts +0 -52
- package/database/utils/ulid.ts +0 -1
- package/dialogDataAccess.ts +0 -186
- package/dialogInternalCommandEntries.ts +0 -11
- package/dialogReadCommands.ts +0 -180
- package/dialogReadHelpers.ts +0 -226
- package/dialogStatusCommands.ts +0 -123
- package/docInternalCommandEntries.ts +0 -20
- package/hybridReadHelpers.ts +0 -109
- package/machineCommandPrompts.ts +0 -79
- package/machineCommandResolution.ts +0 -43
- package/noloReadBridgePrompt.ts +0 -16
- package/pageCreateCommands.ts +0 -219
- package/pageDeleteCommands.ts +0 -167
- package/pageReadCommands.ts +0 -151
- package/pageUpdateCommands.ts +0 -249
- package/pageWriteHelpers.ts +0 -209
- package/publishPackage.ts +0 -36
- package/runtimeInternalCommandEntries.ts +0 -15
- package/runtimePassthroughCommands.ts +0 -22
- package/scriptPassthroughHelpers.ts +0 -28
- package/secretScanHelpers.ts +0 -31
- package/share/helpers.ts +0 -302
- package/share/keys.ts +0 -243
- package/share/types.ts +0 -100
- package/spaceAttachCommands.ts +0 -134
- package/spaceCategoryCommands.ts +0 -263
- package/spaceCommands.ts +0 -295
- package/spaceDeleteCommands.ts +0 -312
- package/spaceInternalCommandEntries.ts +0 -21
- package/spaceMutationHelpers.ts +0 -135
- package/spaceReadCommands.ts +0 -323
- package/tableDataOutput.ts +0 -41
- package/tableDataSafety.ts +0 -26
- package/tableMetaCommands.ts +0 -307
- package/tableMutationCommands.ts +0 -266
- package/tableQueryParsing.ts +0 -90
- package/tableQueryRequest.ts +0 -53
- package/taskRunActions.ts +0 -122
- package/taskRunParsing.ts +0 -86
- package/taskRunPromptShared.ts +0 -55
- package/tui/tuiCatalog.ts +0 -22
- package/tui/tuiCommandInterpreter.test.ts +0 -169
- package/tui/tuiCommandInterpreter.ts +0 -253
- package/tui/tuiPresentation.test.ts +0 -154
- package/tui/tuiPresentation.ts +0 -146
|
@@ -3,7 +3,6 @@ import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
|
|
6
|
-
import { createHostRuntimeConfig } from "../agent-runtime";
|
|
7
6
|
import { runLocalAgentTurn } from "../agent-runtime/localLoop";
|
|
8
7
|
import { createCliLocalRuntimeAdapter } from "./localRuntimeAdapter";
|
|
9
8
|
|
|
@@ -23,9 +22,7 @@ describe("CLI local runtime adapter", () => {
|
|
|
23
22
|
"searchFiles",
|
|
24
23
|
];
|
|
25
24
|
const SHELL_LOCAL_CODING_TOOL_NAMES = [
|
|
26
|
-
|
|
27
|
-
"writeFile",
|
|
28
|
-
"editFile",
|
|
25
|
+
...DEFAULT_LOCAL_CODING_TOOL_NAMES,
|
|
29
26
|
"execShell",
|
|
30
27
|
];
|
|
31
28
|
|
|
@@ -33,14 +30,6 @@ describe("CLI local runtime adapter", () => {
|
|
|
33
30
|
return request?.body?.tools?.map((tool: any) => tool.function.name) ?? [];
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
function createCliHostRuntimeConfig(allowShell = false, workspaceBinding: "explicit-cwd" | "default-cwd" = "explicit-cwd") {
|
|
37
|
-
return createHostRuntimeConfig({
|
|
38
|
-
surface: "cli-local",
|
|
39
|
-
workspaceBinding,
|
|
40
|
-
allowShell,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
33
|
test("loads agent/history from LevelDB and saves dialog/message records back to LevelDB", async () => {
|
|
45
34
|
const requests: Array<{ url: string; body: any; auth: string | null }> = [];
|
|
46
35
|
const store = new Map<string, any>([
|
|
@@ -289,57 +278,6 @@ describe("CLI local runtime adapter", () => {
|
|
|
289
278
|
});
|
|
290
279
|
});
|
|
291
280
|
|
|
292
|
-
test("runs apiSource=cli agents through the local CLI executor even when direct provider env is present", async () => {
|
|
293
|
-
const executions: Array<{ provider: string; prompt: string; options: any }> = [];
|
|
294
|
-
const adapter = createCliLocalRuntimeAdapter({
|
|
295
|
-
env: {
|
|
296
|
-
OPENAI_API_KEY: "sk-local",
|
|
297
|
-
NOLO_LOCAL_OPENAI_BASE_URL: "http://127.0.0.1:11434/v1",
|
|
298
|
-
},
|
|
299
|
-
cwd: import.meta.dir,
|
|
300
|
-
db: {
|
|
301
|
-
get: async () => ({
|
|
302
|
-
dbKey: "agent-local-frontend",
|
|
303
|
-
id: "frontend",
|
|
304
|
-
apiSource: "cli",
|
|
305
|
-
cliProvider: "agy",
|
|
306
|
-
prompt: "Fix UI",
|
|
307
|
-
model: "",
|
|
308
|
-
}),
|
|
309
|
-
put: async () => {},
|
|
310
|
-
batch: async () => {},
|
|
311
|
-
iterator: () => (async function* () {})(),
|
|
312
|
-
},
|
|
313
|
-
fetchImpl: async () => {
|
|
314
|
-
throw new Error("OpenAI-compatible fetch should not run for local CLI agents");
|
|
315
|
-
},
|
|
316
|
-
executeCli: async (provider, prompt, options) => {
|
|
317
|
-
executions.push({ provider, prompt, options });
|
|
318
|
-
return { text: "cli local ok", raw: "cli local ok", elapsed: 10 };
|
|
319
|
-
},
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
const result = await runLocalAgentTurn({
|
|
323
|
-
adapter,
|
|
324
|
-
agentRef: "frontend",
|
|
325
|
-
input: "make it cleaner",
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
expect(result).toMatchObject({
|
|
329
|
-
content: "cli local ok",
|
|
330
|
-
model: "agy",
|
|
331
|
-
});
|
|
332
|
-
expect(executions).toEqual([{
|
|
333
|
-
provider: "agy",
|
|
334
|
-
prompt: "make it cleaner",
|
|
335
|
-
options: expect.objectContaining({
|
|
336
|
-
cwd: import.meta.dir,
|
|
337
|
-
yolo: true,
|
|
338
|
-
systemPrompt: "Fix UI",
|
|
339
|
-
}),
|
|
340
|
-
}]);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
281
|
test("uses agent customProviderUrl for local OpenAI-compatible requests", async () => {
|
|
344
282
|
const requests: Array<{ url: string; auth: string | null; body: any }> = [];
|
|
345
283
|
const store = new Map<string, any>([
|
|
@@ -746,10 +684,6 @@ describe("CLI local runtime adapter", () => {
|
|
|
746
684
|
id: "shell",
|
|
747
685
|
prompt: "Use shell.",
|
|
748
686
|
model: "gpt-4.1-mini",
|
|
749
|
-
runtimeToolPolicy: {
|
|
750
|
-
version: 1,
|
|
751
|
-
runtimeTools: ["execShell"],
|
|
752
|
-
},
|
|
753
687
|
}],
|
|
754
688
|
]);
|
|
755
689
|
const adapter = createCliLocalRuntimeAdapter({
|
|
@@ -1054,28 +988,17 @@ describe("CLI local runtime adapter", () => {
|
|
|
1054
988
|
});
|
|
1055
989
|
});
|
|
1056
990
|
|
|
1057
|
-
test("rejects
|
|
991
|
+
test("rejects tools unless the local tool policy allows and registers them", async () => {
|
|
1058
992
|
const adapter = createCliLocalRuntimeAdapter({
|
|
1059
|
-
env: {
|
|
1060
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(),
|
|
1061
|
-
db: {
|
|
1062
|
-
get: async () => ({
|
|
1063
|
-
dbKey: "agent-user-1-shell",
|
|
1064
|
-
toolNames: ["execShell"],
|
|
1065
|
-
}),
|
|
1066
|
-
put: async () => {},
|
|
1067
|
-
batch: async () => {},
|
|
1068
|
-
iterator: () => (async function* () {})(),
|
|
1069
|
-
},
|
|
993
|
+
env: {},
|
|
1070
994
|
fetchImpl: async () => Response.json({}),
|
|
1071
995
|
});
|
|
1072
996
|
|
|
1073
|
-
await adapter.loadAgentConfig("shell");
|
|
1074
997
|
await expect(adapter.executeTool({
|
|
1075
998
|
id: "call-1",
|
|
1076
999
|
name: "execShell",
|
|
1077
1000
|
arguments: "{}",
|
|
1078
|
-
})).rejects.toThrow("execShell
|
|
1001
|
+
})).rejects.toThrow("execShell requires NOLO_LOCAL_SHELL_MODE");
|
|
1079
1002
|
});
|
|
1080
1003
|
|
|
1081
1004
|
test("executes explicitly allowed registered local tools declared by the agent", async () => {
|
|
@@ -1117,22 +1040,19 @@ describe("CLI local runtime adapter", () => {
|
|
|
1117
1040
|
expect(result.content).toContain("README.md");
|
|
1118
1041
|
});
|
|
1119
1042
|
|
|
1120
|
-
test("
|
|
1043
|
+
test("advertises execShell to OpenAI-compatible providers when shell mode is enabled", async () => {
|
|
1121
1044
|
const requests: Array<{ body: any }> = [];
|
|
1122
1045
|
const adapter = createCliLocalRuntimeAdapter({
|
|
1123
1046
|
env: {
|
|
1124
1047
|
OPENAI_API_KEY: "sk-local",
|
|
1125
1048
|
NOLO_LOCAL_OPENAI_BASE_URL: "http://127.0.0.1:11434/v1",
|
|
1049
|
+
NOLO_LOCAL_SHELL_MODE: "worktree",
|
|
1126
1050
|
},
|
|
1127
1051
|
db: {
|
|
1128
1052
|
get: async () => ({
|
|
1129
1053
|
dbKey: "agent-local-shell",
|
|
1130
1054
|
prompt: "Use shell.",
|
|
1131
1055
|
model: "gpt-4.1-mini",
|
|
1132
|
-
runtimeToolPolicy: {
|
|
1133
|
-
version: 1,
|
|
1134
|
-
runtimeTools: ["execShell"],
|
|
1135
|
-
},
|
|
1136
1056
|
}),
|
|
1137
1057
|
put: async () => {},
|
|
1138
1058
|
batch: async () => {},
|
|
@@ -1155,81 +1075,6 @@ describe("CLI local runtime adapter", () => {
|
|
|
1155
1075
|
expect(toolNamesFromRequest(requests[0])).toEqual(SHELL_LOCAL_CODING_TOOL_NAMES);
|
|
1156
1076
|
});
|
|
1157
1077
|
|
|
1158
|
-
test("keeps advertised fallback workspace tools executable when shell is explicitly disabled", async () => {
|
|
1159
|
-
const workspaceRoot = mkdtempSync(join(tmpdir(), "nolo-cli-runtime-shell-off-"));
|
|
1160
|
-
try {
|
|
1161
|
-
const adapter = createCliLocalRuntimeAdapter({
|
|
1162
|
-
env: {},
|
|
1163
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(false),
|
|
1164
|
-
db: {
|
|
1165
|
-
get: async () => ({
|
|
1166
|
-
dbKey: "agent-local-shell-off",
|
|
1167
|
-
runtimeToolPolicy: {
|
|
1168
|
-
version: 1,
|
|
1169
|
-
runtimeTools: ["execShell"],
|
|
1170
|
-
},
|
|
1171
|
-
}),
|
|
1172
|
-
put: async () => {},
|
|
1173
|
-
batch: async () => {},
|
|
1174
|
-
iterator: () => (async function* () {})(),
|
|
1175
|
-
},
|
|
1176
|
-
cwd: workspaceRoot,
|
|
1177
|
-
fetchImpl: async () => Response.json({}),
|
|
1178
|
-
});
|
|
1179
|
-
|
|
1180
|
-
await adapter.loadAgentConfig("shell-off");
|
|
1181
|
-
const result = await adapter.executeTool({
|
|
1182
|
-
id: "call-list-files",
|
|
1183
|
-
name: "listFiles",
|
|
1184
|
-
arguments: JSON.stringify({ path: "." }),
|
|
1185
|
-
});
|
|
1186
|
-
|
|
1187
|
-
expect(result.metadata).toMatchObject({ path: ".", count: 0 });
|
|
1188
|
-
expect(result.content).toBe("");
|
|
1189
|
-
} finally {
|
|
1190
|
-
rmSync(workspaceRoot, { recursive: true, force: true });
|
|
1191
|
-
}
|
|
1192
|
-
});
|
|
1193
|
-
|
|
1194
|
-
test("does not advertise execShell when only a legacy runtimeToolPolicy.shell block is present", async () => {
|
|
1195
|
-
const requests: Array<{ body: any }> = [];
|
|
1196
|
-
const adapter = createCliLocalRuntimeAdapter({
|
|
1197
|
-
env: {
|
|
1198
|
-
OPENAI_API_KEY: "sk-local",
|
|
1199
|
-
NOLO_LOCAL_OPENAI_BASE_URL: "http://127.0.0.1:11434/v1",
|
|
1200
|
-
},
|
|
1201
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(true),
|
|
1202
|
-
db: {
|
|
1203
|
-
get: async () => ({
|
|
1204
|
-
dbKey: "agent-local-legacy-shell",
|
|
1205
|
-
prompt: "Do not get shell from legacy policy.",
|
|
1206
|
-
model: "gpt-4.1-mini",
|
|
1207
|
-
runtimeToolPolicy: {
|
|
1208
|
-
version: 1,
|
|
1209
|
-
shell: { enabled: true, mode: "worktree" },
|
|
1210
|
-
},
|
|
1211
|
-
}),
|
|
1212
|
-
put: async () => {},
|
|
1213
|
-
batch: async () => {},
|
|
1214
|
-
iterator: () => (async function* () {})(),
|
|
1215
|
-
},
|
|
1216
|
-
fetchImpl: async (_url, init) => {
|
|
1217
|
-
requests.push({ body: JSON.parse(String(init?.body)) });
|
|
1218
|
-
return Response.json({
|
|
1219
|
-
choices: [{ message: { content: "done" } }],
|
|
1220
|
-
});
|
|
1221
|
-
},
|
|
1222
|
-
});
|
|
1223
|
-
|
|
1224
|
-
await runLocalAgentTurn({
|
|
1225
|
-
adapter,
|
|
1226
|
-
agentRef: "legacy-shell",
|
|
1227
|
-
input: "pwd",
|
|
1228
|
-
});
|
|
1229
|
-
|
|
1230
|
-
expect(toolNamesFromRequest(requests[0])).not.toContain("execShell");
|
|
1231
|
-
});
|
|
1232
|
-
|
|
1233
1078
|
test("allows default semantic workspace tools without legacy agent tool declarations", async () => {
|
|
1234
1079
|
const workspaceRoot = mkdtempSync(join(tmpdir(), "nolo-cli-runtime-"));
|
|
1235
1080
|
try {
|
|
@@ -1391,17 +1236,13 @@ describe("CLI local runtime adapter", () => {
|
|
|
1391
1236
|
}
|
|
1392
1237
|
});
|
|
1393
1238
|
|
|
1394
|
-
test("runs execShell locally
|
|
1239
|
+
test("runs execShell locally in explicit worktree shell mode", async () => {
|
|
1395
1240
|
const adapter = createCliLocalRuntimeAdapter({
|
|
1396
|
-
env: {},
|
|
1397
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(true),
|
|
1241
|
+
env: { NOLO_LOCAL_SHELL_MODE: "worktree" },
|
|
1398
1242
|
db: {
|
|
1399
1243
|
get: async () => ({
|
|
1400
1244
|
dbKey: "agent-local-shell",
|
|
1401
|
-
|
|
1402
|
-
version: 1,
|
|
1403
|
-
runtimeTools: ["execShell"],
|
|
1404
|
-
},
|
|
1245
|
+
toolNames: ["execShell"],
|
|
1405
1246
|
}),
|
|
1406
1247
|
put: async () => {},
|
|
1407
1248
|
batch: async () => {},
|
|
@@ -7,7 +7,6 @@ import { request as httpRequest } from "node:http";
|
|
|
7
7
|
import { request as httpsRequest } from "node:https";
|
|
8
8
|
import {
|
|
9
9
|
buildLocalWorkspacePolicyToolNames,
|
|
10
|
-
resolveLocalWorkspaceShellToolExposure,
|
|
11
10
|
buildLocalWorkspaceToolset,
|
|
12
11
|
buildLocalWorkspaceOpenAiTools,
|
|
13
12
|
buildOpenAiCompatibleChatCompletionRequest,
|
|
@@ -16,11 +15,8 @@ import {
|
|
|
16
15
|
parseOpenAiCompatibleChatCompletionResponse,
|
|
17
16
|
parsePlatformChatCompletionData,
|
|
18
17
|
parsePlatformChatCompletionResponse,
|
|
19
|
-
resolveHostRuntimeConfigFromEnv,
|
|
20
18
|
resolvePlatformChatProviderConfig,
|
|
21
|
-
resolveRequestedRuntimeToolNames,
|
|
22
19
|
shouldUsePlatformChatProvider,
|
|
23
|
-
type HostRuntimeConfig,
|
|
24
20
|
} from "../agentRuntimeLocal";
|
|
25
21
|
import type { AgentRuntimeChatMessage } from "../agent-runtime";
|
|
26
22
|
import { getDefaultCliLocalRuntimeDb } from "../localRuntimeDb";
|
|
@@ -52,29 +48,6 @@ import {
|
|
|
52
48
|
type EnvLike = Record<string, string | undefined>;
|
|
53
49
|
type FetchInput = Parameters<typeof fetch>[0];
|
|
54
50
|
type FetchInit = Parameters<typeof fetch>[1];
|
|
55
|
-
type CliLocalRuntimeCliExecution = {
|
|
56
|
-
text: string;
|
|
57
|
-
raw?: string;
|
|
58
|
-
elapsed?: number;
|
|
59
|
-
warnings?: string[];
|
|
60
|
-
};
|
|
61
|
-
type CliLocalRuntimeCliExecutor = (
|
|
62
|
-
provider: string,
|
|
63
|
-
prompt: string,
|
|
64
|
-
options: {
|
|
65
|
-
model?: string;
|
|
66
|
-
timeout?: number;
|
|
67
|
-
cwd?: string;
|
|
68
|
-
yolo?: boolean;
|
|
69
|
-
env?: EnvLike;
|
|
70
|
-
systemPrompt?: string;
|
|
71
|
-
reasoningEffort?: "low" | "medium" | "high" | "xhigh" | "max";
|
|
72
|
-
temperature?: number;
|
|
73
|
-
topP?: number;
|
|
74
|
-
frequencyPenalty?: number;
|
|
75
|
-
maxTokens?: number;
|
|
76
|
-
}
|
|
77
|
-
) => Promise<CliLocalRuntimeCliExecution>;
|
|
78
51
|
const TRANSIENT_FETCH_MAX_ATTEMPTS = 8;
|
|
79
52
|
const TRANSIENT_FETCH_RETRY_BASE_DELAY_MS = 250;
|
|
80
53
|
|
|
@@ -82,17 +55,16 @@ export type CliLocalRuntimeDb = CliKvDb;
|
|
|
82
55
|
|
|
83
56
|
export type CliLocalRuntimeAdapterDeps = {
|
|
84
57
|
env: EnvLike;
|
|
85
|
-
hostRuntimeConfig?: HostRuntimeConfig;
|
|
86
58
|
db?: CliLocalRuntimeDb;
|
|
87
59
|
store?: HybridRecordStore;
|
|
88
60
|
now?: () => number;
|
|
89
61
|
createId?: () => string;
|
|
90
62
|
fetchImpl?: typeof fetch;
|
|
91
63
|
cwd?: string;
|
|
64
|
+
useCwdAsTaskWorkspaceBase?: boolean;
|
|
92
65
|
output?: { write(chunk: string): unknown };
|
|
93
66
|
prepareTaskWorktree?: typeof prepareTaskWorktree;
|
|
94
67
|
localToolExecutors?: Record<string, (call: any) => Promise<{ content: string; metadata?: Record<string, unknown> }>>;
|
|
95
|
-
executeCli?: CliLocalRuntimeCliExecutor;
|
|
96
68
|
sleep?: (ms: number) => Promise<void>;
|
|
97
69
|
loopbackRequest?: (input: FetchInput, init?: FetchInit) => Promise<Response>;
|
|
98
70
|
};
|
|
@@ -101,15 +73,6 @@ async function defaultLocalRuntimeDb(): Promise<CliLocalRuntimeDb> {
|
|
|
101
73
|
return getDefaultCliLocalRuntimeDb();
|
|
102
74
|
}
|
|
103
75
|
|
|
104
|
-
async function defaultExecuteCli(
|
|
105
|
-
provider: string,
|
|
106
|
-
prompt: string,
|
|
107
|
-
options: Parameters<CliLocalRuntimeCliExecutor>[2]
|
|
108
|
-
) {
|
|
109
|
-
const { executeCli } = await import("../ai/agent/cliExecutor");
|
|
110
|
-
return executeCli(provider as any, prompt, options);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
76
|
function createFallbackId() {
|
|
114
77
|
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`.toUpperCase();
|
|
115
78
|
}
|
|
@@ -118,6 +81,10 @@ function resolveLocalUserId(env: EnvLike) {
|
|
|
118
81
|
return env.NOLO_LOCAL_USER_ID || env.NOLO_USER_ID || "local";
|
|
119
82
|
}
|
|
120
83
|
|
|
84
|
+
function shellModeEnabled(env: EnvLike) {
|
|
85
|
+
return ["worktree", "dangerous", "1", "true"].includes(env.NOLO_LOCAL_SHELL_MODE || "");
|
|
86
|
+
}
|
|
87
|
+
|
|
121
88
|
function parseLocalToolBudgets(env: EnvLike) {
|
|
122
89
|
const raw = env.NOLO_LOCAL_TOOL_BUDGETS?.trim();
|
|
123
90
|
if (!raw) return {};
|
|
@@ -234,52 +201,32 @@ async function fetchWithTransientRetry(
|
|
|
234
201
|
throw lastError;
|
|
235
202
|
}
|
|
236
203
|
|
|
237
|
-
function buildOpenAiTools(args: {
|
|
238
|
-
|
|
239
|
-
platformToolNames?: string[];
|
|
240
|
-
hostRuntimeConfig: HostRuntimeConfig;
|
|
241
|
-
}) {
|
|
242
|
-
const toolset = buildLocalWorkspaceToolsetForHost(args);
|
|
204
|
+
function buildOpenAiTools(args: { toolNames?: string[]; env: EnvLike }) {
|
|
205
|
+
const toolset = buildLocalWorkspaceToolsetForEnv(args);
|
|
243
206
|
return [
|
|
244
207
|
...buildLocalWorkspaceOpenAiTools({
|
|
245
208
|
toolNames: toolset.toolNames,
|
|
246
209
|
exposeShellTools: toolset.exposeShellTools,
|
|
247
210
|
}),
|
|
248
|
-
...buildServerPlatformOpenAiTools({ toolNames: args.
|
|
211
|
+
...buildServerPlatformOpenAiTools({ toolNames: args.toolNames }),
|
|
249
212
|
];
|
|
250
213
|
}
|
|
251
214
|
|
|
252
|
-
function
|
|
253
|
-
requestedToolNames?: string[];
|
|
254
|
-
hostRuntimeConfig: HostRuntimeConfig;
|
|
255
|
-
}) {
|
|
256
|
-
const requestedToolNames = args.requestedToolNames ?? [];
|
|
257
|
-
const exposeShellTools = resolveLocalWorkspaceShellToolExposure({
|
|
258
|
-
declaredToolNames: requestedToolNames,
|
|
259
|
-
hostRuntimeConfig: args.hostRuntimeConfig,
|
|
260
|
-
});
|
|
215
|
+
function buildLocalWorkspaceToolsetForEnv(args: { toolNames?: string[]; env: EnvLike }) {
|
|
261
216
|
const toolset = buildLocalWorkspaceToolset({
|
|
262
|
-
declaredToolNames:
|
|
263
|
-
exposeShellTools,
|
|
217
|
+
declaredToolNames: args.toolNames,
|
|
218
|
+
exposeShellTools: shellModeEnabled(args.env),
|
|
264
219
|
});
|
|
265
220
|
return toolset;
|
|
266
221
|
}
|
|
267
222
|
|
|
268
|
-
function buildLocalPolicyToolNames(args: {
|
|
269
|
-
requestedToolNames?: string[];
|
|
270
|
-
platformToolNames?: string[];
|
|
271
|
-
hostRuntimeConfig: HostRuntimeConfig;
|
|
272
|
-
}) {
|
|
273
|
-
const exposeShellTools = resolveLocalWorkspaceShellToolExposure({
|
|
274
|
-
declaredToolNames: args.requestedToolNames,
|
|
275
|
-
hostRuntimeConfig: args.hostRuntimeConfig,
|
|
276
|
-
});
|
|
223
|
+
function buildLocalPolicyToolNames(args: { toolNames?: string[]; env: EnvLike }) {
|
|
277
224
|
return [
|
|
278
225
|
...buildLocalWorkspacePolicyToolNames({
|
|
279
|
-
declaredToolNames: args.
|
|
280
|
-
exposeShellTools,
|
|
226
|
+
declaredToolNames: args.toolNames,
|
|
227
|
+
exposeShellTools: shellModeEnabled(args.env),
|
|
281
228
|
}),
|
|
282
|
-
...((args.
|
|
229
|
+
...((args.toolNames ?? []).includes("taskRun") ? ["taskRun"] : []),
|
|
283
230
|
];
|
|
284
231
|
}
|
|
285
232
|
|
|
@@ -365,33 +312,6 @@ function readLocalWorkspaceMode(agentConfig: AgentRuntimeAgentConfig | null) {
|
|
|
365
312
|
return value === "task-worktree" ? "task-worktree" : "current";
|
|
366
313
|
}
|
|
367
314
|
|
|
368
|
-
function extractRuntimeMessageText(content: AgentRuntimeChatMessage["content"]) {
|
|
369
|
-
if (typeof content === "string") return content;
|
|
370
|
-
if (!Array.isArray(content)) return "";
|
|
371
|
-
return content
|
|
372
|
-
.filter((part): part is Extract<typeof part, { type: "text" }> => part?.type === "text")
|
|
373
|
-
.map((part) => part.text ?? "")
|
|
374
|
-
.join("");
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function buildCliTaskPromptFromMessages(messages: AgentRuntimeChatMessage[]) {
|
|
378
|
-
const history = messages
|
|
379
|
-
.filter((message) => message.role === "user" || message.role === "assistant")
|
|
380
|
-
.map((message) => {
|
|
381
|
-
const text = extractRuntimeMessageText(message.content).trim();
|
|
382
|
-
if (!text) return null;
|
|
383
|
-
return `[${message.role === "user" ? "用户" : "助手"}]\n${text}`;
|
|
384
|
-
})
|
|
385
|
-
.filter((message): message is string => Boolean(message))
|
|
386
|
-
.slice(-6);
|
|
387
|
-
|
|
388
|
-
if (history.length === 0) return "";
|
|
389
|
-
if (history.length === 1 && history[0]?.startsWith("[用户]\n")) {
|
|
390
|
-
return history[0].slice("[用户]\n".length);
|
|
391
|
-
}
|
|
392
|
-
return `请基于以下最近对话继续完成当前任务。\n\n${history.join("\n\n")}`;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
315
|
async function resolveStore(deps: CliLocalRuntimeAdapterDeps) {
|
|
396
316
|
if (deps.store) return deps.store;
|
|
397
317
|
return createCliHybridRecordStore({
|
|
@@ -462,18 +382,12 @@ export function createCliLocalRuntimeAdapter(
|
|
|
462
382
|
const createId = deps.createId ?? createFallbackId;
|
|
463
383
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
464
384
|
const loopbackRequest = deps.loopbackRequest ?? (deps.fetchImpl ? undefined : defaultLoopbackRequest);
|
|
465
|
-
const executeCli = deps.executeCli ?? defaultExecuteCli;
|
|
466
385
|
const userId = resolveLocalUserId(deps.env);
|
|
467
|
-
const hostRuntimeConfig = deps.hostRuntimeConfig ?? resolveHostRuntimeConfigFromEnv({
|
|
468
|
-
env: deps.env,
|
|
469
|
-
surface: "cli-local",
|
|
470
|
-
workspaceBinding: "explicit-cwd",
|
|
471
|
-
});
|
|
472
386
|
const localToolBudgets = parseLocalToolBudgets(deps.env);
|
|
473
387
|
const localToolUsage = new Map<string, number>();
|
|
474
388
|
let activeAgentToolNames: string[] = [];
|
|
475
389
|
let workspaceSession: WorkspaceSession = createWorkspaceSession(
|
|
476
|
-
|
|
390
|
+
deps.useCwdAsTaskWorkspaceBase
|
|
477
391
|
? { defaultCwd: deps.cwd }
|
|
478
392
|
: { cwd: deps.cwd }
|
|
479
393
|
);
|
|
@@ -514,13 +428,9 @@ export function createCliLocalRuntimeAdapter(
|
|
|
514
428
|
store: await resolveStore(deps),
|
|
515
429
|
userId,
|
|
516
430
|
});
|
|
517
|
-
const requestedToolNames = agentConfig
|
|
518
|
-
? resolveRequestedRuntimeToolNames({ agentConfig })
|
|
519
|
-
: [];
|
|
520
431
|
activeAgentToolNames = buildLocalPolicyToolNames({
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
hostRuntimeConfig,
|
|
432
|
+
toolNames: agentConfig?.toolNames,
|
|
433
|
+
env: deps.env,
|
|
524
434
|
});
|
|
525
435
|
await activateAgentWorkspaceSession({ agentRef, agentConfig });
|
|
526
436
|
return agentConfig;
|
|
@@ -538,48 +448,6 @@ export function createCliLocalRuntimeAdapter(
|
|
|
538
448
|
cwd: workspaceSession.workspaceRoot,
|
|
539
449
|
}),
|
|
540
450
|
resolveProvider: async (agentConfig) => {
|
|
541
|
-
if (agentConfig.apiSource === "cli") {
|
|
542
|
-
const cliProvider = String(agentConfig.cliProvider || "copilot").trim() || "copilot";
|
|
543
|
-
return {
|
|
544
|
-
model: agentConfig.model || cliProvider,
|
|
545
|
-
complete: async (messages) => {
|
|
546
|
-
const [firstMessage, ...remainingMessages] = messages;
|
|
547
|
-
const systemPrompt = firstMessage?.role === "system"
|
|
548
|
-
? extractRuntimeMessageText(firstMessage.content).trim()
|
|
549
|
-
: "";
|
|
550
|
-
const taskPrompt = buildCliTaskPromptFromMessages(
|
|
551
|
-
firstMessage?.role === "system" ? remainingMessages : messages
|
|
552
|
-
);
|
|
553
|
-
const result = await executeCli(cliProvider, taskPrompt, {
|
|
554
|
-
...(agentConfig.model ? { model: agentConfig.model } : {}),
|
|
555
|
-
cwd: workspaceSession.workspaceRoot,
|
|
556
|
-
yolo: true,
|
|
557
|
-
env: deps.env,
|
|
558
|
-
...(systemPrompt ? { systemPrompt } : {}),
|
|
559
|
-
...(typeof agentConfig.reasoning_effort === "string"
|
|
560
|
-
? { reasoningEffort: agentConfig.reasoning_effort as "low" | "medium" | "high" | "xhigh" | "max" }
|
|
561
|
-
: {}),
|
|
562
|
-
...(typeof agentConfig.temperature === "number"
|
|
563
|
-
? { temperature: agentConfig.temperature }
|
|
564
|
-
: {}),
|
|
565
|
-
...(typeof agentConfig.top_p === "number" ? { topP: agentConfig.top_p } : {}),
|
|
566
|
-
...(typeof agentConfig.frequency_penalty === "number"
|
|
567
|
-
? { frequencyPenalty: agentConfig.frequency_penalty }
|
|
568
|
-
: {}),
|
|
569
|
-
...(typeof agentConfig.max_tokens === "number"
|
|
570
|
-
? { maxTokens: agentConfig.max_tokens }
|
|
571
|
-
: {}),
|
|
572
|
-
});
|
|
573
|
-
return {
|
|
574
|
-
content: result.text,
|
|
575
|
-
model: agentConfig.model || cliProvider,
|
|
576
|
-
provider: cliProvider,
|
|
577
|
-
trace: messages,
|
|
578
|
-
};
|
|
579
|
-
},
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
|
|
583
451
|
if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
|
|
584
452
|
const providerConfig = resolvePlatformChatProviderConfig({
|
|
585
453
|
agentConfig,
|
|
@@ -588,11 +456,9 @@ export function createCliLocalRuntimeAdapter(
|
|
|
588
456
|
return {
|
|
589
457
|
model: providerConfig.model,
|
|
590
458
|
complete: async (messages) => {
|
|
591
|
-
const requestedToolNames = resolveRequestedRuntimeToolNames({ agentConfig });
|
|
592
459
|
const tools = buildOpenAiTools({
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
hostRuntimeConfig,
|
|
460
|
+
toolNames: agentConfig.toolNames,
|
|
461
|
+
env: deps.env,
|
|
596
462
|
});
|
|
597
463
|
const request = buildPlatformChatCompletionRequest({
|
|
598
464
|
providerConfig,
|
|
@@ -623,11 +489,9 @@ export function createCliLocalRuntimeAdapter(
|
|
|
623
489
|
return {
|
|
624
490
|
model: providerConfig.model,
|
|
625
491
|
complete: async (messages) => {
|
|
626
|
-
const requestedToolNames = resolveRequestedRuntimeToolNames({ agentConfig });
|
|
627
492
|
const tools = buildOpenAiTools({
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
hostRuntimeConfig,
|
|
493
|
+
toolNames: agentConfig.toolNames,
|
|
494
|
+
env: deps.env,
|
|
631
495
|
});
|
|
632
496
|
const request = buildOpenAiCompatibleChatCompletionRequest({
|
|
633
497
|
providerConfig,
|
|
@@ -658,7 +522,6 @@ export function createCliLocalRuntimeAdapter(
|
|
|
658
522
|
});
|
|
659
523
|
const result = await executeLocalToolWithPolicy({
|
|
660
524
|
env: deps.env,
|
|
661
|
-
hostRuntimeConfig,
|
|
662
525
|
agentToolNames: activeAgentToolNames,
|
|
663
526
|
call,
|
|
664
527
|
executors: localToolExecutors,
|
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import { executeLocalToolWithPolicy, resolveLocalToolPolicy } from "./localToolPolicy";
|
|
4
|
-
import { createHostRuntimeConfig } from "../agent-runtime";
|
|
5
|
-
|
|
6
|
-
function createCliHostRuntimeConfig(allowShell = false) {
|
|
7
|
-
return createHostRuntimeConfig({
|
|
8
|
-
surface: "cli-local",
|
|
9
|
-
workspaceBinding: "explicit-cwd",
|
|
10
|
-
allowShell,
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
4
|
|
|
14
5
|
describe("CLI local tool policy", () => {
|
|
15
|
-
test("allows execShell
|
|
6
|
+
test("allows execShell in explicit worktree shell mode", () => {
|
|
16
7
|
expect(resolveLocalToolPolicy({
|
|
17
|
-
env: {},
|
|
18
|
-
|
|
19
|
-
agentToolNames: ["execShell"],
|
|
8
|
+
env: { NOLO_LOCAL_SHELL_MODE: "worktree" },
|
|
9
|
+
agentToolNames: [],
|
|
20
10
|
toolName: "execShell",
|
|
21
11
|
})).toEqual({ allowed: true, toolName: "execShell" });
|
|
22
12
|
});
|
|
23
13
|
|
|
24
|
-
test("blocks execShell unless
|
|
14
|
+
test("blocks execShell unless explicit shell mode is enabled", () => {
|
|
25
15
|
expect(resolveLocalToolPolicy({
|
|
26
16
|
env: { NOLO_LOCAL_ALLOWED_TOOLS: "execShell" },
|
|
27
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(),
|
|
28
17
|
agentToolNames: ["execShell"],
|
|
29
18
|
toolName: "execShell",
|
|
30
19
|
})).toMatchObject({ allowed: false });
|
|
31
20
|
});
|
|
32
21
|
|
|
33
|
-
test("blocks execShell when shell was not requested by the runtime", () => {
|
|
34
|
-
expect(resolveLocalToolPolicy({
|
|
35
|
-
env: {},
|
|
36
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(true),
|
|
37
|
-
agentToolNames: [],
|
|
38
|
-
toolName: "execShell",
|
|
39
|
-
})).toMatchObject({
|
|
40
|
-
allowed: false,
|
|
41
|
-
reason: "execShell is not requested by this agent runtime.",
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
22
|
test("requires both env allowlist and agent declaration", () => {
|
|
46
23
|
expect(resolveLocalToolPolicy({
|
|
47
24
|
env: { NOLO_LOCAL_ALLOWED_TOOLS: "readFile" },
|
|
@@ -59,7 +36,6 @@ describe("CLI local tool policy", () => {
|
|
|
59
36
|
test("executes only registered tools after policy allows them", async () => {
|
|
60
37
|
const result = await executeLocalToolWithPolicy({
|
|
61
38
|
env: { NOLO_LOCAL_ALLOWED_TOOLS: "readFile" },
|
|
62
|
-
hostRuntimeConfig: createCliHostRuntimeConfig(),
|
|
63
39
|
agentToolNames: ["readFile"],
|
|
64
40
|
call: { id: "call-1", name: "readFile", arguments: "{\"path\":\"README.md\"}" },
|
|
65
41
|
executors: {
|
package/client/taskRunPrompt.ts
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export type TaskRunPromptContext = {
|
|
2
|
+
rowDbKey: string;
|
|
3
|
+
taskRunId?: string;
|
|
4
|
+
workItemId?: string;
|
|
5
|
+
artifactIds?: string[];
|
|
6
|
+
};
|
|
7
7
|
|
|
8
8
|
export function prependTaskRunPrompt(message: string, context?: TaskRunPromptContext): string {
|
|
9
|
-
|
|
9
|
+
if (!context?.rowDbKey) return message;
|
|
10
|
+
const artifactIds = context.artifactIds?.filter(Boolean) ?? [];
|
|
11
|
+
return [
|
|
12
|
+
"AI-native task-run context:",
|
|
13
|
+
"- This system is AI-native. The current task board is only the present observation and validation use case; different users, companies, and workflows may use different task owners later.",
|
|
14
|
+
"- Treat the task row meta as the durable execution context. Do not infer branch, runner, handoff, review, or blocker state from chat history alone.",
|
|
15
|
+
`- rowDbKey: ${context.rowDbKey}`,
|
|
16
|
+
...(context.taskRunId ? [`- taskRunId: ${context.taskRunId}`] : []),
|
|
17
|
+
...(context.workItemId ? [`- workItemId: ${context.workItemId}`] : []),
|
|
18
|
+
...(artifactIds.length ? [`- artifactIds: ${artifactIds.join(",")}`] : []),
|
|
19
|
+
"- Handoff rule: start from the durable task context, then inspect existing refs such as workItems.dialogIds, workItems.outcome, review.dialogId, activityRefs, agentRuns.dialogId/resultSummary, and artifactRefs. Use dialog read/search for exact evidence.",
|
|
20
|
+
"- When you create, update, hand off, block, or review work, update the task context with `bun run task:run -- ...`.",
|
|
21
|
+
"- If this turn already includes a server TaskRun preflight snapshot, use that snapshot directly for read-only reporting or planning.",
|
|
22
|
+
"- Keep long reasoning and logs in the dialog; record only resumable references in task row meta.",
|
|
23
|
+
"",
|
|
24
|
+
"User task:",
|
|
25
|
+
message,
|
|
26
|
+
].join("\n");
|
|
10
27
|
}
|