nolo-cli 0.1.32 → 0.1.34
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 +4 -10
- package/agent-runtime/agentRecordConfig.ts +10 -0
- package/agent-runtime/hostAdapter.ts +10 -1
- package/agent-runtime/index.ts +9 -20
- package/agent-runtime/localLoop.ts +49 -2
- package/agent-runtime/localToolPolicy.ts +76 -34
- package/agent-runtime/localWorkspaceTools.ts +30 -333
- package/agent-runtime/openAiCompatibleProvider.ts +7 -3
- package/agent-runtime/openAiCompatibleProviderConfig.ts +15 -26
- package/agent-runtime/platformChatProvider.ts +47 -73
- package/agent-runtime/providerResolution.ts +244 -0
- package/agent-runtime/runtimeToolPolicy.ts +77 -29
- package/agent-runtime/shellCommandPolicy.ts +120 -0
- package/agentAliases.ts +14 -83
- package/agentCommandSupport.ts +3 -6
- package/agentInternalCommandEntries.ts +4 -13
- package/agentListCommands.ts +18 -27
- package/agentMachineCommands.ts +40 -336
- package/agentPullCommand.ts +30 -55
- package/agentRecordCommands.ts +84 -1
- package/agentRecordHelpers.ts +102 -186
- package/agentRunCommand.ts +438 -107
- package/agentRuntimeLocal.ts +2 -9
- package/ai/agent/cliExecutor.ts +19 -323
- package/ai/tools/toolNameAliases.ts +70 -0
- package/authCommands.ts +2 -36
- package/cli/agentAliases.ts +14 -83
- package/cli/agentCommandSupport.ts +3 -6
- package/cli/agentInternalCommandEntries.ts +4 -13
- package/cli/agentListCommands.ts +18 -27
- package/cli/agentMachineCommands.ts +40 -336
- package/cli/agentPullCommand.ts +30 -55
- package/cli/agentRecordCommands.ts +84 -1
- package/cli/agentRecordHelpers.ts +102 -186
- package/cli/agentRunCommand.ts +438 -107
- package/cli/agentRuntimeLocal.ts +2 -9
- package/cli/authCommands.ts +2 -36
- package/cli/cliCommandDispatch.ts +2 -2
- package/cli/cliEnvHelpers.ts +34 -107
- package/cli/client/agentRun.ts +854 -57
- package/cli/client/localRuntimeAdapter.ts +59 -159
- package/cli/client/streamingOutput.ts +3 -1
- package/cli/client/taskRunPrompt.ts +24 -7
- package/cli/commandRegistry.ts +4 -5
- 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 +30 -44
- package/cli/machineWsSession.ts +0 -2
- package/cli/offlineMarxistsAgentCommand.ts +314 -0
- package/cli/runtimeDoctorCommands.ts +72 -15
- 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/cliCommandDispatch.ts +2 -2
- package/cliEnvHelpers.ts +34 -107
- package/client/agentConfigResolver.test.ts +2 -0
- package/client/agentRun.test.ts +12 -208
- package/client/agentRun.ts +854 -57
- package/client/localProviderResolver.test.ts +26 -2
- package/client/localRuntimeAdapter.test.ts +296 -171
- package/client/localRuntimeAdapter.ts +59 -159
- package/client/localToolPolicy.test.ts +4 -28
- package/client/streamingOutput.ts +3 -1
- package/client/taskRunPrompt.ts +24 -7
- package/commandRegistry.ts +4 -5
- package/connectorRunArtifact.ts +10 -34
- package/connectorWebSocketTarget.ts +6 -10
- package/database/server/serverStoreFactory.ts +2 -8
- 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 +30 -44
- package/machineWsSession.ts +0 -2
- package/offlineMarxistsAgentCommand.ts +314 -0
- package/package.json +52 -188
- package/runtimeDoctorCommands.ts +72 -15
- 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/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
package/agentMachineCommands.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import type { MachineHeartbeat } from "./connector-experimental/protocol";
|
|
2
2
|
import { resolveConnectorWebSocketTarget } from "./connectorWebSocketTarget";
|
|
3
|
-
import {
|
|
4
|
-
buildCurrentUserPlatformAgentCandidateKeys,
|
|
5
|
-
resolveCliAgentKeyInput,
|
|
6
|
-
} from "./agentAliases";
|
|
3
|
+
import { resolveCliAgentKeyInput } from "./agentAliases";
|
|
7
4
|
import {
|
|
8
5
|
type AgentCommandDeps,
|
|
9
|
-
getReadableCliDb,
|
|
10
6
|
type LocalCliExecutor,
|
|
11
7
|
type SmokeWebSocketOptions,
|
|
12
8
|
} from "./agentCommandSupport";
|
|
13
|
-
import { buildConnectorCliPrompt } from "./machineCommandPrompts";
|
|
14
9
|
import {
|
|
15
10
|
readAgentRecord,
|
|
16
|
-
resolveAgentRecordFromHybridStore,
|
|
17
11
|
writeAgentRecord,
|
|
18
12
|
} from "./agentRecordHelpers";
|
|
19
13
|
import {
|
|
@@ -34,26 +28,15 @@ async function defaultExecuteCli(
|
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
async function forwardConnectorRunMessage(
|
|
37
|
-
|
|
31
|
+
machine: MachineHeartbeat,
|
|
38
32
|
message: string,
|
|
39
33
|
pushMessage: (response: string) => void,
|
|
40
34
|
executeCli: LocalCliExecutor,
|
|
41
35
|
env: EnvLike,
|
|
42
|
-
fetchImpl: typeof fetch
|
|
43
|
-
dispatchDeps?: AgentCommandDeps["connectorRunDispatchDeps"],
|
|
36
|
+
fetchImpl: typeof fetch
|
|
44
37
|
) {
|
|
45
|
-
const { handleConnectorRunMessage } = await import("./
|
|
46
|
-
return handleConnectorRunMessage(
|
|
47
|
-
message,
|
|
48
|
-
pushMessage,
|
|
49
|
-
executeCli,
|
|
50
|
-
env,
|
|
51
|
-
fetchImpl,
|
|
52
|
-
{
|
|
53
|
-
buildConnectorCliPrompt,
|
|
54
|
-
...(dispatchDeps ?? {}),
|
|
55
|
-
},
|
|
56
|
-
);
|
|
38
|
+
const { handleConnectorRunMessage } = await import("./machineCommands");
|
|
39
|
+
return handleConnectorRunMessage(machine, message, pushMessage, executeCli, env, fetchImpl);
|
|
57
40
|
}
|
|
58
41
|
|
|
59
42
|
async function detectLaunchableMachineInfo() {
|
|
@@ -86,16 +69,9 @@ function shouldRuntimeDoctorPass(args: {
|
|
|
86
69
|
runtimeClass: string;
|
|
87
70
|
requiredCapability: string;
|
|
88
71
|
hasCapability: boolean;
|
|
89
|
-
bindingRequired: boolean;
|
|
90
|
-
isBoundToCurrent: boolean;
|
|
91
|
-
isBindingOwnerCompatible: boolean;
|
|
92
72
|
}) {
|
|
93
73
|
if (args.runtimeClass !== "cli-machine") return args.runtimeClass !== "unknown";
|
|
94
|
-
return Boolean(
|
|
95
|
-
args.requiredCapability &&
|
|
96
|
-
args.hasCapability &&
|
|
97
|
-
(!args.bindingRequired || (args.isBoundToCurrent && args.isBindingOwnerCompatible))
|
|
98
|
-
);
|
|
74
|
+
return Boolean(args.requiredCapability && args.hasCapability);
|
|
99
75
|
}
|
|
100
76
|
|
|
101
77
|
function assertSmokeCompatible(agent: any, machine: MachineHeartbeat) {
|
|
@@ -116,46 +92,6 @@ function assertSmokeCompatible(agent: any, machine: MachineHeartbeat) {
|
|
|
116
92
|
}
|
|
117
93
|
}
|
|
118
94
|
|
|
119
|
-
function runtimeBindingFacts(agent: any, machine: MachineHeartbeat, currentUserId?: string) {
|
|
120
|
-
const runtimeBinding = agent?.runtimeBinding && typeof agent.runtimeBinding === "object"
|
|
121
|
-
? agent.runtimeBinding
|
|
122
|
-
: {};
|
|
123
|
-
const boundMachineId = typeof runtimeBinding.machineId === "string"
|
|
124
|
-
? runtimeBinding.machineId.trim()
|
|
125
|
-
: "";
|
|
126
|
-
const boundOwnerUserId = typeof runtimeBinding.ownerUserId === "string"
|
|
127
|
-
? runtimeBinding.ownerUserId.trim()
|
|
128
|
-
: "";
|
|
129
|
-
const bindingRequired = agent?.apiSource === "cli";
|
|
130
|
-
return {
|
|
131
|
-
bindingRequired,
|
|
132
|
-
boundMachineId,
|
|
133
|
-
boundOwnerUserId,
|
|
134
|
-
isBoundToCurrent: Boolean(boundMachineId) && boundMachineId === machine.machineId,
|
|
135
|
-
isBindingOwnerCompatible: !boundOwnerUserId || !currentUserId || boundOwnerUserId === currentUserId,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function assertSmokeBindingState(args: {
|
|
140
|
-
agent: any;
|
|
141
|
-
machine: MachineHeartbeat;
|
|
142
|
-
currentUserId: string;
|
|
143
|
-
allowRebind: boolean;
|
|
144
|
-
}) {
|
|
145
|
-
const facts = runtimeBindingFacts(args.agent, args.machine, args.currentUserId);
|
|
146
|
-
if (args.allowRebind || !facts.bindingRequired) return;
|
|
147
|
-
if (facts.boundMachineId && !facts.isBoundToCurrent) {
|
|
148
|
-
throw new Error(
|
|
149
|
-
`Agent ${args.agent?.name ?? args.agent?.dbKey ?? "unknown"} is bound to ${facts.boundMachineId}, not current machine ${args.machine.machineId}. Run \`nolo agent bind-current ${args.agent?.dbKey ?? "AGENT_KEY"}\` first or pass --bind to rebind explicitly.`
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
if (facts.boundOwnerUserId && !facts.isBindingOwnerCompatible) {
|
|
153
|
-
throw new Error(
|
|
154
|
-
`Agent ${args.agent?.name ?? args.agent?.dbKey ?? "unknown"} is bound for owner ${facts.boundOwnerUserId}, not current user ${args.currentUserId}. \`nolo agent smoke-current\` only validates a connector launched under your current auth token, so it cannot simulate another owner's binding. If you intend to use the existing shared binding, run \`nolo agent run ${args.agent?.dbKey ?? "AGENT_KEY"}\` and make sure owner ${facts.boundOwnerUserId} has a live connector online. If you intend to take ownership of the binding on this account, run \`nolo agent bind-current ${args.agent?.dbKey ?? "AGENT_KEY"}\` first or pass --bind explicitly.`
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
95
|
const CONNECTOR_WS_KEEPALIVE_MS = 25_000;
|
|
160
96
|
|
|
161
97
|
function buildConnectorKeepaliveMessage() {
|
|
@@ -230,75 +166,19 @@ async function heartbeatCurrentMachine(args: {
|
|
|
230
166
|
}
|
|
231
167
|
}
|
|
232
168
|
|
|
233
|
-
async function resolveMachineAgent(args: {
|
|
234
|
-
agentInput: string;
|
|
235
|
-
cliArgs: string[];
|
|
236
|
-
deps: AgentCommandDeps;
|
|
237
|
-
env: EnvLike;
|
|
238
|
-
fetchImpl: typeof fetch;
|
|
239
|
-
fallbackFetchImpl?: typeof fetch;
|
|
240
|
-
output: typeof process.stdout | { write: (chunk: string) => void };
|
|
241
|
-
userId: string;
|
|
242
|
-
}) {
|
|
243
|
-
const fallbackKey = resolveCliAgentKeyInput(args.agentInput);
|
|
244
|
-
const candidateKeys = buildCurrentUserPlatformAgentCandidateKeys(args.agentInput, args.userId);
|
|
245
|
-
if (candidateKeys.length === 0 || candidateKeys[0] === fallbackKey) {
|
|
246
|
-
return { agentKey: fallbackKey };
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
try {
|
|
250
|
-
const db = args.deps.db ?? await getReadableCliDb(args.output as any);
|
|
251
|
-
const resolved = await resolveAgentRecordFromHybridStore({
|
|
252
|
-
agentInput: args.agentInput,
|
|
253
|
-
cliArgs: args.cliArgs,
|
|
254
|
-
env: args.env,
|
|
255
|
-
db,
|
|
256
|
-
fetchImpl: args.fetchImpl,
|
|
257
|
-
fallbackFetchImpl: args.fallbackFetchImpl,
|
|
258
|
-
});
|
|
259
|
-
return resolved
|
|
260
|
-
? {
|
|
261
|
-
agentKey: resolved.agentKey,
|
|
262
|
-
record: resolved.record,
|
|
263
|
-
source: resolved.source,
|
|
264
|
-
}
|
|
265
|
-
: { agentKey: fallbackKey };
|
|
266
|
-
} catch {
|
|
267
|
-
return { agentKey: fallbackKey };
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
async function readResolvedAgentRecord(args: {
|
|
272
|
-
authToken: string;
|
|
273
|
-
fallbackFetchImpl?: typeof fetch;
|
|
274
|
-
fetchImpl: typeof fetch;
|
|
275
|
-
resolvedAgent: Awaited<ReturnType<typeof resolveMachineAgent>>;
|
|
276
|
-
serverUrl: string;
|
|
277
|
-
}) {
|
|
278
|
-
return args.resolvedAgent.source === "remote-cache"
|
|
279
|
-
? args.resolvedAgent.record
|
|
280
|
-
: await readAgentRecord({
|
|
281
|
-
agentKey: args.resolvedAgent.agentKey,
|
|
282
|
-
authToken: args.authToken,
|
|
283
|
-
fallbackFetchImpl: args.fallbackFetchImpl,
|
|
284
|
-
fetchImpl: args.fetchImpl,
|
|
285
|
-
serverUrl: args.serverUrl,
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
169
|
export async function runAgentBindCurrentCommand(
|
|
290
170
|
args: string[],
|
|
291
171
|
deps: AgentCommandDeps = {}
|
|
292
172
|
) {
|
|
293
173
|
const env = deps.env ?? process.env;
|
|
294
174
|
const output = deps.output ?? process.stdout;
|
|
295
|
-
const
|
|
296
|
-
if (!
|
|
175
|
+
const agentKey = args[0]?.trim();
|
|
176
|
+
if (!agentKey || agentKey === "--help" || agentKey === "-h") {
|
|
297
177
|
output.write("Usage: nolo agent bind-current <agentKey>\n");
|
|
298
|
-
return
|
|
178
|
+
return agentKey ? 0 : 1;
|
|
299
179
|
}
|
|
300
180
|
|
|
301
|
-
const authToken = resolveAuthToken(
|
|
181
|
+
const authToken = resolveAuthToken(env);
|
|
302
182
|
if (!authToken) {
|
|
303
183
|
output.write("[nolo] agent bind-current requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
|
|
304
184
|
return 1;
|
|
@@ -310,28 +190,14 @@ export async function runAgentBindCurrentCommand(
|
|
|
310
190
|
return 1;
|
|
311
191
|
}
|
|
312
192
|
|
|
313
|
-
const serverUrl = resolveServerUrl(
|
|
193
|
+
const serverUrl = resolveServerUrl(env);
|
|
314
194
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
315
195
|
const fallbackFetchImpl = deps.fallbackFetchImpl;
|
|
316
|
-
const resolvedAgent = await resolveMachineAgent({
|
|
317
|
-
agentInput,
|
|
318
|
-
cliArgs: args,
|
|
319
|
-
deps,
|
|
320
|
-
env,
|
|
321
|
-
fetchImpl,
|
|
322
|
-
fallbackFetchImpl,
|
|
323
|
-
output,
|
|
324
|
-
userId,
|
|
325
|
-
});
|
|
326
|
-
const agentKey = resolvedAgent.agentKey;
|
|
327
196
|
const machine = await (deps.machineInfo ?? detectLaunchableMachineInfo)();
|
|
328
197
|
|
|
329
198
|
try {
|
|
330
199
|
await heartbeatCurrentMachine({ authToken, fetchImpl, machine, serverUrl });
|
|
331
|
-
const existing =
|
|
332
|
-
resolvedAgent.source === "remote-cache"
|
|
333
|
-
? resolvedAgent.record
|
|
334
|
-
: await readAgentRecord({ agentKey, authToken, fallbackFetchImpl, fetchImpl, serverUrl });
|
|
200
|
+
const existing = await readAgentRecord({ agentKey, authToken, fallbackFetchImpl, fetchImpl, serverUrl });
|
|
335
201
|
const updated = {
|
|
336
202
|
...existing,
|
|
337
203
|
runtimeBinding: {
|
|
@@ -372,13 +238,13 @@ export async function runAgentSmokeCurrentCommand(
|
|
|
372
238
|
const env = deps.env ?? process.env;
|
|
373
239
|
const output = deps.output ?? process.stdout;
|
|
374
240
|
const agentInput = args[0]?.trim();
|
|
375
|
-
const allowRebind = args.includes("--bind");
|
|
376
241
|
if (!agentInput || agentInput === "--help" || agentInput === "-h") {
|
|
377
|
-
output.write("Usage: nolo agent smoke-current <agent>
|
|
242
|
+
output.write("Usage: nolo agent smoke-current <agent> --msg \"hello\"\n");
|
|
378
243
|
return agentInput ? 0 : 1;
|
|
379
244
|
}
|
|
245
|
+
const agentKey = resolveCliAgentKeyInput(agentInput);
|
|
380
246
|
|
|
381
|
-
const authToken = resolveAuthToken(
|
|
247
|
+
const authToken = resolveAuthToken(env);
|
|
382
248
|
if (!authToken) {
|
|
383
249
|
output.write("[nolo] agent smoke-current requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
|
|
384
250
|
return 1;
|
|
@@ -390,60 +256,35 @@ export async function runAgentSmokeCurrentCommand(
|
|
|
390
256
|
}
|
|
391
257
|
|
|
392
258
|
const userInput = readOption(args, "--msg") ?? "Smoke test from nolo connector.";
|
|
393
|
-
const serverUrl = resolveServerUrl(
|
|
259
|
+
const serverUrl = resolveServerUrl(env);
|
|
394
260
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
395
261
|
const fallbackFetchImpl = deps.fallbackFetchImpl;
|
|
396
|
-
const resolvedAgent = await resolveMachineAgent({
|
|
397
|
-
agentInput,
|
|
398
|
-
cliArgs: args,
|
|
399
|
-
deps,
|
|
400
|
-
env,
|
|
401
|
-
fetchImpl,
|
|
402
|
-
fallbackFetchImpl,
|
|
403
|
-
output,
|
|
404
|
-
userId,
|
|
405
|
-
});
|
|
406
|
-
const agentKey = resolvedAgent.agentKey;
|
|
407
262
|
const machine = await (deps.machineInfo ?? detectLaunchableMachineInfo)();
|
|
408
263
|
const sentMessages: string[] = [];
|
|
409
264
|
|
|
410
265
|
try {
|
|
411
266
|
await heartbeatCurrentMachine({ authToken, fetchImpl, machine, serverUrl });
|
|
412
|
-
const existing = await
|
|
267
|
+
const existing = await readAgentRecord({ agentKey, authToken, fallbackFetchImpl, fetchImpl, serverUrl });
|
|
268
|
+
assertSmokeCompatible(existing, machine);
|
|
269
|
+
await writeAgentRecord({
|
|
270
|
+
agentKey,
|
|
413
271
|
authToken,
|
|
414
272
|
fallbackFetchImpl,
|
|
415
273
|
fetchImpl,
|
|
416
|
-
resolvedAgent,
|
|
417
274
|
serverUrl,
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
await writeAgentRecord({
|
|
428
|
-
agentKey,
|
|
429
|
-
authToken,
|
|
430
|
-
fallbackFetchImpl,
|
|
431
|
-
fetchImpl,
|
|
432
|
-
serverUrl,
|
|
433
|
-
userId,
|
|
434
|
-
record: {
|
|
435
|
-
...existing,
|
|
436
|
-
runtimeBinding: {
|
|
437
|
-
...(existing?.runtimeBinding && typeof existing.runtimeBinding === "object"
|
|
438
|
-
? existing.runtimeBinding
|
|
439
|
-
: {}),
|
|
440
|
-
machineId: machine.machineId,
|
|
441
|
-
ownerUserId: userId,
|
|
442
|
-
},
|
|
443
|
-
updatedAt: Date.now(),
|
|
275
|
+
userId,
|
|
276
|
+
record: {
|
|
277
|
+
...existing,
|
|
278
|
+
runtimeBinding: {
|
|
279
|
+
...(existing?.runtimeBinding && typeof existing.runtimeBinding === "object"
|
|
280
|
+
? existing.runtimeBinding
|
|
281
|
+
: {}),
|
|
282
|
+
machineId: machine.machineId,
|
|
283
|
+
ownerUserId: userId,
|
|
444
284
|
},
|
|
445
|
-
|
|
446
|
-
|
|
285
|
+
updatedAt: Date.now(),
|
|
286
|
+
},
|
|
287
|
+
});
|
|
447
288
|
|
|
448
289
|
let runResponse: any = null;
|
|
449
290
|
const wsTarget = await resolveConnectorWebSocketTarget({
|
|
@@ -470,8 +311,7 @@ export async function runAgentSmokeCurrentCommand(
|
|
|
470
311
|
AUTH_TOKEN: authToken,
|
|
471
312
|
NOLO_MACHINE_API_KEY: authToken,
|
|
472
313
|
},
|
|
473
|
-
fetchImpl
|
|
474
|
-
deps.connectorRunDispatchDeps,
|
|
314
|
+
fetchImpl
|
|
475
315
|
),
|
|
476
316
|
onOpen: async () => {
|
|
477
317
|
const res = await fetchImpl(`${serverUrl}/api/agent/run`, {
|
|
@@ -506,106 +346,6 @@ export async function runAgentSmokeCurrentCommand(
|
|
|
506
346
|
}
|
|
507
347
|
}
|
|
508
348
|
|
|
509
|
-
export async function runAgentSmokeBoundCommand(
|
|
510
|
-
args: string[],
|
|
511
|
-
deps: AgentCommandDeps = {}
|
|
512
|
-
) {
|
|
513
|
-
const env = deps.env ?? process.env;
|
|
514
|
-
const output = deps.output ?? process.stdout;
|
|
515
|
-
const agentInput = args[0]?.trim();
|
|
516
|
-
if (!agentInput || agentInput === "--help" || agentInput === "-h") {
|
|
517
|
-
output.write("Usage: nolo agent smoke-bound <agent> [--msg \"hello\"]\n");
|
|
518
|
-
return agentInput ? 0 : 1;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
const authToken = resolveAuthToken(args, env);
|
|
522
|
-
if (!authToken) {
|
|
523
|
-
output.write("[nolo] agent smoke-bound requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
|
|
524
|
-
return 1;
|
|
525
|
-
}
|
|
526
|
-
const userId = parseUserIdFromAuthToken(authToken);
|
|
527
|
-
if (!userId) {
|
|
528
|
-
output.write("[nolo] agent smoke-bound could not read userId from AUTH_TOKEN.\n");
|
|
529
|
-
return 1;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const userInput = readOption(args, "--msg") ?? "Smoke test existing bound runtime from nolo.";
|
|
533
|
-
const serverUrl = resolveServerUrl(args, env);
|
|
534
|
-
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
535
|
-
const fallbackFetchImpl = deps.fallbackFetchImpl;
|
|
536
|
-
const resolvedAgent = await resolveMachineAgent({
|
|
537
|
-
agentInput,
|
|
538
|
-
cliArgs: args,
|
|
539
|
-
deps,
|
|
540
|
-
env,
|
|
541
|
-
fetchImpl,
|
|
542
|
-
fallbackFetchImpl,
|
|
543
|
-
output,
|
|
544
|
-
userId,
|
|
545
|
-
});
|
|
546
|
-
const agentKey = resolvedAgent.agentKey;
|
|
547
|
-
|
|
548
|
-
try {
|
|
549
|
-
const existing = await readResolvedAgentRecord({
|
|
550
|
-
authToken,
|
|
551
|
-
fallbackFetchImpl,
|
|
552
|
-
fetchImpl,
|
|
553
|
-
resolvedAgent,
|
|
554
|
-
serverUrl,
|
|
555
|
-
});
|
|
556
|
-
const facts = runtimeBindingFacts(existing, { machineId: "", name: "", platform: "", arch: "", capabilities: [] }, userId);
|
|
557
|
-
if (!facts.boundMachineId) {
|
|
558
|
-
throw new Error(
|
|
559
|
-
`Agent ${existing?.name ?? existing?.dbKey ?? agentKey} is not currently bound to a machine. Run \`nolo agent bind-current ${agentKey}\` first.`
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
if (!facts.boundOwnerUserId) {
|
|
563
|
-
throw new Error(
|
|
564
|
-
`Agent ${existing?.name ?? existing?.dbKey ?? agentKey} is missing runtimeBinding.ownerUserId for machine ${facts.boundMachineId}.`
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const res = await fetchImpl(`${serverUrl}/api/agent/run`, {
|
|
569
|
-
method: "POST",
|
|
570
|
-
headers: {
|
|
571
|
-
Authorization: `Bearer ${authToken}`,
|
|
572
|
-
"Content-Type": "application/json",
|
|
573
|
-
},
|
|
574
|
-
body: JSON.stringify({
|
|
575
|
-
agentKey,
|
|
576
|
-
userInput,
|
|
577
|
-
stream: false,
|
|
578
|
-
}),
|
|
579
|
-
});
|
|
580
|
-
const body = await res.json().catch(() => ({}));
|
|
581
|
-
if (!res.ok) {
|
|
582
|
-
const errorMessage = typeof body?.error === "string" ? body.error : `HTTP ${res.status}`;
|
|
583
|
-
const detailMessage = typeof body?.message === "string" ? body.message : "";
|
|
584
|
-
const reason = typeof body?.reason === "string" ? body.reason : "";
|
|
585
|
-
throw new Error(
|
|
586
|
-
[
|
|
587
|
-
`agent run failed: ${errorMessage}`,
|
|
588
|
-
detailMessage,
|
|
589
|
-
reason ? `reason=${reason}` : "",
|
|
590
|
-
].filter(Boolean).join("\n")
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
output.write(
|
|
595
|
-
`Bound run OK: ${body?.dialogId ?? "no-dialog"}\nAgent key: ${agentKey}\nBound owner: ${facts.boundOwnerUserId}\nBound machine: ${facts.boundMachineId}\n`
|
|
596
|
-
);
|
|
597
|
-
if (body?.content) output.write(`${body.content}\n`);
|
|
598
|
-
return 0;
|
|
599
|
-
} catch (error) {
|
|
600
|
-
output.write(
|
|
601
|
-
`[nolo] agent smoke-bound failed: ${
|
|
602
|
-
error instanceof Error ? error.message : String(error)
|
|
603
|
-
}\n`
|
|
604
|
-
);
|
|
605
|
-
return 1;
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
349
|
export async function runAgentRuntimeDoctorCommand(
|
|
610
350
|
args: string[],
|
|
611
351
|
deps: AgentCommandDeps = {}
|
|
@@ -617,45 +357,27 @@ export async function runAgentRuntimeDoctorCommand(
|
|
|
617
357
|
output.write("Usage: nolo agent runtime-doctor <agentKey>\n");
|
|
618
358
|
return agentInput ? 0 : 1;
|
|
619
359
|
}
|
|
360
|
+
const agentKey = resolveCliAgentKeyInput(agentInput);
|
|
620
361
|
|
|
621
|
-
const authToken = resolveAuthToken(
|
|
362
|
+
const authToken = resolveAuthToken(env);
|
|
622
363
|
if (!authToken) {
|
|
623
364
|
output.write("[nolo] agent runtime-doctor requires an auth token. Run `nolo login` or set AUTH_TOKEN.\n");
|
|
624
365
|
return 1;
|
|
625
366
|
}
|
|
626
|
-
const userId = parseUserIdFromAuthToken(authToken);
|
|
627
|
-
if (!userId) {
|
|
628
|
-
output.write("[nolo] agent runtime-doctor could not read userId from AUTH_TOKEN.\n");
|
|
629
|
-
return 1;
|
|
630
|
-
}
|
|
631
367
|
|
|
632
|
-
const serverUrl = resolveServerUrl(
|
|
368
|
+
const serverUrl = resolveServerUrl(env);
|
|
633
369
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
634
370
|
const fallbackFetchImpl = deps.fallbackFetchImpl;
|
|
635
|
-
const resolvedAgent = await resolveMachineAgent({
|
|
636
|
-
agentInput,
|
|
637
|
-
cliArgs: args,
|
|
638
|
-
deps,
|
|
639
|
-
env,
|
|
640
|
-
fetchImpl,
|
|
641
|
-
fallbackFetchImpl,
|
|
642
|
-
output,
|
|
643
|
-
userId,
|
|
644
|
-
});
|
|
645
|
-
const agentKey = resolvedAgent.agentKey;
|
|
646
371
|
const machine = await (deps.machineInfo ?? detectLaunchableMachineInfo)();
|
|
647
372
|
|
|
648
373
|
try {
|
|
649
|
-
const agent =
|
|
650
|
-
resolvedAgent.source === "remote-cache"
|
|
651
|
-
? resolvedAgent.record
|
|
652
|
-
: await readAgentRecord({ agentKey, authToken, fallbackFetchImpl, fetchImpl, serverUrl });
|
|
374
|
+
const agent = await readAgentRecord({ agentKey, authToken, fallbackFetchImpl, fetchImpl, serverUrl });
|
|
653
375
|
const requiredCapability = requiredCapabilityForAgent(agent);
|
|
654
376
|
const runtimeClass = classifyAgentRuntime(agent);
|
|
377
|
+
const isBoundToCurrent = agent?.runtimeBinding?.machineId === machine.machineId;
|
|
655
378
|
const hasCapability = requiredCapability
|
|
656
379
|
? machine.capabilities.includes(requiredCapability)
|
|
657
380
|
: false;
|
|
658
|
-
const bindingFacts = runtimeBindingFacts(agent, machine, userId);
|
|
659
381
|
output.write(`Agent runtime doctor: ${agent?.name ?? agentKey}\n`);
|
|
660
382
|
if (agentInput !== agentKey) output.write(`Agent input: ${agentInput}\n`);
|
|
661
383
|
output.write(`Agent key: ${agentKey}\n`);
|
|
@@ -665,28 +387,10 @@ export async function runAgentRuntimeDoctorCommand(
|
|
|
665
387
|
output.write(`Required capability: ${requiredCapability || "none"}\n`);
|
|
666
388
|
output.write(`Current machine: ${machine.name} (${machine.machineId})\n`);
|
|
667
389
|
output.write(`Current machine capabilities: ${machine.capabilities.length ? machine.capabilities.join(", ") : "none"}\n`);
|
|
668
|
-
output.write(`
|
|
669
|
-
output.write(`Recorded binding owner: ${bindingFacts.boundOwnerUserId || "unknown"}\n`);
|
|
670
|
-
output.write(`Current machine binding: ${runtimeClass === "cli-machine" ? (bindingFacts.isBoundToCurrent ? "yes" : "no") : "not required"}\n`);
|
|
671
|
-
output.write(
|
|
672
|
-
`Binding owner matches current user: ${
|
|
673
|
-
runtimeClass === "cli-machine"
|
|
674
|
-
? (bindingFacts.boundOwnerUserId
|
|
675
|
-
? (bindingFacts.isBindingOwnerCompatible ? "yes" : "no")
|
|
676
|
-
: "unknown")
|
|
677
|
-
: "not required"
|
|
678
|
-
}\n`
|
|
679
|
-
);
|
|
390
|
+
output.write(`Current machine binding: ${runtimeClass === "cli-machine" ? (isBoundToCurrent ? "yes" : "no") : "not required"}\n`);
|
|
680
391
|
output.write(`Current machine has required capability: ${requiredCapability ? (hasCapability ? "yes" : "no") : "not required"}\n`);
|
|
681
392
|
|
|
682
|
-
return shouldRuntimeDoctorPass({
|
|
683
|
-
runtimeClass,
|
|
684
|
-
requiredCapability,
|
|
685
|
-
hasCapability,
|
|
686
|
-
bindingRequired: bindingFacts.bindingRequired,
|
|
687
|
-
isBoundToCurrent: bindingFacts.isBoundToCurrent,
|
|
688
|
-
isBindingOwnerCompatible: bindingFacts.isBindingOwnerCompatible,
|
|
689
|
-
}) ? 0 : 1;
|
|
393
|
+
return shouldRuntimeDoctorPass({ runtimeClass, requiredCapability, hasCapability }) ? 0 : 1;
|
|
690
394
|
} catch (error) {
|
|
691
395
|
output.write(
|
|
692
396
|
`[nolo] agent runtime-doctor failed: ${
|
package/agentPullCommand.ts
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
import { getDefaultCliLocalRuntimeDb } from "./localRuntimeDb";
|
|
2
2
|
import type { CliLocalRuntimeDb } from "./client/localRuntimeAdapter";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
buildCurrentUserPlatformAgentCandidateKeys,
|
|
6
|
-
resolveCliAgentKeyInput,
|
|
7
|
-
} from "./agentAliases";
|
|
8
|
-
import { resolveAgentRecordFromHybridStore } from "./agentRecordHelpers";
|
|
9
|
-
import {
|
|
10
|
-
parseUserIdFromAuthToken,
|
|
11
|
-
readCliOptionValue,
|
|
12
|
-
resolveAuthToken,
|
|
13
|
-
resolveServerUrl,
|
|
14
|
-
} from "./cliEnvHelpers";
|
|
3
|
+
import { resolveCliAgentKeyInput } from "./agentAliases";
|
|
4
|
+
import { resolveAuthToken, resolveServerUrl } from "./cliEnvHelpers";
|
|
15
5
|
|
|
16
6
|
type EnvLike = Record<string, string | undefined>;
|
|
17
7
|
|
|
8
|
+
type OutputLike = {
|
|
9
|
+
write(chunk: string): unknown;
|
|
10
|
+
};
|
|
11
|
+
|
|
18
12
|
type AgentPullCommandDeps = {
|
|
19
13
|
env?: EnvLike;
|
|
20
14
|
output?: OutputLike;
|
|
@@ -27,7 +21,8 @@ export type ParsedAgentPullArgs = {
|
|
|
27
21
|
};
|
|
28
22
|
|
|
29
23
|
function readFlagValue(args: string[], flag: string) {
|
|
30
|
-
|
|
24
|
+
const index = args.indexOf(flag);
|
|
25
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
function positionalArgs(args: string[]) {
|
|
@@ -111,57 +106,37 @@ export async function runAgentPullCommand(args: string[], deps: AgentPullCommand
|
|
|
111
106
|
}
|
|
112
107
|
|
|
113
108
|
const serverUrl = resolveServerUrl(args, env);
|
|
114
|
-
const authToken =
|
|
115
|
-
|
|
109
|
+
const authToken =
|
|
110
|
+
readFlagValue(args, "--token") ||
|
|
111
|
+
readFlagValue(args, "--machine-key") ||
|
|
112
|
+
resolveAuthToken(env, ["BENCHMARK_AUTH_TOKEN"]);
|
|
116
113
|
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
117
114
|
const db = deps.db ?? await getDefaultCliLocalRuntimeDb();
|
|
118
|
-
|
|
119
|
-
let
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
agentInput,
|
|
126
|
-
cliArgs: args,
|
|
127
|
-
env,
|
|
128
|
-
db,
|
|
115
|
+
|
|
116
|
+
let record: any;
|
|
117
|
+
try {
|
|
118
|
+
record = await readRemoteAgent({
|
|
119
|
+
agentKey: parsed.agentKey,
|
|
120
|
+
serverUrl,
|
|
121
|
+
authToken,
|
|
129
122
|
fetchImpl,
|
|
130
123
|
});
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
let record: any = resolvedRecord;
|
|
140
|
-
if (!record) {
|
|
141
|
-
try {
|
|
142
|
-
record = await readRemoteAgent({
|
|
143
|
-
agentKey,
|
|
144
|
-
serverUrl,
|
|
145
|
-
authToken,
|
|
146
|
-
fetchImpl,
|
|
147
|
-
});
|
|
148
|
-
} catch (error) {
|
|
149
|
-
output.write(
|
|
150
|
-
`[nolo] Failed to pull ${agentKey} from ${serverUrl}: ${
|
|
151
|
-
error instanceof Error ? error.message : String(error)
|
|
152
|
-
}\n`
|
|
153
|
-
);
|
|
154
|
-
return 1;
|
|
155
|
-
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
output.write(
|
|
126
|
+
`[nolo] Failed to pull ${parsed.agentKey} from ${serverUrl}: ${
|
|
127
|
+
error instanceof Error ? error.message : String(error)
|
|
128
|
+
}\n`
|
|
129
|
+
);
|
|
130
|
+
return 1;
|
|
156
131
|
}
|
|
157
132
|
|
|
158
133
|
if (!record || typeof record !== "object") {
|
|
159
|
-
output.write(`[nolo] Server returned an empty agent record for ${agentKey}.\n`);
|
|
134
|
+
output.write(`[nolo] Server returned an empty agent record for ${parsed.agentKey}.\n`);
|
|
160
135
|
return 1;
|
|
161
136
|
}
|
|
162
137
|
|
|
163
|
-
const localRecord = normalizeAgentRecord(agentKey, record);
|
|
164
|
-
await db.put(agentKey, localRecord);
|
|
165
|
-
output.write(`[nolo] cached ${agentKey} in local LevelDB\n`);
|
|
138
|
+
const localRecord = normalizeAgentRecord(parsed.agentKey, record);
|
|
139
|
+
await db.put(parsed.agentKey, localRecord);
|
|
140
|
+
output.write(`[nolo] cached ${parsed.agentKey} in local LevelDB\n`);
|
|
166
141
|
return 0;
|
|
167
142
|
}
|