@turingflow/agent-kit 0.0.0-stage → 0.1.0
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 +546 -2
- package/dist/agent.d.ts +27 -0
- package/dist/agent.js +31 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +105 -0
- package/dist/handlers.d.ts +92 -0
- package/dist/handlers.js +211 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +10 -0
- package/dist/sdk.d.ts +106 -0
- package/dist/sdk.js +309 -0
- package/dist/server/agent.d.ts +27 -0
- package/dist/server/agent.js +31 -0
- package/dist/server/artifact-hooks.d.ts +6 -0
- package/dist/server/artifact-hooks.js +37 -0
- package/dist/server/artifact-tool-tracker.d.ts +24 -0
- package/dist/server/artifact-tool-tracker.js +347 -0
- package/dist/server/artifacts.d.ts +227 -0
- package/dist/server/artifacts.js +1061 -0
- package/dist/server/auth/config.d.ts +34 -0
- package/dist/server/auth/config.js +82 -0
- package/dist/server/auth/db.d.ts +159 -0
- package/dist/server/auth/db.js +680 -0
- package/dist/server/auth/handlers.d.ts +27 -0
- package/dist/server/auth/handlers.js +297 -0
- package/dist/server/auth/index.d.ts +15 -0
- package/dist/server/auth/index.js +14 -0
- package/dist/server/auth/login-options.d.ts +14 -0
- package/dist/server/auth/login-options.js +50 -0
- package/dist/server/auth/providers/dingtalk.d.ts +16 -0
- package/dist/server/auth/providers/dingtalk.js +177 -0
- package/dist/server/auth/providers/feishu.d.ts +15 -0
- package/dist/server/auth/providers/feishu.js +100 -0
- package/dist/server/auth/providers/index.d.ts +13 -0
- package/dist/server/auth/providers/index.js +24 -0
- package/dist/server/auth/session.d.ts +48 -0
- package/dist/server/auth/session.js +108 -0
- package/dist/server/auth/types.d.ts +118 -0
- package/dist/server/auth/types.js +7 -0
- package/dist/server/browser-agent-mcp.d.ts +67 -0
- package/dist/server/browser-agent-mcp.js +608 -0
- package/dist/server/cli.d.ts +6 -0
- package/dist/server/cli.js +112 -0
- package/dist/server/debug-log.d.ts +25 -0
- package/dist/server/debug-log.js +86 -0
- package/dist/server/handlers.d.ts +141 -0
- package/dist/server/handlers.js +523 -0
- package/dist/server/index.d.ts +30 -0
- package/dist/server/index.js +28 -0
- package/dist/server/kit-api.d.ts +23 -0
- package/dist/server/kit-api.js +153 -0
- package/dist/server/model-sources.d.ts +32 -0
- package/dist/server/model-sources.js +58 -0
- package/dist/server/oa.d.ts +87 -0
- package/dist/server/oa.js +397 -0
- package/dist/server/providers/openrouter.d.ts +51 -0
- package/dist/server/providers/openrouter.js +283 -0
- package/dist/server/render-markdown.d.ts +2 -0
- package/dist/server/render-markdown.js +50 -0
- package/dist/server/sdk.d.ts +259 -0
- package/dist/server/sdk.js +1991 -0
- package/dist/server/session-access.d.ts +5 -0
- package/dist/server/session-access.js +68 -0
- package/dist/server/session-fork.d.ts +10 -0
- package/dist/server/session-fork.js +142 -0
- package/dist/server/session-store.d.ts +56 -0
- package/dist/server/session-store.js +148 -0
- package/dist/server/sessions.d.ts +24 -0
- package/dist/server/sessions.js +541 -0
- package/dist/server/share.d.ts +15 -0
- package/dist/server/share.js +433 -0
- package/dist/server/tool-activity.d.ts +2 -0
- package/dist/server/tool-activity.js +26 -0
- package/dist/server/transcription/xiaomi-mimo.d.ts +8 -0
- package/dist/server/transcription/xiaomi-mimo.js +86 -0
- package/dist/server/upload.d.ts +13 -0
- package/dist/server/upload.js +81 -0
- package/dist/server/user-files.d.ts +28 -0
- package/dist/server/user-files.js +311 -0
- package/dist/server/voice.d.ts +25 -0
- package/dist/server/voice.js +61 -0
- package/dist/server/web-fetch.d.ts +71 -0
- package/dist/server/web-fetch.js +330 -0
- package/dist/styles.css +3354 -0
- package/dist/transcription/xiaomi-mimo.d.ts +8 -0
- package/dist/transcription/xiaomi-mimo.js +86 -0
- package/dist/ui/index.d.ts +352 -0
- package/dist/ui/index.js +7730 -0
- package/dist/upload.d.ts +13 -0
- package/dist/upload.js +81 -0
- package/dist/voice.d.ts +25 -0
- package/dist/voice.js +61 -0
- package/package.json +74 -4
package/dist/upload.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface UploadOptions {
|
|
2
|
+
/** 保存目录(默认 <cwd>/public/uploads) */
|
|
3
|
+
dir?: string;
|
|
4
|
+
/** 单文件大小上限字节(默认 20MB) */
|
|
5
|
+
maxBytes?: number;
|
|
6
|
+
/** 允许的 MIME → 扩展名映射(默认覆盖图片/PDF/Office/文本/压缩包) */
|
|
7
|
+
allowedTypes?: Record<string, string>;
|
|
8
|
+
/** 返回给前端的 URL 前缀(默认 /uploads,配合 public 目录静态访问) */
|
|
9
|
+
urlPrefix?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function createUploadHandler(options?: UploadOptions): {
|
|
12
|
+
POST: (request: Request) => Promise<Response>;
|
|
13
|
+
};
|
package/dist/upload.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-kit · 附件上传端点(Next.js App Router 通用 handler)
|
|
3
|
+
*
|
|
4
|
+
* 默认把文件保存到 <cwd>/public/uploads/ 并返回可访问的相对 URL,
|
|
5
|
+
* 与前端 ChatWindow 的「+ 上传 / 拖拽添加」流程对接。
|
|
6
|
+
* 第三方 Next.js 工程只需在 app/api/upload/route.js 里:
|
|
7
|
+
* import { createUploadHandler } from "agent-kit";
|
|
8
|
+
* export const { POST } = createUploadHandler();
|
|
9
|
+
*/
|
|
10
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import crypto from "node:crypto";
|
|
13
|
+
const DEFAULT_ALLOWED = {
|
|
14
|
+
"image/jpeg": "jpg",
|
|
15
|
+
"image/jpg": "jpg",
|
|
16
|
+
"image/png": "png",
|
|
17
|
+
"image/webp": "webp",
|
|
18
|
+
"image/gif": "gif",
|
|
19
|
+
"application/pdf": "pdf",
|
|
20
|
+
"text/plain": "txt",
|
|
21
|
+
"application/msword": "doc",
|
|
22
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
23
|
+
"application/vnd.ms-excel": "xls",
|
|
24
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
25
|
+
"application/zip": "zip",
|
|
26
|
+
};
|
|
27
|
+
function extFromName(name = "") {
|
|
28
|
+
const i = name.lastIndexOf(".");
|
|
29
|
+
return i >= 0 ? name.slice(i + 1).toLowerCase() : "";
|
|
30
|
+
}
|
|
31
|
+
/** 文件名安全化:替换 Windows/URL 非法字符与空白,保留中文等可读字符,截断防超长 */
|
|
32
|
+
function safeName(name = "") {
|
|
33
|
+
return name.replace(/[\\/:*?"<>|\s]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 80);
|
|
34
|
+
}
|
|
35
|
+
export function createUploadHandler(options = {}) {
|
|
36
|
+
const dir = options.dir ?? path.join(process.cwd(), "public", "uploads");
|
|
37
|
+
const maxBytes = options.maxBytes ?? 20 * 1024 * 1024;
|
|
38
|
+
const allowed = options.allowedTypes ?? DEFAULT_ALLOWED;
|
|
39
|
+
const urlPrefix = (options.urlPrefix ?? "/uploads").replace(/\/+$/, "");
|
|
40
|
+
async function POST(request) {
|
|
41
|
+
let form;
|
|
42
|
+
try {
|
|
43
|
+
form = await request.formData();
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return Response.json({ ok: false, error: "请求格式错误" }, { status: 400 });
|
|
47
|
+
}
|
|
48
|
+
const file = form.get("file");
|
|
49
|
+
if (!file || typeof file === "string" || !file.size) {
|
|
50
|
+
return Response.json({ ok: false, error: "没有收到文件" }, { status: 400 });
|
|
51
|
+
}
|
|
52
|
+
const ext = allowed[String(file.type).toLowerCase()] || extFromName(file.name);
|
|
53
|
+
if (!ext) {
|
|
54
|
+
return Response.json({ ok: false, error: "不支持的文件类型(支持图片/PDF/Office/文本/压缩包)" }, { status: 400 });
|
|
55
|
+
}
|
|
56
|
+
const buf = Buffer.from(await file.arrayBuffer());
|
|
57
|
+
if (buf.length > maxBytes) {
|
|
58
|
+
return Response.json({ ok: false, error: `文件超过 ${Math.floor(maxBytes / 1024 / 1024)}MB 上限` }, { status: 400 });
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
await mkdir(dir, { recursive: true });
|
|
62
|
+
// 保留原文件名(uuid 前缀防冲突):模型/用户能对得上文件名,
|
|
63
|
+
// 配合 chat handler 注入的磁盘路径即可直接 Read。
|
|
64
|
+
// 去掉原名扩展名再追加规范扩展名,避免 "光伏设备.txt.txt"。
|
|
65
|
+
const nameBase = safeName(file.name).replace(/\.[^./\\]+$/, "") || "file";
|
|
66
|
+
const filename = `${crypto.randomUUID()}_${nameBase}.${ext}`;
|
|
67
|
+
await writeFile(path.join(dir, filename), buf);
|
|
68
|
+
return Response.json({
|
|
69
|
+
ok: true,
|
|
70
|
+
url: `${urlPrefix}/${filename}`,
|
|
71
|
+
name: file.name,
|
|
72
|
+
size: buf.length,
|
|
73
|
+
mime: file.type,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return Response.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, { status: 500 });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { POST };
|
|
81
|
+
}
|
package/dist/voice.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface VoiceUser {
|
|
2
|
+
userId?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
sub?: string;
|
|
5
|
+
nick?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createVoiceToken(user: VoiceUser, { ttlSeconds }?: {
|
|
8
|
+
ttlSeconds?: number;
|
|
9
|
+
}): {
|
|
10
|
+
token: string;
|
|
11
|
+
tokenType: string;
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function verifyVoiceToken(token: string | null | undefined): {
|
|
15
|
+
purpose?: string;
|
|
16
|
+
exp?: number;
|
|
17
|
+
} | null;
|
|
18
|
+
export declare function transcribeVoice({ bytes, mimeType, fileName, }: {
|
|
19
|
+
bytes: Buffer;
|
|
20
|
+
mimeType: string;
|
|
21
|
+
fileName: string;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
text: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
}>;
|
package/dist/voice.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-kit · 语音输入服务端(Next.js App Router 通用 handler)
|
|
3
|
+
*
|
|
4
|
+
* 短时令牌(HMAC-SHA256 签名,默认 10 分钟有效)+ ASR 转写。
|
|
5
|
+
* 前端录音前先取 token,再带 Bearer token 调 transcribe 接口。
|
|
6
|
+
* 默认转写后端:BrandAgent / 小米 MiMo(见 transcription/xiaomi-mimo.ts)。
|
|
7
|
+
*/
|
|
8
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
9
|
+
import { transcribeWithXiaomiMimo } from "./transcription/xiaomi-mimo.js";
|
|
10
|
+
const DEFAULT_TTL_MS = 10 * 60 * 1000;
|
|
11
|
+
function tokenSecret() {
|
|
12
|
+
return (process.env.AGENT_KIT_VOICE_TOKEN_SECRET ||
|
|
13
|
+
process.env.HOTLINE_ASR_TOKEN_SECRET ||
|
|
14
|
+
process.env.HOTLINE_SESSION_SECRET ||
|
|
15
|
+
"agent-kit-2026");
|
|
16
|
+
}
|
|
17
|
+
function sign(value) {
|
|
18
|
+
return createHmac("sha256", tokenSecret()).update(value).digest("base64url");
|
|
19
|
+
}
|
|
20
|
+
export function createVoiceToken(user, { ttlSeconds } = {}) {
|
|
21
|
+
const ttlMs = Math.min(DEFAULT_TTL_MS, Math.max(60_000, (Number(ttlSeconds) || 600) * 1000));
|
|
22
|
+
const payload = Buffer.from(JSON.stringify({
|
|
23
|
+
purpose: "agent-kit-voice",
|
|
24
|
+
sub: user.userId || user.sub || "user",
|
|
25
|
+
name: user.name || user.nick || "",
|
|
26
|
+
exp: Date.now() + ttlMs,
|
|
27
|
+
})).toString("base64url");
|
|
28
|
+
return { token: `${payload}.${sign(payload)}`, tokenType: "Bearer", expiresAt: Date.now() + ttlMs };
|
|
29
|
+
}
|
|
30
|
+
export function verifyVoiceToken(token) {
|
|
31
|
+
if (!token || !token.includes("."))
|
|
32
|
+
return null;
|
|
33
|
+
const [payload, signature] = token.split(".");
|
|
34
|
+
if (!payload || !signature)
|
|
35
|
+
return null;
|
|
36
|
+
const expected = Buffer.from(sign(payload));
|
|
37
|
+
const provided = Buffer.from(signature);
|
|
38
|
+
if (provided.length !== expected.length || !timingSafeEqual(provided, expected))
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
const data = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
42
|
+
if (data.purpose !== "agent-kit-voice")
|
|
43
|
+
return null;
|
|
44
|
+
if (typeof data.exp !== "number" || data.exp <= Date.now())
|
|
45
|
+
return null;
|
|
46
|
+
return data;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 按环境变量选择转写后端(默认小米 MiMo,经 BrandAgent 平台)。
|
|
53
|
+
export async function transcribeVoice({ bytes, mimeType, fileName, }) {
|
|
54
|
+
const provider = (process.env.AGENT_KIT_ASR_PROVIDER || process.env.HOTLINE_ASR_PROVIDER || "xiaomi")
|
|
55
|
+
.trim()
|
|
56
|
+
.toLowerCase();
|
|
57
|
+
if (provider === "tencent" || provider === "tencent-cloud") {
|
|
58
|
+
throw new Error("腾讯云转写未接入(agent-kit 默认提供 BrandAgent / 小米 MiMo)");
|
|
59
|
+
}
|
|
60
|
+
return transcribeWithXiaomiMimo({ bytes, mimeType, fileName });
|
|
61
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,76 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turingflow/agent-kit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Agent 前后端一体 SDK:服务端订阅对话(CodeBuddy / hy3)+ 前端 workbuddy 风格聊天 UI。Next.js 工程后台引主入口、前台引 /ui",
|
|
7
|
+
"main": "./dist/server/index.js",
|
|
8
|
+
"types": "./dist/server/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/server/index.d.ts",
|
|
12
|
+
"import": "./dist/server/index.js",
|
|
13
|
+
"default": "./dist/server/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./ui": {
|
|
16
|
+
"types": "./dist/ui/index.d.ts",
|
|
17
|
+
"import": "./dist/ui/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./styles.css": "./dist/styles.css"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"package.json"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "npm run build:server && npm run build:ui && npm run build:css",
|
|
29
|
+
"build:server": "tsc -p tsconfig.json",
|
|
30
|
+
"build:ui": "tsup --config tsup.ui.config.ts",
|
|
31
|
+
"build:css": "node scripts/check-css-comments.cjs && node -e \"require('fs').copyFileSync('src/ui/styles.css','dist/styles.css')\"",
|
|
32
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
33
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.ui.json --noEmit",
|
|
34
|
+
"test:artifacts": "tsx scripts/test-all-artifacts.ts",
|
|
35
|
+
"test:tool-activity": "tsx scripts/test-tool-activity.ts",
|
|
36
|
+
"test:markdown": "tsx scripts/test-assistant-text.tsx",
|
|
37
|
+
"test:fork": "tsx scripts/test-session-fork.ts",
|
|
38
|
+
"demo": "tsx src/server/cli.ts --demo",
|
|
39
|
+
"cli": "tsx src/server/cli.ts",
|
|
40
|
+
"prepublishOnly": "npm run build"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@summersmile/voice-dictation": "^0.1.0",
|
|
44
|
+
"@tencent-ai/agent-sdk": "^0.3.266",
|
|
45
|
+
"mammoth": "^1.13.0",
|
|
46
|
+
"pg": "^8.23.1",
|
|
47
|
+
"playwright": "^1.63.0",
|
|
48
|
+
"prismjs": "1.30.0",
|
|
49
|
+
"react-markdown": "^10.1.0",
|
|
50
|
+
"rehype-highlight": "^7.0.2",
|
|
51
|
+
"rehype-raw": "^7.0.0",
|
|
52
|
+
"rehype-sanitize": "^6.0.0",
|
|
53
|
+
"rehype-stringify": "^10.0.1",
|
|
54
|
+
"remark-gfm": "^4.0.1",
|
|
55
|
+
"remark-parse": "^11.0.0",
|
|
56
|
+
"remark-rehype": "^11.1.2",
|
|
57
|
+
"unified": "^11.0.5",
|
|
58
|
+
"zod": "^4.6.5"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"react": ">=18",
|
|
62
|
+
"react-dom": ">=18"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@types/node": "^26.6.3",
|
|
66
|
+
"@types/react": "^19.0.0",
|
|
67
|
+
"@types/react-dom": "^19.0.0",
|
|
68
|
+
"tsup": "^8.3.5",
|
|
69
|
+
"tsx": "^4.19.0",
|
|
70
|
+
"typescript": "^5.6.0"
|
|
71
|
+
},
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public",
|
|
74
|
+
"registry": "https://registry.npmjs.org/"
|
|
75
|
+
}
|
|
76
|
+
}
|