@seaverse/conversation-sdk 0.2.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 +284 -0
- package/dist/aggregated/apps-with-conversations.d.ts +47 -0
- package/dist/aggregated/apps-with-conversations.d.ts.map +1 -0
- package/dist/aggregated/apps-with-conversations.js +90 -0
- package/dist/aggregated/apps-with-conversations.js.map +1 -0
- package/dist/aggregated/index.d.ts +3 -0
- package/dist/aggregated/index.d.ts.map +1 -0
- package/dist/aggregated/index.js +2 -0
- package/dist/aggregated/index.js.map +1 -0
- package/dist/client/ConversationClient.d.ts +24 -0
- package/dist/client/ConversationClient.d.ts.map +1 -0
- package/dist/client/ConversationClient.js +56 -0
- package/dist/client/ConversationClient.js.map +1 -0
- package/dist/client/ConversationsClient.d.ts +31 -0
- package/dist/client/ConversationsClient.d.ts.map +1 -0
- package/dist/client/ConversationsClient.js +50 -0
- package/dist/client/ConversationsClient.js.map +1 -0
- package/dist/client/EnvironmentConfig.d.ts +12 -0
- package/dist/client/EnvironmentConfig.d.ts.map +1 -0
- package/dist/client/EnvironmentConfig.js +21 -0
- package/dist/client/EnvironmentConfig.js.map +1 -0
- package/dist/client/MessagesClient.d.ts +31 -0
- package/dist/client/MessagesClient.d.ts.map +1 -0
- package/dist/client/MessagesClient.js +57 -0
- package/dist/client/MessagesClient.js.map +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/data/DbClient.d.ts +76 -0
- package/dist/data/DbClient.d.ts.map +1 -0
- package/dist/data/DbClient.js +107 -0
- package/dist/data/DbClient.js.map +1 -0
- package/dist/data/index.d.ts +2 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +2 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/postgrest-headers.d.ts +10 -0
- package/dist/data/postgrest-headers.d.ts.map +1 -0
- package/dist/data/postgrest-headers.js +58 -0
- package/dist/data/postgrest-headers.js.map +1 -0
- package/dist/data/query.types.d.ts +62 -0
- package/dist/data/query.types.d.ts.map +1 -0
- package/dist/data/query.types.js +2 -0
- package/dist/data/query.types.js.map +1 -0
- package/dist/errors/AuthError.d.ts +8 -0
- package/dist/errors/AuthError.d.ts.map +1 -0
- package/dist/errors/AuthError.js +10 -0
- package/dist/errors/AuthError.js.map +1 -0
- package/dist/errors/BaseError.d.ts +17 -0
- package/dist/errors/BaseError.d.ts.map +1 -0
- package/dist/errors/BaseError.js +26 -0
- package/dist/errors/BaseError.js.map +1 -0
- package/dist/errors/NetworkError.d.ts +8 -0
- package/dist/errors/NetworkError.d.ts.map +1 -0
- package/dist/errors/NetworkError.js +10 -0
- package/dist/errors/NetworkError.js.map +1 -0
- package/dist/errors/ProtocolError.d.ts +8 -0
- package/dist/errors/ProtocolError.d.ts.map +1 -0
- package/dist/errors/ProtocolError.js +10 -0
- package/dist/errors/ProtocolError.js.map +1 -0
- package/dist/errors/TimeoutError.d.ts +8 -0
- package/dist/errors/TimeoutError.d.ts.map +1 -0
- package/dist/errors/TimeoutError.js +10 -0
- package/dist/errors/TimeoutError.js.map +1 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +6 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/functional-api.d.ts +24 -0
- package/dist/functional-api.d.ts.map +1 -0
- package/dist/functional-api.js +59 -0
- package/dist/functional-api.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/AppsResource.d.ts +37 -0
- package/dist/resources/AppsResource.d.ts.map +1 -0
- package/dist/resources/AppsResource.js +51 -0
- package/dist/resources/AppsResource.js.map +1 -0
- package/dist/resources/ConversationsResource.d.ts +81 -0
- package/dist/resources/ConversationsResource.d.ts.map +1 -0
- package/dist/resources/ConversationsResource.js +103 -0
- package/dist/resources/ConversationsResource.js.map +1 -0
- package/dist/resources/MessagesResource.d.ts +56 -0
- package/dist/resources/MessagesResource.d.ts.map +1 -0
- package/dist/resources/MessagesResource.js +115 -0
- package/dist/resources/MessagesResource.js.map +1 -0
- package/dist/session/session-token.d.ts +38 -0
- package/dist/session/session-token.d.ts.map +1 -0
- package/dist/session/session-token.js +74 -0
- package/dist/session/session-token.js.map +1 -0
- package/dist/transforms/app.transform.d.ts +6 -0
- package/dist/transforms/app.transform.d.ts.map +1 -0
- package/dist/transforms/app.transform.js +39 -0
- package/dist/transforms/app.transform.js.map +1 -0
- package/dist/transforms/conversation.transform.d.ts +10 -0
- package/dist/transforms/conversation.transform.d.ts.map +1 -0
- package/dist/transforms/conversation.transform.js +45 -0
- package/dist/transforms/conversation.transform.js.map +1 -0
- package/dist/transforms/message.transform.d.ts +12 -0
- package/dist/transforms/message.transform.d.ts.map +1 -0
- package/dist/transforms/message.transform.js +119 -0
- package/dist/transforms/message.transform.js.map +1 -0
- package/dist/transport/HttpClient.d.ts +34 -0
- package/dist/transport/HttpClient.d.ts.map +1 -0
- package/dist/transport/HttpClient.js +158 -0
- package/dist/transport/HttpClient.js.map +1 -0
- package/dist/transport/config.types.d.ts +40 -0
- package/dist/transport/config.types.d.ts.map +1 -0
- package/dist/transport/config.types.js +2 -0
- package/dist/transport/config.types.js.map +1 -0
- package/dist/transport/index.d.ts +10 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +11 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/timeout.d.ts +12 -0
- package/dist/transport/timeout.d.ts.map +1 -0
- package/dist/transport/timeout.js +29 -0
- package/dist/transport/timeout.js.map +1 -0
- package/dist/types/common.types.d.ts +24 -0
- package/dist/types/common.types.d.ts.map +1 -0
- package/dist/types/common.types.js +5 -0
- package/dist/types/common.types.js.map +1 -0
- package/dist/types/config.types.d.ts +28 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/config.types.js +2 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/http.types.d.ts +47 -0
- package/dist/types/http.types.d.ts.map +1 -0
- package/dist/types/http.types.js +2 -0
- package/dist/types/http.types.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/models.types.d.ts +118 -0
- package/dist/types/models.types.d.ts.map +1 -0
- package/dist/types/models.types.js +5 -0
- package/dist/types/models.types.js.map +1 -0
- package/dist/types/pagination.types.d.ts +69 -0
- package/dist/types/pagination.types.d.ts.map +1 -0
- package/dist/types/pagination.types.js +24 -0
- package/dist/types/pagination.types.js.map +1 -0
- package/dist/types/token.types.d.ts +6 -0
- package/dist/types/token.types.d.ts.map +1 -0
- package/dist/types/token.types.js +2 -0
- package/dist/types/token.types.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeoutError.js","sourceRoot":"","sources":["../../src/errors/TimeoutError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,YAAY,UAAkB,iBAAiB,EAAE,SAAkB;QACjE,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BaseError } from './BaseError.js';
|
|
2
|
+
export { NetworkError } from './NetworkError.js';
|
|
3
|
+
export { AuthError } from './AuthError.js';
|
|
4
|
+
export { TimeoutError } from './TimeoutError.js';
|
|
5
|
+
export { ProtocolError } from './ProtocolError.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BaseError } from './BaseError.js';
|
|
2
|
+
export { NetworkError } from './NetworkError.js';
|
|
3
|
+
export { AuthError } from './AuthError.js';
|
|
4
|
+
export { TimeoutError } from './TimeoutError.js';
|
|
5
|
+
export { ProtocolError } from './ProtocolError.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 函数式 API
|
|
3
|
+
* 提供简洁的函数式调用方式
|
|
4
|
+
*/
|
|
5
|
+
import type { ConversationClientConfig } from './types/config.types.js';
|
|
6
|
+
import type { ListAppsWithConversationsResult, Message } from './types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* 初始化 Conversation SDK
|
|
9
|
+
*/
|
|
10
|
+
export declare function initConversationSdk(config: ConversationClientConfig): {
|
|
11
|
+
getAppsWithConversationsList: (options?: {
|
|
12
|
+
appId?: string;
|
|
13
|
+
page?: number;
|
|
14
|
+
pageSize?: number;
|
|
15
|
+
}) => Promise<ListAppsWithConversationsResult>;
|
|
16
|
+
getMessagesList: (conversationId: string, options?: {
|
|
17
|
+
page?: number;
|
|
18
|
+
pageSize?: number;
|
|
19
|
+
}) => Promise<{
|
|
20
|
+
messages: Message[];
|
|
21
|
+
hasMore: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=functional-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functional-api.d.ts","sourceRoot":"","sources":["../src/functional-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAGxE,OAAO,KAAK,EAAE,+BAA+B,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGjF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,wBAAwB;6CA4BZ;QACpD,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,KAAG,OAAO,CAAC,+BAA+B,CAAC;sCAW1B,MAAM,YACZ;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,KACA,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;EActD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 函数式 API
|
|
3
|
+
* 提供简洁的函数式调用方式
|
|
4
|
+
*/
|
|
5
|
+
import { createHttpClient } from './transport/index.js';
|
|
6
|
+
import { DbClient } from './data/DbClient.js';
|
|
7
|
+
import { getEnvironmentConfig } from './client/EnvironmentConfig.js';
|
|
8
|
+
import { listAppsWithConversations } from './aggregated/apps-with-conversations.js';
|
|
9
|
+
import { MessagesResource } from './resources/MessagesResource.js';
|
|
10
|
+
/**
|
|
11
|
+
* 初始化 Conversation SDK
|
|
12
|
+
*/
|
|
13
|
+
export function initConversationSdk(config) {
|
|
14
|
+
// 环境配置解析
|
|
15
|
+
const envConfig = getEnvironmentConfig(config.environment);
|
|
16
|
+
const fullConfig = {
|
|
17
|
+
environment: config.environment,
|
|
18
|
+
token: config.token,
|
|
19
|
+
getToken: config.getToken || (() => config.token),
|
|
20
|
+
fetch: config.fetch || globalThis.fetch,
|
|
21
|
+
timeout: config.timeout || 30000,
|
|
22
|
+
urls: envConfig,
|
|
23
|
+
};
|
|
24
|
+
// 创建底层客户端
|
|
25
|
+
const http = createHttpClient({
|
|
26
|
+
baseUrl: fullConfig.urls.postgrest,
|
|
27
|
+
fetch: fullConfig.fetch,
|
|
28
|
+
getAuthToken: fullConfig.getToken,
|
|
29
|
+
timeoutMs: fullConfig.timeout,
|
|
30
|
+
});
|
|
31
|
+
const db = new DbClient(http);
|
|
32
|
+
const messagesResource = new MessagesResource(db);
|
|
33
|
+
/**
|
|
34
|
+
* 获取 Apps 及其会话列表
|
|
35
|
+
* 每个 app 只返回消息最多的那一个会话
|
|
36
|
+
*/
|
|
37
|
+
async function getAppsWithConversationsList(options) {
|
|
38
|
+
return listAppsWithConversations({
|
|
39
|
+
...options,
|
|
40
|
+
db,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 获取会话的消息列表(旧 API 格式)
|
|
45
|
+
*/
|
|
46
|
+
async function getMessagesList(conversationId, options) {
|
|
47
|
+
const result = await messagesResource.list(conversationId, options);
|
|
48
|
+
// 转换为旧 API 格式:{messages: [...], hasMore: boolean}
|
|
49
|
+
return {
|
|
50
|
+
messages: result.data,
|
|
51
|
+
hasMore: result.pagination.hasNextPage,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
getAppsWithConversationsList,
|
|
56
|
+
getMessagesList,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=functional-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functional-api.js","sourceRoot":"","sources":["../src/functional-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAgC;IAClE,SAAS;IACT,MAAM,SAAS,GAAG,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3D,MAAM,UAAU,GAAG;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;QACjD,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK;QACvC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK;QAChC,IAAI,EAAE,SAAS;KAChB,CAAC;IAEF,UAAU;IACV,MAAM,IAAI,GAAG,gBAAgB,CAAC;QAC5B,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS;QAClC,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,YAAY,EAAE,UAAU,CAAC,QAAQ;QACjC,SAAS,EAAE,UAAU,CAAC,OAAO;KAC9B,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAElD;;;OAGG;IACH,KAAK,UAAU,4BAA4B,CAAC,OAI3C;QACC,OAAO,yBAAyB,CAAC;YAC/B,GAAG,OAAO;YACV,EAAE;SACH,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,eAAe,CAC5B,cAAsB,EACtB,OAGC;QAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAEpE,kDAAkD;QAClD,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,IAAI;YACrB,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW;SACvC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,4BAA4B;QAC5B,eAAe;KAChB,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { initConversationSdk } from './functional-api.js';
|
|
2
|
+
export type { ConversationClientConfig } from './types/config.types.js';
|
|
3
|
+
export type { Conversation, Message, ToolCall, } from './types/index.js';
|
|
4
|
+
export { BaseError, NetworkError, AuthError, TimeoutError, ProtocolError, } from './errors/index.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAKxE,YAAY,EAEV,YAAY,EAEZ,OAAO,EACP,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,GACd,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// ═══════════════════════════════════════
|
|
2
|
+
// 主 API
|
|
3
|
+
// ═══════════════════════════════════════
|
|
4
|
+
export { initConversationSdk } from './functional-api.js';
|
|
5
|
+
// ═══════════════════════════════════════
|
|
6
|
+
// 错误类型(供错误处理使用)
|
|
7
|
+
// ═══════════════════════════════════════
|
|
8
|
+
export { BaseError, NetworkError, AuthError, TimeoutError, ProtocolError, } from './errors/index.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,QAAQ;AACR,0CAA0C;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAc1D,0CAA0C;AAC1C,gBAAgB;AAChB,0CAA0C;AAC1C,OAAO,EACL,SAAS,EACT,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,aAAa,GACd,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DbClient } from '../data/DbClient.js';
|
|
2
|
+
import type { App } from '../types/models.types.js';
|
|
3
|
+
import type { PaginationOptions, PaginatedResult } from '../types/pagination.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 应用列表查询选项
|
|
6
|
+
*/
|
|
7
|
+
export interface ListAppsOptions extends PaginationOptions {
|
|
8
|
+
/**
|
|
9
|
+
* 按用户 ID 过滤
|
|
10
|
+
*/
|
|
11
|
+
userId?: string;
|
|
12
|
+
/**
|
|
13
|
+
* 按状态过滤
|
|
14
|
+
*/
|
|
15
|
+
status?: 'draft' | 'published' | 'archived';
|
|
16
|
+
/**
|
|
17
|
+
* 排序方向
|
|
18
|
+
* @default 'desc'
|
|
19
|
+
*/
|
|
20
|
+
order?: 'asc' | 'desc';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 应用资源类
|
|
24
|
+
*/
|
|
25
|
+
export declare class AppsResource {
|
|
26
|
+
private readonly db;
|
|
27
|
+
constructor(db: DbClient);
|
|
28
|
+
/**
|
|
29
|
+
* 列出应用(带分页)
|
|
30
|
+
*/
|
|
31
|
+
list(options?: ListAppsOptions): Promise<PaginatedResult<App>>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取单个应用
|
|
34
|
+
*/
|
|
35
|
+
get(id: string): Promise<App | null>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=AppsResource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppsResource.d.ts","sourceRoot":"","sources":["../../src/resources/AppsResource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,GAAG,EAAY,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIvF;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,CAAC;IAE5C;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAEzC;;OAEG;IACG,IAAI,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IA6BxE;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;CAS3C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { calculatePaginationMeta, pageToOffset } from '../types/pagination.types.js';
|
|
2
|
+
import { transformApp } from '../transforms/app.transform.js';
|
|
3
|
+
/**
|
|
4
|
+
* 应用资源类
|
|
5
|
+
*/
|
|
6
|
+
export class AppsResource {
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 列出应用(带分页)
|
|
12
|
+
*/
|
|
13
|
+
async list(options = {}) {
|
|
14
|
+
// 分页参数
|
|
15
|
+
const page = options.page || 1;
|
|
16
|
+
const pageSize = options.pageSize || 20;
|
|
17
|
+
const { limit, offset } = pageToOffset(page, pageSize);
|
|
18
|
+
// 构建过滤条件
|
|
19
|
+
const filter = {};
|
|
20
|
+
if (options.userId)
|
|
21
|
+
filter.user_id = `eq.${options.userId}`;
|
|
22
|
+
if (options.status)
|
|
23
|
+
filter.status = `eq.${options.status}`;
|
|
24
|
+
const dbApps = await this.db.get('apps', {
|
|
25
|
+
filter,
|
|
26
|
+
order: `created_at.${options.order || 'desc'}`,
|
|
27
|
+
limit,
|
|
28
|
+
offset,
|
|
29
|
+
count: 'exact',
|
|
30
|
+
});
|
|
31
|
+
// 获取总数(从响应头)
|
|
32
|
+
const total = dbApps.count || 0;
|
|
33
|
+
const pagination = calculatePaginationMeta(total, page, pageSize);
|
|
34
|
+
return {
|
|
35
|
+
data: dbApps.data.map(transformApp),
|
|
36
|
+
pagination,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 获取单个应用
|
|
41
|
+
*/
|
|
42
|
+
async get(id) {
|
|
43
|
+
const dbApp = await this.db.getOne('apps', {
|
|
44
|
+
filter: { app_id: `eq.${id}` },
|
|
45
|
+
});
|
|
46
|
+
if (!dbApp)
|
|
47
|
+
return null;
|
|
48
|
+
return transformApp(dbApp);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=AppsResource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppsResource.js","sourceRoot":"","sources":["../../src/resources/AppsResource.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAuB9D;;GAEG;AACH,MAAM,OAAO,YAAY;IACvB,YAA6B,EAAY;QAAZ,OAAE,GAAF,EAAE,CAAU;IAAG,CAAC;IAE7C;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,UAA2B,EAAE;QACtC,OAAO;QACP,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;QACxC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEvD,SAAS;QACT,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,MAAM;YAAE,MAAM,CAAC,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QAC5D,IAAI,OAAO,CAAC,MAAM;YAAE,MAAM,CAAC,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,GAAG,CAAe,MAAM,EAAE;YACrD,MAAM;YACN,KAAK,EAAE,cAAc,OAAO,CAAC,KAAK,IAAI,MAAM,EAAE;YAC9C,KAAK;YACL,MAAM;YACN,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;QAEH,aAAa;QACb,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAElE,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;YACnC,UAAU;SACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAe,MAAM,EAAE;YACvD,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { DbClient } from '../data/DbClient.js';
|
|
2
|
+
import type { Conversation, ListAppsWithConversationsResult } from '../types/models.types.js';
|
|
3
|
+
import type { PaginationOptions, PaginatedResult } from '../types/pagination.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 会话列表查询选项
|
|
6
|
+
*/
|
|
7
|
+
export interface ListConversationsOptions extends PaginationOptions {
|
|
8
|
+
/**
|
|
9
|
+
* 按应用 ID 过滤
|
|
10
|
+
*/
|
|
11
|
+
appId?: string;
|
|
12
|
+
/**
|
|
13
|
+
* 按用户 ID 过滤
|
|
14
|
+
*/
|
|
15
|
+
userId?: string;
|
|
16
|
+
/**
|
|
17
|
+
* 排序字段
|
|
18
|
+
* @default 'createdAt'
|
|
19
|
+
*/
|
|
20
|
+
orderBy?: 'createdAt' | 'updatedAt' | 'lastActiveAt';
|
|
21
|
+
/**
|
|
22
|
+
* 排序方向
|
|
23
|
+
* @default 'desc'
|
|
24
|
+
*/
|
|
25
|
+
order?: 'asc' | 'desc';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 创建会话数据
|
|
29
|
+
*/
|
|
30
|
+
export interface CreateConversationData {
|
|
31
|
+
title: string;
|
|
32
|
+
appId?: string | null;
|
|
33
|
+
userId: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 更新会话数据
|
|
37
|
+
*/
|
|
38
|
+
export interface UpdateConversationData {
|
|
39
|
+
title?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 会话资源类
|
|
43
|
+
*/
|
|
44
|
+
export declare class ConversationsResource {
|
|
45
|
+
private readonly db;
|
|
46
|
+
constructor(db: DbClient);
|
|
47
|
+
/**
|
|
48
|
+
* 列出会话(带分页)
|
|
49
|
+
*/
|
|
50
|
+
list(options?: ListConversationsOptions): Promise<PaginatedResult<Conversation>>;
|
|
51
|
+
/**
|
|
52
|
+
* 获取单个会话
|
|
53
|
+
*/
|
|
54
|
+
get(id: string): Promise<Conversation | null>;
|
|
55
|
+
/**
|
|
56
|
+
* 创建会话
|
|
57
|
+
*/
|
|
58
|
+
create(data: CreateConversationData): Promise<Conversation>;
|
|
59
|
+
/**
|
|
60
|
+
* 更新会话
|
|
61
|
+
*/
|
|
62
|
+
update(id: string, data: UpdateConversationData): Promise<Conversation>;
|
|
63
|
+
/**
|
|
64
|
+
* 删除会话
|
|
65
|
+
*/
|
|
66
|
+
delete(id: string): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* 聚合查询:获取应用及其会话列表
|
|
69
|
+
* 每个 app 只返回 message_count 最大的会话
|
|
70
|
+
*
|
|
71
|
+
* 替代 builder-sdk 的 GET /api/apps/with-conversations
|
|
72
|
+
* 直接从 PostgREST 并行获取数据
|
|
73
|
+
*/
|
|
74
|
+
listAppsWithConversations(options?: {
|
|
75
|
+
appId?: string;
|
|
76
|
+
userId?: string;
|
|
77
|
+
page?: number;
|
|
78
|
+
pageSize?: number;
|
|
79
|
+
}): Promise<ListAppsWithConversationsResult>;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=ConversationsResource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversationsResource.d.ts","sourceRoot":"","sources":["../../src/resources/ConversationsResource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EACV,YAAY,EAEZ,+BAA+B,EAEhC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAMvF;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;IAErD;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAG/B;;OAEG;IACG,IAAI,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IAoC1F;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAUnD;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBjE;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC;IAa7E;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;;;;;OAMG;IACG,yBAAyB,CAAC,OAAO,CAAC,EAAE;QACxC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,+BAA+B,CAAC;CAW7C"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { calculatePaginationMeta, pageToOffset } from '../types/pagination.types.js';
|
|
2
|
+
import { transformConversation, toDbConversation } from '../transforms/conversation.transform.js';
|
|
3
|
+
import { listAppsWithConversations as listAppsWithConversationsAggregated } from '../aggregated/apps-with-conversations.js';
|
|
4
|
+
/**
|
|
5
|
+
* 会话资源类
|
|
6
|
+
*/
|
|
7
|
+
export class ConversationsResource {
|
|
8
|
+
constructor(db) {
|
|
9
|
+
this.db = db;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 列出会话(带分页)
|
|
13
|
+
*/
|
|
14
|
+
async list(options = {}) {
|
|
15
|
+
// 分页参数
|
|
16
|
+
const page = options.page || 1;
|
|
17
|
+
const pageSize = options.pageSize || 20;
|
|
18
|
+
const { limit, offset } = pageToOffset(page, pageSize);
|
|
19
|
+
// 构建过滤条件
|
|
20
|
+
const filter = {};
|
|
21
|
+
if (options.appId)
|
|
22
|
+
filter.app_id = `eq.${options.appId}`;
|
|
23
|
+
if (options.userId)
|
|
24
|
+
filter.user_id = `eq.${options.userId}`;
|
|
25
|
+
// 构建排序
|
|
26
|
+
const orderField = options.orderBy === 'lastActiveAt' ? 'last_message_created_at' :
|
|
27
|
+
options.orderBy === 'updatedAt' ? 'updated_at' :
|
|
28
|
+
'created_at';
|
|
29
|
+
const order = `${orderField}.${options.order || 'desc'}`;
|
|
30
|
+
const dbConversations = await this.db.get('conversations', {
|
|
31
|
+
filter,
|
|
32
|
+
order,
|
|
33
|
+
limit,
|
|
34
|
+
offset,
|
|
35
|
+
count: 'exact',
|
|
36
|
+
});
|
|
37
|
+
// 获取总数(从响应头)
|
|
38
|
+
const total = dbConversations.count || 0;
|
|
39
|
+
const pagination = calculatePaginationMeta(total, page, pageSize);
|
|
40
|
+
return {
|
|
41
|
+
data: dbConversations.data.map(conv => transformConversation(conv)),
|
|
42
|
+
pagination,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 获取单个会话
|
|
47
|
+
*/
|
|
48
|
+
async get(id) {
|
|
49
|
+
const dbConv = await this.db.getOne('conversations', {
|
|
50
|
+
filter: { id: `eq.${id}` },
|
|
51
|
+
});
|
|
52
|
+
if (!dbConv)
|
|
53
|
+
return null;
|
|
54
|
+
return transformConversation(dbConv);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 创建会话
|
|
58
|
+
*/
|
|
59
|
+
async create(data) {
|
|
60
|
+
const dbData = toDbConversation({
|
|
61
|
+
title: data.title,
|
|
62
|
+
appId: data.appId,
|
|
63
|
+
userId: data.userId,
|
|
64
|
+
});
|
|
65
|
+
const results = await this.db.post('conversations', dbData, {
|
|
66
|
+
returning: 'representation',
|
|
67
|
+
});
|
|
68
|
+
const dbConv = results[0];
|
|
69
|
+
return transformConversation(dbConv);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 更新会话
|
|
73
|
+
*/
|
|
74
|
+
async update(id, data) {
|
|
75
|
+
const dbData = toDbConversation(data);
|
|
76
|
+
const results = await this.db.patch('conversations', { id: `eq.${id}` }, dbData, { returning: 'representation' });
|
|
77
|
+
return transformConversation(results[0]);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 删除会话
|
|
81
|
+
*/
|
|
82
|
+
async delete(id) {
|
|
83
|
+
await this.db.delete('conversations', { id: `eq.${id}` });
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 聚合查询:获取应用及其会话列表
|
|
87
|
+
* 每个 app 只返回 message_count 最大的会话
|
|
88
|
+
*
|
|
89
|
+
* 替代 builder-sdk 的 GET /api/apps/with-conversations
|
|
90
|
+
* 直接从 PostgREST 并行获取数据
|
|
91
|
+
*/
|
|
92
|
+
async listAppsWithConversations(options) {
|
|
93
|
+
// 注意:这里暂时忽略 userId 过滤,因为聚合函数还不支持
|
|
94
|
+
// TODO: 在 apps-with-conversations.ts 中添加 userId 过滤支持
|
|
95
|
+
return await listAppsWithConversationsAggregated({
|
|
96
|
+
appId: options?.appId,
|
|
97
|
+
page: options?.page,
|
|
98
|
+
pageSize: options?.pageSize,
|
|
99
|
+
db: this.db,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=ConversationsResource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversationsResource.js","sourceRoot":"","sources":["../../src/resources/ConversationsResource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { DbClient } from '../data/DbClient.js';
|
|
2
|
+
import type { Message } from '../types/models.types.js';
|
|
3
|
+
import type { PaginationOptions, PaginatedResult } from '../types/pagination.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 消息列表查询选项
|
|
6
|
+
*/
|
|
7
|
+
export interface ListMessagesOptions extends PaginationOptions {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 创建消息数据
|
|
11
|
+
*/
|
|
12
|
+
export interface CreateMessageData {
|
|
13
|
+
role: 'user' | 'assistant' | 'system';
|
|
14
|
+
content: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 消息资源类
|
|
19
|
+
*/
|
|
20
|
+
export declare class MessagesResource {
|
|
21
|
+
private readonly db;
|
|
22
|
+
constructor(db: DbClient);
|
|
23
|
+
/**
|
|
24
|
+
* 列出会话的消息(带分页和去重)
|
|
25
|
+
*/
|
|
26
|
+
list(conversationId: string, options?: ListMessagesOptions): Promise<PaginatedResult<Message>>;
|
|
27
|
+
/**
|
|
28
|
+
* 获取单条消息
|
|
29
|
+
*/
|
|
30
|
+
get(messageId: string): Promise<Message | null>;
|
|
31
|
+
/**
|
|
32
|
+
* 添加消息
|
|
33
|
+
*/
|
|
34
|
+
create(conversationId: string, data: CreateMessageData): Promise<Message>;
|
|
35
|
+
/**
|
|
36
|
+
* 更新消息
|
|
37
|
+
*/
|
|
38
|
+
update(messageId: string, data: Partial<CreateMessageData>): Promise<Message>;
|
|
39
|
+
/**
|
|
40
|
+
* 删除消息
|
|
41
|
+
*/
|
|
42
|
+
delete(messageId: string): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* 去重媒体消息
|
|
45
|
+
* 如果两条消息具有相同的 role、content、timestamp 和 media 内容,只保留第一条
|
|
46
|
+
*
|
|
47
|
+
* 参考 runtime-plugins/conversations/src/handlers/messages.ts
|
|
48
|
+
*/
|
|
49
|
+
private deduplicateMediaMessages;
|
|
50
|
+
/**
|
|
51
|
+
* 创建媒体去重键
|
|
52
|
+
* 对数组进行排序以确保 ["a", "b"] 和 ["b", "a"] 被视为相同
|
|
53
|
+
*/
|
|
54
|
+
private createMediaKey;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=MessagesResource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessagesResource.d.ts","sourceRoot":"","sources":["../../src/resources/MessagesResource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAIvF;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;CAE7D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAEzC;;OAEG;IACG,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IA8BxG;;OAEG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAUrD;;OAEG;IACG,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAa/E;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAanF;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAgChC;;;OAGG;IACH,OAAO,CAAC,cAAc;CAiBvB"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { calculatePaginationMeta, pageToOffset } from '../types/pagination.types.js';
|
|
2
|
+
import { transformMessage, toDbMessage } from '../transforms/message.transform.js';
|
|
3
|
+
/**
|
|
4
|
+
* 消息资源类
|
|
5
|
+
*/
|
|
6
|
+
export class MessagesResource {
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 列出会话的消息(带分页和去重)
|
|
12
|
+
*/
|
|
13
|
+
async list(conversationId, options = {}) {
|
|
14
|
+
// 分页参数
|
|
15
|
+
const page = options.page || 1;
|
|
16
|
+
const pageSize = options.pageSize || 100;
|
|
17
|
+
const { limit, offset } = pageToOffset(page, pageSize);
|
|
18
|
+
const dbMessages = await this.db.get('messages', {
|
|
19
|
+
filter: { conversation_id: `eq.${conversationId}` },
|
|
20
|
+
order: 'created_at.desc', // 默认倒序,最新的消息在前
|
|
21
|
+
limit,
|
|
22
|
+
offset,
|
|
23
|
+
count: 'exact',
|
|
24
|
+
});
|
|
25
|
+
// 转换消息
|
|
26
|
+
const messages = dbMessages.data.map(transformMessage);
|
|
27
|
+
// 去重(移除重复的媒体消息)
|
|
28
|
+
const dedupedMessages = this.deduplicateMediaMessages(messages);
|
|
29
|
+
// 获取总数(从响应头)
|
|
30
|
+
const total = dbMessages.count || 0;
|
|
31
|
+
const pagination = calculatePaginationMeta(total, page, pageSize);
|
|
32
|
+
return {
|
|
33
|
+
data: dedupedMessages,
|
|
34
|
+
pagination,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 获取单条消息
|
|
39
|
+
*/
|
|
40
|
+
async get(messageId) {
|
|
41
|
+
const dbMsg = await this.db.getOne('messages', {
|
|
42
|
+
filter: { id: `eq.${messageId}` },
|
|
43
|
+
});
|
|
44
|
+
if (!dbMsg)
|
|
45
|
+
return null;
|
|
46
|
+
return transformMessage(dbMsg);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 添加消息
|
|
50
|
+
*/
|
|
51
|
+
async create(conversationId, data) {
|
|
52
|
+
const dbData = {
|
|
53
|
+
conversation_id: conversationId,
|
|
54
|
+
...toDbMessage(data),
|
|
55
|
+
};
|
|
56
|
+
const results = await this.db.post('messages', dbData, {
|
|
57
|
+
returning: 'representation',
|
|
58
|
+
});
|
|
59
|
+
return transformMessage(results[0]);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 更新消息
|
|
63
|
+
*/
|
|
64
|
+
async update(messageId, data) {
|
|
65
|
+
const dbData = toDbMessage(data);
|
|
66
|
+
const results = await this.db.patch('messages', { id: `eq.${messageId}` }, dbData, { returning: 'representation' });
|
|
67
|
+
return transformMessage(results[0]);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 删除消息
|
|
71
|
+
*/
|
|
72
|
+
async delete(messageId) {
|
|
73
|
+
await this.db.delete('messages', { id: `eq.${messageId}` });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 去重媒体消息
|
|
77
|
+
* 如果两条消息具有相同的 role、content、timestamp 和 media 内容,只保留第一条
|
|
78
|
+
*
|
|
79
|
+
* 参考 runtime-plugins/conversations/src/handlers/messages.ts
|
|
80
|
+
*/
|
|
81
|
+
deduplicateMediaMessages(messages) {
|
|
82
|
+
const result = [];
|
|
83
|
+
const seenMedia = new Set();
|
|
84
|
+
for (const msg of messages) {
|
|
85
|
+
// 检查消息的 metadata 中是否包含 media 字段(需要通过 any 类型访问)
|
|
86
|
+
const metadata = msg.metadata;
|
|
87
|
+
const hasMedia = metadata?.type === 'media' && metadata?.media;
|
|
88
|
+
if (hasMedia) {
|
|
89
|
+
// 创建去重键(基于 content、role、timestamp 和 media)
|
|
90
|
+
const mediaKey = this.createMediaKey(msg.content || '', msg.role || 'unknown', msg.timestamp, metadata.media);
|
|
91
|
+
// 如果已经见过这个媒体内容,跳过
|
|
92
|
+
if (seenMedia.has(mediaKey)) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
seenMedia.add(mediaKey);
|
|
96
|
+
}
|
|
97
|
+
result.push(msg);
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 创建媒体去重键
|
|
103
|
+
* 对数组进行排序以确保 ["a", "b"] 和 ["b", "a"] 被视为相同
|
|
104
|
+
*/
|
|
105
|
+
createMediaKey(content, role, timestamp, media) {
|
|
106
|
+
// 排序图片
|
|
107
|
+
const images = (media.images || []).slice().sort();
|
|
108
|
+
// 排序音频
|
|
109
|
+
const audios = (media.audios || []).slice().sort();
|
|
110
|
+
// 排序视频
|
|
111
|
+
const videos = (media.videos || []).slice().sort();
|
|
112
|
+
return `content:${content}|role:${role}|ts:${timestamp}|images:${JSON.stringify(images)}|audios:${JSON.stringify(audios)}|videos:${JSON.stringify(videos)}`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=MessagesResource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessagesResource.js","sourceRoot":"","sources":["../../src/resources/MessagesResource.ts"],"names":[],"mappings":"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"}
|