nolo-cli 0.1.33 → 0.1.35
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 +15 -5
- package/agent-runtime/agentRecordConfig.ts +8 -0
- package/agent-runtime/hostAdapter.ts +9 -1
- package/agent-runtime/index.ts +10 -0
- package/agent-runtime/localLoop.ts +49 -2
- package/agent-runtime/localToolPolicy.ts +71 -22
- package/agent-runtime/localWorkspaceTools.ts +5 -2
- package/agent-runtime/openAiCompatibleProvider.ts +7 -3
- package/agent-runtime/openAiCompatibleProviderConfig.ts +15 -26
- package/agent-runtime/platformChatProvider.ts +48 -71
- package/agent-runtime/providerResolution.ts +242 -0
- package/agent-runtime/runtimeToolPolicy.ts +33 -0
- package/agent-runtime/shellCommandPolicy.ts +120 -0
- package/agentCommandSupport.ts +4 -0
- package/agentInternalCommandEntries.ts +2 -0
- package/agentListCommands.ts +74 -12
- package/agentListHelpers.ts +56 -1
- package/agentPullCommand.ts +6 -11
- package/agentRecordCommands.ts +87 -2
- package/agentRecordHelpers.ts +132 -9
- package/agentRuntimeLocal.ts +3 -0
- package/ai/tools/toolNameAliases.ts +70 -0
- package/cli/agentCommandSupport.ts +4 -0
- package/cli/agentInternalCommandEntries.ts +2 -0
- package/cli/agentListCommands.ts +74 -12
- package/cli/agentListHelpers.ts +56 -1
- package/cli/agentPullCommand.ts +6 -11
- package/cli/agentRecordCommands.ts +87 -2
- package/cli/agentRecordHelpers.ts +132 -9
- package/cli/agentRuntimeLocal.ts +3 -0
- package/cli/cliCommandDispatch.ts +2 -2
- package/cli/cliEnvHelpers.ts +80 -12
- package/cli/cliSpaceHelpers.ts +39 -0
- package/cli/client/agentRun.ts +1 -0
- package/cli/client/localRuntimeAdapter.ts +44 -7
- package/cli/commandRegistry.ts +2 -2
- package/cli/connectorWebSocketTarget.ts +10 -3
- package/cli/dialogCommands.ts +446 -0
- package/cli/dialogInternalCommandEntries.ts +13 -0
- package/cli/globalRecordOperations.ts +258 -0
- package/cli/internalCommandEntries.ts +2 -0
- package/cli/localRuntimeAuthority.ts +182 -0
- package/cli/localRuntimeDb.ts +2 -4
- package/cli/machineCommands.ts +1 -1
- package/cli/machineWsRunDispatch.ts +29 -12
- package/cli/machineWsSession.ts +2 -0
- package/cli/offlineMarxistsAgentCommand.ts +1 -1
- package/cli/runtimeDoctorCommands.ts +65 -9
- package/cli/tableCommands.ts +1 -1
- package/cli/taskRunCommand.ts +1 -1
- package/cliCommandDispatch.ts +2 -2
- package/cliEnvHelpers.ts +80 -12
- package/cliSpaceHelpers.ts +39 -0
- package/client/agentRun.ts +1 -0
- package/client/localProviderResolver.test.ts +26 -2
- package/client/localRuntimeAdapter.test.ts +287 -3
- package/client/localRuntimeAdapter.ts +44 -7
- package/commandRegistry.ts +2 -2
- package/connectorWebSocketTarget.ts +10 -3
- package/database/server/authorityStoreTypes.ts +31 -0
- package/database/server/cliAuthorityBrokerClient.ts +227 -0
- package/database/server/cliAuthorityBrokerServer.ts +283 -0
- package/database/server/cliAuthorityBrokerTypes.ts +43 -0
- package/database/server/cliAuthorityStoreDriver.ts +98 -0
- package/database/server/legacyServerDb.ts +58 -0
- package/database/server/levelAuthorityStore.ts +95 -0
- package/database/tombstones.ts +52 -0
- package/database/userDataMerge.ts +95 -0
- package/dialogCommands.ts +446 -0
- package/dialogInternalCommandEntries.ts +13 -0
- package/globalRecordOperations.ts +258 -0
- package/internalCommandEntries.ts +2 -0
- package/localRuntimeAuthority.ts +182 -0
- package/localRuntimeDb.ts +2 -4
- package/machineCommands.ts +1 -1
- package/machineWsRunDispatch.ts +29 -12
- package/machineWsSession.ts +2 -0
- package/offlineMarxistsAgentCommand.ts +1 -1
- package/package.json +24 -4
- package/runtimeDoctorCommands.ts +65 -9
- package/tableCommands.ts +1 -1
- package/taskRunCommand.ts +1 -1
- package/database/server/db.ts +0 -118
- package/database/server/ensureDbOpen.ts +0 -12
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { resolveAgentRuntimeDecision } from "../agent-runtime/runtimeDecision";
|
|
2
|
+
import {
|
|
3
|
+
resolveCliAuthorityBrokerEndpoint,
|
|
4
|
+
resolveCliAuthorityBrokerHealthPath,
|
|
5
|
+
resolveCliAuthorityBrokerMetadataPath,
|
|
6
|
+
resolveCliAuthorityStoreDriver,
|
|
7
|
+
} from "../database/server/cliAuthorityStoreDriver";
|
|
2
8
|
import {
|
|
3
9
|
type AgentCommandDeps,
|
|
4
10
|
type LocalRuntimeProbeResult,
|
|
@@ -39,23 +45,57 @@ function detectProviderLabel(env: EnvLike) {
|
|
|
39
45
|
async function defaultLocalRuntimeProbe(env: EnvLike): Promise<LocalRuntimeProbeResult> {
|
|
40
46
|
const { resolveCliLocalRuntimeDbPath } = await import("./localRuntimeDb");
|
|
41
47
|
const dbPath = resolveCliLocalRuntimeDbPath({ env });
|
|
48
|
+
const authorityDriver = resolveCliAuthorityStoreDriver({ env });
|
|
49
|
+
const authorityEndpoint = resolveCliAuthorityBrokerEndpoint({ transport: "tcp", env });
|
|
50
|
+
const authorityMetadataPath = resolveCliAuthorityBrokerMetadataPath({ transport: "tcp", env });
|
|
51
|
+
const authorityHealthPath = resolveCliAuthorityBrokerHealthPath({ transport: "tcp", env });
|
|
42
52
|
const agentKey = readLocalAgentKey(env);
|
|
43
53
|
try {
|
|
44
54
|
const { getDefaultCliLocalRuntimeDb } = await import("./localRuntimeDb");
|
|
45
|
-
const db = await getDefaultCliLocalRuntimeDb();
|
|
55
|
+
const db = await getDefaultCliLocalRuntimeDb({ env });
|
|
46
56
|
if (!agentKey) {
|
|
47
|
-
return {
|
|
57
|
+
return {
|
|
58
|
+
ok: true,
|
|
59
|
+
dbPath,
|
|
60
|
+
authorityDriver,
|
|
61
|
+
authorityEndpoint,
|
|
62
|
+
authorityMetadataPath,
|
|
63
|
+
authorityHealthPath,
|
|
64
|
+
agentFound: false,
|
|
65
|
+
};
|
|
48
66
|
}
|
|
49
67
|
try {
|
|
50
|
-
await db.get(agentKey);
|
|
51
|
-
return {
|
|
68
|
+
const record = await db.get(agentKey);
|
|
69
|
+
return {
|
|
70
|
+
ok: true,
|
|
71
|
+
dbPath,
|
|
72
|
+
authorityDriver,
|
|
73
|
+
authorityEndpoint,
|
|
74
|
+
authorityMetadataPath,
|
|
75
|
+
authorityHealthPath,
|
|
76
|
+
agentFound: record != null,
|
|
77
|
+
agentKey,
|
|
78
|
+
};
|
|
52
79
|
} catch {
|
|
53
|
-
return {
|
|
80
|
+
return {
|
|
81
|
+
ok: true,
|
|
82
|
+
dbPath,
|
|
83
|
+
authorityDriver,
|
|
84
|
+
authorityEndpoint,
|
|
85
|
+
authorityMetadataPath,
|
|
86
|
+
authorityHealthPath,
|
|
87
|
+
agentFound: false,
|
|
88
|
+
agentKey,
|
|
89
|
+
};
|
|
54
90
|
}
|
|
55
91
|
} catch (error) {
|
|
56
92
|
return {
|
|
57
93
|
ok: false,
|
|
58
94
|
dbPath,
|
|
95
|
+
authorityDriver,
|
|
96
|
+
authorityEndpoint,
|
|
97
|
+
authorityMetadataPath,
|
|
98
|
+
authorityHealthPath,
|
|
59
99
|
agentFound: false,
|
|
60
100
|
...(agentKey ? { agentKey } : {}),
|
|
61
101
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -64,13 +104,13 @@ async function defaultLocalRuntimeProbe(env: EnvLike): Promise<LocalRuntimeProbe
|
|
|
64
104
|
}
|
|
65
105
|
|
|
66
106
|
export async function runDoctorRuntimeCommand(
|
|
67
|
-
|
|
107
|
+
args: string[],
|
|
68
108
|
deps: AgentCommandDeps = {}
|
|
69
109
|
) {
|
|
70
110
|
const env = deps.env ?? process.env;
|
|
71
111
|
const output = deps.output ?? process.stdout;
|
|
72
|
-
const authToken = resolveAuthToken(env);
|
|
73
|
-
const serverUrl = resolveServerUrl(env);
|
|
112
|
+
const authToken = resolveAuthToken(args, env);
|
|
113
|
+
const serverUrl = resolveServerUrl(args, env);
|
|
74
114
|
const localProbe = await (deps.localRuntimeProbe ?? defaultLocalRuntimeProbe)(env);
|
|
75
115
|
const hasLocalAgentConfig = detectLocalAgentConfig(env) && localProbe.ok && localProbe.agentFound;
|
|
76
116
|
const hasLocalProvider = detectLocalProvider(env);
|
|
@@ -88,13 +128,29 @@ export async function runDoctorRuntimeCommand(
|
|
|
88
128
|
hasLocalPersistence: true,
|
|
89
129
|
missingLocalCapabilities,
|
|
90
130
|
requiresServer: false,
|
|
91
|
-
serverFallbackAvailable: Boolean(
|
|
131
|
+
serverFallbackAvailable: Boolean(
|
|
132
|
+
authToken ||
|
|
133
|
+
args.includes("--server") ||
|
|
134
|
+
args.includes("--server-url") ||
|
|
135
|
+
env.NOLO_SERVER ||
|
|
136
|
+
env.BASE_URL
|
|
137
|
+
),
|
|
92
138
|
});
|
|
93
139
|
|
|
94
140
|
output.write(`Runtime: ${decision.mode}\n`);
|
|
95
141
|
output.write(`Reason: ${decision.reason}\n`);
|
|
96
142
|
output.write(`LevelDB: ${localProbe.ok ? "ok" : "failed"}\n`);
|
|
97
143
|
output.write(`DB path: ${localProbe.dbPath}\n`);
|
|
144
|
+
output.write(`Authority driver: ${localProbe.authorityDriver ?? "unknown"}\n`);
|
|
145
|
+
if (localProbe.authorityEndpoint) {
|
|
146
|
+
output.write(`Authority endpoint: ${localProbe.authorityEndpoint}\n`);
|
|
147
|
+
}
|
|
148
|
+
if (localProbe.authorityMetadataPath) {
|
|
149
|
+
output.write(`Authority metadata: ${localProbe.authorityMetadataPath}\n`);
|
|
150
|
+
}
|
|
151
|
+
if (localProbe.authorityHealthPath) {
|
|
152
|
+
output.write(`Authority health: ${localProbe.authorityHealthPath}\n`);
|
|
153
|
+
}
|
|
98
154
|
if (!localProbe.ok && localProbe.error) {
|
|
99
155
|
output.write(`DB error: ${localProbe.error}\n`);
|
|
100
156
|
}
|
package/cli/tableCommands.ts
CHANGED
|
@@ -80,7 +80,7 @@ function resolveServerUrl(args: string[], env: EnvLike): string {
|
|
|
80
80
|
|
|
81
81
|
function resolveAuthToken(args: string[], env: EnvLike): string {
|
|
82
82
|
return (
|
|
83
|
-
readOption(args, "--
|
|
83
|
+
readOption(args, "--machine-key") ||
|
|
84
84
|
readOption(args, "--token") ||
|
|
85
85
|
env.AUTH_TOKEN ||
|
|
86
86
|
env.AUTH ||
|
package/cli/taskRunCommand.ts
CHANGED
|
@@ -82,7 +82,7 @@ function resolveServerUrl(args: string[], env: EnvLike) {
|
|
|
82
82
|
|
|
83
83
|
function resolveAuthToken(args: string[], env: EnvLike) {
|
|
84
84
|
return (
|
|
85
|
-
readOption(args, "--
|
|
85
|
+
readOption(args, "--machine-key") ||
|
|
86
86
|
readOption(args, "--token") ||
|
|
87
87
|
env.NOLO_TASK_RUN_TOKEN ||
|
|
88
88
|
env.NOLO_MACHINE_API_KEY ||
|
package/cliCommandDispatch.ts
CHANGED
|
@@ -31,7 +31,7 @@ function readOption(args: string[], flag: string) {
|
|
|
31
31
|
|
|
32
32
|
function buildDaemonEnv(args: string[], runtimeEnv: NodeJS.ProcessEnv) {
|
|
33
33
|
const serverUrl = readOption(args, "--server-url") || readOption(args, "--server");
|
|
34
|
-
const apiKey = readOption(args, "--
|
|
34
|
+
const apiKey = readOption(args, "--machine-key") || readOption(args, "--token");
|
|
35
35
|
return {
|
|
36
36
|
...runtimeEnv,
|
|
37
37
|
...(serverUrl ? { NOLO_SERVER: serverUrl } : {}),
|
|
@@ -40,7 +40,7 @@ function buildDaemonEnv(args: string[], runtimeEnv: NodeJS.ProcessEnv) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export function looksLikeDaemonShortcut(args: string[]) {
|
|
43
|
-
return args.includes("--server-url") || args.includes("--
|
|
43
|
+
return args.includes("--server-url") || args.includes("--machine-key");
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export function createCliRuntimeContext(args: {
|
package/cliEnvHelpers.ts
CHANGED
|
@@ -3,19 +3,17 @@ import { NOLO_CLUSTER_SERVERS } from "./database/config";
|
|
|
3
3
|
|
|
4
4
|
export type EnvLike = Record<string, string | undefined>;
|
|
5
5
|
|
|
6
|
-
export function
|
|
6
|
+
export function resolveServerUrlFromEnv(env: EnvLike) {
|
|
7
7
|
return (env.NOLO_SERVER || env.BASE_URL || DEFAULT_NOLO_SERVER_URL).replace(/\/+$/, "");
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
...NOLO_CLUSTER_SERVERS,
|
|
18
|
-
];
|
|
10
|
+
type ResolverInput = string[] | EnvLike;
|
|
11
|
+
|
|
12
|
+
function isCliArgs(value: ResolverInput): value is string[] {
|
|
13
|
+
return Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function buildServerCandidates(values: Array<string | null | undefined>) {
|
|
19
17
|
return [...new Set(
|
|
20
18
|
values
|
|
21
19
|
.filter((value): value is string => typeof value === "string" && value.trim().length > 0)
|
|
@@ -23,8 +21,78 @@ export function resolveServerCandidates(env: EnvLike, preferred?: string | null)
|
|
|
23
21
|
)];
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
export function
|
|
27
|
-
|
|
24
|
+
export function resolveServerUrl(env: EnvLike): string;
|
|
25
|
+
export function resolveServerUrl(args: string[], env: EnvLike): string;
|
|
26
|
+
export function resolveServerUrl(input: ResolverInput, env?: EnvLike) {
|
|
27
|
+
if (isCliArgs(input)) {
|
|
28
|
+
const explicit =
|
|
29
|
+
readOption(input, "--server-url") ||
|
|
30
|
+
readOption(input, "--server");
|
|
31
|
+
return explicit?.replace(/\/+$/, "") || resolveServerUrlFromEnv(env ?? {});
|
|
32
|
+
}
|
|
33
|
+
return resolveServerUrlFromEnv(input);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resolveServerCandidates(env: EnvLike, preferred?: string | null): string[];
|
|
37
|
+
export function resolveServerCandidates(
|
|
38
|
+
args: string[],
|
|
39
|
+
env: EnvLike,
|
|
40
|
+
preferred?: string | null,
|
|
41
|
+
): string[];
|
|
42
|
+
export function resolveServerCandidates(
|
|
43
|
+
input: ResolverInput,
|
|
44
|
+
envOrPreferred?: EnvLike | string | null,
|
|
45
|
+
preferred?: string | null,
|
|
46
|
+
) {
|
|
47
|
+
if (isCliArgs(input)) {
|
|
48
|
+
const env = (envOrPreferred ?? {}) as EnvLike;
|
|
49
|
+
const explicitServer = resolveServerUrl(input, env);
|
|
50
|
+
return buildServerCandidates([
|
|
51
|
+
explicitServer,
|
|
52
|
+
preferred?.trim(),
|
|
53
|
+
env.NOLO_SERVER,
|
|
54
|
+
env.BASE_URL,
|
|
55
|
+
env.NOLO_SERVER_URL,
|
|
56
|
+
DEFAULT_NOLO_SERVER_URL,
|
|
57
|
+
...NOLO_CLUSTER_SERVERS,
|
|
58
|
+
]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const env = input;
|
|
62
|
+
return buildServerCandidates([
|
|
63
|
+
typeof envOrPreferred === "string" ? envOrPreferred.trim() : undefined,
|
|
64
|
+
env.NOLO_SERVER,
|
|
65
|
+
env.BASE_URL,
|
|
66
|
+
env.NOLO_SERVER_URL,
|
|
67
|
+
DEFAULT_NOLO_SERVER_URL,
|
|
68
|
+
...NOLO_CLUSTER_SERVERS,
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function resolveAuthTokenFromEnv(env: EnvLike, extraEnvKeys: string[] = []) {
|
|
73
|
+
for (const key of ["AUTH_TOKEN", "AUTH", ...extraEnvKeys]) {
|
|
74
|
+
const value = env[key];
|
|
75
|
+
if (typeof value === "string" && value.trim()) return value;
|
|
76
|
+
}
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function resolveAuthToken(env: EnvLike, extraEnvKeys?: string[]): string;
|
|
81
|
+
export function resolveAuthToken(args: string[], env: EnvLike, extraEnvKeys?: string[]): string;
|
|
82
|
+
export function resolveAuthToken(
|
|
83
|
+
input: ResolverInput,
|
|
84
|
+
envOrExtraEnvKeys?: EnvLike | string[],
|
|
85
|
+
extraEnvKeys: string[] = [],
|
|
86
|
+
) {
|
|
87
|
+
if (isCliArgs(input)) {
|
|
88
|
+
const env = (envOrExtraEnvKeys ?? {}) as EnvLike;
|
|
89
|
+
return (
|
|
90
|
+
readOption(input, "--token") ||
|
|
91
|
+
readOption(input, "--machine-key") ||
|
|
92
|
+
resolveAuthTokenFromEnv(env, extraEnvKeys)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return resolveAuthTokenFromEnv(input, (envOrExtraEnvKeys as string[] | undefined) ?? []);
|
|
28
96
|
}
|
|
29
97
|
|
|
30
98
|
export function parseUserIdFromAuthToken(token: string) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function normalizeSpaceIdInput(rawInput: string) {
|
|
2
|
+
const raw = rawInput.trim();
|
|
3
|
+
if (!raw) return "";
|
|
4
|
+
|
|
5
|
+
if (raw.startsWith("http://") || raw.startsWith("https://")) {
|
|
6
|
+
const url = new URL(raw);
|
|
7
|
+
const match = url.pathname.match(/^\/space\/([^/?#]+)/);
|
|
8
|
+
if (match?.[1]) return decodeURIComponent(match[1]);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return raw.startsWith("space-") ? raw.slice("space-".length) : raw;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildSpaceLookup(rawInput: string) {
|
|
15
|
+
const spaceId = normalizeSpaceIdInput(rawInput);
|
|
16
|
+
return {
|
|
17
|
+
spaceId,
|
|
18
|
+
spaceKey: spaceId.startsWith("space-") ? spaceId : `space-${spaceId}`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getSpaceContentKeys(spaceRecord: any): Set<string> {
|
|
23
|
+
const keys = new Set<string>();
|
|
24
|
+
const contents = spaceRecord?.contents;
|
|
25
|
+
if (!contents || typeof contents !== "object") return keys;
|
|
26
|
+
|
|
27
|
+
for (const [entryKey, value] of Object.entries(contents)) {
|
|
28
|
+
if (typeof entryKey === "string" && entryKey.trim()) {
|
|
29
|
+
keys.add(entryKey.trim());
|
|
30
|
+
}
|
|
31
|
+
if (value && typeof value === "object") {
|
|
32
|
+
const contentKey = (value as any).contentKey;
|
|
33
|
+
if (typeof contentKey === "string" && contentKey.trim()) {
|
|
34
|
+
keys.add(contentKey.trim());
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return keys;
|
|
39
|
+
}
|
package/client/agentRun.ts
CHANGED
|
@@ -778,6 +778,7 @@ async function runLocalAgentTurnForCli(
|
|
|
778
778
|
background: options.background,
|
|
779
779
|
noStream: options.noStream,
|
|
780
780
|
maxToolRounds: options.maxToolRounds,
|
|
781
|
+
...(typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : {}),
|
|
781
782
|
...(traceLocalTools || collectToolEvidence
|
|
782
783
|
? {
|
|
783
784
|
onToolEvent: (event) => {
|
|
@@ -11,15 +11,18 @@ describe("CLI local provider resolver", () => {
|
|
|
11
11
|
provider: "custom",
|
|
12
12
|
apiSource: "custom",
|
|
13
13
|
customProviderUrl: "https://provider.example/v1/chat/completions",
|
|
14
|
+
apiKey: "sk-agent-custom",
|
|
15
|
+
apiKeyHeader: "api-key",
|
|
14
16
|
},
|
|
15
17
|
env: {
|
|
16
|
-
OPENAI_API_KEY: "sk-env",
|
|
18
|
+
OPENAI_API_KEY: "sk-env-should-not-win",
|
|
17
19
|
NOLO_LOCAL_OPENAI_BASE_URL: "http://127.0.0.1:11434/v1",
|
|
18
20
|
},
|
|
19
21
|
})).toEqual({
|
|
20
22
|
model: "qwen-coder",
|
|
21
23
|
endpoint: "https://provider.example/v1/chat/completions",
|
|
22
|
-
apiKey: "sk-
|
|
24
|
+
apiKey: "sk-agent-custom",
|
|
25
|
+
apiKeyHeader: "api-key",
|
|
23
26
|
provider: "custom",
|
|
24
27
|
requestOptions: {},
|
|
25
28
|
});
|
|
@@ -53,6 +56,27 @@ describe("CLI local provider resolver", () => {
|
|
|
53
56
|
});
|
|
54
57
|
});
|
|
55
58
|
|
|
59
|
+
test("defaults Xiaomi custom endpoints to api-key auth header", () => {
|
|
60
|
+
expect(resolveCliOpenAiProviderConfig({
|
|
61
|
+
agentConfig: {
|
|
62
|
+
key: "agent-user-1-mimo",
|
|
63
|
+
provider: "custom",
|
|
64
|
+
apiSource: "custom",
|
|
65
|
+
model: "mimo-v2.5-pro",
|
|
66
|
+
customProviderUrl: "https://token-plan-cn.xiaomimimo.com/v1",
|
|
67
|
+
apiKey: "mimo-monthly-key",
|
|
68
|
+
},
|
|
69
|
+
env: {},
|
|
70
|
+
})).toEqual({
|
|
71
|
+
model: "mimo-v2.5-pro",
|
|
72
|
+
endpoint: "https://token-plan-cn.xiaomimimo.com/v1/chat/completions",
|
|
73
|
+
apiKey: "mimo-monthly-key",
|
|
74
|
+
apiKeyHeader: "api-key",
|
|
75
|
+
provider: "custom",
|
|
76
|
+
requestOptions: {},
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
56
80
|
test("carries explicit agent inference options for request body construction", () => {
|
|
57
81
|
expect(resolveCliOpenAiProviderConfig({
|
|
58
82
|
agentConfig: {
|