@shareai-lab/kode-sdk 2.7.2 → 2.7.4
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 -1
- package/README.zh-CN.md +15 -1
- package/dist/core/agent.d.ts +7 -0
- package/dist/core/agent.js +111 -8
- package/dist/core/skills/management-manager.d.ts +93 -60
- package/dist/core/skills/management-manager.js +661 -391
- package/dist/core/skills/manager.d.ts +4 -0
- package/dist/core/skills/manager.js +39 -16
- package/dist/core/skills/types.d.ts +12 -0
- package/dist/core/types.d.ts +9 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -2
- package/dist/infra/opensandbox/index.d.ts +3 -0
- package/dist/infra/opensandbox/index.js +7 -0
- package/dist/infra/opensandbox/opensandbox-fs.d.ts +27 -0
- package/dist/infra/opensandbox/opensandbox-fs.js +113 -0
- package/dist/infra/opensandbox/opensandbox-sandbox.d.ts +35 -0
- package/dist/infra/opensandbox/opensandbox-sandbox.js +325 -0
- package/dist/infra/opensandbox/types.d.ts +30 -0
- package/dist/infra/opensandbox/types.js +2 -0
- package/dist/infra/providers/anthropic.js +16 -0
- package/dist/infra/providers/gemini.js +32 -4
- package/dist/infra/providers/openai.js +27 -3
- package/dist/infra/providers/types.d.ts +35 -1
- package/dist/infra/providers/utils.d.ts +19 -1
- package/dist/infra/providers/utils.js +83 -3
- package/dist/infra/sandbox-factory.js +5 -0
- package/dist/infra/sandbox.d.ts +1 -1
- package/dist/infra/store/json-store.js +2 -1
- package/dist/tools/skills.js +2 -2
- package/dist/tools/type-inference.d.ts +1 -1
- package/package.json +6 -3
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Shared utilities for provider implementations.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.AUDIO_UNSUPPORTED_TEXT = exports.IMAGE_UNSUPPORTED_TEXT = exports.FILE_UNSUPPORTED_TEXT = void 0;
|
|
6
|
+
exports.OPENAI_SUPPORTED_AUDIO_FORMATS = exports.VIDEO_UNSUPPORTED_TEXT = exports.AUDIO_UNSUPPORTED_TEXT = exports.IMAGE_UNSUPPORTED_TEXT = exports.FILE_UNSUPPORTED_TEXT = void 0;
|
|
7
7
|
exports.resolveProxyUrl = resolveProxyUrl;
|
|
8
8
|
exports.getProxyDispatcher = getProxyDispatcher;
|
|
9
9
|
exports.withProxy = withProxy;
|
|
@@ -23,6 +23,10 @@ exports.splitThinkText = splitThinkText;
|
|
|
23
23
|
exports.extractReasoningDetails = extractReasoningDetails;
|
|
24
24
|
exports.buildGeminiImagePart = buildGeminiImagePart;
|
|
25
25
|
exports.buildGeminiFilePart = buildGeminiFilePart;
|
|
26
|
+
exports.buildGeminiAudioPart = buildGeminiAudioPart;
|
|
27
|
+
exports.buildGeminiVideoPart = buildGeminiVideoPart;
|
|
28
|
+
exports.extractOpenAIAudioFormat = extractOpenAIAudioFormat;
|
|
29
|
+
exports.buildOpenAIAudioPart = buildOpenAIAudioPart;
|
|
26
30
|
exports.sanitizeGeminiSchema = sanitizeGeminiSchema;
|
|
27
31
|
exports.hasAnthropicFileBlocks = hasAnthropicFileBlocks;
|
|
28
32
|
exports.mergeAnthropicBetaHeader = mergeAnthropicBetaHeader;
|
|
@@ -78,8 +82,8 @@ function normalizeBaseUrl(url) {
|
|
|
78
82
|
}
|
|
79
83
|
function normalizeOpenAIBaseUrl(url) {
|
|
80
84
|
let normalized = url.replace(/\/+$/, '');
|
|
81
|
-
// Auto-append /v1 if
|
|
82
|
-
if (
|
|
85
|
+
// Auto-append /v1 if no version path detected (e.g., /v1, /v2, /v4)
|
|
86
|
+
if (!/\/v\d+$/.test(normalized)) {
|
|
83
87
|
normalized += '/v1';
|
|
84
88
|
}
|
|
85
89
|
return normalized;
|
|
@@ -150,6 +154,7 @@ function safeJsonStringify(value) {
|
|
|
150
154
|
exports.FILE_UNSUPPORTED_TEXT = '[file unsupported] This model does not support PDF input. Please extract text or images first.';
|
|
151
155
|
exports.IMAGE_UNSUPPORTED_TEXT = '[image unsupported] This model does not support image URLs; please provide base64 data if supported.';
|
|
152
156
|
exports.AUDIO_UNSUPPORTED_TEXT = '[audio unsupported] This model does not support audio input; please provide a text transcript instead.';
|
|
157
|
+
exports.VIDEO_UNSUPPORTED_TEXT = '[video unsupported] This model does not support video input; please provide text description or extracted frames instead.';
|
|
153
158
|
// =============================================================================
|
|
154
159
|
// Reasoning/Thinking Utilities
|
|
155
160
|
// =============================================================================
|
|
@@ -270,6 +275,81 @@ function buildGeminiFilePart(block) {
|
|
|
270
275
|
}
|
|
271
276
|
return null;
|
|
272
277
|
}
|
|
278
|
+
function buildGeminiAudioPart(block) {
|
|
279
|
+
const mimeType = block.mime_type || 'audio/wav';
|
|
280
|
+
if (block.file_id) {
|
|
281
|
+
return { file_data: { mime_type: mimeType, file_uri: block.file_id } };
|
|
282
|
+
}
|
|
283
|
+
if (block.url) {
|
|
284
|
+
if (block.url.startsWith('gs://')) {
|
|
285
|
+
return { file_data: { mime_type: mimeType, file_uri: block.url } };
|
|
286
|
+
}
|
|
287
|
+
// Gemini supports https URLs for audio via file_data
|
|
288
|
+
return { file_data: { mime_type: mimeType, file_uri: block.url } };
|
|
289
|
+
}
|
|
290
|
+
if (block.base64) {
|
|
291
|
+
return { inline_data: { mime_type: mimeType, data: block.base64 } };
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
function buildGeminiVideoPart(block) {
|
|
296
|
+
const mimeType = block.mime_type || 'video/mp4';
|
|
297
|
+
if (block.file_id) {
|
|
298
|
+
return { file_data: { mime_type: mimeType, file_uri: block.file_id } };
|
|
299
|
+
}
|
|
300
|
+
if (block.url) {
|
|
301
|
+
if (block.url.startsWith('gs://')) {
|
|
302
|
+
return { file_data: { mime_type: mimeType, file_uri: block.url } };
|
|
303
|
+
}
|
|
304
|
+
// Gemini supports https URLs for video via file_data
|
|
305
|
+
return { file_data: { mime_type: mimeType, file_uri: block.url } };
|
|
306
|
+
}
|
|
307
|
+
if (block.base64) {
|
|
308
|
+
return { inline_data: { mime_type: mimeType, data: block.base64 } };
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
// =============================================================================
|
|
313
|
+
// OpenAI Audio Helpers
|
|
314
|
+
// =============================================================================
|
|
315
|
+
/** Supported OpenAI audio formats */
|
|
316
|
+
exports.OPENAI_SUPPORTED_AUDIO_FORMATS = ['wav', 'mp3'];
|
|
317
|
+
/**
|
|
318
|
+
* Extract and validate OpenAI audio format from MIME type.
|
|
319
|
+
* OpenAI Chat Completions API only supports wav and mp3.
|
|
320
|
+
* @returns The audio format if supported, null otherwise
|
|
321
|
+
*/
|
|
322
|
+
function extractOpenAIAudioFormat(mimeType) {
|
|
323
|
+
if (!mimeType)
|
|
324
|
+
return null;
|
|
325
|
+
const lower = mimeType.toLowerCase();
|
|
326
|
+
if (lower === 'audio/wav' || lower === 'audio/x-wav' || lower === 'audio/wave') {
|
|
327
|
+
return 'wav';
|
|
328
|
+
}
|
|
329
|
+
if (lower === 'audio/mpeg' || lower === 'audio/mp3') {
|
|
330
|
+
return 'mp3';
|
|
331
|
+
}
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Build OpenAI input_audio content part from AudioContentBlock.
|
|
336
|
+
* OpenAI only supports base64 encoded audio (no URLs).
|
|
337
|
+
* @returns The OpenAI input_audio part or null if not supported
|
|
338
|
+
*/
|
|
339
|
+
function buildOpenAIAudioPart(block) {
|
|
340
|
+
const format = extractOpenAIAudioFormat(block.mime_type);
|
|
341
|
+
if (!format)
|
|
342
|
+
return null;
|
|
343
|
+
if (!block.base64)
|
|
344
|
+
return null;
|
|
345
|
+
return {
|
|
346
|
+
type: 'input_audio',
|
|
347
|
+
input_audio: {
|
|
348
|
+
data: block.base64,
|
|
349
|
+
format,
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
}
|
|
273
353
|
function sanitizeGeminiSchema(schema) {
|
|
274
354
|
if (schema === null || schema === undefined)
|
|
275
355
|
return schema;
|
|
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SandboxFactory = void 0;
|
|
4
4
|
const sandbox_1 = require("./sandbox");
|
|
5
5
|
const e2b_sandbox_1 = require("./e2b/e2b-sandbox");
|
|
6
|
+
const opensandbox_1 = require("./opensandbox");
|
|
6
7
|
class SandboxFactory {
|
|
7
8
|
constructor() {
|
|
8
9
|
this.factories = new Map();
|
|
9
10
|
this.factories.set('local', (config) => new sandbox_1.LocalSandbox(config));
|
|
10
11
|
this.factories.set('e2b', (config) => new e2b_sandbox_1.E2BSandbox(config));
|
|
12
|
+
this.factories.set('opensandbox', (config) => new opensandbox_1.OpenSandbox(config));
|
|
11
13
|
}
|
|
12
14
|
register(kind, factory) {
|
|
13
15
|
this.factories.set(kind, factory);
|
|
@@ -24,6 +26,9 @@ class SandboxFactory {
|
|
|
24
26
|
if (config.kind === 'e2b' && sandbox instanceof e2b_sandbox_1.E2BSandbox) {
|
|
25
27
|
await sandbox.init();
|
|
26
28
|
}
|
|
29
|
+
if (config.kind === 'opensandbox' && sandbox instanceof opensandbox_1.OpenSandbox) {
|
|
30
|
+
await sandbox.init();
|
|
31
|
+
}
|
|
27
32
|
return sandbox;
|
|
28
33
|
}
|
|
29
34
|
}
|
package/dist/infra/sandbox.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SandboxKind = 'local' | 'docker' | 'k8s' | 'remote' | 'vfs' | 'e2b';
|
|
1
|
+
export type SandboxKind = 'local' | 'docker' | 'k8s' | 'remote' | 'vfs' | 'e2b' | 'opensandbox';
|
|
2
2
|
export interface SandboxFS {
|
|
3
3
|
resolve(path: string): string;
|
|
4
4
|
isInside(path: string): boolean;
|
|
@@ -582,7 +582,8 @@ class JSONStore {
|
|
|
582
582
|
const fs = require('fs').promises;
|
|
583
583
|
try {
|
|
584
584
|
await fs.access(this.getAgentDir(agentId));
|
|
585
|
-
|
|
585
|
+
const info = await this.loadInfo(agentId);
|
|
586
|
+
return !!(info && info.metadata);
|
|
586
587
|
}
|
|
587
588
|
catch {
|
|
588
589
|
return false;
|
package/dist/tools/skills.js
CHANGED
|
@@ -51,11 +51,11 @@ function createSkillsTool(skillsManager) {
|
|
|
51
51
|
const { action, skill_name } = args;
|
|
52
52
|
// 注释掉 list 操作的代码
|
|
53
53
|
// if (action === 'list') {
|
|
54
|
-
// // 列出所有skills
|
|
54
|
+
// // 列出所有skills(使用文件夹名称作为标识符)
|
|
55
55
|
// const skills = await skillsManager.getSkillsMetadata();
|
|
56
56
|
//
|
|
57
57
|
// const skillsList = skills.map(s => ({
|
|
58
|
-
// name: s.name,
|
|
58
|
+
// name: s.name, // 文件夹名称
|
|
59
59
|
// description: s.description,
|
|
60
60
|
// }));
|
|
61
61
|
//
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shareai-lab/kode-sdk",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.4",
|
|
4
4
|
"description": "Event-driven, long-running AI Agent development framework with enterprise-grade persistence and context management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"example:room": "ts-node examples/03-room-collab.ts",
|
|
23
23
|
"example:scheduler": "ts-node examples/04-scheduler-watch.ts",
|
|
24
24
|
"example:nextjs": "ts-node examples/nextjs-api-route.ts",
|
|
25
|
+
"example:opensandbox": "ts-node examples/opensandbox-usage.ts",
|
|
25
26
|
"example:openrouter": "ts-node examples/05-openrouter-complete.ts",
|
|
26
27
|
"example:openrouter-stream": "ts-node examples/06-openrouter-stream.ts",
|
|
27
28
|
"example:openrouter-agent": "ts-node examples/07-openrouter-agent.ts",
|
|
@@ -42,16 +43,18 @@
|
|
|
42
43
|
"author": "",
|
|
43
44
|
"license": "MIT",
|
|
44
45
|
"dependencies": {
|
|
46
|
+
"@alibaba-group/opensandbox": "~0.1.4",
|
|
45
47
|
"@modelcontextprotocol/sdk": "~1.22.0",
|
|
46
48
|
"ajv": "^8.17.1",
|
|
47
49
|
"better-sqlite3": "^12.6.2",
|
|
48
50
|
"dotenv": "^16.4.5",
|
|
49
51
|
"e2b": "^2.10.3",
|
|
50
52
|
"fast-glob": "^3.3.2",
|
|
53
|
+
"minimatch": "^10.2.4",
|
|
51
54
|
"pg": "^8.17.2",
|
|
52
55
|
"undici": "^7.18.2",
|
|
53
|
-
"zod": "
|
|
54
|
-
"zod-to-json-schema": "
|
|
56
|
+
"zod": "^4.3.5",
|
|
57
|
+
"zod-to-json-schema": "^3.24.6"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@shareai-lab/kode-sdk": "file:.",
|