@langgraph-js/pure-graph 2.10.0 → 3.0.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/dist/adapter/fetch/assistants.d.ts +42 -0
- package/dist/adapter/fetch/endpoint.d.ts +25 -0
- package/dist/adapter/fetch/index.d.ts +5 -3
- package/dist/adapter/fetch/index.js +858 -25
- package/dist/adapter/fetch/index.js.map +1 -1
- package/dist/adapter/fetch/runs-extended.d.ts +21 -0
- package/dist/adapter/fetch/runs-stateless.d.ts +28 -0
- package/dist/adapter/fetch/runs.d.ts +0 -4
- package/dist/adapter/fetch/threads.d.ts +36 -0
- package/dist/adapter/nextjs/index.js +1 -1
- package/dist/adapter/zod.d.ts +292 -1
- package/dist/agents/ask_subagents.d.ts +1 -1
- package/dist/createEndpoint-BViLxrhh.js +208 -0
- package/dist/createEndpoint-BViLxrhh.js.map +1 -0
- package/dist/createEndpoint.d.ts +25 -0
- package/dist/index.js +2 -2
- package/dist/queue/stream_queue.d.ts +2 -2
- package/dist/queue-CtVch_az.js +153 -0
- package/dist/queue-CtVch_az.js.map +1 -0
- package/dist/remote/index.js +158 -0
- package/dist/remote/index.js.map +1 -0
- package/dist/remote-threads-CrG03ZS7.js +255 -0
- package/dist/remote-threads-CrG03ZS7.js.map +1 -0
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/kysely/index.d.ts +1 -0
- package/dist/storage/kysely/remote-threads.d.ts +124 -0
- package/dist/storage/kysely/threads.d.ts +26 -2
- package/dist/storage/kysely/types.d.ts +10 -0
- package/dist/storage/memory/threads.d.ts +27 -1
- package/dist/storage/redis/queue.d.ts +14 -11
- package/dist/storage/remote/fetch.d.ts +20 -0
- package/dist/storage/remote/remote-server.d.ts +17 -0
- package/dist/storage/remote/server.d.ts +11 -0
- package/dist/storage/remote/types.d.ts +121 -0
- package/dist/{stream-D0YD2Pjq.js → stream-umoA6h4q.js} +502 -78
- package/dist/stream-umoA6h4q.js.map +1 -0
- package/dist/threads/index.d.ts +25 -1
- package/dist/types.d.ts +53 -1
- package/package.json +10 -4
- package/dist/createEndpoint-CN_RHDEd.js +0 -122
- package/dist/createEndpoint-CN_RHDEd.js.map +0 -1
- package/dist/queue-D6tEGCGs.js +0 -146
- package/dist/queue-D6tEGCGs.js.map +0 -1
- package/dist/stream-D0YD2Pjq.js.map +0 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { B as BaseStreamQueue, C as CancelEventMessage } from './stream-umoA6h4q.js';
|
|
2
|
+
import { createClient } from 'redis';
|
|
3
|
+
|
|
4
|
+
class RedisStreamQueue extends BaseStreamQueue {
|
|
5
|
+
// 轮询间隔(毫秒)
|
|
6
|
+
constructor(id, compressMessages = true, ttl = 300) {
|
|
7
|
+
super(id, true, ttl);
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.compressMessages = compressMessages;
|
|
10
|
+
this.ttl = ttl;
|
|
11
|
+
this.streamKey = `stream:${this.id}`;
|
|
12
|
+
this.listKey = `queue:${this.id}`;
|
|
13
|
+
this.redis = createClient({
|
|
14
|
+
url: process.env.REDIS_URL
|
|
15
|
+
});
|
|
16
|
+
this.cancelSignal = new AbortController();
|
|
17
|
+
if (!this.redis.isOpen) {
|
|
18
|
+
this.redis.connect();
|
|
19
|
+
}
|
|
20
|
+
this.isConnected = true;
|
|
21
|
+
}
|
|
22
|
+
redis;
|
|
23
|
+
streamKey;
|
|
24
|
+
listKey;
|
|
25
|
+
isConnected = false;
|
|
26
|
+
cancelSignal;
|
|
27
|
+
lastStreamId = "0";
|
|
28
|
+
// 最后读取的 Stream ID
|
|
29
|
+
pollInterval = 100;
|
|
30
|
+
/**
|
|
31
|
+
* 推送消息到 Redis Stream 和 List
|
|
32
|
+
* - Stream: 用于实时推送(集群友好)
|
|
33
|
+
* - List: 用于 getAll() 批量获取历史数据
|
|
34
|
+
*/
|
|
35
|
+
async push(item) {
|
|
36
|
+
const encodedData = await this.encodeData(item);
|
|
37
|
+
const dataString = Buffer.from(encodedData).toString("base64");
|
|
38
|
+
const serializedData = Buffer.from(encodedData);
|
|
39
|
+
await this.redis.xAdd(this.streamKey, "*", { data: dataString });
|
|
40
|
+
await this.redis.expire(this.streamKey, this.ttl);
|
|
41
|
+
await this.redis.rPush(this.listKey, serializedData);
|
|
42
|
+
await this.redis.expire(this.listKey, this.ttl);
|
|
43
|
+
this.emit("dataChange", dataString);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 异步生成器:使用 Redis Streams XREAD 轮询消费队列数据
|
|
47
|
+
*/
|
|
48
|
+
async *onDataReceive() {
|
|
49
|
+
let isStreamEnded = false;
|
|
50
|
+
if (this.cancelSignal.signal.aborted) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const abortHandler = () => {
|
|
54
|
+
isStreamEnded = true;
|
|
55
|
+
};
|
|
56
|
+
this.cancelSignal.signal.addEventListener("abort", abortHandler);
|
|
57
|
+
try {
|
|
58
|
+
while (!isStreamEnded && !this.cancelSignal.signal.aborted) {
|
|
59
|
+
const streams = await this.redis.xRead([{ key: this.streamKey, id: this.lastStreamId }], {
|
|
60
|
+
BLOCK: this.pollInterval,
|
|
61
|
+
COUNT: 10
|
|
62
|
+
});
|
|
63
|
+
if (streams && streams.length > 0) {
|
|
64
|
+
for (const stream of streams) {
|
|
65
|
+
for (const message of stream.messages) {
|
|
66
|
+
this.lastStreamId = message.id;
|
|
67
|
+
const dataString = message.message.data;
|
|
68
|
+
const data = Buffer.from(dataString, "base64");
|
|
69
|
+
const item = await this.decodeData(data);
|
|
70
|
+
if (item.event === "__stream_end__" || item.event === "__stream_error__" || item.event === "__stream_cancel__") {
|
|
71
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
72
|
+
isStreamEnded = true;
|
|
73
|
+
if (item.event === "__stream_cancel__") {
|
|
74
|
+
await this.cancel();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
yield item;
|
|
78
|
+
if (isStreamEnded) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (isStreamEnded) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!isStreamEnded && !this.cancelSignal.signal.aborted) {
|
|
88
|
+
await new Promise((resolve) => setTimeout(resolve, this.pollInterval));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} finally {
|
|
92
|
+
this.cancelSignal.signal.removeEventListener("abort", abortHandler);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 获取队列中的所有数据(从 List 获取历史数据)
|
|
97
|
+
*/
|
|
98
|
+
async getAll() {
|
|
99
|
+
const data = await this.redis.lRange(this.listKey, 0, -1);
|
|
100
|
+
if (!data || data.length === 0) {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
if (this.compressMessages) {
|
|
104
|
+
return await Promise.all(
|
|
105
|
+
data.map((item) => {
|
|
106
|
+
const buffer = typeof item === "string" ? Buffer.from(item, "binary") : item;
|
|
107
|
+
return this.decodeData(buffer);
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
} else {
|
|
111
|
+
return data.map((item) => JSON.parse(item));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 清空队列
|
|
116
|
+
*/
|
|
117
|
+
clear() {
|
|
118
|
+
if (this.isConnected) {
|
|
119
|
+
this.redis.del(this.streamKey);
|
|
120
|
+
this.redis.del(this.listKey);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 取消操作
|
|
125
|
+
*/
|
|
126
|
+
async cancel() {
|
|
127
|
+
this.cancelSignal.abort("user cancel this run");
|
|
128
|
+
await this.push(new CancelEventMessage());
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 复制队列到另一个队列
|
|
132
|
+
*/
|
|
133
|
+
async copyToQueue(toId, ttl) {
|
|
134
|
+
const queue = new RedisStreamQueue(toId, this.compressMessages, ttl ?? this.ttl);
|
|
135
|
+
await this.redis.copy(this.listKey, queue.listKey);
|
|
136
|
+
await this.redis.expire(queue.listKey, ttl ?? this.ttl);
|
|
137
|
+
const allStreamData = await this.redis.xRange(this.streamKey, "-", "+");
|
|
138
|
+
if (allStreamData && allStreamData.length > 0) {
|
|
139
|
+
for (const message of allStreamData) {
|
|
140
|
+
const fields = {};
|
|
141
|
+
for (const [key, value] of Object.entries(message.message)) {
|
|
142
|
+
fields[key] = String(value);
|
|
143
|
+
}
|
|
144
|
+
await this.redis.xAdd(queue.streamKey, "*", fields);
|
|
145
|
+
}
|
|
146
|
+
await this.redis.expire(queue.streamKey, ttl ?? this.ttl);
|
|
147
|
+
}
|
|
148
|
+
return queue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export { RedisStreamQueue };
|
|
153
|
+
//# sourceMappingURL=queue-CtVch_az.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-CtVch_az.js","sources":["../src/storage/redis/queue.ts"],"sourcesContent":["import { CancelEventMessage, EventMessage } from '../../queue/event_message.js';\nimport { BaseStreamQueue } from '../../queue/stream_queue.js';\nimport { BaseStreamQueueInterface } from '../../queue/stream_queue.js';\nimport { createClient, RedisClientType } from 'redis';\n\n/**\n * Redis Stream 实现的消息队列,用于存储消息\n * 使用 Redis Streams 替代 pub/sub,支持集群模式\n */\nexport class RedisStreamQueue extends BaseStreamQueue implements BaseStreamQueueInterface {\n private redis: RedisClientType;\n private streamKey: string;\n private listKey: string;\n private isConnected = false;\n public cancelSignal: AbortController;\n private lastStreamId: string = '0'; // 最后读取的 Stream ID\n private pollInterval: number = 100; // 轮询间隔(毫秒)\n\n constructor(readonly id: string, readonly compressMessages: boolean = true, readonly ttl: number = 300) {\n super(id, true, ttl);\n this.streamKey = `stream:${this.id}`;\n this.listKey = `queue:${this.id}`;\n this.redis = createClient({\n url: process.env.REDIS_URL,\n });\n this.cancelSignal = new AbortController();\n\n // 连接 Redis 客户端(检查是否已经连接)\n if (!this.redis.isOpen) {\n this.redis.connect();\n }\n this.isConnected = true;\n }\n\n /**\n * 推送消息到 Redis Stream 和 List\n * - Stream: 用于实时推送(集群友好)\n * - List: 用于 getAll() 批量获取历史数据\n */\n async push(item: EventMessage): Promise<void> {\n const encodedData = await this.encodeData(item);\n // 将 Uint8Array 转换为 base64 字符串,以便存储到 Redis Stream\n const dataString = Buffer.from(encodedData).toString('base64');\n const serializedData = Buffer.from(encodedData);\n\n // 推送到 Stream(实时推送)\n // 注意:xAdd 的第三个参数必须是简单的键值对对象,值必须是字符串\n await this.redis.xAdd(this.streamKey, '*', { data: dataString });\n\n // 设置 Stream TTL\n await this.redis.expire(this.streamKey, this.ttl);\n\n // 同时推送到 List(用于 getAll)\n await this.redis.rPush(this.listKey, serializedData);\n await this.redis.expire(this.listKey, this.ttl);\n\n this.emit('dataChange', dataString);\n }\n\n /**\n * 异步生成器:使用 Redis Streams XREAD 轮询消费队列数据\n */\n async *onDataReceive(): AsyncGenerator<EventMessage, void, unknown> {\n let isStreamEnded = false;\n\n // 检查是否已取消\n if (this.cancelSignal.signal.aborted) {\n return;\n }\n\n // 监听取消信号\n const abortHandler = () => {\n isStreamEnded = true;\n };\n this.cancelSignal.signal.addEventListener('abort', abortHandler);\n\n try {\n while (!isStreamEnded && !this.cancelSignal.signal.aborted) {\n // 从 Stream 读取新消息(XREAD 阻塞读取)\n const streams = await this.redis.xRead([{ key: this.streamKey, id: this.lastStreamId }], {\n BLOCK: this.pollInterval,\n COUNT: 10,\n });\n\n if (streams && streams.length > 0) {\n for (const stream of streams) {\n for (const message of stream.messages) {\n // 更新最后读取的 ID\n this.lastStreamId = message.id;\n\n // 解析消息:从 base64 字符串转换回 Uint8Array\n const dataString = message.message.data as string;\n const data = Buffer.from(dataString, 'base64');\n const item = (await this.decodeData(data)) as EventMessage;\n\n // 检查是否为流结束或错误信号\n if (\n item.event === '__stream_end__' ||\n item.event === '__stream_error__' ||\n item.event === '__stream_cancel__'\n ) {\n // 延迟 300ms 后结束,确保消息被消费\n await new Promise((resolve) => setTimeout(resolve, 300));\n isStreamEnded = true;\n\n if (item.event === '__stream_cancel__') {\n await this.cancel();\n }\n }\n\n yield item;\n\n if (isStreamEnded) {\n break;\n }\n }\n if (isStreamEnded) {\n break;\n }\n }\n }\n\n // 轮询间隔\n if (!isStreamEnded && !this.cancelSignal.signal.aborted) {\n await new Promise((resolve) => setTimeout(resolve, this.pollInterval));\n }\n }\n } finally {\n this.cancelSignal.signal.removeEventListener('abort', abortHandler);\n }\n }\n\n /**\n * 获取队列中的所有数据(从 List 获取历史数据)\n */\n async getAll(): Promise<EventMessage[]> {\n const data = await this.redis.lRange(this.listKey, 0, -1);\n\n if (!data || data.length === 0) {\n return [];\n }\n\n if (this.compressMessages) {\n return (await Promise.all(\n data.map((item: Buffer | string) => {\n // 处理 Buffer 或字符串类型\n const buffer = typeof item === 'string' ? Buffer.from(item, 'binary') : item;\n return this.decodeData(buffer);\n }),\n )) as EventMessage[];\n } else {\n return data.map((item: string) => JSON.parse(item) as EventMessage);\n }\n }\n\n /**\n * 清空队列\n */\n clear(): void {\n if (this.isConnected) {\n // 同时清空 Stream 和 List\n this.redis.del(this.streamKey);\n this.redis.del(this.listKey);\n }\n }\n\n /**\n * 取消操作\n */\n async cancel(): Promise<void> {\n // First abort to stop any waiting generators\n this.cancelSignal.abort('user cancel this run');\n // Then push the cancel message to signal other consumers\n await this.push(new CancelEventMessage());\n }\n\n /**\n * 复制队列到另一个队列\n */\n async copyToQueue(toId: string, ttl?: number): Promise<RedisStreamQueue> {\n const queue = new RedisStreamQueue(toId, this.compressMessages, ttl ?? this.ttl);\n\n // 复制 List\n await this.redis.copy(this.listKey, queue.listKey);\n await this.redis.expire(queue.listKey, ttl ?? this.ttl);\n\n // 复制 Stream(需要遍历并重新添加)\n const allStreamData = await this.redis.xRange(this.streamKey, '-', '+');\n if (allStreamData && allStreamData.length > 0) {\n for (const message of allStreamData) {\n // 确保所有值都是字符串,Redis Streams 只支持 string 值\n const fields: Record<string, string> = {};\n for (const [key, value] of Object.entries(message.message)) {\n fields[key] = String(value);\n }\n await this.redis.xAdd(queue.streamKey, '*', fields);\n }\n await this.redis.expire(queue.streamKey, ttl ?? this.ttl);\n }\n\n return queue;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { PostgresAdapter } from '../pg-adapter-BFtir1GE.js';
|
|
3
|
+
import { K as KyselyThreadsManager } from '../stream-umoA6h4q.js';
|
|
4
|
+
import { Pool } from 'pg';
|
|
5
|
+
|
|
6
|
+
class RemoteServer {
|
|
7
|
+
constructor(threadsManager) {
|
|
8
|
+
this.threadsManager = threadsManager;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 创建 Hono 路由
|
|
12
|
+
*/
|
|
13
|
+
getRouter() {
|
|
14
|
+
const app = new Hono();
|
|
15
|
+
app.post("/setup", async (c) => {
|
|
16
|
+
await this.threadsManager.setup();
|
|
17
|
+
const response = {
|
|
18
|
+
success: true,
|
|
19
|
+
data: { message: "Database initialized successfully" }
|
|
20
|
+
};
|
|
21
|
+
return c.json(response, 200);
|
|
22
|
+
});
|
|
23
|
+
app.post("/threads", async (c) => {
|
|
24
|
+
const body = await c.req.json();
|
|
25
|
+
const thread = await this.threadsManager.create(body);
|
|
26
|
+
const response = {
|
|
27
|
+
success: true,
|
|
28
|
+
data: thread
|
|
29
|
+
};
|
|
30
|
+
return c.json(response, 201);
|
|
31
|
+
});
|
|
32
|
+
app.get("/threads", async (c) => {
|
|
33
|
+
const query = {
|
|
34
|
+
ids: c.req.query("ids") ? JSON.parse(c.req.query("ids")) : void 0,
|
|
35
|
+
metadata: c.req.query("metadata") ? JSON.parse(c.req.query("metadata")) : void 0,
|
|
36
|
+
limit: c.req.query("limit") ? parseInt(c.req.query("limit")) : void 0,
|
|
37
|
+
offset: c.req.query("offset") ? parseInt(c.req.query("offset")) : void 0,
|
|
38
|
+
status: c.req.query("status"),
|
|
39
|
+
sortBy: c.req.query("sortBy"),
|
|
40
|
+
sortOrder: c.req.query("sortOrder"),
|
|
41
|
+
values: c.req.query("values") ? JSON.parse(c.req.query("values")) : void 0,
|
|
42
|
+
select: c.req.query("select") ? JSON.parse(c.req.query("select")) : void 0,
|
|
43
|
+
withoutDetails: c.req.query("withoutDetails") === "true"
|
|
44
|
+
};
|
|
45
|
+
const threads = await this.threadsManager.search(query);
|
|
46
|
+
const response = {
|
|
47
|
+
success: true,
|
|
48
|
+
data: threads
|
|
49
|
+
};
|
|
50
|
+
return c.json(response, 200);
|
|
51
|
+
});
|
|
52
|
+
app.get("/threads/:threadId", async (c) => {
|
|
53
|
+
const threadId = c.req.param("threadId");
|
|
54
|
+
const thread = await this.threadsManager.get(threadId);
|
|
55
|
+
const response = {
|
|
56
|
+
success: true,
|
|
57
|
+
data: thread
|
|
58
|
+
};
|
|
59
|
+
return c.json(response, 200);
|
|
60
|
+
});
|
|
61
|
+
app.put("/threads/:threadId", async (c) => {
|
|
62
|
+
const threadId = c.req.param("threadId");
|
|
63
|
+
const body = await c.req.json();
|
|
64
|
+
await this.threadsManager.set(threadId, body);
|
|
65
|
+
const response = {
|
|
66
|
+
success: true
|
|
67
|
+
};
|
|
68
|
+
return c.json(response, 200);
|
|
69
|
+
});
|
|
70
|
+
app.delete("/threads/:threadId", async (c) => {
|
|
71
|
+
const threadId = c.req.param("threadId");
|
|
72
|
+
await this.threadsManager.delete(threadId);
|
|
73
|
+
const response = {
|
|
74
|
+
success: true
|
|
75
|
+
};
|
|
76
|
+
return c.json(response, 200);
|
|
77
|
+
});
|
|
78
|
+
app.post("/threads/:threadId/state", async (c) => {
|
|
79
|
+
const threadId = c.req.param("threadId");
|
|
80
|
+
const body = await c.req.json();
|
|
81
|
+
const result = await this.threadsManager.updateState(threadId, body);
|
|
82
|
+
const response = {
|
|
83
|
+
success: true,
|
|
84
|
+
data: result
|
|
85
|
+
};
|
|
86
|
+
return c.json(response, 200);
|
|
87
|
+
});
|
|
88
|
+
app.post("/threads/:threadId/runs", async (c) => {
|
|
89
|
+
const threadId = c.req.param("threadId");
|
|
90
|
+
const assistantId = c.req.query("assistantId");
|
|
91
|
+
const body = await c.req.json();
|
|
92
|
+
const run = await this.threadsManager.createRun(threadId, assistantId, body);
|
|
93
|
+
const response = {
|
|
94
|
+
success: true,
|
|
95
|
+
data: run
|
|
96
|
+
};
|
|
97
|
+
return c.json(response, 201);
|
|
98
|
+
});
|
|
99
|
+
app.get("/threads/:threadId/runs", async (c) => {
|
|
100
|
+
const threadId = c.req.param("threadId");
|
|
101
|
+
const query = {
|
|
102
|
+
limit: c.req.query("limit") ? parseInt(c.req.query("limit")) : void 0,
|
|
103
|
+
offset: c.req.query("offset") ? parseInt(c.req.query("offset")) : void 0,
|
|
104
|
+
status: c.req.query("status")
|
|
105
|
+
};
|
|
106
|
+
const runs = await this.threadsManager.listRuns(threadId, query);
|
|
107
|
+
const response = {
|
|
108
|
+
success: true,
|
|
109
|
+
data: runs
|
|
110
|
+
};
|
|
111
|
+
return c.json(response, 200);
|
|
112
|
+
});
|
|
113
|
+
app.put("/runs/:runId", async (c) => {
|
|
114
|
+
const runId = c.req.param("runId");
|
|
115
|
+
const body = await c.req.json();
|
|
116
|
+
await this.threadsManager.updateRun(runId, body);
|
|
117
|
+
const response = {
|
|
118
|
+
success: true
|
|
119
|
+
};
|
|
120
|
+
return c.json(response, 200);
|
|
121
|
+
});
|
|
122
|
+
return app;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const app = new Hono();
|
|
127
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
128
|
+
if (!databaseUrl) {
|
|
129
|
+
console.error("DATABASE_URL environment variable is required");
|
|
130
|
+
console.error("Example: DATABASE_URL=postgresql://user:password@localhost:5432/dbname");
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
console.log("Starting Remote PostgreSQL Server...");
|
|
134
|
+
const pool = new Pool({
|
|
135
|
+
connectionString: databaseUrl
|
|
136
|
+
});
|
|
137
|
+
const pgAdapter = new PostgresAdapter(pool);
|
|
138
|
+
const threadsManager = new KyselyThreadsManager(pgAdapter);
|
|
139
|
+
await threadsManager.setup();
|
|
140
|
+
const remoteServer = new RemoteServer(threadsManager);
|
|
141
|
+
app.route("/api/remote", remoteServer.getRouter());
|
|
142
|
+
app.get("/health", (c) => {
|
|
143
|
+
return c.json({ status: "ok", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
144
|
+
});
|
|
145
|
+
const port = parseInt(process.env.PORT || "3001");
|
|
146
|
+
console.log(`Remote PostgreSQL Server is running on port ${port}`);
|
|
147
|
+
console.log(`API Base URL: http://localhost:${port}/api/remote`);
|
|
148
|
+
console.log(`Health Check: http://localhost:${port}/health`);
|
|
149
|
+
console.log("");
|
|
150
|
+
console.log("Client Configuration:");
|
|
151
|
+
console.log(` DATABASE_URL=http://localhost:${port}/api/remote`);
|
|
152
|
+
const server = {
|
|
153
|
+
fetch: app.fetch,
|
|
154
|
+
port
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export { server as default };
|
|
158
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/storage/remote/remote-server.ts","../../src/storage/remote/server.ts"],"sourcesContent":["/**\n * Remote PostgreSQL Server\n * 提供 HTTP API 端点,代理 PostgreSQL 操作\n */\n\nimport { Hono } from 'hono';\nimport { BaseThreadsManager } from '../../threads';\nimport {\n RemoteResponse,\n RemoteApiError,\n RemoteErrorCode,\n SetupResponse,\n CreateThreadRequest,\n SearchThreadsRequest,\n UpdateThreadRequest,\n UpdateStateRequest,\n UpdateStateResponse,\n CreateRunRequest,\n ListRunsRequest,\n UpdateRunRequest,\n} from './types';\n\n/**\n * Remote Server 类\n */\nexport class RemoteServer {\n constructor(private threadsManager: BaseThreadsManager) {}\n\n /**\n * 创建 Hono 路由\n */\n getRouter(): Hono {\n const app = new Hono();\n\n // Setup API\n app.post('/setup', async (c) => {\n await this.threadsManager.setup();\n const response: RemoteResponse<SetupResponse> = {\n success: true,\n data: { message: 'Database initialized successfully' },\n };\n return c.json(response, 200);\n });\n\n // Thread: Create\n app.post('/threads', async (c) => {\n const body: CreateThreadRequest = await c.req.json();\n const thread = await this.threadsManager.create(body);\n const response: RemoteResponse = {\n success: true,\n data: thread,\n };\n return c.json(response, 201);\n });\n\n // Thread: Search\n app.get('/threads', async (c) => {\n const query: SearchThreadsRequest = {\n ids: c.req.query('ids') ? JSON.parse(c.req.query('ids')!) : undefined,\n metadata: c.req.query('metadata') ? JSON.parse(c.req.query('metadata')!) : undefined,\n limit: c.req.query('limit') ? parseInt(c.req.query('limit')!) : undefined,\n offset: c.req.query('offset') ? parseInt(c.req.query('offset')!) : undefined,\n status: c.req.query('status') as any,\n sortBy: c.req.query('sortBy') as any,\n sortOrder: c.req.query('sortOrder') as any,\n values: c.req.query('values') ? JSON.parse(c.req.query('values')!) : undefined,\n select: c.req.query('select') ? JSON.parse(c.req.query('select')!) : undefined,\n withoutDetails: c.req.query('withoutDetails') === 'true',\n };\n const threads = await this.threadsManager.search(query);\n const response: RemoteResponse = {\n success: true,\n data: threads,\n };\n return c.json(response, 200);\n });\n\n // Thread: Get\n app.get('/threads/:threadId', async (c) => {\n const threadId = c.req.param('threadId')!;\n const thread = await this.threadsManager.get(threadId);\n const response: RemoteResponse = {\n success: true,\n data: thread,\n };\n return c.json(response, 200);\n });\n\n // Thread: Update\n app.put('/threads/:threadId', async (c) => {\n const threadId = c.req.param('threadId')!;\n const body: UpdateThreadRequest = await c.req.json();\n await this.threadsManager.set(threadId, body);\n const response: RemoteResponse = {\n success: true,\n };\n return c.json(response, 200);\n });\n\n // Thread: Delete\n app.delete('/threads/:threadId', async (c) => {\n const threadId = c.req.param('threadId')!;\n await this.threadsManager.delete(threadId);\n const response: RemoteResponse = {\n success: true,\n };\n return c.json(response, 200);\n });\n\n // Thread: Update State\n app.post('/threads/:threadId/state', async (c) => {\n const threadId = c.req.param('threadId')!;\n const body: UpdateStateRequest = await c.req.json();\n const result = await this.threadsManager.updateState(threadId, body);\n const response: RemoteResponse<UpdateStateResponse> = {\n success: true,\n data: result as any,\n };\n return c.json(response, 200);\n });\n\n // Run: Create\n app.post('/threads/:threadId/runs', async (c) => {\n const threadId = c.req.param('threadId')!;\n const assistantId = c.req.query('assistantId')!;\n const body: CreateRunRequest = await c.req.json();\n const run = await this.threadsManager.createRun(threadId, assistantId, body);\n const response: RemoteResponse = {\n success: true,\n data: run,\n };\n return c.json(response, 201);\n });\n\n // Run: List\n app.get('/threads/:threadId/runs', async (c) => {\n const threadId = c.req.param('threadId')!;\n const query: ListRunsRequest = {\n limit: c.req.query('limit') ? parseInt(c.req.query('limit')!) : undefined,\n offset: c.req.query('offset') ? parseInt(c.req.query('offset')!) : undefined,\n status: c.req.query('status') as any,\n };\n const runs = await this.threadsManager.listRuns(threadId, query);\n const response: RemoteResponse = {\n success: true,\n data: runs,\n };\n return c.json(response, 200);\n });\n\n // Run: Update\n app.put('/runs/:runId', async (c) => {\n const runId = c.req.param('runId')!;\n const body: UpdateRunRequest = await c.req.json();\n await this.threadsManager.updateRun(runId, body);\n const response: RemoteResponse = {\n success: true,\n };\n return c.json(response, 200);\n });\n\n return app;\n }\n}\n","/**\n * Remote PostgreSQL Server 启动示例\n *\n * 这个文件展示如何启动一个远程 PG 服务器\n * 运行: bun run src/storage/remote/server.ts\n */\n\nimport { Hono } from 'hono';\nimport { RemoteServer } from './remote-server';\nimport { PostgresAdapter } from '../kysely/pg-adapter';\nimport { KyselyThreadsManager } from '../kysely/threads';\nimport { Pool } from 'pg';\n\nconst app = new Hono();\n// 从环境变量获取数据库连接字符串\nconst databaseUrl = process.env.DATABASE_URL;\n\nif (!databaseUrl) {\n console.error('DATABASE_URL environment variable is required');\n console.error('Example: DATABASE_URL=postgresql://user:password@localhost:5432/dbname');\n process.exit(1);\n}\n\nconsole.log('Starting Remote PostgreSQL Server...');\n\n// 创建 PG 连接池\nconst pool = new Pool({\n connectionString: databaseUrl,\n});\n\n// 创建适配器\nconst pgAdapter = new PostgresAdapter(pool);\n\n// 创建 ThreadsManager\nconst threadsManager = new KyselyThreadsManager(pgAdapter);\n\nawait threadsManager.setup();\n// 创建远程服务器\nconst remoteServer = new RemoteServer(threadsManager);\n\n// 注册路由\napp.route('/api/remote', remoteServer.getRouter());\n\n// 添加健康检查端点\napp.get('/health', (c) => {\n return c.json({ status: 'ok', timestamp: new Date().toISOString() });\n});\n\n// 获取配置的端口\nconst port = parseInt(process.env.PORT || '3001');\n\nconsole.log(`Remote PostgreSQL Server is running on port ${port}`);\nconsole.log(`API Base URL: http://localhost:${port}/api/remote`);\nconsole.log(`Health Check: http://localhost:${port}/health`);\nconsole.log('');\nconsole.log('Client Configuration:');\nconsole.log(` DATABASE_URL=http://localhost:${port}/api/remote`);\n// 启动服务器\nexport default {\n fetch: app.fetch,\n port,\n};\n"],"names":[],"mappings":";;;;;AAyBO,MAAM,YAAA,CAAa;AAAA,EACtB,YAAoB,cAAA,EAAoC;AAApC,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AAAA,EAAqC;AAAA;AAAA;AAAA;AAAA,EAKzD,SAAA,GAAkB;AACd,IAAA,MAAM,GAAA,GAAM,IAAI,IAAA,EAAK;AAGrB,IAAA,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU,OAAO,CAAA,KAAM;AAC5B,MAAA,MAAM,IAAA,CAAK,eAAe,KAAA,EAAM;AAChC,MAAA,MAAM,QAAA,GAA0C;AAAA,QAC5C,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM,EAAE,OAAA,EAAS,mCAAA;AAAoC,OACzD;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,IAAA,CAAK,UAAA,EAAY,OAAO,CAAA,KAAM;AAC9B,MAAA,MAAM,IAAA,GAA4B,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AACnD,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAe,OAAO,IAAI,CAAA;AACpD,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACV;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,GAAA,CAAI,UAAA,EAAY,OAAO,CAAA,KAAM;AAC7B,MAAA,MAAM,KAAA,GAA8B;AAAA,QAChC,GAAA,EAAK,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,KAAK,CAAE,CAAA,GAAI,MAAA;AAAA,QAC5D,QAAA,EAAU,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAE,CAAA,GAAI,MAAA;AAAA,QAC3E,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,OAAO,CAAE,CAAA,GAAI,MAAA;AAAA,QAChE,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAE,CAAA,GAAI,MAAA;AAAA,QACnE,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA;AAAA,QAC5B,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA;AAAA,QAC5B,SAAA,EAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,WAAW,CAAA;AAAA,QAClC,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAE,CAAA,GAAI,MAAA;AAAA,QACrE,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAE,CAAA,GAAI,MAAA;AAAA,QACrE,cAAA,EAAgB,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,gBAAgB,CAAA,KAAM;AAAA,OACtD;AACA,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,cAAA,CAAe,OAAO,KAAK,CAAA;AACtD,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACV;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,GAAA,CAAI,oBAAA,EAAsB,OAAO,CAAA,KAAM;AACvC,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA;AACvC,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,QAAQ,CAAA;AACrD,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACV;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,GAAA,CAAI,oBAAA,EAAsB,OAAO,CAAA,KAAM;AACvC,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA;AACvC,MAAA,MAAM,IAAA,GAA4B,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AACnD,MAAA,MAAM,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,QAAA,EAAU,IAAI,CAAA;AAC5C,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS;AAAA,OACb;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,MAAA,CAAO,oBAAA,EAAsB,OAAO,CAAA,KAAM;AAC1C,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA;AACvC,MAAA,MAAM,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AACzC,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS;AAAA,OACb;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,IAAA,CAAK,0BAAA,EAA4B,OAAO,CAAA,KAAM;AAC9C,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA;AACvC,MAAA,MAAM,IAAA,GAA2B,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAClD,MAAA,MAAM,SAAS,MAAM,IAAA,CAAK,cAAA,CAAe,WAAA,CAAY,UAAU,IAAI,CAAA;AACnE,MAAA,MAAM,QAAA,GAAgD;AAAA,QAClD,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACV;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,IAAA,CAAK,yBAAA,EAA2B,OAAO,CAAA,KAAM;AAC7C,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA;AACvC,MAAA,MAAM,WAAA,GAAc,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,aAAa,CAAA;AAC7C,MAAA,MAAM,IAAA,GAAyB,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAChD,MAAA,MAAM,MAAM,MAAM,IAAA,CAAK,eAAe,SAAA,CAAU,QAAA,EAAU,aAAa,IAAI,CAAA;AAC3E,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACV;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,GAAA,CAAI,yBAAA,EAA2B,OAAO,CAAA,KAAM;AAC5C,MAAA,MAAM,QAAA,GAAW,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,UAAU,CAAA;AACvC,MAAA,MAAM,KAAA,GAAyB;AAAA,QAC3B,KAAA,EAAO,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,OAAO,CAAE,CAAA,GAAI,MAAA;AAAA,QAChE,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ,CAAE,CAAA,GAAI,MAAA;AAAA,QACnE,MAAA,EAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,QAAQ;AAAA,OAChC;AACA,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,cAAA,CAAe,QAAA,CAAS,UAAU,KAAK,CAAA;AAC/D,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM;AAAA,OACV;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAGD,IAAA,GAAA,CAAI,GAAA,CAAI,cAAA,EAAgB,OAAO,CAAA,KAAM;AACjC,MAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AACjC,MAAA,MAAM,IAAA,GAAyB,MAAM,CAAA,CAAE,GAAA,CAAI,IAAA,EAAK;AAChD,MAAA,MAAM,IAAA,CAAK,cAAA,CAAe,SAAA,CAAU,KAAA,EAAO,IAAI,CAAA;AAC/C,MAAA,MAAM,QAAA,GAA2B;AAAA,QAC7B,OAAA,EAAS;AAAA,OACb;AACA,MAAA,OAAO,CAAA,CAAE,IAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAAA,IAC/B,CAAC,CAAA;AAED,IAAA,OAAO,GAAA;AAAA,EACX;AACJ;;ACtJA,MAAM,GAAA,GAAM,IAAI,IAAA,EAAK;AAErB,MAAM,WAAA,GAAc,QAAQ,GAAA,CAAI,YAAA;AAEhC,IAAI,CAAC,WAAA,EAAa;AACd,EAAA,OAAA,CAAQ,MAAM,+CAA+C,CAAA;AAC7D,EAAA,OAAA,CAAQ,MAAM,wEAAwE,CAAA;AACtF,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAClB;AAEA,OAAA,CAAQ,IAAI,sCAAsC,CAAA;AAGlD,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK;AAAA,EAClB,gBAAA,EAAkB;AACtB,CAAC,CAAA;AAGD,MAAM,SAAA,GAAY,IAAI,eAAA,CAAgB,IAAI,CAAA;AAG1C,MAAM,cAAA,GAAiB,IAAI,oBAAA,CAAqB,SAAS,CAAA;AAEzD,MAAM,eAAe,KAAA,EAAM;AAE3B,MAAM,YAAA,GAAe,IAAI,YAAA,CAAa,cAAc,CAAA;AAGpD,GAAA,CAAI,KAAA,CAAM,aAAA,EAAe,YAAA,CAAa,SAAA,EAAW,CAAA;AAGjD,GAAA,CAAI,GAAA,CAAI,SAAA,EAAW,CAAC,CAAA,KAAM;AACtB,EAAA,OAAO,CAAA,CAAE,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAG,CAAA;AACvE,CAAC,CAAA;AAGD,MAAM,IAAA,GAAO,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,QAAQ,MAAM,CAAA;AAEhD,OAAA,CAAQ,GAAA,CAAI,CAAA,4CAAA,EAA+C,IAAI,CAAA,CAAE,CAAA;AACjE,OAAA,CAAQ,GAAA,CAAI,CAAA,+BAAA,EAAkC,IAAI,CAAA,WAAA,CAAa,CAAA;AAC/D,OAAA,CAAQ,GAAA,CAAI,CAAA,+BAAA,EAAkC,IAAI,CAAA,OAAA,CAAS,CAAA;AAC3D,OAAA,CAAQ,IAAI,EAAE,CAAA;AACd,OAAA,CAAQ,IAAI,uBAAuB,CAAA;AACnC,OAAA,CAAQ,GAAA,CAAI,CAAA,gCAAA,EAAmC,IAAI,CAAA,WAAA,CAAa,CAAA;AAEhE,eAAe;AAAA,EACX,OAAO,GAAA,CAAI,KAAA;AAAA,EACX;AACJ,CAAA;;;;"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
var RemoteErrorCode = /* @__PURE__ */ ((RemoteErrorCode2) => {
|
|
2
|
+
RemoteErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
3
|
+
RemoteErrorCode2["CONNECTION_TIMEOUT"] = "CONNECTION_TIMEOUT";
|
|
4
|
+
RemoteErrorCode2["INTERNAL_ERROR"] = "INTERNAL_ERROR";
|
|
5
|
+
RemoteErrorCode2["THREAD_NOT_FOUND"] = "THREAD_NOT_FOUND";
|
|
6
|
+
RemoteErrorCode2["THREAD_BUSY"] = "THREAD_BUSY";
|
|
7
|
+
RemoteErrorCode2["RUN_NOT_FOUND"] = "RUN_NOT_FOUND";
|
|
8
|
+
RemoteErrorCode2["GRAPH_NOT_FOUND"] = "GRAPH_NOT_FOUND";
|
|
9
|
+
RemoteErrorCode2["INVALID_REQUEST"] = "INVALID_REQUEST";
|
|
10
|
+
return RemoteErrorCode2;
|
|
11
|
+
})(RemoteErrorCode || {});
|
|
12
|
+
class RemoteApiError extends Error {
|
|
13
|
+
constructor(code, message, statusCode) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.statusCode = statusCode;
|
|
17
|
+
this.name = "RemoteApiError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function request(url, method, options) {
|
|
22
|
+
try {
|
|
23
|
+
let requestUrl = url;
|
|
24
|
+
if (options?.query) {
|
|
25
|
+
const searchParams = new URLSearchParams();
|
|
26
|
+
Object.entries(options.query).forEach(([key, value]) => {
|
|
27
|
+
searchParams.append(key, String(value));
|
|
28
|
+
});
|
|
29
|
+
requestUrl += `?${searchParams.toString()}`;
|
|
30
|
+
}
|
|
31
|
+
const response = await fetch(requestUrl, {
|
|
32
|
+
method,
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json"
|
|
35
|
+
},
|
|
36
|
+
body: options?.body ? JSON.stringify(options.body) : void 0
|
|
37
|
+
});
|
|
38
|
+
const data = await response.json();
|
|
39
|
+
if (!response.ok || !data.success) {
|
|
40
|
+
throw new RemoteApiError(
|
|
41
|
+
data.error?.code || RemoteErrorCode.INTERNAL_ERROR,
|
|
42
|
+
data.error?.message || "Unknown error",
|
|
43
|
+
response.status
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return data;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error instanceof RemoteApiError) {
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
throw new RemoteApiError(
|
|
52
|
+
RemoteErrorCode.NETWORK_ERROR,
|
|
53
|
+
`Network error: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function remoteGet(url, query) {
|
|
58
|
+
return request(url, "GET", { query });
|
|
59
|
+
}
|
|
60
|
+
async function remotePost(url, body, query) {
|
|
61
|
+
return request(url, "POST", { body, query });
|
|
62
|
+
}
|
|
63
|
+
async function remotePut(url, body, query) {
|
|
64
|
+
return request(url, "PUT", { body, query });
|
|
65
|
+
}
|
|
66
|
+
async function remoteDelete(url, query) {
|
|
67
|
+
return request(url, "DELETE", { query });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class RemoteKyselyThreadsManager {
|
|
71
|
+
constructor(serverUrl, httpClient) {
|
|
72
|
+
this.serverUrl = serverUrl;
|
|
73
|
+
this.httpClient = httpClient;
|
|
74
|
+
this.serverUrl = serverUrl.replace(/\/$/, "");
|
|
75
|
+
this.httpClient = httpClient || fetch;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 初始化数据库
|
|
79
|
+
*/
|
|
80
|
+
async setup() {
|
|
81
|
+
await remotePost(`${this.serverUrl}/setup`);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 创建线程
|
|
85
|
+
*/
|
|
86
|
+
async create(payload) {
|
|
87
|
+
const response = await remotePost(`${this.serverUrl}/threads`, payload);
|
|
88
|
+
return response.data;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 搜索线程
|
|
92
|
+
*/
|
|
93
|
+
async search(query) {
|
|
94
|
+
const params = {};
|
|
95
|
+
if (query?.ids !== void 0 && query.ids.length > 0) {
|
|
96
|
+
params.ids = JSON.stringify(query.ids);
|
|
97
|
+
}
|
|
98
|
+
if (query?.metadata !== void 0) {
|
|
99
|
+
params.metadata = JSON.stringify(query.metadata);
|
|
100
|
+
}
|
|
101
|
+
if (query?.limit !== void 0) {
|
|
102
|
+
params.limit = query.limit;
|
|
103
|
+
}
|
|
104
|
+
if (query?.offset !== void 0) {
|
|
105
|
+
params.offset = query.offset;
|
|
106
|
+
}
|
|
107
|
+
if (query?.status !== void 0) {
|
|
108
|
+
params.status = query.status;
|
|
109
|
+
}
|
|
110
|
+
if (query?.sortBy !== void 0) {
|
|
111
|
+
params.sortBy = query.sortBy;
|
|
112
|
+
}
|
|
113
|
+
if (query?.sortOrder !== void 0) {
|
|
114
|
+
params.sortOrder = query.sortOrder;
|
|
115
|
+
}
|
|
116
|
+
if (query?.values !== void 0) {
|
|
117
|
+
params.values = JSON.stringify(query.values);
|
|
118
|
+
}
|
|
119
|
+
if (query?.select !== void 0) {
|
|
120
|
+
params.select = JSON.stringify(query.select);
|
|
121
|
+
}
|
|
122
|
+
if (query?.withoutDetails !== void 0) {
|
|
123
|
+
params.withoutDetails = query.withoutDetails;
|
|
124
|
+
}
|
|
125
|
+
const response = await remoteGet(`${this.serverUrl}/threads`, params);
|
|
126
|
+
return response.data;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 获取线程
|
|
130
|
+
*/
|
|
131
|
+
async get(threadId) {
|
|
132
|
+
const response = await remoteGet(`${this.serverUrl}/threads/${threadId}`);
|
|
133
|
+
return response.data;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 更新线程
|
|
137
|
+
*/
|
|
138
|
+
async set(threadId, thread) {
|
|
139
|
+
await remotePut(`${this.serverUrl}/threads/${threadId}`, thread);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 删除线程
|
|
143
|
+
*/
|
|
144
|
+
async delete(threadId) {
|
|
145
|
+
await remoteDelete(`${this.serverUrl}/threads/${threadId}`);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 更新状态
|
|
149
|
+
*/
|
|
150
|
+
async updateState(threadId, thread) {
|
|
151
|
+
const response = await remotePost(
|
|
152
|
+
`${this.serverUrl}/threads/${threadId}/state`,
|
|
153
|
+
thread
|
|
154
|
+
);
|
|
155
|
+
return response.data;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 创建运行
|
|
159
|
+
*/
|
|
160
|
+
async createRun(threadId, assistantId, payload) {
|
|
161
|
+
const response = await remotePost(`${this.serverUrl}/threads/${threadId}/runs`, payload || {}, {
|
|
162
|
+
assistantId
|
|
163
|
+
});
|
|
164
|
+
return response.data;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 列出运行
|
|
168
|
+
*/
|
|
169
|
+
async listRuns(threadId, options) {
|
|
170
|
+
const params = {};
|
|
171
|
+
if (options?.limit !== void 0) {
|
|
172
|
+
params.limit = options.limit;
|
|
173
|
+
}
|
|
174
|
+
if (options?.offset !== void 0) {
|
|
175
|
+
params.offset = options.offset;
|
|
176
|
+
}
|
|
177
|
+
if (options?.status !== void 0) {
|
|
178
|
+
params.status = options.status;
|
|
179
|
+
}
|
|
180
|
+
const response = await remoteGet(`${this.serverUrl}/threads/${threadId}/runs`, params);
|
|
181
|
+
return response.data;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 更新运行
|
|
185
|
+
*/
|
|
186
|
+
async updateRun(runId, run) {
|
|
187
|
+
await remotePut(`${this.serverUrl}/runs/${runId}`, run);
|
|
188
|
+
}
|
|
189
|
+
// New methods for Threads API
|
|
190
|
+
/**
|
|
191
|
+
* 计算线程数量
|
|
192
|
+
*/
|
|
193
|
+
async count(query) {
|
|
194
|
+
const params = {};
|
|
195
|
+
if (query?.ids !== void 0 && query.ids.length > 0) {
|
|
196
|
+
params.ids = JSON.stringify(query.ids);
|
|
197
|
+
}
|
|
198
|
+
if (query?.metadata !== void 0) {
|
|
199
|
+
params.metadata = JSON.stringify(query.metadata);
|
|
200
|
+
}
|
|
201
|
+
if (query?.status !== void 0) {
|
|
202
|
+
params.status = query.status;
|
|
203
|
+
}
|
|
204
|
+
if (query?.values !== void 0) {
|
|
205
|
+
params.values = JSON.stringify(query.values);
|
|
206
|
+
}
|
|
207
|
+
const response = await remoteGet(`${this.serverUrl}/threads/count`, params);
|
|
208
|
+
return response.data;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 更新线程元数据
|
|
212
|
+
*/
|
|
213
|
+
async patch(threadId, updates) {
|
|
214
|
+
const response = await remotePost(`${this.serverUrl}/threads/${threadId}`, updates);
|
|
215
|
+
return response.data;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* 获取线程状态
|
|
219
|
+
*/
|
|
220
|
+
async getState(threadId, options) {
|
|
221
|
+
const params = {};
|
|
222
|
+
if (options?.subgraphs !== void 0) {
|
|
223
|
+
params.subgraphs = options.subgraphs;
|
|
224
|
+
}
|
|
225
|
+
if (options?.checkpointId !== void 0) {
|
|
226
|
+
params.checkpointId = options.checkpointId;
|
|
227
|
+
}
|
|
228
|
+
const response = await remotePost(`${this.serverUrl}/threads/${threadId}/state`, params);
|
|
229
|
+
return response.data;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 获取线程历史
|
|
233
|
+
*/
|
|
234
|
+
async getStateHistory(threadId, options) {
|
|
235
|
+
const params = {};
|
|
236
|
+
if (options?.limit !== void 0) {
|
|
237
|
+
params.limit = options.limit;
|
|
238
|
+
}
|
|
239
|
+
if (options?.before !== void 0) {
|
|
240
|
+
params.before = options.before;
|
|
241
|
+
}
|
|
242
|
+
const response = await remotePost(`${this.serverUrl}/threads/${threadId}/history`, params);
|
|
243
|
+
return response.data;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* 复制线程
|
|
247
|
+
*/
|
|
248
|
+
async copy(threadId) {
|
|
249
|
+
const response = await remotePost(`${this.serverUrl}/threads/${threadId}/copy`);
|
|
250
|
+
return response.data;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export { RemoteKyselyThreadsManager };
|
|
255
|
+
//# sourceMappingURL=remote-threads-CrG03ZS7.js.map
|