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
|
@@ -5,7 +5,6 @@ import type {
|
|
|
5
5
|
AgentRuntimeToolCallInput,
|
|
6
6
|
AgentRuntimeToolResult,
|
|
7
7
|
} from "./types";
|
|
8
|
-
import type { HostRuntimeConfig } from "./hostRuntimeConfig";
|
|
9
8
|
|
|
10
9
|
type LocalWorkspaceToolArgs = {
|
|
11
10
|
workspaceRoot: string;
|
|
@@ -19,13 +18,9 @@ type WorkspaceFileArgs = {
|
|
|
19
18
|
oldText?: unknown;
|
|
20
19
|
newText?: unknown;
|
|
21
20
|
expectedReplacements?: unknown;
|
|
22
|
-
edits?: unknown;
|
|
23
|
-
offset?: unknown;
|
|
24
|
-
limit?: unknown;
|
|
25
21
|
query?: unknown;
|
|
26
22
|
command?: unknown;
|
|
27
23
|
cmd?: unknown;
|
|
28
|
-
timeout?: unknown;
|
|
29
24
|
patch?: unknown;
|
|
30
25
|
script?: unknown;
|
|
31
26
|
args?: unknown;
|
|
@@ -79,13 +74,6 @@ const DEFAULT_LOCAL_CODING_TOOL_NAMES = [
|
|
|
79
74
|
"searchFiles",
|
|
80
75
|
] as const;
|
|
81
76
|
|
|
82
|
-
const DEFAULT_LOCAL_CODING_TOOL_NAMES_WITH_SHELL = [
|
|
83
|
-
"readFile",
|
|
84
|
-
"writeFile",
|
|
85
|
-
"editFile",
|
|
86
|
-
"execShell",
|
|
87
|
-
] as const;
|
|
88
|
-
|
|
89
77
|
const SHELL_TOOL_NAMES = ["execShell"] as const;
|
|
90
78
|
const WORKSPACE_TOOL_NAME_SET = new Set<string>(WORKSPACE_TOOL_NAMES);
|
|
91
79
|
const REMOVED_WORKSPACE_TOOL_NAMES = new Set([
|
|
@@ -127,19 +115,11 @@ function buildReadWorkspaceFileTool(): OpenAiCompatibleTool {
|
|
|
127
115
|
function: {
|
|
128
116
|
name: "readWorkspaceFile",
|
|
129
117
|
description:
|
|
130
|
-
"Read a UTF-8 text file inside the workspace. Read before editing when you need the current content or exact text for replaceWorkspaceText; skip unnecessary reads for trivial known writes.
|
|
118
|
+
"Read a UTF-8 text file inside the workspace. Read before editing when you need the current content or exact text for replaceWorkspaceText; skip unnecessary reads for trivial known writes.",
|
|
131
119
|
parameters: {
|
|
132
120
|
type: "object",
|
|
133
121
|
properties: {
|
|
134
122
|
path: buildWorkspacePathProperty(),
|
|
135
|
-
offset: {
|
|
136
|
-
type: "integer",
|
|
137
|
-
description: "Optional zero-based starting line offset.",
|
|
138
|
-
},
|
|
139
|
-
limit: {
|
|
140
|
-
type: "integer",
|
|
141
|
-
description: "Optional maximum number of lines to return.",
|
|
142
|
-
},
|
|
143
123
|
},
|
|
144
124
|
required: ["path"],
|
|
145
125
|
},
|
|
@@ -192,26 +172,8 @@ function buildReplaceWorkspaceTextTool(): OpenAiCompatibleTool {
|
|
|
192
172
|
type: "integer",
|
|
193
173
|
description: "Expected replacement count. Defaults to 1.",
|
|
194
174
|
},
|
|
195
|
-
edits: {
|
|
196
|
-
type: "array",
|
|
197
|
-
description: "Optional batch exact-text replacements applied against the original file snapshot.",
|
|
198
|
-
items: {
|
|
199
|
-
type: "object",
|
|
200
|
-
properties: {
|
|
201
|
-
oldText: {
|
|
202
|
-
type: "string",
|
|
203
|
-
description: "Exact text currently present in the file.",
|
|
204
|
-
},
|
|
205
|
-
newText: {
|
|
206
|
-
type: "string",
|
|
207
|
-
description: "Replacement text to write in place of oldText.",
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
required: ["oldText", "newText"],
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
175
|
},
|
|
214
|
-
required: ["path"],
|
|
176
|
+
required: ["path", "oldText", "newText"],
|
|
215
177
|
},
|
|
216
178
|
},
|
|
217
179
|
};
|
|
@@ -354,7 +316,7 @@ function buildExecShellTool(toolName: string): OpenAiCompatibleTool {
|
|
|
354
316
|
function: {
|
|
355
317
|
name: toolName,
|
|
356
318
|
description:
|
|
357
|
-
"Run a shell command in the local workspace.
|
|
319
|
+
"Run a shell command in the local workspace. Commands already execute from the workspace root; do not cd into guessed paths such as /workspace, /repo, /home/user, or /home/user/workspace. Prefer one command that performs a complete verification or related git operation instead of many tiny commands. For branch setup, prefer idempotent commands such as git switch -C <branch> when replacing or recreating a benchmark branch is acceptable. Use portable POSIX commands for macOS/BSD shells; avoid GNU-only flags such as cat -A. Do not use cat -A. Do not use brittle byte-offset commands such as xxd -s -32. For separator lines, use echo or printf '%s\\n'. For text-file content or trailing-newline checks, prefer readFile over shell byte inspection when that tool is available. Do not run repeated git status, git log, git rev-parse, or branch checks after a successful command already returned the needed clean status and commit information; use one final verification command. If a command fails, use the error output to adjust the next command rather than repeating the same shape.",
|
|
358
320
|
parameters: {
|
|
359
321
|
type: "object",
|
|
360
322
|
properties: {
|
|
@@ -366,10 +328,6 @@ function buildExecShellTool(toolName: string): OpenAiCompatibleTool {
|
|
|
366
328
|
type: "string",
|
|
367
329
|
description: "Shell command to run.",
|
|
368
330
|
},
|
|
369
|
-
timeout: {
|
|
370
|
-
type: "integer",
|
|
371
|
-
description: "Optional timeout in milliseconds. The runtime clamps values above its configured maximum.",
|
|
372
|
-
},
|
|
373
331
|
},
|
|
374
332
|
},
|
|
375
333
|
},
|
|
@@ -494,28 +452,18 @@ function filterDeclaredWorkspaceToolNames(args: {
|
|
|
494
452
|
return (args.toolNames ?? []).filter((toolName) =>
|
|
495
453
|
WORKSPACE_TOOL_NAME_SET.has(toolName) &&
|
|
496
454
|
!REMOVED_WORKSPACE_TOOL_NAMES.has(toolName) &&
|
|
497
|
-
|
|
455
|
+
(args.exposeShellTools || !SHELL_TOOL_NAMES.includes(toolName as any))
|
|
498
456
|
);
|
|
499
457
|
}
|
|
500
458
|
|
|
501
|
-
export function resolveLocalWorkspaceShellToolExposure(args: {
|
|
502
|
-
declaredToolNames?: string[];
|
|
503
|
-
hostRuntimeConfig?: Pick<HostRuntimeConfig, "capabilities">;
|
|
504
|
-
}) {
|
|
505
|
-
return args.hostRuntimeConfig?.capabilities.allowShell === true &&
|
|
506
|
-
(args.declaredToolNames ?? []).includes("execShell");
|
|
507
|
-
}
|
|
508
|
-
|
|
509
459
|
export function buildLocalWorkspaceToolset(args: {
|
|
510
460
|
declaredToolNames?: string[];
|
|
511
461
|
exposeShellTools?: boolean;
|
|
512
462
|
}) {
|
|
513
463
|
const exposeShellTools = args.exposeShellTools === true;
|
|
514
|
-
const defaultToolNames = exposeShellTools
|
|
515
|
-
? DEFAULT_LOCAL_CODING_TOOL_NAMES_WITH_SHELL
|
|
516
|
-
: DEFAULT_LOCAL_CODING_TOOL_NAMES;
|
|
517
464
|
const toolNames = removeRedundantWorkspaceToolAliases(new Set([
|
|
518
|
-
...
|
|
465
|
+
...DEFAULT_LOCAL_CODING_TOOL_NAMES,
|
|
466
|
+
...(exposeShellTools ? SHELL_TOOL_NAMES : []),
|
|
519
467
|
...filterDeclaredWorkspaceToolNames({
|
|
520
468
|
toolNames: args.declaredToolNames,
|
|
521
469
|
exposeShellTools,
|
|
@@ -590,31 +538,6 @@ function requireWorkspaceToolPath(args: WorkspaceFileArgs) {
|
|
|
590
538
|
return requestedPath;
|
|
591
539
|
}
|
|
592
540
|
|
|
593
|
-
function readOptionalNonNegativeIntegerArg(value: unknown, label: string) {
|
|
594
|
-
if (value === undefined) return undefined;
|
|
595
|
-
const number = Number(value);
|
|
596
|
-
if (!Number.isInteger(number) || number < 0) {
|
|
597
|
-
throw new Error(`${label} must be a non-negative integer.`);
|
|
598
|
-
}
|
|
599
|
-
return number;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
function readOptionalPositiveIntegerArg(value: unknown, label: string) {
|
|
603
|
-
if (value === undefined) return undefined;
|
|
604
|
-
const number = Number(value);
|
|
605
|
-
if (!Number.isInteger(number) || number < 1) {
|
|
606
|
-
throw new Error(`${label} must be a positive integer.`);
|
|
607
|
-
}
|
|
608
|
-
return number;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
function readWorkspaceReadWindow(args: WorkspaceFileArgs) {
|
|
612
|
-
return {
|
|
613
|
-
offset: readOptionalNonNegativeIntegerArg(args.offset, "readWorkspaceFile offset") ?? 0,
|
|
614
|
-
limit: readOptionalPositiveIntegerArg(args.limit, "readWorkspaceFile limit"),
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
|
|
618
541
|
function requireWorkspaceFileContent(args: WorkspaceFileArgs) {
|
|
619
542
|
if (typeof args.content !== "string") {
|
|
620
543
|
throw new Error("writeWorkspaceFile requires string content.");
|
|
@@ -636,37 +559,6 @@ function requireWorkspaceNewText(args: WorkspaceFileArgs) {
|
|
|
636
559
|
return args.newText;
|
|
637
560
|
}
|
|
638
561
|
|
|
639
|
-
type WorkspaceStructuredEdit = {
|
|
640
|
-
oldText: string;
|
|
641
|
-
newText: string;
|
|
642
|
-
};
|
|
643
|
-
|
|
644
|
-
function readWorkspaceStructuredEdits(args: WorkspaceFileArgs) {
|
|
645
|
-
if (args.edits === undefined) return null;
|
|
646
|
-
if (!Array.isArray(args.edits) || args.edits.length === 0) {
|
|
647
|
-
throw new Error("editFile edits must be a non-empty array.");
|
|
648
|
-
}
|
|
649
|
-
return args.edits.map((entry, index) => {
|
|
650
|
-
if (!entry || typeof entry !== "object") {
|
|
651
|
-
throw new Error(`editFile edits[${index}] must be an object.`);
|
|
652
|
-
}
|
|
653
|
-
const oldText = typeof (entry as Record<string, unknown>).oldText === "string"
|
|
654
|
-
? ((entry as Record<string, unknown>).oldText as string)
|
|
655
|
-
: "";
|
|
656
|
-
if (!oldText) {
|
|
657
|
-
throw new Error(`editFile edits[${index}] oldText must be a non-empty string.`);
|
|
658
|
-
}
|
|
659
|
-
const newTextValue = (entry as Record<string, unknown>).newText;
|
|
660
|
-
if (typeof newTextValue !== "string") {
|
|
661
|
-
throw new Error(`editFile edits[${index}] newText must be a string.`);
|
|
662
|
-
}
|
|
663
|
-
return {
|
|
664
|
-
oldText,
|
|
665
|
-
newText: newTextValue,
|
|
666
|
-
};
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
|
|
670
562
|
function readExpectedReplacementCount(args: WorkspaceFileArgs) {
|
|
671
563
|
if (args.expectedReplacements === undefined) return 1;
|
|
672
564
|
const value = Number(args.expectedReplacements);
|
|
@@ -687,79 +579,6 @@ function pluralizeReplacement(count: number) {
|
|
|
687
579
|
return count === 1 ? "replacement" : "replacements";
|
|
688
580
|
}
|
|
689
581
|
|
|
690
|
-
function findUniqueEditRange(args: {
|
|
691
|
-
content: string;
|
|
692
|
-
oldText: string;
|
|
693
|
-
requestedPath: string;
|
|
694
|
-
index: number;
|
|
695
|
-
}) {
|
|
696
|
-
const start = args.content.indexOf(args.oldText);
|
|
697
|
-
if (start < 0) {
|
|
698
|
-
throw new Error(`editFile edits[${args.index}] oldText was not found in ${args.requestedPath}.`);
|
|
699
|
-
}
|
|
700
|
-
if (args.content.indexOf(args.oldText, start + 1) >= 0) {
|
|
701
|
-
throw new Error(
|
|
702
|
-
`editFile edits[${args.index}] oldText must match exactly once in ${args.requestedPath}.`
|
|
703
|
-
);
|
|
704
|
-
}
|
|
705
|
-
return {
|
|
706
|
-
start,
|
|
707
|
-
end: start + args.oldText.length,
|
|
708
|
-
};
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
function countLineNumberAtOffset(args: {
|
|
712
|
-
content: string;
|
|
713
|
-
offset: number;
|
|
714
|
-
}) {
|
|
715
|
-
let lineNumber = 1;
|
|
716
|
-
for (let index = 0; index < args.offset; index += 1) {
|
|
717
|
-
if (args.content[index] === "\n") {
|
|
718
|
-
lineNumber += 1;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
return lineNumber;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
function applyWorkspaceStructuredEdits(args: {
|
|
725
|
-
content: string;
|
|
726
|
-
edits: WorkspaceStructuredEdit[];
|
|
727
|
-
requestedPath: string;
|
|
728
|
-
}) {
|
|
729
|
-
const ranges = args.edits.map((edit, index) => ({
|
|
730
|
-
...edit,
|
|
731
|
-
index,
|
|
732
|
-
...findUniqueEditRange({
|
|
733
|
-
content: args.content,
|
|
734
|
-
oldText: edit.oldText,
|
|
735
|
-
requestedPath: args.requestedPath,
|
|
736
|
-
index,
|
|
737
|
-
}),
|
|
738
|
-
})).sort((left, right) => left.start - right.start);
|
|
739
|
-
for (let index = 1; index < ranges.length; index += 1) {
|
|
740
|
-
if (ranges[index]!.start < ranges[index - 1]!.end) {
|
|
741
|
-
throw new Error(`editFile edits overlap in ${args.requestedPath}.`);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
let nextContent = args.content;
|
|
745
|
-
for (const range of [...ranges].sort((left, right) => right.start - left.start)) {
|
|
746
|
-
nextContent =
|
|
747
|
-
nextContent.slice(0, range.start) +
|
|
748
|
-
range.newText +
|
|
749
|
-
nextContent.slice(range.end);
|
|
750
|
-
}
|
|
751
|
-
return {
|
|
752
|
-
nextContent,
|
|
753
|
-
firstChangedLine: ranges.length > 0
|
|
754
|
-
? countLineNumberAtOffset({
|
|
755
|
-
content: args.content,
|
|
756
|
-
offset: ranges[0]!.start,
|
|
757
|
-
})
|
|
758
|
-
: 1,
|
|
759
|
-
replacements: ranges.length,
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
|
|
763
582
|
function requireWorkspaceSearchQuery(args: WorkspaceFileArgs) {
|
|
764
583
|
const query = typeof args.query === "string" ? args.query.trim() : "";
|
|
765
584
|
if (!query) throw new Error("searchWorkspace requires a non-empty query.");
|
|
@@ -788,10 +607,6 @@ function requirePackageScript(args: WorkspaceFileArgs) {
|
|
|
788
607
|
return script;
|
|
789
608
|
}
|
|
790
609
|
|
|
791
|
-
function readShellTimeoutMs(args: WorkspaceFileArgs) {
|
|
792
|
-
return readOptionalPositiveIntegerArg(args.timeout, "execShell timeout");
|
|
793
|
-
}
|
|
794
|
-
|
|
795
610
|
function requireVisualWaitSelector(args: WorkspaceFileArgs) {
|
|
796
611
|
const selector = typeof args.waitSelector === "string" ? args.waitSelector.trim() : "";
|
|
797
612
|
if (!selector) throw new Error("captureVisualState requires a non-empty waitSelector.");
|
|
@@ -851,38 +666,9 @@ function formatAvailableScripts(scripts: string[]) {
|
|
|
851
666
|
return scripts.length ? scripts.join(", ") : "(none)";
|
|
852
667
|
}
|
|
853
668
|
|
|
854
|
-
function splitContentIntoLines(content: string) {
|
|
855
|
-
if (!content) return [];
|
|
856
|
-
const lines: string[] = [];
|
|
857
|
-
let start = 0;
|
|
858
|
-
for (let index = 0; index < content.length; index += 1) {
|
|
859
|
-
if (content[index] !== "\n") continue;
|
|
860
|
-
lines.push(content.slice(start, index + 1));
|
|
861
|
-
start = index + 1;
|
|
862
|
-
}
|
|
863
|
-
if (start < content.length) {
|
|
864
|
-
lines.push(content.slice(start));
|
|
865
|
-
}
|
|
866
|
-
return lines;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
function appendReadContinuationHint(content: string, hint: string) {
|
|
870
|
-
if (!content) return hint;
|
|
871
|
-
return content.endsWith("\n") ? `${content}\n${hint}` : `${content}\n\n${hint}`;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
669
|
function truncateToolOutput(value: string, limit = 20_000) {
|
|
875
|
-
if (value.length <= limit)
|
|
876
|
-
|
|
877
|
-
}
|
|
878
|
-
return {
|
|
879
|
-
content: `${value.slice(0, limit)}\n\n[truncated ${value.length - limit} chars]`,
|
|
880
|
-
truncated: true,
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
function sanitizeWorkspaceTempName(value: string) {
|
|
885
|
-
return value.replace(/[^a-zA-Z0-9._-]+/g, "_");
|
|
670
|
+
if (value.length <= limit) return value;
|
|
671
|
+
return `${value.slice(0, limit)}\n\n[truncated ${value.length - limit} chars]`;
|
|
886
672
|
}
|
|
887
673
|
|
|
888
674
|
function parseLastJsonObject(text: string): Record<string, unknown> | null {
|
|
@@ -982,20 +768,16 @@ async function runWorkspaceCommand(args: {
|
|
|
982
768
|
const stderr = timedOut
|
|
983
769
|
? `${rawStderr.trim() ? `${rawStderr.trim()}\n` : ""}command timed out after ${timeoutMs}ms\n`
|
|
984
770
|
: rawStderr;
|
|
985
|
-
const fullContent = [
|
|
986
|
-
stdout.trim() ? `stdout:\n${stdout.trim()}` : "",
|
|
987
|
-
stderr.trim() ? `stderr:\n${stderr.trim()}` : "",
|
|
988
|
-
`exitCode: ${exitCode}`,
|
|
989
|
-
].filter(Boolean).join("\n\n");
|
|
990
|
-
const summarizedContent = truncateToolOutput(fullContent);
|
|
991
771
|
return {
|
|
992
772
|
stdout,
|
|
993
773
|
stderr,
|
|
994
774
|
exitCode,
|
|
995
775
|
timedOut,
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
776
|
+
content: truncateToolOutput([
|
|
777
|
+
stdout.trim() ? `stdout:\n${stdout.trim()}` : "",
|
|
778
|
+
stderr.trim() ? `stderr:\n${stderr.trim()}` : "",
|
|
779
|
+
`exitCode: ${exitCode}`,
|
|
780
|
+
].filter(Boolean).join("\n\n")),
|
|
999
781
|
};
|
|
1000
782
|
}
|
|
1001
783
|
|
|
@@ -1017,46 +799,19 @@ async function readWorkspaceFileTool(args: {
|
|
|
1017
799
|
}): Promise<AgentRuntimeToolResult> {
|
|
1018
800
|
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
1019
801
|
const requestedPath = requireWorkspaceToolPath(parsed);
|
|
1020
|
-
const readWindow = readWorkspaceReadWindow(parsed);
|
|
1021
802
|
const absolutePath = resolveLocalWorkspaceToolPath({
|
|
1022
803
|
workspaceRoot: args.workspaceRoot,
|
|
1023
804
|
requestedPath,
|
|
1024
805
|
});
|
|
1025
806
|
const content = await readFile(absolutePath, "utf8");
|
|
1026
|
-
const lines = splitContentIntoLines(content);
|
|
1027
|
-
const lineOffset = Math.min(readWindow.offset, lines.length);
|
|
1028
|
-
const endLineIndex = readWindow.limit === undefined
|
|
1029
|
-
? lines.length
|
|
1030
|
-
: Math.min(lineOffset + readWindow.limit, lines.length);
|
|
1031
|
-
const pagedContent = lines.slice(lineOffset, endLineIndex).join("");
|
|
1032
|
-
const returnedLineCount = endLineIndex - lineOffset;
|
|
1033
|
-
const truncated = readWindow.limit !== undefined && endLineIndex < lines.length;
|
|
1034
|
-
const toolContent = truncated && returnedLineCount > 0
|
|
1035
|
-
? appendReadContinuationHint(
|
|
1036
|
-
pagedContent,
|
|
1037
|
-
`[readFile truncated: returned lines ${lineOffset + 1}-${endLineIndex} of ${lines.length}; ` +
|
|
1038
|
-
`call readFile again with offset ${endLineIndex}.]`
|
|
1039
|
-
)
|
|
1040
|
-
: pagedContent;
|
|
1041
|
-
const relativePath = normalizeWorkspaceRelativePath({
|
|
1042
|
-
workspaceRoot: resolve(args.workspaceRoot),
|
|
1043
|
-
targetPath: absolutePath,
|
|
1044
|
-
});
|
|
1045
807
|
return {
|
|
1046
|
-
content
|
|
808
|
+
content,
|
|
1047
809
|
metadata: {
|
|
1048
|
-
path:
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
...(readWindow.limit !== undefined ? { limit: readWindow.limit } : {}),
|
|
1054
|
-
returnedLineCount,
|
|
1055
|
-
totalLineCount: lines.length,
|
|
1056
|
-
truncated,
|
|
1057
|
-
...(truncated ? { nextOffset: endLineIndex } : {}),
|
|
1058
|
-
}
|
|
1059
|
-
: {}),
|
|
810
|
+
path: normalizeWorkspaceRelativePath({
|
|
811
|
+
workspaceRoot: resolve(args.workspaceRoot),
|
|
812
|
+
targetPath: absolutePath,
|
|
813
|
+
}),
|
|
814
|
+
bytes: Buffer.byteLength(content),
|
|
1060
815
|
},
|
|
1061
816
|
};
|
|
1062
817
|
}
|
|
@@ -1093,37 +848,14 @@ async function replaceWorkspaceTextTool(args: {
|
|
|
1093
848
|
}): Promise<AgentRuntimeToolResult> {
|
|
1094
849
|
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
1095
850
|
const requestedPath = requireWorkspaceToolPath(parsed);
|
|
1096
|
-
const
|
|
851
|
+
const oldText = requireWorkspaceOldText(parsed);
|
|
852
|
+
const newText = requireWorkspaceNewText(parsed);
|
|
853
|
+
const expectedReplacements = readExpectedReplacementCount(parsed);
|
|
1097
854
|
const absolutePath = resolveLocalWorkspaceToolPath({
|
|
1098
855
|
workspaceRoot: args.workspaceRoot,
|
|
1099
856
|
requestedPath,
|
|
1100
857
|
});
|
|
1101
858
|
const content = await readFile(absolutePath, "utf8");
|
|
1102
|
-
const relativePath = normalizeWorkspaceRelativePath({
|
|
1103
|
-
workspaceRoot: resolve(args.workspaceRoot),
|
|
1104
|
-
targetPath: absolutePath,
|
|
1105
|
-
});
|
|
1106
|
-
if (structuredEdits) {
|
|
1107
|
-
const result = applyWorkspaceStructuredEdits({
|
|
1108
|
-
content,
|
|
1109
|
-
edits: structuredEdits,
|
|
1110
|
-
requestedPath,
|
|
1111
|
-
});
|
|
1112
|
-
await writeFile(absolutePath, result.nextContent, "utf8");
|
|
1113
|
-
return {
|
|
1114
|
-
content: `applied ${result.replacements} edit${result.replacements === 1 ? "" : "s"} in ${relativePath}`,
|
|
1115
|
-
metadata: {
|
|
1116
|
-
path: relativePath,
|
|
1117
|
-
replacements: result.replacements,
|
|
1118
|
-
editCount: structuredEdits.length,
|
|
1119
|
-
bytes: Buffer.byteLength(result.nextContent),
|
|
1120
|
-
firstChangedLine: result.firstChangedLine,
|
|
1121
|
-
},
|
|
1122
|
-
};
|
|
1123
|
-
}
|
|
1124
|
-
const oldText = requireWorkspaceOldText(parsed);
|
|
1125
|
-
const newText = requireWorkspaceNewText(parsed);
|
|
1126
|
-
const expectedReplacements = readExpectedReplacementCount(parsed);
|
|
1127
859
|
const replacementCount = countExactTextOccurrences({ content, oldText });
|
|
1128
860
|
if (replacementCount !== expectedReplacements) {
|
|
1129
861
|
throw new Error(
|
|
@@ -1133,6 +865,10 @@ async function replaceWorkspaceTextTool(args: {
|
|
|
1133
865
|
}
|
|
1134
866
|
const nextContent = content.split(oldText).join(newText);
|
|
1135
867
|
await writeFile(absolutePath, nextContent, "utf8");
|
|
868
|
+
const relativePath = normalizeWorkspaceRelativePath({
|
|
869
|
+
workspaceRoot: resolve(args.workspaceRoot),
|
|
870
|
+
targetPath: absolutePath,
|
|
871
|
+
});
|
|
1136
872
|
return {
|
|
1137
873
|
content: `replaced ${replacementCount} occurrence${replacementCount === 1 ? "" : "s"} in ${relativePath}`,
|
|
1138
874
|
metadata: {
|
|
@@ -1426,20 +1162,7 @@ async function previewLifecycleTool(args: {
|
|
|
1426
1162
|
const summary = parseLastJsonObject(String(result.metadata?.stdoutTail ?? result.content)) ?? {};
|
|
1427
1163
|
return {
|
|
1428
1164
|
content: [
|
|
1429
|
-
typeof summary.
|
|
1430
|
-
? `preferredPreviewUrl: ${summary.preferredPreviewUrl}`
|
|
1431
|
-
: "",
|
|
1432
|
-
typeof summary.assignedPreviewUrl === "string"
|
|
1433
|
-
? `assignedPreviewUrl: ${summary.assignedPreviewUrl}`
|
|
1434
|
-
: typeof summary.previewUrl === "string"
|
|
1435
|
-
? `assignedPreviewUrl: ${summary.previewUrl}`
|
|
1436
|
-
: "",
|
|
1437
|
-
typeof summary.previewUrlVerified === "boolean"
|
|
1438
|
-
? `previewUrlVerified: ${String(summary.previewUrlVerified)}`
|
|
1439
|
-
: "",
|
|
1440
|
-
typeof summary.previewVerificationReason === "string"
|
|
1441
|
-
? `previewVerificationReason: ${summary.previewVerificationReason}`
|
|
1442
|
-
: "",
|
|
1165
|
+
typeof summary.previewUrl === "string" ? `previewUrl: ${summary.previewUrl}` : "",
|
|
1443
1166
|
typeof summary.localApiOrigin === "string" ? `localApiOrigin: ${summary.localApiOrigin}` : "",
|
|
1444
1167
|
typeof summary.serverDbPath === "string" ? `serverDbPath: ${summary.serverDbPath}` : "",
|
|
1445
1168
|
"",
|
|
@@ -1461,13 +1184,6 @@ async function execShellTool(args: {
|
|
|
1461
1184
|
}): Promise<AgentRuntimeToolResult> {
|
|
1462
1185
|
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
1463
1186
|
const command = requireShellCommand(parsed, args.call.name);
|
|
1464
|
-
const requestedTimeoutMs = readShellTimeoutMs(parsed);
|
|
1465
|
-
const timeoutMs = requestedTimeoutMs === undefined
|
|
1466
|
-
? args.commandTimeoutMs
|
|
1467
|
-
: Math.min(
|
|
1468
|
-
requestedTimeoutMs,
|
|
1469
|
-
args.commandTimeoutMs ?? DEFAULT_WORKSPACE_COMMAND_TIMEOUT_MS,
|
|
1470
|
-
);
|
|
1471
1187
|
const result = await runWorkspaceCommand({
|
|
1472
1188
|
workspaceRoot: args.workspaceRoot,
|
|
1473
1189
|
command: buildWorkspaceShellCommand({
|
|
@@ -1475,31 +1191,12 @@ async function execShellTool(args: {
|
|
|
1475
1191
|
command,
|
|
1476
1192
|
shell: parsed.shell,
|
|
1477
1193
|
}),
|
|
1478
|
-
timeoutMs,
|
|
1194
|
+
timeoutMs: args.commandTimeoutMs,
|
|
1479
1195
|
commandPrefix: args.commandPrefix,
|
|
1480
1196
|
});
|
|
1481
|
-
let fullOutputPath: string | undefined;
|
|
1482
|
-
if (result.outputTruncated) {
|
|
1483
|
-
const relativeOutputPath = `.tmp/agent-runtime/execShell/${sanitizeWorkspaceTempName(args.call.id)}.log`;
|
|
1484
|
-
const absoluteOutputPath = resolve(args.workspaceRoot, relativeOutputPath);
|
|
1485
|
-
await mkdir(dirname(absoluteOutputPath), { recursive: true });
|
|
1486
|
-
await writeFile(absoluteOutputPath, result.fullContent, "utf8");
|
|
1487
|
-
fullOutputPath = normalizeWorkspaceRelativePath({
|
|
1488
|
-
workspaceRoot: resolve(args.workspaceRoot),
|
|
1489
|
-
targetPath: absoluteOutputPath,
|
|
1490
|
-
});
|
|
1491
|
-
}
|
|
1492
1197
|
return {
|
|
1493
|
-
content:
|
|
1494
|
-
|
|
1495
|
-
: result.content,
|
|
1496
|
-
metadata: {
|
|
1497
|
-
exitCode: result.exitCode,
|
|
1498
|
-
timedOut: result.timedOut,
|
|
1499
|
-
timeoutMs: timeoutMs ?? DEFAULT_WORKSPACE_COMMAND_TIMEOUT_MS,
|
|
1500
|
-
...(result.outputTruncated ? { outputTruncated: true } : {}),
|
|
1501
|
-
...(fullOutputPath ? { fullOutputPath } : {}),
|
|
1502
|
-
},
|
|
1198
|
+
content: result.content,
|
|
1199
|
+
metadata: { exitCode: result.exitCode, timedOut: result.timedOut },
|
|
1503
1200
|
};
|
|
1504
1201
|
}
|
|
1505
1202
|
|
|
@@ -2,11 +2,13 @@ import type {
|
|
|
2
2
|
AgentRuntimeChatMessage,
|
|
3
3
|
AgentRuntimeResult,
|
|
4
4
|
} from "./types";
|
|
5
|
+
import { buildProviderAuthHeaders } from "./providerResolution";
|
|
5
6
|
|
|
6
7
|
export type OpenAiCompatibleProviderConfig = {
|
|
7
8
|
model: string;
|
|
8
9
|
endpoint: string;
|
|
9
10
|
apiKey: string;
|
|
11
|
+
apiKeyHeader?: string;
|
|
10
12
|
provider: string;
|
|
11
13
|
requestOptions: Record<string, number | string>;
|
|
12
14
|
};
|
|
@@ -41,9 +43,11 @@ export function buildOpenAiCompatibleChatCompletionRequest(args: {
|
|
|
41
43
|
method: "POST",
|
|
42
44
|
headers: {
|
|
43
45
|
"Content-Type": "application/json",
|
|
44
|
-
...(
|
|
45
|
-
|
|
46
|
-
:
|
|
46
|
+
...buildProviderAuthHeaders({
|
|
47
|
+
endpoint: args.providerConfig.endpoint,
|
|
48
|
+
apiKey: args.providerConfig.apiKey,
|
|
49
|
+
apiKeyHeader: args.providerConfig.apiKeyHeader,
|
|
50
|
+
}),
|
|
47
51
|
},
|
|
48
52
|
body: JSON.stringify(body),
|
|
49
53
|
},
|
|
@@ -1,38 +1,27 @@
|
|
|
1
1
|
import type { AgentRuntimeAgentConfig } from "./hostAdapter";
|
|
2
2
|
import type { OpenAiCompatibleProviderConfig } from "./openAiCompatibleProvider";
|
|
3
|
-
import {
|
|
3
|
+
import { buildProviderExecutionPlan } from "./providerResolution";
|
|
4
4
|
|
|
5
5
|
type EnvLike = Record<string, string | undefined>;
|
|
6
6
|
|
|
7
|
-
function trimTrailingSlash(value: string) {
|
|
8
|
-
return value.replace(/\/+$/, "");
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function resolveChatCompletionsEndpoint(value: string) {
|
|
12
|
-
const trimmed = trimTrailingSlash(value.trim());
|
|
13
|
-
return trimmed.endsWith("/chat/completions")
|
|
14
|
-
? trimmed
|
|
15
|
-
: `${trimmed}/chat/completions`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function resolveOpenAiCompatibleBaseUrl(env: EnvLike) {
|
|
19
|
-
return env.NOLO_LOCAL_OPENAI_BASE_URL || env.OPENAI_BASE_URL || "https://api.openai.com/v1";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function resolveOpenAiCompatibleApiKey(env: EnvLike) {
|
|
23
|
-
return env.OPENAI_API_KEY || env.NOLO_LOCAL_OPENAI_API_KEY || "";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
7
|
export function resolveOpenAiCompatibleProviderConfig(args: {
|
|
27
8
|
agentConfig: AgentRuntimeAgentConfig;
|
|
28
9
|
env: EnvLike;
|
|
29
10
|
}): OpenAiCompatibleProviderConfig {
|
|
30
|
-
const
|
|
11
|
+
const plan = buildProviderExecutionPlan({
|
|
12
|
+
agentConfig: args.agentConfig,
|
|
13
|
+
env: args.env,
|
|
14
|
+
runtimeKind: "local",
|
|
15
|
+
});
|
|
16
|
+
if (plan.mode === "cli" || plan.transport !== "direct") {
|
|
17
|
+
throw new Error("OpenAI-compatible provider config requires a direct provider execution plan.");
|
|
18
|
+
}
|
|
31
19
|
return {
|
|
32
|
-
model:
|
|
33
|
-
endpoint:
|
|
34
|
-
apiKey:
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
model: plan.model,
|
|
21
|
+
endpoint: plan.endpoint,
|
|
22
|
+
apiKey: plan.apiKey,
|
|
23
|
+
...(plan.apiKeyHeader ? { apiKeyHeader: plan.apiKeyHeader } : {}),
|
|
24
|
+
provider: plan.provider,
|
|
25
|
+
requestOptions: plan.requestOptions,
|
|
37
26
|
};
|
|
38
27
|
}
|