nolo-cli 0.1.19 → 0.1.21

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.
Files changed (111) hide show
  1. package/README.md +9 -1
  2. package/agent-runtime/agentConfigOptions.ts +12 -0
  3. package/agent-runtime/agentRecordConfig.ts +99 -0
  4. package/agent-runtime/agentRecordKeys.ts +14 -0
  5. package/agent-runtime/dialogMessageRecord.ts +16 -0
  6. package/agent-runtime/dialogWritePlan.ts +130 -0
  7. package/agent-runtime/hostAdapter.ts +13 -0
  8. package/agent-runtime/hybridRecordStore.ts +147 -0
  9. package/agent-runtime/index.ts +69 -0
  10. package/agent-runtime/localLoop.ts +69 -5
  11. package/agent-runtime/localToolPolicy.ts +130 -0
  12. package/agent-runtime/localWorkspaceTools.ts +1532 -0
  13. package/agent-runtime/openAiCompatibleProvider.ts +70 -0
  14. package/agent-runtime/openAiCompatibleProviderConfig.ts +38 -0
  15. package/agent-runtime/platformChatProvider.ts +241 -0
  16. package/agent-runtime/taskWorkspace.ts +193 -0
  17. package/agent-runtime/types.ts +1 -0
  18. package/agent-runtime/workspaceSession.ts +76 -0
  19. package/agentAliases.ts +37 -0
  20. package/agentPullCommand.ts +1 -1
  21. package/agentRunCommand.ts +278 -52
  22. package/agentRuntimeCommands.ts +354 -164
  23. package/agentRuntimeLocal.ts +38 -0
  24. package/ai/agent/agentSlice.ts +10 -0
  25. package/ai/agent/buildEditingContext.ts +5 -0
  26. package/ai/agent/buildSystemPrompt.ts +41 -18
  27. package/ai/agent/canvasEditingContext.ts +49 -0
  28. package/ai/agent/cliExecutor.ts +15 -4
  29. package/ai/agent/createAgentSchema.ts +2 -0
  30. package/ai/agent/executeToolCall.ts +3 -2
  31. package/ai/agent/hooks/usePublicAgents.ts +6 -0
  32. package/ai/agent/pageBuilderHandoffRules.ts +75 -0
  33. package/ai/agent/runAgentClientLoop.ts +4 -1
  34. package/ai/agent/runtimeGuidance.ts +19 -0
  35. package/ai/agent/server/fetchPublicAgents.ts +51 -1
  36. package/ai/agent/streamAgentChatTurn.ts +20 -2
  37. package/ai/agent/streamAgentChatTurnUtils.ts +60 -16
  38. package/ai/chat/accumulateToolCallChunks.ts +40 -9
  39. package/ai/chat/parseApiError.ts +3 -0
  40. package/ai/chat/sendOpenAICompletionsRequest.native.ts +23 -10
  41. package/ai/chat/sendOpenAICompletionsRequest.ts +13 -1
  42. package/ai/chat/updateTotalUsage.ts +26 -9
  43. package/ai/llm/deepinfra.ts +51 -0
  44. package/ai/llm/getPricing.ts +6 -0
  45. package/ai/llm/kimi.ts +2 -0
  46. package/ai/llm/openrouterModels.ts +0 -135
  47. package/ai/llm/providers.ts +1 -0
  48. package/ai/llm/types.ts +8 -0
  49. package/ai/taskRun/taskRunProtocol.ts +882 -0
  50. package/ai/token/calculatePrice.ts +30 -0
  51. package/ai/token/externalToolCost.ts +49 -29
  52. package/ai/token/prepareTokenUsageData.ts +6 -1
  53. package/ai/token/serverTokenWriter.ts +4 -2
  54. package/ai/tools/agent/agentTools.ts +21 -0
  55. package/ai/tools/agent/presets/appBuilderPreset.ts +7 -0
  56. package/ai/tools/agent/streamParallelAgentsTool.ts +2 -1
  57. package/ai/tools/agent/taskRunTool.ts +112 -0
  58. package/ai/tools/applyEditTool.ts +6 -3
  59. package/ai/tools/applyLineEditsTool.ts +6 -3
  60. package/ai/tools/checkEnvTool.ts +14 -9
  61. package/ai/tools/codeSearchTool.ts +17 -5
  62. package/ai/tools/execBashTool.ts +33 -29
  63. package/ai/tools/fetchWebpageSupport.ts +24 -0
  64. package/ai/tools/fetchWebpageTool.ts +18 -5
  65. package/ai/tools/index.ts +158 -0
  66. package/ai/tools/jdProductScraperTool.ts +821 -0
  67. package/ai/tools/listFilesTool.ts +6 -3
  68. package/ai/tools/localFilesTool.ts +200 -0
  69. package/ai/tools/readFileTool.ts +6 -3
  70. package/ai/tools/searchRepoTool.ts +6 -3
  71. package/ai/tools/table/rowTools.ts +6 -1
  72. package/ai/tools/taobaoTmallProductScraperTool.ts +49 -0
  73. package/ai/tools/toolApiClient.ts +20 -6
  74. package/ai/tools/wereadGatewayTool.ts +152 -0
  75. package/ai/tools/writeFileTool.ts +6 -3
  76. package/client/agentConfigResolver.test.ts +70 -0
  77. package/client/agentConfigResolver.ts +1 -0
  78. package/client/agentRun.test.ts +430 -7
  79. package/client/agentRun.ts +504 -64
  80. package/client/hybridRecordStore.test.ts +115 -0
  81. package/client/hybridRecordStore.ts +41 -0
  82. package/client/localAgentRecords.test.ts +27 -0
  83. package/client/localAgentRecords.ts +7 -0
  84. package/client/localDialogRecords.test.ts +124 -0
  85. package/client/localDialogRecords.ts +30 -0
  86. package/client/localProviderResolver.test.ts +78 -0
  87. package/client/localProviderResolver.ts +1 -0
  88. package/client/localRuntimeAdapter.test.ts +621 -9
  89. package/client/localRuntimeAdapter.ts +275 -250
  90. package/client/localRuntimeDryRun.test.ts +116 -0
  91. package/client/localToolPolicy.ts +8 -81
  92. package/client/taskRunPrompt.ts +26 -0
  93. package/client/taskWorktree.ts +8 -0
  94. package/client/workspaceSession.test.ts +57 -0
  95. package/client/workspaceSession.ts +11 -0
  96. package/commandRegistry.ts +23 -6
  97. package/connectorRunArtifact.ts +121 -0
  98. package/database/actions/write.ts +16 -2
  99. package/database/hooks/useUserData.ts +9 -3
  100. package/database/server/dataHandlers.ts +18 -20
  101. package/database/server/emailRepository.ts +3 -3
  102. package/database/server/patch.ts +18 -10
  103. package/database/server/query.ts +43 -4
  104. package/database/server/read.ts +24 -38
  105. package/database/server/recordIdentity.ts +100 -0
  106. package/database/server/write.ts +21 -25
  107. package/index.ts +70 -33
  108. package/machineCommands.ts +318 -144
  109. package/package.json +4 -1
  110. package/tableCommands.ts +181 -0
  111. package/taskRunCommand.ts +265 -0
@@ -0,0 +1,115 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ createCliHybridRecordStore,
5
+ shouldCacheRemoteRecord,
6
+ } from "./hybridRecordStore";
7
+
8
+ function createMemoryDb(initial: Record<string, any> = {}) {
9
+ const store = new Map(Object.entries(initial));
10
+ return {
11
+ store,
12
+ db: {
13
+ get: async (key: string) => {
14
+ if (!store.has(key)) throw new Error(`not found: ${key}`);
15
+ return store.get(key);
16
+ },
17
+ put: async (key: string, value: any) => {
18
+ store.set(key, value);
19
+ },
20
+ batch: async (ops: Array<{ type: "put"; key: string; value: any }>) => {
21
+ for (const op of ops) {
22
+ if (op.type === "put") store.set(op.key, op.value);
23
+ }
24
+ },
25
+ iterator: ({ gte, lte }: { gte: string; lte?: string }) => (async function* () {
26
+ for (const entry of [...store.entries()].sort(([a], [b]) => a.localeCompare(b))) {
27
+ if (entry[0] >= gte && (!lte || entry[0] <= lte)) yield entry;
28
+ }
29
+ })(),
30
+ },
31
+ };
32
+ }
33
+
34
+ describe("CLI hybrid record store", () => {
35
+ test("returns a local record without requiring a server", async () => {
36
+ const { db } = createMemoryDb({
37
+ "agent-user-1-a": { dbKey: "agent-user-1-a", name: "local" },
38
+ });
39
+ const store = createCliHybridRecordStore({
40
+ db,
41
+ env: {},
42
+ fetchImpl: async () => {
43
+ throw new Error("network should not be used for local hits");
44
+ },
45
+ });
46
+
47
+ await expect(store.read("agent-user-1-a")).resolves.toMatchObject({
48
+ name: "local",
49
+ });
50
+ });
51
+
52
+ test("reads through to the configured server on local miss and caches the record with serverOrigin", async () => {
53
+ const { db, store: memory } = createMemoryDb();
54
+ const requests: Array<{ url: string; auth: string | null }> = [];
55
+ const hybrid = createCliHybridRecordStore({
56
+ db,
57
+ env: {
58
+ NOLO_SERVER: "https://us.nolo.chat/",
59
+ AUTH_TOKEN: "token-1",
60
+ },
61
+ fetchImpl: async (url, init) => {
62
+ requests.push({
63
+ url: String(url),
64
+ auth: new Headers(init?.headers).get("Authorization"),
65
+ });
66
+ return Response.json({
67
+ data: {
68
+ dbKey: "agent-user-1-remote",
69
+ name: "remote",
70
+ updatedAt: "2026-05-13T00:00:00.000Z",
71
+ },
72
+ });
73
+ },
74
+ });
75
+
76
+ await expect(hybrid.read("agent-user-1-remote")).resolves.toMatchObject({
77
+ name: "remote",
78
+ serverOrigin: "https://us.nolo.chat",
79
+ });
80
+ expect(requests).toEqual([{
81
+ url: "https://us.nolo.chat/api/v1/db/read/agent-user-1-remote",
82
+ auth: "Bearer token-1",
83
+ }]);
84
+ expect(memory.get("agent-user-1-remote")).toMatchObject({
85
+ name: "remote",
86
+ serverOrigin: "https://us.nolo.chat",
87
+ });
88
+ });
89
+
90
+ test("keeps newer local records over stale remote records", () => {
91
+ expect(shouldCacheRemoteRecord(
92
+ { updatedAt: "2026-05-12T00:00:00.000Z" },
93
+ { updatedAt: "2026-05-13T00:00:00.000Z" }
94
+ )).toBe(false);
95
+ expect(shouldCacheRemoteRecord(
96
+ { updatedAt: "2026-05-14T00:00:00.000Z" },
97
+ { updatedAt: "2026-05-13T00:00:00.000Z" }
98
+ )).toBe(true);
99
+ });
100
+
101
+ test("writes and batches through the same store interface used by runtime adapters", async () => {
102
+ const { db, store: memory } = createMemoryDb();
103
+ const hybrid = createCliHybridRecordStore({ db, env: {} });
104
+
105
+ await hybrid.write("dialog-user-1-a", { id: "a" });
106
+ await hybrid.batch([
107
+ { type: "put", key: "dialog-a-msg-001", value: { role: "user" } },
108
+ { type: "put", key: "dialog-a-msg-002", value: { role: "assistant" } },
109
+ ]);
110
+
111
+ expect(memory.get("dialog-user-1-a")).toEqual({ id: "a", dbKey: "dialog-user-1-a" });
112
+ expect(memory.get("dialog-a-msg-001")).toEqual({ role: "user", dbKey: "dialog-a-msg-001" });
113
+ expect(memory.get("dialog-a-msg-002")).toEqual({ role: "assistant", dbKey: "dialog-a-msg-002" });
114
+ });
115
+ });
@@ -0,0 +1,41 @@
1
+ import { DEFAULT_NOLO_SERVER_URL } from "../defaultServer";
2
+ import {
3
+ createHybridRecordStore,
4
+ shouldCacheHybridRemoteRecord,
5
+ type HybridRecordKvDb,
6
+ type HybridRecordStore,
7
+ } from "../agentRuntimeLocal";
8
+
9
+ type EnvLike = Record<string, string | undefined>;
10
+
11
+ export type CliKvDb = HybridRecordKvDb;
12
+ export type { HybridRecordStore };
13
+
14
+ type CliHybridRecordStoreDeps = {
15
+ db: CliKvDb;
16
+ env: EnvLike;
17
+ fetchImpl?: typeof fetch;
18
+ };
19
+
20
+ function normalizeServer(value: string) {
21
+ return value.trim().replace(/\/+$/, "");
22
+ }
23
+
24
+ function resolveAuthToken(env: EnvLike) {
25
+ return env.AUTH_TOKEN || env.AUTH || env.BENCHMARK_AUTH_TOKEN || "";
26
+ }
27
+
28
+ export function shouldCacheRemoteRecord(remoteRecord: any, localRecord: any) {
29
+ return shouldCacheHybridRemoteRecord(remoteRecord, localRecord);
30
+ }
31
+
32
+ export function createCliHybridRecordStore(
33
+ deps: CliHybridRecordStoreDeps
34
+ ): HybridRecordStore {
35
+ return createHybridRecordStore({
36
+ db: deps.db,
37
+ defaultServer: normalizeServer(deps.env.NOLO_SERVER || deps.env.BASE_URL || DEFAULT_NOLO_SERVER_URL),
38
+ authToken: resolveAuthToken(deps.env),
39
+ fetchImpl: deps.fetchImpl,
40
+ });
41
+ }
@@ -0,0 +1,27 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ buildLocalAgentLookupKeys,
5
+ shouldReadAgentKeyRemotely,
6
+ } from "./localAgentRecords";
7
+
8
+ describe("CLI local agent records", () => {
9
+ test("builds explicit and user-scoped agent lookup keys in order", () => {
10
+ expect(buildLocalAgentLookupKeys({
11
+ agentRef: "frontend",
12
+ userId: "user-1",
13
+ })).toEqual([
14
+ "frontend",
15
+ "agent-user-1-frontend",
16
+ "cybot-user-1-frontend",
17
+ ]);
18
+ });
19
+
20
+ test("only remote reads concrete agent or cybot keys", () => {
21
+ expect(shouldReadAgentKeyRemotely("agent-user-1-frontend")).toBe(true);
22
+ expect(shouldReadAgentKeyRemotely("agent-pub-01ABC")).toBe(true);
23
+ expect(shouldReadAgentKeyRemotely("cybot-user-1-frontend")).toBe(true);
24
+ expect(shouldReadAgentKeyRemotely("frontend")).toBe(false);
25
+ expect(shouldReadAgentKeyRemotely("dialog-user-1-frontend")).toBe(false);
26
+ });
27
+ });
@@ -0,0 +1,7 @@
1
+ import {
2
+ buildAgentRuntimeAgentLookupKeys,
3
+ shouldFetchAgentRuntimeRecordRemotely,
4
+ } from "../agentRuntimeLocal";
5
+
6
+ export const buildLocalAgentLookupKeys = buildAgentRuntimeAgentLookupKeys;
7
+ export const shouldReadAgentKeyRemotely = shouldFetchAgentRuntimeRecordRemotely;
@@ -0,0 +1,124 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ buildLocalDialogWritePlan,
5
+ localDialogMessageRecordToRuntimeMessage,
6
+ } from "./localDialogRecords";
7
+
8
+ describe("CLI local dialog records", () => {
9
+ test("converts persisted dialog message records into runtime messages", () => {
10
+ expect(localDialogMessageRecordToRuntimeMessage({
11
+ role: "assistant",
12
+ content: "previous answer",
13
+ tool_calls: [{ id: "call-1", type: "function" }],
14
+ })).toEqual({
15
+ role: "assistant",
16
+ content: "previous answer",
17
+ tool_calls: [{ id: "call-1", type: "function" }],
18
+ });
19
+
20
+ expect(localDialogMessageRecordToRuntimeMessage({
21
+ role: "tool",
22
+ content: "file contents",
23
+ toolCallId: "call-1",
24
+ })).toEqual({
25
+ role: "tool",
26
+ content: "file contents",
27
+ tool_call_id: "call-1",
28
+ });
29
+
30
+ expect(localDialogMessageRecordToRuntimeMessage({ role: "system", content: "skip" })).toBeNull();
31
+ expect(localDialogMessageRecordToRuntimeMessage({ role: "unknown", content: "skip" })).toBeNull();
32
+ });
33
+
34
+ test("builds dialog meta and message write ops for a local turn", () => {
35
+ const plan = buildLocalDialogWritePlan({
36
+ input: {
37
+ agentKey: "agent-user-1-frontend",
38
+ messages: [
39
+ { role: "system", content: "System prompt" },
40
+ { role: "user", content: "make it cleaner" },
41
+ { role: "assistant", content: "done" },
42
+ ],
43
+ result: {
44
+ content: "done",
45
+ model: "custom-coder",
46
+ provider: "custom",
47
+ usage: { prompt_tokens: 4, completion_tokens: 3 },
48
+ toolCallCount: 1,
49
+ },
50
+ },
51
+ userId: "user-1",
52
+ now: 1710000000000,
53
+ createId: () => "01LOCAL",
54
+ cwd: "/repo/.worktrees/task",
55
+ });
56
+
57
+ expect(plan.dialogId).toBe("01LOCAL");
58
+ expect(plan.ops.map((op) => op.key)).toEqual([
59
+ "dialog-user-1-01LOCAL",
60
+ "dialog-01LOCAL-msg-1710000000000-001",
61
+ "dialog-01LOCAL-msg-1710000000000-002",
62
+ ]);
63
+ expect(plan.ops[0]?.value).toMatchObject({
64
+ id: "01LOCAL",
65
+ dbKey: "dialog-user-1-01LOCAL",
66
+ type: "dialog",
67
+ userId: "user-1",
68
+ cybots: ["agent-user-1-frontend"],
69
+ primaryAgentKey: "agent-user-1-frontend",
70
+ title: "make it cleaner",
71
+ status: "done",
72
+ triggerType: "cli-local",
73
+ executionMode: "foreground",
74
+ createdAt: "2024-03-09T16:00:00.000Z",
75
+ updatedAt: "2024-03-09T16:00:00.000Z",
76
+ finishedAt: 1710000000000,
77
+ usage: { prompt_tokens: 4, completion_tokens: 3 },
78
+ toolCallCount: 1,
79
+ localRuntime: {
80
+ host: "cli",
81
+ worktreePath: "/repo/.worktrees/task",
82
+ },
83
+ });
84
+ expect(plan.ops[1]?.value).toMatchObject({
85
+ id: "1710000000000-001",
86
+ dbKey: "dialog-01LOCAL-msg-1710000000000-001",
87
+ dialogId: "01LOCAL",
88
+ role: "user",
89
+ content: "make it cleaner",
90
+ userId: "user-1",
91
+ });
92
+ expect(plan.ops[2]?.value).toMatchObject({
93
+ role: "assistant",
94
+ content: "done",
95
+ agentKey: "agent-user-1-frontend",
96
+ cybotKey: "agent-user-1-frontend",
97
+ });
98
+ });
99
+
100
+ test("preserves existing dialog title and createdAt when continuing", () => {
101
+ const plan = buildLocalDialogWritePlan({
102
+ input: {
103
+ agentKey: "agent-user-1-frontend",
104
+ continueDialogId: "dialog-existing",
105
+ messages: [{ role: "user", content: "new task" }],
106
+ result: { content: "ok", model: "gpt-4.1-mini", provider: "openai" },
107
+ },
108
+ existingDialog: {
109
+ title: "Existing title",
110
+ createdAt: "2024-01-01T00:00:00.000Z",
111
+ },
112
+ userId: "user-1",
113
+ now: 1710000000000,
114
+ createId: () => "unused",
115
+ });
116
+
117
+ expect(plan.dialogId).toBe("dialog-existing");
118
+ expect(plan.ops[0]?.value).toMatchObject({
119
+ title: "Existing title",
120
+ createdAt: "2024-01-01T00:00:00.000Z",
121
+ updatedAt: "2024-03-09T16:00:00.000Z",
122
+ });
123
+ });
124
+ });
@@ -0,0 +1,30 @@
1
+ import {
2
+ buildAgentRuntimeDialogWritePlan,
3
+ dialogMessageRecordToAgentRuntimeMessage,
4
+ type AgentRuntimeSaveTurnInput,
5
+ } from "../agentRuntimeLocal";
6
+
7
+ type LocalDialogRecord = Record<string, any>;
8
+
9
+ export const localDialogMessageRecordToRuntimeMessage = dialogMessageRecordToAgentRuntimeMessage;
10
+
11
+ export function buildLocalDialogWritePlan(args: {
12
+ input: AgentRuntimeSaveTurnInput;
13
+ userId: string;
14
+ now: number;
15
+ createId: () => string;
16
+ existingDialog?: LocalDialogRecord | null;
17
+ cwd?: string;
18
+ }) {
19
+ return buildAgentRuntimeDialogWritePlan({
20
+ input: args.input,
21
+ userId: args.userId,
22
+ now: args.now,
23
+ createId: args.createId,
24
+ existingDialog: args.existingDialog,
25
+ runtimeHost: "cli",
26
+ runtimeMetadata: {
27
+ ...(args.cwd ? { worktreePath: args.cwd } : {}),
28
+ },
29
+ });
30
+ }
@@ -0,0 +1,78 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { resolveCliOpenAiProviderConfig } from "./localProviderResolver";
4
+
5
+ describe("CLI local provider resolver", () => {
6
+ test("uses agent customProviderUrl as the OpenAI-compatible chat completions endpoint", () => {
7
+ expect(resolveCliOpenAiProviderConfig({
8
+ agentConfig: {
9
+ key: "agent-user-1-custom",
10
+ model: "qwen-coder",
11
+ provider: "custom",
12
+ apiSource: "custom",
13
+ customProviderUrl: "https://provider.example/v1/chat/completions",
14
+ },
15
+ env: {
16
+ OPENAI_API_KEY: "sk-env",
17
+ NOLO_LOCAL_OPENAI_BASE_URL: "http://127.0.0.1:11434/v1",
18
+ },
19
+ })).toEqual({
20
+ model: "qwen-coder",
21
+ endpoint: "https://provider.example/v1/chat/completions",
22
+ apiKey: "sk-env",
23
+ provider: "custom",
24
+ requestOptions: {},
25
+ });
26
+ });
27
+
28
+ test("appends chat completions to custom provider base urls", () => {
29
+ expect(resolveCliOpenAiProviderConfig({
30
+ agentConfig: {
31
+ key: "agent-user-1-custom",
32
+ customProviderUrl: "https://provider.example/v1/",
33
+ },
34
+ env: {},
35
+ }).endpoint).toBe("https://provider.example/v1/chat/completions");
36
+ });
37
+
38
+ test("falls back to the env OpenAI-compatible base url", () => {
39
+ expect(resolveCliOpenAiProviderConfig({
40
+ agentConfig: {
41
+ key: "agent-user-1-openai",
42
+ },
43
+ env: {
44
+ NOLO_LOCAL_OPENAI_BASE_URL: "http://127.0.0.1:11434/v1/",
45
+ NOLO_LOCAL_OPENAI_API_KEY: "sk-local",
46
+ },
47
+ })).toEqual({
48
+ model: "gpt-4.1-mini",
49
+ endpoint: "http://127.0.0.1:11434/v1/chat/completions",
50
+ apiKey: "sk-local",
51
+ provider: "openai-compatible",
52
+ requestOptions: {},
53
+ });
54
+ });
55
+
56
+ test("carries explicit agent inference options for request body construction", () => {
57
+ expect(resolveCliOpenAiProviderConfig({
58
+ agentConfig: {
59
+ key: "agent-user-1-tuned",
60
+ temperature: 0.2,
61
+ top_p: 0.9,
62
+ frequency_penalty: 0.1,
63
+ presence_penalty: 0.3,
64
+ max_tokens: 4096,
65
+ reasoning_effort: "medium",
66
+ },
67
+ env: {},
68
+ }).requestOptions).toEqual({
69
+ temperature: 0.2,
70
+ top_p: 0.9,
71
+ frequency_penalty: 0.1,
72
+ presence_penalty: 0.3,
73
+ max_tokens: 4096,
74
+ reasoning_effort: "medium",
75
+ });
76
+ });
77
+
78
+ });
@@ -0,0 +1 @@
1
+ export { resolveOpenAiCompatibleProviderConfig as resolveCliOpenAiProviderConfig } from "../agentRuntimeLocal";