@lobehub/lobehub 2.0.0-next.312 → 2.0.0-next.313
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/CHANGELOG.md +26 -0
- package/apps/desktop/src/main/controllers/AuthCtr.ts +75 -7
- package/changelog/v1.json +9 -0
- package/docs/usage/providers/internlm.mdx +2 -2
- package/docs/usage/providers/internlm.zh-CN.mdx +3 -3
- package/locales/en-US/error.json +10 -1
- package/locales/en-US/subscription.json +1 -1
- package/locales/zh-CN/desktop-onboarding.json +5 -0
- package/locales/zh-CN/error.json +10 -1
- package/locales/zh-CN/subscription.json +1 -1
- package/package.json +1 -1
- package/packages/agent-runtime/src/agents/GeneralChatAgent.ts +14 -2
- package/packages/agent-runtime/src/agents/__tests__/GeneralChatAgent.test.ts +275 -1
- package/packages/builtin-tool-cloud-sandbox/package.json +1 -0
- package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +105 -134
- package/packages/builtin-tool-cloud-sandbox/src/executor/index.ts +254 -0
- package/packages/builtin-tool-cloud-sandbox/src/index.ts +1 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/api.ts +22 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/index.ts +4 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/params.ts +85 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/service.ts +48 -0
- package/packages/builtin-tool-cloud-sandbox/src/{types.ts → types/state.ts} +0 -23
- package/packages/builtin-tool-memory/src/manifest.ts +5 -5
- package/packages/editor-runtime/src/__tests__/EditorRuntime.real.test.ts +1 -1
- package/packages/editor-runtime/src/__tests__/EditorRuntime.test.ts +1 -1
- package/packages/electron-client-ipc/src/events/index.ts +5 -1
- package/packages/electron-client-ipc/src/events/remoteServer.ts +23 -0
- package/packages/memory-user-memory/src/schemas/index.ts +0 -1
- package/packages/model-bank/src/modelProviders/internlm.ts +1 -1
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +5 -15
- package/packages/model-runtime/src/providers/internlm/index.test.ts +15 -15
- package/packages/model-runtime/src/providers/internlm/index.ts +1 -1
- package/packages/types/src/tool/intervention.ts +4 -2
- package/packages/types/src/user/preference.ts +1 -0
- package/src/app/[variants]/(desktop)/desktop-onboarding/features/LoginStep.tsx +84 -26
- package/src/app/[variants]/(main)/_layout/DesktopAutoOidcOnFirstOpen.tsx +4 -0
- package/src/business/server/user.ts +4 -0
- package/src/features/Conversation/Messages/Task/Actions/index.tsx +0 -2
- package/src/features/Conversation/Messages/Task/index.tsx +1 -1
- package/src/features/Conversation/Messages/Tasks/shared/ProcessingState.tsx +0 -2
- package/src/features/NavPanel/components/NavPanelDraggable.tsx +0 -14
- package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +4 -3
- package/src/features/SharePopover/index.tsx +5 -3
- package/src/hooks/useAppOrigin.ts +16 -0
- package/src/layout/GlobalProvider/useUserStateRedirect.ts +37 -24
- package/src/libs/trusted-client/index.ts +2 -5
- package/src/locales/default/desktop-onboarding.ts +5 -0
- package/src/locales/default/error.ts +11 -0
- package/src/locales/default/subscription.ts +1 -1
- package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +2 -0
- package/src/server/routers/lambda/user.ts +24 -10
- package/src/server/services/agentRuntime/AgentRuntimeService.test.ts +3 -0
- package/src/server/services/agentRuntime/AgentRuntimeService.ts +8 -5
- package/src/server/services/agentRuntime/types.ts +7 -0
- package/src/server/services/aiAgent/__tests__/execGroupSubAgentTask.test.ts +3 -0
- package/src/server/services/aiAgent/index.ts +10 -4
- package/src/server/services/market/index.ts +7 -0
- package/src/server/services/sandbox/index.ts +120 -0
- package/src/server/services/toolExecution/builtin.ts +12 -18
- package/src/server/services/toolExecution/index.ts +1 -1
- package/src/server/services/toolExecution/serverRuntimes/cloudSandbox.ts +31 -0
- package/src/server/services/toolExecution/serverRuntimes/index.ts +55 -0
- package/src/server/services/toolExecution/serverRuntimes/types.ts +14 -0
- package/src/server/services/toolExecution/serverRuntimes/webBrowsing.ts +20 -0
- package/src/server/services/toolExecution/types.ts +2 -0
- package/src/services/{codeInterpreter.ts → cloudSandbox.ts} +3 -3
- package/src/services/electron/remoteServer.ts +8 -0
- package/src/store/chat/agents/GroupOrchestration/__tests__/batch-exec-async-tasks.test.ts +626 -0
- package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +294 -0
- package/src/store/chat/slices/plugin/action.test.ts +0 -48
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +0 -131
- package/src/store/tool/slices/builtin/executors/index.ts +2 -0
- package/src/store/user/slices/settings/selectors/toolIntervention.test.ts +143 -0
- package/src/store/user/slices/settings/selectors/toolIntervention.ts +11 -2
- package/packages/memory-user-memory/src/schemas/jsonSchemas.ts +0 -37
|
@@ -1,125 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatEditResult,
|
|
3
|
+
formatFileContent,
|
|
4
|
+
formatFileList,
|
|
5
|
+
formatFileSearchResults,
|
|
6
|
+
formatGlobResults,
|
|
7
|
+
formatMoveResults,
|
|
8
|
+
formatRenameResult,
|
|
9
|
+
formatWriteResult,
|
|
10
|
+
} from '@lobechat/prompts';
|
|
1
11
|
import { type BuiltinServerRuntimeOutput } from '@lobechat/types';
|
|
2
12
|
|
|
3
|
-
import { codeInterpreterService } from '@/services/codeInterpreter';
|
|
4
|
-
|
|
5
13
|
import {
|
|
14
|
+
type EditLocalFileParams,
|
|
6
15
|
type EditLocalFileState,
|
|
16
|
+
type ExecuteCodeParams,
|
|
7
17
|
type ExecuteCodeState,
|
|
18
|
+
type ExportFileParams,
|
|
8
19
|
type ExportFileState,
|
|
20
|
+
type GetCommandOutputParams,
|
|
9
21
|
type GetCommandOutputState,
|
|
10
22
|
type GlobFilesState,
|
|
23
|
+
type GlobLocalFilesParams,
|
|
24
|
+
type GrepContentParams,
|
|
11
25
|
type GrepContentState,
|
|
26
|
+
type ISandboxService,
|
|
27
|
+
type KillCommandParams,
|
|
12
28
|
type KillCommandState,
|
|
29
|
+
type ListLocalFilesParams,
|
|
13
30
|
type ListLocalFilesState,
|
|
31
|
+
type MoveLocalFilesParams,
|
|
14
32
|
type MoveLocalFilesState,
|
|
33
|
+
type ReadLocalFileParams,
|
|
15
34
|
type ReadLocalFileState,
|
|
35
|
+
type RenameLocalFileParams,
|
|
16
36
|
type RenameLocalFileState,
|
|
37
|
+
type RunCommandParams,
|
|
17
38
|
type RunCommandState,
|
|
39
|
+
type SearchLocalFilesParams,
|
|
18
40
|
type SearchLocalFilesState,
|
|
41
|
+
type WriteLocalFileParams,
|
|
19
42
|
type WriteLocalFileState,
|
|
20
43
|
} from '../types';
|
|
21
44
|
|
|
22
45
|
/**
|
|
23
46
|
* Cloud Sandbox Execution Runtime
|
|
24
47
|
*
|
|
25
|
-
* This runtime executes tools via the
|
|
26
|
-
*
|
|
48
|
+
* This runtime executes tools via the injected ISandboxService.
|
|
49
|
+
* The service handles context (topicId, userId) internally - Runtime doesn't need to know about it.
|
|
27
50
|
*
|
|
28
|
-
*
|
|
29
|
-
* -
|
|
30
|
-
* -
|
|
31
|
-
* - The sessionExpiredAndRecreated flag indicates if recreation occurred
|
|
51
|
+
* Dependency Injection:
|
|
52
|
+
* - Client: Inject codeInterpreterService (uses tRPC client)
|
|
53
|
+
* - Server: Inject ServerSandboxService (uses MarketSDK directly)
|
|
32
54
|
*/
|
|
33
|
-
|
|
34
|
-
interface ExecutionContext {
|
|
35
|
-
topicId: string;
|
|
36
|
-
userId: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Types for tool parameters matching market-sdk
|
|
40
|
-
interface ListLocalFilesParams {
|
|
41
|
-
directoryPath: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface ReadLocalFileParams {
|
|
45
|
-
endLine?: number;
|
|
46
|
-
path: string;
|
|
47
|
-
startLine?: number;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface WriteLocalFileParams {
|
|
51
|
-
content: string;
|
|
52
|
-
createDirectories?: boolean;
|
|
53
|
-
path: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
interface EditLocalFileParams {
|
|
57
|
-
all?: boolean;
|
|
58
|
-
path: string;
|
|
59
|
-
replace: string;
|
|
60
|
-
search: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
interface SearchLocalFilesParams {
|
|
64
|
-
directory: string;
|
|
65
|
-
fileType?: string;
|
|
66
|
-
keyword?: string;
|
|
67
|
-
modifiedAfter?: string;
|
|
68
|
-
modifiedBefore?: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface MoveLocalFilesParams {
|
|
72
|
-
operations: Array<{
|
|
73
|
-
destination: string;
|
|
74
|
-
source: string;
|
|
75
|
-
}>;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface RenameLocalFileParams {
|
|
79
|
-
newName: string;
|
|
80
|
-
oldPath: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
interface RunCommandParams {
|
|
84
|
-
background?: boolean;
|
|
85
|
-
command: string;
|
|
86
|
-
timeout?: number;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface GetCommandOutputParams {
|
|
90
|
-
commandId: string;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
interface KillCommandParams {
|
|
94
|
-
commandId: string;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
interface GrepContentParams {
|
|
98
|
-
directory: string;
|
|
99
|
-
filePattern?: string;
|
|
100
|
-
pattern: string;
|
|
101
|
-
recursive?: boolean;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
interface GlobLocalFilesParams {
|
|
105
|
-
directory?: string;
|
|
106
|
-
pattern: string;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
interface ExportFileParams {
|
|
110
|
-
path: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
interface ExecuteCodeParams {
|
|
114
|
-
code: string;
|
|
115
|
-
language?: 'javascript' | 'python' | 'typescript';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
55
|
export class CloudSandboxExecutionRuntime {
|
|
119
|
-
private
|
|
56
|
+
private sandboxService: ISandboxService;
|
|
120
57
|
|
|
121
|
-
constructor(
|
|
122
|
-
this.
|
|
58
|
+
constructor(sandboxService: ISandboxService) {
|
|
59
|
+
this.sandboxService = sandboxService;
|
|
123
60
|
}
|
|
124
61
|
|
|
125
62
|
// ==================== File Operations ====================
|
|
@@ -128,12 +65,19 @@ export class CloudSandboxExecutionRuntime {
|
|
|
128
65
|
try {
|
|
129
66
|
const result = await this.callTool('listLocalFiles', args);
|
|
130
67
|
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
68
|
+
const files = result.result?.files || [];
|
|
69
|
+
const state: ListLocalFilesState = { files };
|
|
70
|
+
|
|
71
|
+
const content = formatFileList(
|
|
72
|
+
files.map((f: { isDirectory: boolean; name: string }) => ({
|
|
73
|
+
isDirectory: f.isDirectory,
|
|
74
|
+
name: f.name,
|
|
75
|
+
})),
|
|
76
|
+
args.directoryPath,
|
|
77
|
+
);
|
|
134
78
|
|
|
135
79
|
return {
|
|
136
|
-
content
|
|
80
|
+
content,
|
|
137
81
|
state,
|
|
138
82
|
success: true,
|
|
139
83
|
};
|
|
@@ -154,8 +98,19 @@ export class CloudSandboxExecutionRuntime {
|
|
|
154
98
|
totalLines: result.result?.totalLines,
|
|
155
99
|
};
|
|
156
100
|
|
|
101
|
+
const lineRange: [number, number] | undefined =
|
|
102
|
+
args.startLine !== undefined && args.endLine !== undefined
|
|
103
|
+
? [args.startLine, args.endLine]
|
|
104
|
+
: undefined;
|
|
105
|
+
|
|
106
|
+
const content = formatFileContent({
|
|
107
|
+
content: result.result?.content || '',
|
|
108
|
+
lineRange,
|
|
109
|
+
path: args.path,
|
|
110
|
+
});
|
|
111
|
+
|
|
157
112
|
return {
|
|
158
|
-
content
|
|
113
|
+
content,
|
|
159
114
|
state,
|
|
160
115
|
success: true,
|
|
161
116
|
};
|
|
@@ -174,11 +129,13 @@ export class CloudSandboxExecutionRuntime {
|
|
|
174
129
|
success: result.success,
|
|
175
130
|
};
|
|
176
131
|
|
|
132
|
+
const content = formatWriteResult({
|
|
133
|
+
path: args.path,
|
|
134
|
+
success: true,
|
|
135
|
+
});
|
|
136
|
+
|
|
177
137
|
return {
|
|
178
|
-
content
|
|
179
|
-
message: `Successfully wrote to ${args.path}`,
|
|
180
|
-
success: true,
|
|
181
|
-
}),
|
|
138
|
+
content,
|
|
182
139
|
state,
|
|
183
140
|
success: true,
|
|
184
141
|
};
|
|
@@ -199,13 +156,15 @@ export class CloudSandboxExecutionRuntime {
|
|
|
199
156
|
replacements: result.result?.replacements || 0,
|
|
200
157
|
};
|
|
201
158
|
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
159
|
+
const content = formatEditResult({
|
|
160
|
+
filePath: args.path,
|
|
161
|
+
linesAdded: state.linesAdded,
|
|
162
|
+
linesDeleted: state.linesDeleted,
|
|
163
|
+
replacements: state.replacements,
|
|
164
|
+
});
|
|
206
165
|
|
|
207
166
|
return {
|
|
208
|
-
content
|
|
167
|
+
content,
|
|
209
168
|
state,
|
|
210
169
|
success: true,
|
|
211
170
|
};
|
|
@@ -218,13 +177,18 @@ export class CloudSandboxExecutionRuntime {
|
|
|
218
177
|
try {
|
|
219
178
|
const result = await this.callTool('searchLocalFiles', args);
|
|
220
179
|
|
|
180
|
+
const results = result.result?.results || [];
|
|
221
181
|
const state: SearchLocalFilesState = {
|
|
222
|
-
results
|
|
182
|
+
results,
|
|
223
183
|
totalCount: result.result?.totalCount || 0,
|
|
224
184
|
};
|
|
225
185
|
|
|
186
|
+
const content = formatFileSearchResults(
|
|
187
|
+
results.map((r: { path: string }) => ({ path: r.path })),
|
|
188
|
+
);
|
|
189
|
+
|
|
226
190
|
return {
|
|
227
|
-
content
|
|
191
|
+
content,
|
|
228
192
|
state,
|
|
229
193
|
success: true,
|
|
230
194
|
};
|
|
@@ -237,17 +201,17 @@ export class CloudSandboxExecutionRuntime {
|
|
|
237
201
|
try {
|
|
238
202
|
const result = await this.callTool('moveLocalFiles', args);
|
|
239
203
|
|
|
204
|
+
const results = result.result?.results || [];
|
|
240
205
|
const state: MoveLocalFilesState = {
|
|
241
|
-
results
|
|
206
|
+
results,
|
|
242
207
|
successCount: result.result?.successCount || 0,
|
|
243
208
|
totalCount: args.operations.length,
|
|
244
209
|
};
|
|
245
210
|
|
|
211
|
+
const content = formatMoveResults(results);
|
|
212
|
+
|
|
246
213
|
return {
|
|
247
|
-
content
|
|
248
|
-
message: `Moved ${state.successCount}/${state.totalCount} items`,
|
|
249
|
-
results: state.results,
|
|
250
|
-
}),
|
|
214
|
+
content,
|
|
251
215
|
state,
|
|
252
216
|
success: true,
|
|
253
217
|
};
|
|
@@ -267,11 +231,15 @@ export class CloudSandboxExecutionRuntime {
|
|
|
267
231
|
success: result.success,
|
|
268
232
|
};
|
|
269
233
|
|
|
234
|
+
const content = formatRenameResult({
|
|
235
|
+
error: result.result?.error,
|
|
236
|
+
newName: args.newName,
|
|
237
|
+
oldPath: args.oldPath,
|
|
238
|
+
success: result.success,
|
|
239
|
+
});
|
|
240
|
+
|
|
270
241
|
return {
|
|
271
|
-
content
|
|
272
|
-
message: `Successfully renamed ${args.oldPath} to ${args.newName}`,
|
|
273
|
-
success: true,
|
|
274
|
-
}),
|
|
242
|
+
content,
|
|
275
243
|
state,
|
|
276
244
|
success: result.success,
|
|
277
245
|
};
|
|
@@ -405,14 +373,22 @@ export class CloudSandboxExecutionRuntime {
|
|
|
405
373
|
try {
|
|
406
374
|
const result = await this.callTool('globLocalFiles', args);
|
|
407
375
|
|
|
376
|
+
const files = result.result?.files || [];
|
|
377
|
+
const totalCount = result.result?.totalCount || 0;
|
|
378
|
+
|
|
408
379
|
const state: GlobFilesState = {
|
|
409
|
-
files
|
|
380
|
+
files,
|
|
410
381
|
pattern: args.pattern,
|
|
411
|
-
totalCount
|
|
382
|
+
totalCount,
|
|
412
383
|
};
|
|
413
384
|
|
|
385
|
+
const content = formatGlobResults({
|
|
386
|
+
files,
|
|
387
|
+
totalFiles: totalCount,
|
|
388
|
+
});
|
|
389
|
+
|
|
414
390
|
return {
|
|
415
|
-
content
|
|
391
|
+
content,
|
|
416
392
|
state,
|
|
417
393
|
success: true,
|
|
418
394
|
};
|
|
@@ -425,7 +401,7 @@ export class CloudSandboxExecutionRuntime {
|
|
|
425
401
|
|
|
426
402
|
/**
|
|
427
403
|
* Export a file from the sandbox to cloud storage
|
|
428
|
-
* Uses a single
|
|
404
|
+
* Uses a single call that handles:
|
|
429
405
|
* 1. Generate pre-signed upload URL
|
|
430
406
|
* 2. Call sandbox to upload file
|
|
431
407
|
* 3. Create persistent file record
|
|
@@ -437,11 +413,7 @@ export class CloudSandboxExecutionRuntime {
|
|
|
437
413
|
const filename = args.path.split('/').pop() || 'exported_file';
|
|
438
414
|
|
|
439
415
|
// Single call that handles everything: upload URL generation, sandbox upload, and file record creation
|
|
440
|
-
const result = await
|
|
441
|
-
args.path,
|
|
442
|
-
filename,
|
|
443
|
-
this.context.topicId,
|
|
444
|
-
);
|
|
416
|
+
const result = await this.sandboxService.exportAndUploadFile(args.path, filename);
|
|
445
417
|
|
|
446
418
|
const state: ExportFileState = {
|
|
447
419
|
downloadUrl: result.success && result.url ? result.url : '',
|
|
@@ -478,17 +450,16 @@ export class CloudSandboxExecutionRuntime {
|
|
|
478
450
|
// ==================== Helper Methods ====================
|
|
479
451
|
|
|
480
452
|
/**
|
|
481
|
-
* Call a tool via the
|
|
482
|
-
* Routes through: ExecutionRuntime -> codeInterpreterService -> tRPC -> codeInterpreterRouter -> MarketSDK
|
|
453
|
+
* Call a tool via the injected sandbox service
|
|
483
454
|
*/
|
|
484
455
|
private async callTool(
|
|
485
456
|
toolName: string,
|
|
486
457
|
params: Record<string, any>,
|
|
487
458
|
): Promise<{ result: any; sessionExpiredAndRecreated?: boolean; success: boolean }> {
|
|
488
|
-
const result = await
|
|
459
|
+
const result = await this.sandboxService.callTool(toolName, params);
|
|
489
460
|
|
|
490
461
|
if (!result.success) {
|
|
491
|
-
throw new Error(
|
|
462
|
+
throw new Error(result.error?.message || `Cloud Sandbox tool ${toolName} failed`);
|
|
492
463
|
}
|
|
493
464
|
|
|
494
465
|
return result;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { BaseExecutor, type BuiltinToolContext, type BuiltinToolResult } from '@lobechat/types';
|
|
2
|
+
|
|
3
|
+
import { cloudSandboxService } from '@/services/cloudSandbox';
|
|
4
|
+
import { useUserStore } from '@/store/user';
|
|
5
|
+
import { userProfileSelectors } from '@/store/user/slices/auth/selectors';
|
|
6
|
+
|
|
7
|
+
import { CloudSandboxExecutionRuntime } from '../ExecutionRuntime';
|
|
8
|
+
import { CloudSandboxIdentifier } from '../manifest';
|
|
9
|
+
import {
|
|
10
|
+
CloudSandboxApiName,
|
|
11
|
+
type EditLocalFileParams,
|
|
12
|
+
type ExecuteCodeParams,
|
|
13
|
+
type ExportFileParams,
|
|
14
|
+
type GetCommandOutputParams,
|
|
15
|
+
type GlobLocalFilesParams,
|
|
16
|
+
type GrepContentParams,
|
|
17
|
+
type ISandboxService,
|
|
18
|
+
type KillCommandParams,
|
|
19
|
+
type ListLocalFilesParams,
|
|
20
|
+
type MoveLocalFilesParams,
|
|
21
|
+
type ReadLocalFileParams,
|
|
22
|
+
type RenameLocalFileParams,
|
|
23
|
+
type RunCommandParams,
|
|
24
|
+
type SandboxCallToolResult,
|
|
25
|
+
type SandboxExportFileResult,
|
|
26
|
+
type SearchLocalFilesParams,
|
|
27
|
+
type WriteLocalFileParams,
|
|
28
|
+
} from '../types';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Client-side Sandbox Service
|
|
32
|
+
* Wraps codeInterpreterService with bound context (topicId, userId)
|
|
33
|
+
*/
|
|
34
|
+
class ClientSandboxService implements ISandboxService {
|
|
35
|
+
private topicId: string;
|
|
36
|
+
private userId: string;
|
|
37
|
+
|
|
38
|
+
constructor(topicId: string) {
|
|
39
|
+
this.topicId = topicId;
|
|
40
|
+
// Get userId from user store - client-side auth
|
|
41
|
+
const userId = userProfileSelectors.userId(useUserStore.getState());
|
|
42
|
+
if (!userId) {
|
|
43
|
+
throw new Error('userId must be provided');
|
|
44
|
+
}
|
|
45
|
+
this.userId = userId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async callTool(toolName: string, params: Record<string, any>): Promise<SandboxCallToolResult> {
|
|
49
|
+
return cloudSandboxService.callTool(toolName, params, {
|
|
50
|
+
topicId: this.topicId,
|
|
51
|
+
userId: this.userId,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async exportAndUploadFile(path: string, filename: string): Promise<SandboxExportFileResult> {
|
|
56
|
+
return cloudSandboxService.exportAndUploadFile(path, filename, this.topicId);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Cloud Sandbox Client Executor
|
|
62
|
+
*
|
|
63
|
+
* This executor handles Cloud Sandbox tool calls on the client side.
|
|
64
|
+
* It creates a CloudSandboxExecutionRuntime with a ClientSandboxService
|
|
65
|
+
* that has topicId bound at construction time.
|
|
66
|
+
*/
|
|
67
|
+
class CloudSandboxExecutor extends BaseExecutor<typeof CloudSandboxApiName> {
|
|
68
|
+
readonly identifier = CloudSandboxIdentifier;
|
|
69
|
+
protected readonly apiEnum = CloudSandboxApiName;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get or create a runtime for the given context
|
|
73
|
+
*/
|
|
74
|
+
private getRuntime(ctx: BuiltinToolContext): CloudSandboxExecutionRuntime {
|
|
75
|
+
const topicId = ctx.topicId;
|
|
76
|
+
|
|
77
|
+
if (!topicId) {
|
|
78
|
+
throw new Error('Can not init runtime with empty topicId');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const service = new ClientSandboxService(topicId);
|
|
82
|
+
return new CloudSandboxExecutionRuntime(service);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ==================== File Operations ====================
|
|
86
|
+
|
|
87
|
+
listLocalFiles = async (
|
|
88
|
+
params: ListLocalFilesParams,
|
|
89
|
+
ctx: BuiltinToolContext,
|
|
90
|
+
): Promise<BuiltinToolResult> => {
|
|
91
|
+
const runtime = this.getRuntime(ctx);
|
|
92
|
+
const result = await runtime.listLocalFiles(params);
|
|
93
|
+
return this.toBuiltinResult(result);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
readLocalFile = async (
|
|
97
|
+
params: ReadLocalFileParams,
|
|
98
|
+
ctx: BuiltinToolContext,
|
|
99
|
+
): Promise<BuiltinToolResult> => {
|
|
100
|
+
const runtime = this.getRuntime(ctx);
|
|
101
|
+
const result = await runtime.readLocalFile(params);
|
|
102
|
+
return this.toBuiltinResult(result);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
writeLocalFile = async (
|
|
106
|
+
params: WriteLocalFileParams,
|
|
107
|
+
ctx: BuiltinToolContext,
|
|
108
|
+
): Promise<BuiltinToolResult> => {
|
|
109
|
+
const runtime = this.getRuntime(ctx);
|
|
110
|
+
const result = await runtime.writeLocalFile(params);
|
|
111
|
+
return this.toBuiltinResult(result);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
editLocalFile = async (
|
|
115
|
+
params: EditLocalFileParams,
|
|
116
|
+
ctx: BuiltinToolContext,
|
|
117
|
+
): Promise<BuiltinToolResult> => {
|
|
118
|
+
const runtime = this.getRuntime(ctx);
|
|
119
|
+
const result = await runtime.editLocalFile(params);
|
|
120
|
+
return this.toBuiltinResult(result);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
searchLocalFiles = async (
|
|
124
|
+
params: SearchLocalFilesParams,
|
|
125
|
+
ctx: BuiltinToolContext,
|
|
126
|
+
): Promise<BuiltinToolResult> => {
|
|
127
|
+
const runtime = this.getRuntime(ctx);
|
|
128
|
+
const result = await runtime.searchLocalFiles(params);
|
|
129
|
+
return this.toBuiltinResult(result);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
moveLocalFiles = async (
|
|
133
|
+
params: MoveLocalFilesParams,
|
|
134
|
+
ctx: BuiltinToolContext,
|
|
135
|
+
): Promise<BuiltinToolResult> => {
|
|
136
|
+
const runtime = this.getRuntime(ctx);
|
|
137
|
+
const result = await runtime.moveLocalFiles(params);
|
|
138
|
+
return this.toBuiltinResult(result);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
renameLocalFile = async (
|
|
142
|
+
params: RenameLocalFileParams,
|
|
143
|
+
ctx: BuiltinToolContext,
|
|
144
|
+
): Promise<BuiltinToolResult> => {
|
|
145
|
+
const runtime = this.getRuntime(ctx);
|
|
146
|
+
const result = await runtime.renameLocalFile(params);
|
|
147
|
+
return this.toBuiltinResult(result);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// ==================== Code Execution ====================
|
|
151
|
+
|
|
152
|
+
executeCode = async (
|
|
153
|
+
params: ExecuteCodeParams,
|
|
154
|
+
ctx: BuiltinToolContext,
|
|
155
|
+
): Promise<BuiltinToolResult> => {
|
|
156
|
+
const runtime = this.getRuntime(ctx);
|
|
157
|
+
const result = await runtime.executeCode(params);
|
|
158
|
+
return this.toBuiltinResult(result);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// ==================== Shell Commands ====================
|
|
162
|
+
|
|
163
|
+
runCommand = async (
|
|
164
|
+
params: RunCommandParams,
|
|
165
|
+
ctx: BuiltinToolContext,
|
|
166
|
+
): Promise<BuiltinToolResult> => {
|
|
167
|
+
const runtime = this.getRuntime(ctx);
|
|
168
|
+
const result = await runtime.runCommand(params);
|
|
169
|
+
return this.toBuiltinResult(result);
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
getCommandOutput = async (
|
|
173
|
+
params: GetCommandOutputParams,
|
|
174
|
+
ctx: BuiltinToolContext,
|
|
175
|
+
): Promise<BuiltinToolResult> => {
|
|
176
|
+
const runtime = this.getRuntime(ctx);
|
|
177
|
+
const result = await runtime.getCommandOutput(params);
|
|
178
|
+
return this.toBuiltinResult(result);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
killCommand = async (
|
|
182
|
+
params: KillCommandParams,
|
|
183
|
+
ctx: BuiltinToolContext,
|
|
184
|
+
): Promise<BuiltinToolResult> => {
|
|
185
|
+
const runtime = this.getRuntime(ctx);
|
|
186
|
+
const result = await runtime.killCommand(params);
|
|
187
|
+
return this.toBuiltinResult(result);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// ==================== Search & Find ====================
|
|
191
|
+
|
|
192
|
+
grepContent = async (
|
|
193
|
+
params: GrepContentParams,
|
|
194
|
+
ctx: BuiltinToolContext,
|
|
195
|
+
): Promise<BuiltinToolResult> => {
|
|
196
|
+
const runtime = this.getRuntime(ctx);
|
|
197
|
+
const result = await runtime.grepContent(params);
|
|
198
|
+
return this.toBuiltinResult(result);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
globLocalFiles = async (
|
|
202
|
+
params: GlobLocalFilesParams,
|
|
203
|
+
ctx: BuiltinToolContext,
|
|
204
|
+
): Promise<BuiltinToolResult> => {
|
|
205
|
+
const runtime = this.getRuntime(ctx);
|
|
206
|
+
const result = await runtime.globLocalFiles(params);
|
|
207
|
+
return this.toBuiltinResult(result);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// ==================== Export Operations ====================
|
|
211
|
+
|
|
212
|
+
exportFile = async (
|
|
213
|
+
params: ExportFileParams,
|
|
214
|
+
ctx: BuiltinToolContext,
|
|
215
|
+
): Promise<BuiltinToolResult> => {
|
|
216
|
+
const runtime = this.getRuntime(ctx);
|
|
217
|
+
const result = await runtime.exportFile(params);
|
|
218
|
+
return this.toBuiltinResult(result);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// ==================== Helper Methods ====================
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Convert BuiltinServerRuntimeOutput to BuiltinToolResult
|
|
225
|
+
*/
|
|
226
|
+
private toBuiltinResult(output: {
|
|
227
|
+
content: string;
|
|
228
|
+
error?: any;
|
|
229
|
+
state?: any;
|
|
230
|
+
success: boolean;
|
|
231
|
+
}): BuiltinToolResult {
|
|
232
|
+
if (!output.success) {
|
|
233
|
+
return {
|
|
234
|
+
content: output.content,
|
|
235
|
+
error: {
|
|
236
|
+
body: output.error,
|
|
237
|
+
message: output.content || 'Unknown error',
|
|
238
|
+
type: 'PluginServerError',
|
|
239
|
+
},
|
|
240
|
+
state: output.state,
|
|
241
|
+
success: false,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
content: output.content,
|
|
247
|
+
state: output.state,
|
|
248
|
+
success: true,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Export the executor instance for registration
|
|
254
|
+
export const cloudSandboxExecutor = new CloudSandboxExecutor();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API names for Cloud Sandbox tool
|
|
3
|
+
*/
|
|
4
|
+
export const CloudSandboxApiName = {
|
|
5
|
+
editLocalFile: 'editLocalFile',
|
|
6
|
+
executeCode: 'executeCode',
|
|
7
|
+
exportFile: 'exportFile',
|
|
8
|
+
getCommandOutput: 'getCommandOutput',
|
|
9
|
+
globLocalFiles: 'globLocalFiles',
|
|
10
|
+
grepContent: 'grepContent',
|
|
11
|
+
killCommand: 'killCommand',
|
|
12
|
+
listLocalFiles: 'listLocalFiles',
|
|
13
|
+
moveLocalFiles: 'moveLocalFiles',
|
|
14
|
+
readLocalFile: 'readLocalFile',
|
|
15
|
+
renameLocalFile: 'renameLocalFile',
|
|
16
|
+
runCommand: 'runCommand',
|
|
17
|
+
searchLocalFiles: 'searchLocalFiles',
|
|
18
|
+
writeLocalFile: 'writeLocalFile',
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export type CloudSandboxApiNameType =
|
|
22
|
+
(typeof CloudSandboxApiName)[keyof typeof CloudSandboxApiName];
|