@cicctencent/agent-server 0.1.1 → 0.1.2

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.
Files changed (49) hide show
  1. package/dist/cjs/index.d.ts +2 -0
  2. package/dist/cjs/index.d.ts.map +1 -1
  3. package/dist/cjs/index.js +23 -1
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/spi/adapters.d.ts +111 -0
  6. package/dist/cjs/spi/adapters.d.ts.map +1 -0
  7. package/dist/cjs/spi/adapters.js +285 -0
  8. package/dist/cjs/spi/adapters.js.map +1 -0
  9. package/dist/cjs/spi/examples/typeorm-example.d.ts +208 -0
  10. package/dist/cjs/spi/examples/typeorm-example.d.ts.map +1 -0
  11. package/dist/cjs/spi/examples/typeorm-example.js +274 -0
  12. package/dist/cjs/spi/examples/typeorm-example.js.map +1 -0
  13. package/dist/cjs/spi/index.d.ts +110 -0
  14. package/dist/cjs/spi/index.d.ts.map +1 -0
  15. package/dist/cjs/spi/index.js +143 -0
  16. package/dist/cjs/spi/index.js.map +1 -0
  17. package/dist/cjs/spi/storage.d.ts +109 -0
  18. package/dist/cjs/spi/storage.d.ts.map +1 -0
  19. package/dist/cjs/spi/storage.js +344 -0
  20. package/dist/cjs/spi/storage.js.map +1 -0
  21. package/dist/cjs/spi/types.d.ts +317 -0
  22. package/dist/cjs/spi/types.d.ts.map +1 -0
  23. package/dist/cjs/spi/types.js +6 -0
  24. package/dist/cjs/spi/types.js.map +1 -0
  25. package/dist/esm/index.d.ts +2 -0
  26. package/dist/esm/index.d.ts.map +1 -1
  27. package/dist/esm/index.js +8 -0
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/spi/adapters.d.ts +111 -0
  30. package/dist/esm/spi/adapters.d.ts.map +1 -0
  31. package/dist/esm/spi/adapters.js +273 -0
  32. package/dist/esm/spi/adapters.js.map +1 -0
  33. package/dist/esm/spi/examples/typeorm-example.d.ts +208 -0
  34. package/dist/esm/spi/examples/typeorm-example.d.ts.map +1 -0
  35. package/dist/esm/spi/examples/typeorm-example.js +315 -0
  36. package/dist/esm/spi/examples/typeorm-example.js.map +1 -0
  37. package/dist/esm/spi/index.d.ts +110 -0
  38. package/dist/esm/spi/index.d.ts.map +1 -0
  39. package/dist/esm/spi/index.js +131 -0
  40. package/dist/esm/spi/index.js.map +1 -0
  41. package/dist/esm/spi/storage.d.ts +109 -0
  42. package/dist/esm/spi/storage.d.ts.map +1 -0
  43. package/dist/esm/spi/storage.js +301 -0
  44. package/dist/esm/spi/storage.js.map +1 -0
  45. package/dist/esm/spi/types.d.ts +317 -0
  46. package/dist/esm/spi/types.d.ts.map +1 -0
  47. package/dist/esm/spi/types.js +5 -0
  48. package/dist/esm/spi/types.js.map +1 -0
  49. package/package.json +1 -1
@@ -0,0 +1,208 @@
1
+ import type { ChatStoreProvider, BaseThreadEntity, BaseMessageEntity, BaseSettingsEntity, ListStorageAdapter } from '../types.js';
2
+ /**
3
+ * BI 项目的 Thread 实体(TypeORM)
4
+ * 注意:字段可能与 agent-server 默认实体不同
5
+ */
6
+ interface BIThreadEntity extends BaseThreadEntity {
7
+ id: number;
8
+ workspaceId?: number;
9
+ userId?: number;
10
+ agentType?: string;
11
+ modelConfig?: string;
12
+ createdAt: Date;
13
+ updatedAt: Date;
14
+ }
15
+ /**
16
+ * BI 项目的 Message 实体(TypeORM)
17
+ */
18
+ interface BIMessageEntity extends BaseMessageEntity {
19
+ id: number;
20
+ threadId: number;
21
+ tokens?: number;
22
+ latency?: number;
23
+ model?: string;
24
+ createdAt: Date;
25
+ }
26
+ /**
27
+ * BI 项目的 Settings 实体
28
+ */
29
+ interface BISettingsEntity extends BaseSettingsEntity {
30
+ id: number;
31
+ userId: number;
32
+ theme: string;
33
+ language: string;
34
+ modelProviders: Array<{
35
+ id: string;
36
+ name: string;
37
+ provider: string;
38
+ model: string;
39
+ apiKey?: string;
40
+ baseUrl?: string;
41
+ }>;
42
+ createdAt: Date;
43
+ updatedAt: Date;
44
+ }
45
+ /**
46
+ * TypeORM 列表存储适配器
47
+ * 将 TypeORM Repository 包装为 ListStorageAdapter
48
+ */
49
+ declare class TypeORMListStorage<T extends {
50
+ id: number | string;
51
+ }> implements ListStorageAdapter<T> {
52
+ private data;
53
+ list(): Promise<T[]>;
54
+ findById(id: number | string): Promise<T | null>;
55
+ add(entity: T): Promise<T>;
56
+ update(id: number | string, data: Partial<T>): Promise<T | null>;
57
+ remove(id: number | string): Promise<boolean>;
58
+ }
59
+ /**
60
+ * BI 项目的 ChatStoreProvider 实现
61
+ * 使用 TypeORM Repository 作为底层存储
62
+ */
63
+ declare class TypeORMChatStoreProvider implements ChatStoreProvider<BIThreadEntity, BIMessageEntity> {
64
+ private threadStorage;
65
+ private messageStorages;
66
+ constructor();
67
+ private getMessageStorage;
68
+ getThreads(workspaceId?: number | string): Promise<BIThreadEntity[]>;
69
+ getThread(id: number | string): Promise<BIThreadEntity | undefined>;
70
+ createThread(data: Partial<BIThreadEntity>): Promise<BIThreadEntity>;
71
+ updateThread(id: number | string, data: Partial<BIThreadEntity>): Promise<BIThreadEntity | undefined>;
72
+ deleteThread(id: number | string): Promise<boolean>;
73
+ getMessages(threadId: number | string, options?: {
74
+ limit?: number;
75
+ offset?: number;
76
+ }): Promise<{
77
+ items: BIMessageEntity[];
78
+ total: number;
79
+ hasMore: boolean;
80
+ }>;
81
+ addMessage(data: Partial<BIMessageEntity> & {
82
+ threadId: number | string;
83
+ role: string;
84
+ content: string;
85
+ }): Promise<BIMessageEntity>;
86
+ updateMessage(threadId: number | string, id: number | string, data: Partial<BIMessageEntity>): Promise<BIMessageEntity | undefined>;
87
+ deleteMessage(threadId: number | string, id: number | string): Promise<boolean>;
88
+ clearThreadMessages(threadId: number | string): Promise<void>;
89
+ buildThreadHistory(threadId: number | string, limit?: number): Promise<any[]>;
90
+ }
91
+ /**
92
+ * MidwayJS Agent 服务示例
93
+ * 使用 SPI 适配到 MidwayJS + TypeORM
94
+ *
95
+ * 在实际项目中,这会是:
96
+ *
97
+ * @Provide()
98
+ * @Scope(ScopeEnum.Singleton)
99
+ * export class AgentService {
100
+ * @Inject()
101
+ * threadRepository: Repository<BIThreadEntity>;
102
+ *
103
+ * @Inject()
104
+ * messageRepository: Repository<BIMessageEntity>;
105
+ *
106
+ * private server: AgentServer;
107
+ *
108
+ * @Init()
109
+ * async init() {
110
+ * const chatStoreProvider = new TypeORMChatStoreProvider(
111
+ * this.threadRepository,
112
+ * this.messageRepository
113
+ * );
114
+ *
115
+ * this.server = createAgentServer({
116
+ * llmProvider: await this.createLLMProvider(),
117
+ * chatStoreProvider,
118
+ * // 使用 Koa 适配器
119
+ * createSSEResponseAdapter: (ctx) => new KoaSSEAdapter(ctx),
120
+ * });
121
+ * }
122
+ *
123
+ * @Get('/chat/stream')
124
+ * async chatStream(@Ctx() ctx: Context, @Query() query: { message: string }) {
125
+ * const adapter = new KoaSSEAdapter(ctx);
126
+ * await this.server.runAgentStream(adapter, { content: query.message });
127
+ * }
128
+ * }
129
+ */
130
+ export { TypeORMListStorage, TypeORMChatStoreProvider, BIThreadEntity, BIMessageEntity, BISettingsEntity, };
131
+ /**
132
+ * ## 使用说明
133
+ *
134
+ * ### 1. 在 MidwayJS 项目中使用 agent-server
135
+ *
136
+ * ```typescript
137
+ * // src/service/agent.service.ts
138
+ * import { Provide, Scope, ScopeEnum, Inject, Init, Get, Ctx, Query } from '@midwayjs/core';
139
+ * import { Context } from '@midwayjs/koa';
140
+ * import { createAgentServer, KoaSSEAdapter, type AgentServer } from '@cicctencent/agent-server';
141
+ * import { TypeORMChatStoreProvider } from './spi/typeorm-chat-provider';
142
+ *
143
+ * @Provide()
144
+ * @Scope(ScopeEnum.Singleton)
145
+ * export class AgentService {
146
+ * @Inject()
147
+ * threadRepository: Repository<ThreadEntity>;
148
+ *
149
+ * @Inject()
150
+ * messageRepository: Repository<MessageEntity>;
151
+ *
152
+ * private server: AgentServer;
153
+ *
154
+ * @Init()
155
+ * async init() {
156
+ * // 使用 TypeORM 存储适配器
157
+ * const chatStoreProvider = new TypeORMChatStoreProvider(
158
+ * this.threadRepository,
159
+ * this.messageRepository
160
+ * );
161
+ *
162
+ * this.server = createAgentServer({
163
+ * llmProvider: await this.createLLMProvider(),
164
+ * chatStoreProvider, // 替换默认 JSON 文件存储
165
+ * });
166
+ * }
167
+ *
168
+ * @Get('/chat/stream')
169
+ * async chatStream(@Ctx() ctx: Context, @Query() query: { message: string }) {
170
+ * // 使用 Koa/MidwayJS SSE 适配器
171
+ * const adapter = new KoaSSEAdapter(ctx);
172
+ * await this.server.runAgentStream(adapter, { content: query.message });
173
+ * }
174
+ * }
175
+ * ```
176
+ *
177
+ * ### 2. 自定义实体字段
178
+ *
179
+ * agent-server 现在支持泛型实体类型,你可以:
180
+ * - 使用自己的实体结构(如 TypeORM 实体)
181
+ * - 自定义字段(如 userId, modelConfig 等)
182
+ * - 使用不同的 ID 类型(number / string / UUID)
183
+ *
184
+ * ### 3. 组件级使用(不依赖工厂)
185
+ *
186
+ * 如果不想使用 createAgentServer 工厂,可以只导入需要的组件:
187
+ *
188
+ * ```typescript
189
+ * import {
190
+ * MemoryService,
191
+ * writeSSE,
192
+ * createBuiltinTools,
193
+ * KoaSSEAdapter
194
+ * } from '@cicctencent/agent-server';
195
+ *
196
+ * // 只使用需要的组件
197
+ * const memoryService = new MemoryService('./data');
198
+ * const tools = createBuiltinTools();
199
+ *
200
+ * // 在 MidwayJS 中使用 SSE
201
+ * @Get('/stream')
202
+ * async stream(@Ctx() ctx: Context) {
203
+ * const adapter = new KoaSSEAdapter(ctx);
204
+ * writeSSE(adapter, 'start', { message: 'Hello' });
205
+ * }
206
+ * ```
207
+ */
208
+ //# sourceMappingURL=typeorm-example.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeorm-example.d.ts","sourceRoot":"","sources":["../../../../src/spi/examples/typeorm-example.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ // ============================================================
3
+ // TypeORM SPI 实现示例 — BI 项目可参考此实现
4
+ // ============================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TypeORMChatStoreProvider = exports.TypeORMListStorage = void 0;
7
+ // ============================================================
8
+ // TypeORM 存储适配器实现
9
+ // ============================================================
10
+ /**
11
+ * TypeORM 列表存储适配器
12
+ * 将 TypeORM Repository 包装为 ListStorageAdapter
13
+ */
14
+ class TypeORMListStorage {
15
+ // 在实际项目中,这里会是 TypeORM Repository
16
+ // constructor(private repository: Repository<T>) {}
17
+ // 模拟 TypeORM Repository(示例)
18
+ data = [];
19
+ async list() {
20
+ // 实际实现: return this.repository.find();
21
+ return this.data;
22
+ }
23
+ async findById(id) {
24
+ // 实际实现: return this.repository.findOne({ where: { id } });
25
+ return this.data.find(item => item.id === id) ?? null;
26
+ }
27
+ async add(entity) {
28
+ // 实际实现: return this.repository.save(entity);
29
+ this.data.push(entity);
30
+ return entity;
31
+ }
32
+ async update(id, data) {
33
+ // 实际实现:
34
+ // const entity = await this.repository.findOne({ where: { id } });
35
+ // if (!entity) return null;
36
+ // Object.assign(entity, data);
37
+ // return this.repository.save(entity);
38
+ const idx = this.data.findIndex(item => item.id === id);
39
+ if (idx === -1)
40
+ return null;
41
+ this.data[idx] = { ...this.data[idx], ...data };
42
+ return this.data[idx];
43
+ }
44
+ async remove(id) {
45
+ // 实际实现:
46
+ // const result = await this.repository.delete(id);
47
+ // return result.affected > 0;
48
+ const idx = this.data.findIndex(item => item.id === id);
49
+ if (idx === -1)
50
+ return false;
51
+ this.data.splice(idx, 1);
52
+ return true;
53
+ }
54
+ }
55
+ exports.TypeORMListStorage = TypeORMListStorage;
56
+ // ============================================================
57
+ // TypeORM ChatStoreProvider 实现
58
+ // ============================================================
59
+ /**
60
+ * BI 项目的 ChatStoreProvider 实现
61
+ * 使用 TypeORM Repository 作为底层存储
62
+ */
63
+ class TypeORMChatStoreProvider {
64
+ // 在实际项目中,这里会是 TypeORM Repository
65
+ threadStorage;
66
+ messageStorages = new Map();
67
+ constructor(
68
+ // threadRepository: Repository<BIThreadEntity>,
69
+ // messageRepository: Repository<BIMessageEntity>
70
+ ) {
71
+ this.threadStorage = new TypeORMListStorage();
72
+ }
73
+ getMessageStorage(threadId) {
74
+ if (!this.messageStorages.has(threadId)) {
75
+ this.messageStorages.set(threadId, new TypeORMListStorage());
76
+ }
77
+ return this.messageStorages.get(threadId);
78
+ }
79
+ // ===== Thread CRUD =====
80
+ // 注意:TypeORM 实现使用异步方法
81
+ async getThreads(workspaceId) {
82
+ // 实际 TypeORM 实现:
83
+ // if (workspaceId) {
84
+ // return this.threadRepository.find({ where: { workspaceId } });
85
+ // }
86
+ // return this.threadRepository.find();
87
+ const all = await this.threadStorage.list();
88
+ return all;
89
+ }
90
+ async getThread(id) {
91
+ // 实际 TypeORM 实现:
92
+ // return this.threadRepository.findOne({ where: { id } });
93
+ const result = await this.threadStorage.findById(id);
94
+ return result;
95
+ }
96
+ async createThread(data) {
97
+ // 实际 TypeORM 实现:
98
+ // const thread = this.threadRepository.create(data);
99
+ // return this.threadRepository.save(thread);
100
+ const now = new Date();
101
+ const thread = {
102
+ id: Date.now(),
103
+ title: data.title || '新对话',
104
+ workspaceId: data.workspaceId,
105
+ userId: data.userId,
106
+ status: 'active',
107
+ createdAt: now,
108
+ updatedAt: now,
109
+ };
110
+ await this.threadStorage.add(thread);
111
+ return thread;
112
+ }
113
+ async updateThread(id, data) {
114
+ // 实际 TypeORM 实现:
115
+ // const thread = await this.threadRepository.findOne({ where: { id } });
116
+ // if (!thread) return null;
117
+ // Object.assign(thread, data, { updatedAt: new Date() });
118
+ // return this.threadRepository.save(thread);
119
+ const result = await this.threadStorage.update(id, { ...data, updatedAt: new Date() });
120
+ return result;
121
+ }
122
+ async deleteThread(id) {
123
+ // 实际 TypeORM 实现:
124
+ // const result = await this.threadRepository.delete(id);
125
+ // return result.affected > 0;
126
+ return this.threadStorage.remove(id);
127
+ }
128
+ // ===== Message CRUD =====
129
+ async getMessages(threadId, options) {
130
+ // 实际 TypeORM 实现:
131
+ // const [items, total] = await this.messageRepository.findAndCount({
132
+ // where: { threadId },
133
+ // order: { createdAt: 'DESC' },
134
+ // skip: options?.offset || 0,
135
+ // take: options?.limit || 50,
136
+ // });
137
+ // return { items, total, hasMore: (options?.offset || 0) + items.length < total };
138
+ const storage = this.getMessageStorage(Number(threadId));
139
+ const all = await storage.list();
140
+ const limit = options?.limit || 50;
141
+ const offset = options?.offset || 0;
142
+ const items = all.slice(offset, offset + limit);
143
+ return { items, total: all.length, hasMore: offset + items.length < all.length };
144
+ }
145
+ async addMessage(data) {
146
+ // 实际 TypeORM 实现:
147
+ // const msg = this.messageRepository.create({
148
+ // threadId: data.threadId,
149
+ // role: data.role,
150
+ // content: data.content,
151
+ // createdAt: new Date(),
152
+ // });
153
+ // return this.messageRepository.save(msg);
154
+ const storage = this.getMessageStorage(Number(data.threadId));
155
+ const msg = {
156
+ id: Date.now(),
157
+ threadId: Number(data.threadId),
158
+ role: data.role,
159
+ content: data.content,
160
+ createdAt: new Date(),
161
+ };
162
+ await storage.add(msg);
163
+ return msg;
164
+ }
165
+ async updateMessage(threadId, id, data) {
166
+ // 实际 TypeORM 实现:
167
+ // const msg = await this.messageRepository.findOne({ where: { id, threadId } });
168
+ // if (!msg) return null;
169
+ // Object.assign(msg, data);
170
+ // return this.messageRepository.save(msg);
171
+ const storage = this.getMessageStorage(Number(threadId));
172
+ const result = await storage.update(id, data);
173
+ return result;
174
+ }
175
+ async deleteMessage(threadId, id) {
176
+ // 实际 TypeORM 实现:
177
+ // const result = await this.messageRepository.delete({ id, threadId });
178
+ // return result.affected > 0;
179
+ const storage = this.getMessageStorage(Number(threadId));
180
+ return storage.remove(id);
181
+ }
182
+ async clearThreadMessages(threadId) {
183
+ // 实际 TypeORM 实现:
184
+ // await this.messageRepository.delete({ threadId });
185
+ this.messageStorages.delete(Number(threadId));
186
+ }
187
+ // ===== 历史重建 =====
188
+ async buildThreadHistory(threadId, limit) {
189
+ const { items } = await this.getMessages(threadId, { limit: limit || 20 });
190
+ return items.map(msg => ({
191
+ role: msg.role,
192
+ content: msg.content,
193
+ }));
194
+ }
195
+ }
196
+ exports.TypeORMChatStoreProvider = TypeORMChatStoreProvider;
197
+ /**
198
+ * ## 使用说明
199
+ *
200
+ * ### 1. 在 MidwayJS 项目中使用 agent-server
201
+ *
202
+ * ```typescript
203
+ * // src/service/agent.service.ts
204
+ * import { Provide, Scope, ScopeEnum, Inject, Init, Get, Ctx, Query } from '@midwayjs/core';
205
+ * import { Context } from '@midwayjs/koa';
206
+ * import { createAgentServer, KoaSSEAdapter, type AgentServer } from '@cicctencent/agent-server';
207
+ * import { TypeORMChatStoreProvider } from './spi/typeorm-chat-provider';
208
+ *
209
+ * @Provide()
210
+ * @Scope(ScopeEnum.Singleton)
211
+ * export class AgentService {
212
+ * @Inject()
213
+ * threadRepository: Repository<ThreadEntity>;
214
+ *
215
+ * @Inject()
216
+ * messageRepository: Repository<MessageEntity>;
217
+ *
218
+ * private server: AgentServer;
219
+ *
220
+ * @Init()
221
+ * async init() {
222
+ * // 使用 TypeORM 存储适配器
223
+ * const chatStoreProvider = new TypeORMChatStoreProvider(
224
+ * this.threadRepository,
225
+ * this.messageRepository
226
+ * );
227
+ *
228
+ * this.server = createAgentServer({
229
+ * llmProvider: await this.createLLMProvider(),
230
+ * chatStoreProvider, // 替换默认 JSON 文件存储
231
+ * });
232
+ * }
233
+ *
234
+ * @Get('/chat/stream')
235
+ * async chatStream(@Ctx() ctx: Context, @Query() query: { message: string }) {
236
+ * // 使用 Koa/MidwayJS SSE 适配器
237
+ * const adapter = new KoaSSEAdapter(ctx);
238
+ * await this.server.runAgentStream(adapter, { content: query.message });
239
+ * }
240
+ * }
241
+ * ```
242
+ *
243
+ * ### 2. 自定义实体字段
244
+ *
245
+ * agent-server 现在支持泛型实体类型,你可以:
246
+ * - 使用自己的实体结构(如 TypeORM 实体)
247
+ * - 自定义字段(如 userId, modelConfig 等)
248
+ * - 使用不同的 ID 类型(number / string / UUID)
249
+ *
250
+ * ### 3. 组件级使用(不依赖工厂)
251
+ *
252
+ * 如果不想使用 createAgentServer 工厂,可以只导入需要的组件:
253
+ *
254
+ * ```typescript
255
+ * import {
256
+ * MemoryService,
257
+ * writeSSE,
258
+ * createBuiltinTools,
259
+ * KoaSSEAdapter
260
+ * } from '@cicctencent/agent-server';
261
+ *
262
+ * // 只使用需要的组件
263
+ * const memoryService = new MemoryService('./data');
264
+ * const tools = createBuiltinTools();
265
+ *
266
+ * // 在 MidwayJS 中使用 SSE
267
+ * @Get('/stream')
268
+ * async stream(@Ctx() ctx: Context) {
269
+ * const adapter = new KoaSSEAdapter(ctx);
270
+ * writeSSE(adapter, 'start', { message: 'Hello' });
271
+ * }
272
+ * ```
273
+ */
274
+ //# sourceMappingURL=typeorm-example.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeorm-example.js","sourceRoot":"","sources":["../../../../src/spi/examples/typeorm-example.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,iCAAiC;AACjC,+DAA+D;;;AAoE/D,+DAA+D;AAC/D,kBAAkB;AAClB,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,kBAAkB;IACtB,iCAAiC;IACjC,oDAAoD;IAEpD,4BAA4B;IACpB,IAAI,GAAQ,EAAE,CAAC;IAEvB,KAAK,CAAC,IAAI;QACR,uCAAuC;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAmB;QAChC,2DAA2D;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAS;QACjB,6CAA6C;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAmB,EAAE,IAAgB;QAChD,SAAS;QACT,mEAAmE;QACnE,4BAA4B;QAC5B,+BAA+B;QAC/B,uCAAuC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAO,CAAC;QACrD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAmB;QAC9B,SAAS;QACT,mDAAmD;QACnD,8BAA8B;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAqNC,gDAAkB;AAnNpB,+DAA+D;AAC/D,+BAA+B;AAC/B,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,wBAAwB;IAC5B,iCAAiC;IACzB,aAAa,CAAqC;IAClD,eAAe,GAAqD,IAAI,GAAG,EAAE,CAAC;IAEtF;IACE,gDAAgD;IAChD,iDAAiD;;QAEjD,IAAI,CAAC,aAAa,GAAG,IAAI,kBAAkB,EAAkB,CAAC;IAChE,CAAC;IAEO,iBAAiB,CAAC,QAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,kBAAkB,EAAmB,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;IAC7C,CAAC;IAED,0BAA0B;IAC1B,sBAAsB;IAEtB,KAAK,CAAC,UAAU,CAAC,WAA6B;QAC5C,iBAAiB;QACjB,qBAAqB;QACrB,mEAAmE;QACnE,IAAI;QACJ,uCAAuC;QACvC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAC5C,OAAO,GAAuB,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAmB;QACjC,kBAAkB;QAClB,2DAA2D;QAC3D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrD,OAAO,MAAoC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAA6B;QAC9C,iBAAiB;QACjB,qDAAqD;QACrD,6CAA6C;QAC7C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAmB;YAC7B,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;YACd,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;YAC1B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC;QACF,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAmB,EAAE,IAA6B;QACnE,iBAAiB;QACjB,yEAAyE;QACzE,4BAA4B;QAC5B,0DAA0D;QAC1D,6CAA6C;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QACvF,OAAO,MAAoC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,EAAmB;QACpC,iBAAiB;QACjB,yDAAyD;QACzD,8BAA8B;QAC9B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,2BAA2B;IAE3B,KAAK,CAAC,WAAW,CAAC,QAAyB,EAAE,OAA6C;QAKxF,iBAAiB;QACjB,qEAAqE;QACrE,yBAAyB;QACzB,kCAAkC;QAClC,gCAAgC;QAChC,gCAAgC;QAChC,MAAM;QACN,mFAAmF;QACnF,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAsB,CAAC;QACrE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;IACnF,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAA6F;QAC5G,iBAAiB;QACjB,8CAA8C;QAC9C,6BAA6B;QAC7B,qBAAqB;QACrB,2BAA2B;QAC3B,2BAA2B;QAC3B,MAAM;QACN,2CAA2C;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAoB;YAC3B,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;YACd,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC/B,IAAI,EAAE,IAAI,CAAC,IAAuC;YAClD,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC;QACF,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAyB,EAAE,EAAmB,EAAE,IAA8B;QAChG,iBAAiB;QACjB,iFAAiF;QACjF,yBAAyB;QACzB,4BAA4B;QAC5B,2CAA2C;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO,MAAqC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAyB,EAAE,EAAmB;QAChE,iBAAiB;QACjB,wEAAwE;QACxE,8BAA8B;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACzD,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,QAAyB;QACjD,iBAAiB;QACjB,qDAAqD;QACrD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,mBAAmB;IAEnB,KAAK,CAAC,kBAAkB,CAAC,QAAyB,EAAE,KAAc;QAChE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3E,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC,CAAC,CAAC;IACN,CAAC;CACF;AAoDC,4DAAwB;AAM1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG"}
@@ -0,0 +1,110 @@
1
+ export type { BaseThreadEntity, BaseMessageEntity, BaseWorkspaceEntity, BaseAgentProfileEntity, BaseSettingsEntity, KVStorageAdapter, ListStorageAdapter, QueryOptions, SettingsProvider, ChatStoreProvider, AgentProfileProvider, PromptBuilderProvider, ModelConfigResolver, SSEResponseAdapter, RequestContextAdapter, AgentServerSPIOptions, ThreadEntity, MessageEntity, WorkspaceEntity, AgentProfileEntity, SettingsEntity, } from './types.js';
2
+ export { JsonFileKVStorage, JsonFileListStorage, InMemoryKVStorage, InMemoryListStorage, DatabaseListStorage, createJsonFileStorage, createInMemoryStorage, } from './storage.js';
3
+ export { ExpressSSEAdapter, KoaSSEAdapter, FastifySSEAdapter, NativeHttpSSEAdapter, adaptSSE, ExpressRequestAdapter, KoaRequestAdapter, adaptRequest, CustomSSEAdapter, } from './adapters.js';
4
+ /**
5
+ * ## SPI 使用示例
6
+ *
7
+ * ### 1. 使用默认 JSON 文件存储
8
+ *
9
+ * ```typescript
10
+ * import { createAgentServer } from '@cicctencent/agent-server';
11
+ *
12
+ * const server = createAgentServer({
13
+ * llmProvider: myProvider,
14
+ * dataDir: './data', // 使用默认 JSON 文件存储
15
+ * });
16
+ * ```
17
+ *
18
+ * ### 2. 自定义存储(数据库)
19
+ *
20
+ * ```typescript
21
+ * import { createAgentServer, DatabaseListStorage, type ChatStoreProvider } from '@cicctencent/agent-server';
22
+ *
23
+ * // 实现数据库存储
24
+ * class TypeORMThreadStorage extends DatabaseListStorage<ThreadEntity> {
25
+ * constructor(private repository: Repository<ThreadEntity>) {
26
+ * super();
27
+ * }
28
+ * async list() { return this.repository.find(); }
29
+ * async findById(id) { return this.repository.findOne({ where: { id } }); }
30
+ * async add(entity) { return this.repository.save(entity); }
31
+ * // ...
32
+ * }
33
+ *
34
+ * // 实现 ChatStoreProvider
35
+ * class TypeORMChatStoreProvider implements ChatStoreProvider {
36
+ * constructor(private threadRepo: Repository<ThreadEntity>, private msgRepo: Repository<MessageEntity>) {}
37
+ * getThreads() { return this.threadRepo.find(); }
38
+ * // ...
39
+ * }
40
+ *
41
+ * const server = createAgentServer({
42
+ * llmProvider: myProvider,
43
+ * chatStoreProvider: new TypeORMChatStoreProvider(threadRepo, msgRepo),
44
+ * });
45
+ * ```
46
+ *
47
+ * ### 3. 自定义框架适配(MidwayJS)
48
+ *
49
+ * ```typescript
50
+ * import { createAgentServer, KoaSSEAdapter } from '@cicctencent/agent-server';
51
+ *
52
+ * @Provide()
53
+ * @Scope(ScopeEnum.Singleton)
54
+ * export class AgentService {
55
+ * private server: AgentServer;
56
+ *
57
+ * @Init()
58
+ * async init() {
59
+ * this.server = createAgentServer({
60
+ * llmProvider: await this.createProvider(),
61
+ * // 使用 Koa 适配器
62
+ * createSSEResponseAdapter: (ctx) => new KoaSSEAdapter(ctx),
63
+ * });
64
+ * }
65
+ *
66
+ * @Get('/chat/stream')
67
+ * async chatStream(@Ctx() ctx: Context) {
68
+ * const adapter = new KoaSSEAdapter(ctx);
69
+ * await this.server.runAgentStream(adapter, { content: ctx.query.message });
70
+ * }
71
+ * }
72
+ * ```
73
+ *
74
+ * ### 4. 自定义 Prompt 构建
75
+ *
76
+ * ```typescript
77
+ * import { createAgentServer, type PromptBuilderProvider } from '@cicctencent/agent-server';
78
+ *
79
+ * class CustomPromptBuilder implements PromptBuilderProvider {
80
+ * buildDefaultPrompt(profile, tools, memory) {
81
+ * // 自定义 Prompt 构建逻辑
82
+ * return `你是一个专业的 BI 分析助手...\n${memory || ''}`;
83
+ * }
84
+ * // ...
85
+ * }
86
+ *
87
+ * const server = createAgentServer({
88
+ * llmProvider: myProvider,
89
+ * promptBuilder: new CustomPromptBuilder(),
90
+ * });
91
+ * ```
92
+ *
93
+ * ### 5. 组件级使用(不使用工厂)
94
+ *
95
+ * ```typescript
96
+ * import { MemoryService, writeSSE, createBuiltinTools, KoaSSEAdapter } from '@cicctencent/agent-server';
97
+ *
98
+ * // 只使用需要的组件,不依赖 createAgentServer
99
+ * const memoryService = new MemoryService('./data');
100
+ * const tools = createBuiltinTools();
101
+ *
102
+ * // 在 MidwayJS 中使用 SSE
103
+ * @Get('/stream')
104
+ * async stream(@Ctx() ctx: Context) {
105
+ * const adapter = new KoaSSEAdapter(ctx);
106
+ * writeSSE(adapter, 'start', { message: 'Hello' });
107
+ * }
108
+ * ```
109
+ */
110
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/spi/index.ts"],"names":[],"mappings":"AAKA,YAAY,EAEV,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAElB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EAEZ,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EAEnB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EAErB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EAEL,iBAAiB,EACjB,mBAAmB,EAEnB,iBAAiB,EACjB,mBAAmB,EAEnB,mBAAmB,EAEnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAEL,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EAER,qBAAqB,EACrB,iBAAiB,EACjB,YAAY,EAEZ,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAMvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG"}