@yss123/cage-ai 0.0.0-stage → 0.3.1

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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -2
  3. package/dist/budget.d.ts +64 -0
  4. package/dist/budget.js +54 -0
  5. package/dist/budget.js.map +1 -0
  6. package/dist/context-read.d.ts +38 -0
  7. package/dist/context-read.js +124 -0
  8. package/dist/context-read.js.map +1 -0
  9. package/dist/context-schema.d.ts +9 -0
  10. package/dist/context-schema.js +16 -0
  11. package/dist/context-schema.js.map +1 -0
  12. package/dist/context.d.ts +27 -0
  13. package/dist/context.js +83 -0
  14. package/dist/context.js.map +1 -0
  15. package/dist/execution-schema.d.ts +9 -0
  16. package/dist/execution-schema.js +20 -0
  17. package/dist/execution-schema.js.map +1 -0
  18. package/dist/history.d.ts +43 -0
  19. package/dist/history.js +139 -0
  20. package/dist/history.js.map +1 -0
  21. package/dist/http.d.ts +15 -0
  22. package/dist/http.js +197 -0
  23. package/dist/http.js.map +1 -0
  24. package/dist/index.d.ts +33 -0
  25. package/dist/index.js +100 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/model-failure.d.ts +66 -0
  28. package/dist/model-failure.js +85 -0
  29. package/dist/model-failure.js.map +1 -0
  30. package/dist/model.d.ts +50 -0
  31. package/dist/model.js +93 -0
  32. package/dist/model.js.map +1 -0
  33. package/dist/models.d.ts +75 -0
  34. package/dist/models.js +241 -0
  35. package/dist/models.js.map +1 -0
  36. package/dist/personalities.d.ts +87 -0
  37. package/dist/personalities.js +191 -0
  38. package/dist/personalities.js.map +1 -0
  39. package/dist/personality-presets.d.ts +14 -0
  40. package/dist/personality-presets.js +24 -0
  41. package/dist/personality-presets.js.map +1 -0
  42. package/dist/prompt.d.ts +67 -0
  43. package/dist/prompt.js +148 -0
  44. package/dist/prompt.js.map +1 -0
  45. package/dist/query.d.ts +13 -0
  46. package/dist/query.js +82 -0
  47. package/dist/query.js.map +1 -0
  48. package/dist/request-plan.d.ts +59 -0
  49. package/dist/request-plan.js +168 -0
  50. package/dist/request-plan.js.map +1 -0
  51. package/dist/responses.d.ts +29 -0
  52. package/dist/responses.js +134 -0
  53. package/dist/responses.js.map +1 -0
  54. package/dist/runtime.d.ts +172 -0
  55. package/dist/runtime.js +1189 -0
  56. package/dist/runtime.js.map +1 -0
  57. package/dist/schema.d.ts +11 -0
  58. package/dist/schema.js +51 -0
  59. package/dist/schema.js.map +1 -0
  60. package/dist/security.d.ts +23 -0
  61. package/dist/security.js +73 -0
  62. package/dist/security.js.map +1 -0
  63. package/dist/state.d.ts +238 -0
  64. package/dist/state.js +11 -0
  65. package/dist/state.js.map +1 -0
  66. package/dist/store.d.ts +113 -0
  67. package/dist/store.js +456 -0
  68. package/dist/store.js.map +1 -0
  69. package/dist/text-stream.d.ts +62 -0
  70. package/dist/text-stream.js +99 -0
  71. package/dist/text-stream.js.map +1 -0
  72. package/dist/tool-catalog.d.ts +23 -0
  73. package/dist/tool-catalog.js +53 -0
  74. package/dist/tool-catalog.js.map +1 -0
  75. package/dist/tools.d.ts +54 -0
  76. package/dist/tools.js +259 -0
  77. package/dist/tools.js.map +1 -0
  78. package/dist/types.d.ts +283 -0
  79. package/dist/types.js +16 -0
  80. package/dist/types.js.map +1 -0
  81. package/package.json +41 -3
@@ -0,0 +1,43 @@
1
+ import type { Ctx, Kernel } from '@yss123/cage-kernel';
2
+ import type { ModelMessage } from './types.js';
3
+ import type { RemoteHistory, StoredRun } from './state.js';
4
+ /**
5
+ * 恢复一轮消息所需的持久字段子集;history_start 把本轮消息与当时借用的前轮窗口分开,避免递归重复历史。
6
+ */
7
+ type HistoryRun = Pick<StoredRun, 'id' | 'input' | 'answer' | 'history' | 'history_start' | 'status'>;
8
+ /** 只恢复该运行自身的消息,避免把每轮保存的近期窗口递归复制进下一轮。 */
9
+ /**
10
+ * 提取运行自身的消息并清理不完整工具调用组及孤立回执。
11
+ * 没有消息时用原始任务和最终状态构造最小交互;非成功运行追加需核对回执的提示,不能把未完成调用重放成已成功动作。返回新数组,不修改持久历史。
12
+ */
13
+ export declare function turnHistory(run: HistoryRun): ModelMessage[];
14
+ /**
15
+ * 已恢复的可发送消息和远端接续信息。
16
+ * omitted 只表示本次上下文预算省略了旧资料,完整历史仍保留;state 是否真正可用由请求规划再次核对配置键。
17
+ */
18
+ export interface ConversationHistory {
19
+ /**
20
+ * 按对话顺序排列的已恢复统一消息,可能包含已压缩证据引用。
21
+ */
22
+ messages: ModelMessage[];
23
+ /**
24
+ * 是否因本次预算省略较早资料;不能据此断言历史不存在。
25
+ */
26
+ omitted: boolean;
27
+ /**
28
+ * 最近可承接的远端响应状态;null 表示从本地消息重建。
29
+ */
30
+ state: RemoteHistory | null;
31
+ /**
32
+ * 此前证实不支持接续的 provider 配置键;配置变化后可重新判断。
33
+ */
34
+ disabledKey: string | null;
35
+ }
36
+ /** 逐页恢复近期完整交互,按 Token 预算停止;完整记录始终可经 context_read 读取。 */
37
+ /**
38
+ * 只为 assistant 按 created_at/id 游标逐页恢复此前已结束运行,每页 10 条。
39
+ * 限定同会话、租户、用户、当前权限指纹和注册表指纹;只从最近一轮同模型且成功的记录承接远端状态。
40
+ * 优先保留完整近期轮次,最近一轮本身超预算时尝试压缩为引用,不能容纳则标记 omitted;不会删除数据库历史或放宽授权。
41
+ */
42
+ export declare function loadConversation(kernel: Kernel, ctx: Ctx, run: StoredRun, maxTokens: number, stateKey?: string): Promise<ConversationHistory>;
43
+ export {};
@@ -0,0 +1,139 @@
1
+ /**
2
+ * 按当前授权和 Token 预算恢复同一助理会话的近期历史。
3
+ * 运行时准备新轮上下文时调用;持久记录完整保留,窗口裁剪只影响本次模型输入,失败或取消的工具调用不会被伪装成成功历史。
4
+ */
5
+ import { sql } from 'kysely';
6
+ import { authFingerprint } from './security.js';
7
+ import { messageTokens, packPrompt } from './prompt.js';
8
+ /** 只恢复该运行自身的消息,避免把每轮保存的近期窗口递归复制进下一轮。 */
9
+ /**
10
+ * 提取运行自身的消息并清理不完整工具调用组及孤立回执。
11
+ * 没有消息时用原始任务和最终状态构造最小交互;非成功运行追加需核对回执的提示,不能把未完成调用重放成已成功动作。返回新数组,不修改持久历史。
12
+ */
13
+ export function turnHistory(run) {
14
+ const own = run.history.slice(run.history_start);
15
+ if (!own.length)
16
+ return [
17
+ { role: 'user', content: run.input, runId: run.id },
18
+ { role: 'assistant', content: run.answer ?? `上轮状态:${run.status}。执行结果需核对动作回执。`, runId: run.id },
19
+ ];
20
+ const messages = [];
21
+ for (let index = 0; index < own.length; index++) {
22
+ const message = own[index];
23
+ if (message.toolCalls?.length) {
24
+ const ids = new Set(message.toolCalls.map((call) => call.id));
25
+ let end = index + 1;
26
+ while (end < own.length && own[end].role === 'tool' && ids.has(own[end].toolCallId))
27
+ end++;
28
+ if (end - index - 1 !== ids.size) {
29
+ // 失败/取消可以留下未执行调用;不能将其重放为完整调用组或伪造业务成功。
30
+ if (message.content)
31
+ messages.push({ role: 'assistant', content: message.content, runId: run.id });
32
+ index = end - 1;
33
+ continue;
34
+ }
35
+ }
36
+ if (message.role === 'tool' &&
37
+ !messages.some((item) => item.toolCalls?.some((call) => call.id === message.toolCallId)))
38
+ continue;
39
+ messages.push({ ...message, runId: run.id });
40
+ }
41
+ if (run.status !== 'succeeded')
42
+ messages.push({
43
+ role: 'assistant',
44
+ content: `上轮状态:${run.status}。未完成操作不能视为成功;用 context_read 核对回执。`,
45
+ runId: run.id,
46
+ });
47
+ return messages;
48
+ }
49
+ /** 逐页恢复近期完整交互,按 Token 预算停止;完整记录始终可经 context_read 读取。 */
50
+ /**
51
+ * 只为 assistant 按 created_at/id 游标逐页恢复此前已结束运行,每页 10 条。
52
+ * 限定同会话、租户、用户、当前权限指纹和注册表指纹;只从最近一轮同模型且成功的记录承接远端状态。
53
+ * 优先保留完整近期轮次,最近一轮本身超预算时尝试压缩为引用,不能容纳则标记 omitted;不会删除数据库历史或放宽授权。
54
+ */
55
+ export async function loadConversation(kernel, ctx, run, maxTokens, stateKey) {
56
+ const result = { messages: [], omitted: false, state: null, disabledKey: null };
57
+ if (run.mode !== 'assistant')
58
+ return result;
59
+ let cursor;
60
+ let latest = true;
61
+ for (;;) {
62
+ let query = kernel.app
63
+ .selectFrom('sys.ai_run')
64
+ .select([
65
+ 'id',
66
+ 'input',
67
+ 'answer',
68
+ 'history',
69
+ 'history_start',
70
+ 'status',
71
+ 'model',
72
+ 'model_state',
73
+ 'continuation_disabled_key',
74
+ 'created_at',
75
+ ])
76
+ .where('session_id', '=', run.session_id)
77
+ .where('tenant_id', '=', ctx.tenantId)
78
+ .where('user_id', '=', ctx.userId)
79
+ .where('id', '<>', run.id)
80
+ .where('status', 'in', ['succeeded', 'failed', 'cancelled', 'expired'])
81
+ .where('auth_fingerprint', '=', authFingerprint(ctx))
82
+ .where('fingerprint', '=', run.fingerprint)
83
+ .where(sql `(created_at, id) < (select created_at, id from sys.ai_run where id = ${run.id}::uuid)`)
84
+ .orderBy('created_at', 'desc')
85
+ .orderBy('id', 'desc')
86
+ .limit(10);
87
+ if (cursor)
88
+ query = query.where(sql `(created_at, id) < (select created_at, id from sys.ai_run where id = ${cursor}::uuid)`);
89
+ const rows = await query.execute();
90
+ if (!rows.length)
91
+ break;
92
+ for (const row of rows) {
93
+ if (latest) {
94
+ if (row.model === run.model) {
95
+ result.state = row.status === 'succeeded' ? row.model_state : null;
96
+ result.disabledKey = row.continuation_disabled_key;
97
+ }
98
+ latest = false;
99
+ }
100
+ const messages = turnHistory(row);
101
+ const combined = [...messages, ...result.messages];
102
+ if (messageTokens(combined, stateKey) > maxTokens) {
103
+ // 最近一轮很大时仍尝试保留完整补充输入和最近工具组,普通证据收起为引用。
104
+ if (!result.messages.length) {
105
+ try {
106
+ result.messages = packPrompt({
107
+ instructions: '',
108
+ context: null,
109
+ tools: [],
110
+ history: messages,
111
+ maxInputTokens: maxTokens,
112
+ stateKey,
113
+ }).messages.slice(1);
114
+ }
115
+ catch (error) {
116
+ if (!(error instanceof Error) || error.message !== 'AI_CONTEXT_TOO_LARGE')
117
+ throw error;
118
+ }
119
+ }
120
+ result.omitted = true;
121
+ return withCursor(result);
122
+ }
123
+ result.messages = combined;
124
+ }
125
+ const last = rows[rows.length - 1];
126
+ cursor = last.id;
127
+ }
128
+ return withCursor(result);
129
+ }
130
+ /**
131
+ * 把远端状态的 historyLength 对齐到实际恢复的消息数。
132
+ * 该游标使接续请求只发送新增消息,修改的是当前恢复结果,不回写历史运行。
133
+ */
134
+ function withCursor(history) {
135
+ if (history.state)
136
+ history.state = { ...history.state, historyLength: history.messages.length };
137
+ return history;
138
+ }
139
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { AiRuntime } from './runtime.js';
3
+ /**
4
+ * 从固定接口清单生成 OpenAPI path、请求 schema、幂等头和能力元数据。
5
+ * 事件及性格试聊同时描述 JSON/SSE 响应;x-capability 供文档发现,实际认证、归属和权限仍由挂载接口及服务执行。
6
+ */
7
+ export declare function aiOpenApi(): Record<string, Record<string, unknown>>;
8
+ /** 固定框架接口复用宿主的 cookie/CSRF/限流。运行、互动和事件均按登录租户及用户隔离。 */
9
+ /**
10
+ * 注册助理与管理接口,并跟踪所有 SSE 连接以便应用关闭时取消。
11
+ * identity 验证会话仍存在且未过期后重建 ctx;管理接口使用独立能力,不把普通助理能力当作管理权限。
12
+ * 运行事件按 sequence 续传、每页最多 200 条,慢消费者等待 drain;连接约 55 秒轮换并持续核验身份,撤销、断线或终态结束连接。
13
+ * 性格试聊支持 JSON 与 SSE,连接中断取消请求,只向流返回稳定错误码;详细状态和持久事务由 runtime/store 负责。
14
+ */
15
+ export declare function mountHttp(app: FastifyInstance, runtime: AiRuntime): void;
package/dist/http.js ADDED
@@ -0,0 +1,197 @@
1
+ /**
2
+ * 挂载 AI 会话、运行、事件流及模型/性格管理固定 HTTP 接口,并生成对应 OpenAPI 路径。
3
+ * 由 AI 运行时接入宿主 Fastify,复用会话 Cookie、CSRF 与限流;每次读写重新获取当前授权,长连接持续复核,HTTP 不直接执行领域写入。
4
+ */
5
+ import { setTimeout as delay } from 'node:timers/promises';
6
+ import { cageError, isCageError } from '@yss123/cage-kernel';
7
+ import { z } from 'zod';
8
+ import { needUser, parse } from './security.js';
9
+ import { TERMINAL } from './types.js';
10
+ import { messageInputSchema, interactionResponseSchema, modelConfigSchema, personalityInputSchema, personalitySettingsSchema, personalitySelectionSchema, personalityPreviewSchema, sessionInputSchema } from '@yss123/cage-ai-protocol';
11
+ import { MODEL_CAPABILITY } from './models.js';
12
+ import { PERSONALITY_CAPABILITY } from './personalities.js';
13
+ /**
14
+ * 从固定接口清单生成 OpenAPI path、请求 schema、幂等头和能力元数据。
15
+ * 事件及性格试聊同时描述 JSON/SSE 响应;x-capability 供文档发现,实际认证、归属和权限仍由挂载接口及服务执行。
16
+ */
17
+ export function aiOpenApi() {
18
+ const definitions = [
19
+ ['get', '/api/ai/sessions', '本人会话列表', 200], ['post', '/api/ai/sessions', '新建会话', 201, sessionInputSchema],
20
+ ['get', '/api/ai/personalities', '可用助理性格与默认项', 200],
21
+ ['post', '/api/ai/sessions/{id}/personality', '选择会话性格(下一轮生效)', 200, personalitySelectionSchema],
22
+ ['get', '/api/ai/sessions/{id}/runs', '本人会话轮次', 200], ['post', '/api/ai/sessions/{id}/messages', '提交消息与页面快照', 202, messageInputSchema],
23
+ ['get', '/api/ai/runs/{id}', '运行状态和待处理互动', 200], ['get', '/api/ai/runs/{id}/events', '按序号读取或订阅事件', 200],
24
+ ['post', '/api/ai/runs/{id}/cancel', '取消运行', 200], ['post', '/api/ai/runs/{id}/interactions/{interactionId}', '回复互动', 200, interactionResponseSchema],
25
+ ['get', '/api/ai/memory', '本人偏好', 200], ['delete', '/api/ai/memory/{id}', '删除本人偏好', 200],
26
+ ['get', '/api/ai/admin/models', '本租户模型配置(不返回密钥)', 200],
27
+ ['post', '/api/ai/admin/models/{key}', '保存模型配置', 200, modelConfigSchema],
28
+ ['post', '/api/ai/admin/models/{key}/test', '测试已保存的模型连接', 200],
29
+ ['get', '/api/ai/admin/personalities', '本租户助理性格配置', 200],
30
+ ['post', '/api/ai/admin/personalities/{key}', '保存助理性格', 200, personalityInputSchema],
31
+ ['post', '/api/ai/admin/assistant-settings', '设置默认助理性格', 200, personalitySettingsSchema],
32
+ ['post', '/api/ai/admin/personality-preview', '试聊未保存的性格(支持 SSE)', 200, personalityPreviewSchema],
33
+ ];
34
+ const paths = {};
35
+ for (const [method, path, summary, status, schema] of definitions) {
36
+ const parameters = [...path.matchAll(/\{(\w+)\}/g)].map(m => ({ name: m[1], in: 'path', required: true, schema: { type: 'string', ...(m[1] === 'key' ? {} : { format: 'uuid' }) } }));
37
+ if (path.endsWith('/messages'))
38
+ parameters.push({ name: 'Idempotency-Key', in: 'header', required: true, schema: { type: 'string', minLength: 1, maxLength: 160 } });
39
+ if (path.endsWith('/events'))
40
+ parameters.push({ name: 'after', in: 'query', schema: { type: 'integer', minimum: 0 } });
41
+ (paths[path] ??= {})[method] = { summary, 'x-capability': path.includes('/admin/models') ? MODEL_CAPABILITY : path.includes('/admin/') ? PERSONALITY_CAPABILITY : 'Sys.ai.use', parameters,
42
+ ...(schema ? { requestBody: { required: true, content: { 'application/json': { schema: z.toJSONSchema(schema, { io: 'input', unrepresentable: 'any' }) } } } } : {}),
43
+ responses: { [status]: { description: summary, content: { 'application/json': { schema: {} }, ...((path.endsWith('/events') || path.endsWith('/personality-preview')) ? { 'text/event-stream': { schema: { type: 'string' } } } : {}) } },
44
+ default: { description: 'CageError;校验登录、CSRF、归属和当前授权', content: { 'application/json': { schema: { $ref: '#/components/schemas/CageError' } } } } } };
45
+ }
46
+ return paths;
47
+ }
48
+ /** 固定框架接口复用宿主的 cookie/CSRF/限流。运行、互动和事件均按登录租户及用户隔离。 */
49
+ /**
50
+ * 注册助理与管理接口,并跟踪所有 SSE 连接以便应用关闭时取消。
51
+ * identity 验证会话仍存在且未过期后重建 ctx;管理接口使用独立能力,不把普通助理能力当作管理权限。
52
+ * 运行事件按 sequence 续传、每页最多 200 条,慢消费者等待 drain;连接约 55 秒轮换并持续核验身份,撤销、断线或终态结束连接。
53
+ * 性格试聊支持 JSON 与 SSE,连接中断取消请求,只向流返回稳定错误码;详细状态和持久事务由 runtime/store 负责。
54
+ */
55
+ export function mountHttp(app, runtime) {
56
+ const streams = new Set();
57
+ app.addHook('preClose', async () => { for (const stream of streams)
58
+ stream.abort(); });
59
+ // Cookie 的解析结果仍需核验数据库会话有效期,再重建最新 ctx;管理接口跳过助理能力检查,但各自管理服务另查独立能力。
60
+ const identity = async (req, assistant = true) => {
61
+ const session = req.cageSession;
62
+ if (!session)
63
+ throw cageError('UNAUTHENTICATED');
64
+ const valid = await runtime.kernel.app.selectFrom('sys.session').select('id').where('id', '=', session.id)
65
+ .where('tenant_id', '=', session.tenantId).where('user_id', '=', session.userId).where('expires_at', '>', new Date()).executeTakeFirst();
66
+ if (!valid)
67
+ throw cageError('UNAUTHENTICATED');
68
+ const ctx = await runtime.kernel.contextFor(session.userId, session.tenantId, { stepUpAt: session.stepUpAt, source: 'api', requestId: String(req.id) });
69
+ if (!ctx)
70
+ throw cageError('UNAUTHENTICATED');
71
+ if (assistant)
72
+ needUser(ctx);
73
+ return ctx;
74
+ };
75
+ app.get('/api/ai/admin/models', async (req) => runtime.models.list(await identity(req, false)));
76
+ app.post('/api/ai/admin/models/:key', async (req) => runtime.models.save(await identity(req, false), req.params.key, req.body));
77
+ app.post('/api/ai/admin/models/:key/test', async (req) => runtime.models.test(await identity(req, false), req.params.key));
78
+ app.get('/api/ai/admin/personalities', async (req) => runtime.personalities.list(await identity(req, false)));
79
+ app.post('/api/ai/admin/personalities/:key', async (req) => runtime.personalities.save(await identity(req, false), req.params.key, req.body));
80
+ app.post('/api/ai/admin/assistant-settings', async (req) => runtime.personalities.saveSettings(await identity(req, false), req.body));
81
+ app.get('/api/ai/personalities', async (req) => runtime.personalities.available(await identity(req)));
82
+ app.post('/api/ai/sessions/:id/personality', async (req) => runtime.selectPersonality(await identity(req), req.params.id, req.body));
83
+ app.post('/api/ai/admin/personality-preview', async (req, reply) => {
84
+ const ctx = await identity(req, false);
85
+ runtime.personalities.need(ctx);
86
+ const input = parse(personalityPreviewSchema, req.body);
87
+ const controller = new AbortController(), close = () => controller.abort();
88
+ streams.add(controller);
89
+ reply.raw.on('close', close);
90
+ const streaming = String(req.headers.accept).includes('text/event-stream');
91
+ if (streaming) {
92
+ reply.raw.writeHead(200, { 'content-type': 'text/event-stream; charset=utf-8', 'cache-control': 'no-cache, no-store, no-transform', 'x-accel-buffering': 'no' });
93
+ reply.hijack();
94
+ reply.raw.socket?.setNoDelay(true);
95
+ reply.raw.flushHeaders();
96
+ }
97
+ let checkedAt = 0;
98
+ const write = async (value) => {
99
+ controller.signal.throwIfAborted();
100
+ if (Date.now() - checkedAt >= 200) {
101
+ runtime.personalities.need(await identity(req, false));
102
+ checkedAt = Date.now();
103
+ }
104
+ if (!reply.raw.write(`data: ${JSON.stringify(value)}\n\n`))
105
+ await new Promise((resolve, reject) => {
106
+ const done = () => { reply.raw.off('drain', done); controller.signal.removeEventListener('abort', abort); resolve(); };
107
+ const abort = () => { reply.raw.off('drain', done); reject(new Error('closed')); };
108
+ reply.raw.once('drain', done);
109
+ controller.signal.addEventListener('abort', abort, { once: true });
110
+ });
111
+ };
112
+ try {
113
+ const result = await runtime.previewPersonality(ctx, input, streaming ? text => write({ type: 'delta', text }) : undefined, controller.signal);
114
+ if (!streaming)
115
+ return result;
116
+ await write({ type: 'done', result });
117
+ }
118
+ catch (error) {
119
+ if (!streaming)
120
+ throw error;
121
+ // 连接器错误可能包含上游正文,试聊只交付稳定错误码。
122
+ if (!controller.signal.aborted)
123
+ await write({ type: 'error', code: isCageError(error) ? error.code : 'MODEL_PREVIEW_FAILED' }).catch(() => { });
124
+ }
125
+ finally {
126
+ streams.delete(controller);
127
+ reply.raw.off('close', close);
128
+ if (streaming)
129
+ reply.raw.end();
130
+ }
131
+ });
132
+ app.get('/api/ai/sessions', async (req) => runtime.sessions(await identity(req)));
133
+ app.post('/api/ai/sessions', async (req, reply) => {
134
+ const body = parse(sessionInputSchema, req.body ?? {});
135
+ return reply.code(201).send(await runtime.createSession(await identity(req), body.title, body.personalityKey));
136
+ });
137
+ app.get('/api/ai/sessions/:id/runs', async (req) => runtime.runs(await identity(req), req.params.id));
138
+ app.post('/api/ai/sessions/:id/messages', async (req, reply) => {
139
+ const key = parse(z.string().min(1).max(160), req.headers['idempotency-key']);
140
+ const run = await runtime.submit(await identity(req), req.params.id, req.body, key, req.cageSession.id);
141
+ return reply.code(202).send(run);
142
+ });
143
+ app.get('/api/ai/runs/:id', async (req) => runtime.run(await identity(req), req.params.id));
144
+ app.post('/api/ai/runs/:id/cancel', async (req) => runtime.cancel(await identity(req), req.params.id));
145
+ app.post('/api/ai/runs/:id/interactions/:interactionId', async (req) => {
146
+ const p = req.params;
147
+ return runtime.respond(await identity(req), p.id, p.interactionId, req.body);
148
+ });
149
+ app.get('/api/ai/memory', async (req) => runtime.memories(await identity(req)));
150
+ app.delete('/api/ai/memory/:id', async (req) => { await runtime.deleteMemory(await identity(req), req.params.id); return { ok: true }; });
151
+ app.get('/api/ai/runs/:id/events', async (req, reply) => {
152
+ const id = req.params.id, query = (req.query ?? {});
153
+ let cursor = parse(z.coerce.number().int().nonnegative(), query.after ?? req.headers['last-event-id'] ?? 0);
154
+ const ctx = await identity(req);
155
+ const initial = await runtime.eventPage(ctx, id, cursor);
156
+ if (!String(req.headers.accept).includes('text/event-stream'))
157
+ return initial.events;
158
+ reply.raw.writeHead(200, { 'content-type': 'text/event-stream; charset=utf-8', 'cache-control': 'no-cache, no-store, no-transform', 'x-accel-buffering': 'no' });
159
+ reply.hijack();
160
+ reply.raw.socket?.setNoDelay(true);
161
+ reply.raw.flushHeaders();
162
+ const controller = new AbortController(), endAt = Date.now() + 55_000;
163
+ streams.add(controller);
164
+ const close = () => controller.abort();
165
+ reply.raw.on('close', close);
166
+ try {
167
+ let page = initial;
168
+ while (!controller.signal.aborted && Date.now() < endAt) {
169
+ for (const event of page.events) {
170
+ // 尊重慢消费者背压,不在内存中无限积压事件。
171
+ if (!reply.raw.write(`id: ${event.sequence}\nevent: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`)) {
172
+ await new Promise((resolve, reject) => {
173
+ const done = () => { reply.raw.off('drain', done); controller.signal.removeEventListener('abort', abort); resolve(); };
174
+ const abort = () => { reply.raw.off('drain', done); reject(new Error('closed')); };
175
+ reply.raw.once('drain', done);
176
+ controller.signal.addEventListener('abort', abort, { once: true });
177
+ });
178
+ }
179
+ cursor = event.sequence;
180
+ }
181
+ if (cursor >= page.nextSequence && (TERMINAL.includes(page.status) || page.status.startsWith('waiting_')))
182
+ break;
183
+ // 有积压时立即追赶;在线跟随只增加至多约 100ms 等待,并持续核验会话和权限。
184
+ if (page.events.length < 200)
185
+ await delay(100, undefined, { signal: controller.signal });
186
+ page = await runtime.eventPage(await identity(req), id, cursor);
187
+ }
188
+ }
189
+ catch { /* 会话撤销、权限改变或断线立即结束;续连走完整 HTTP 授权。 */ }
190
+ finally {
191
+ streams.delete(controller);
192
+ reply.raw.off('close', close);
193
+ reply.raw.end();
194
+ }
195
+ });
196
+ }
197
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * AI 包公开入口。应用顶层 ai() 声明向注册表提供服务、能力和迁移,供 CLI/API/worker 一致使用。
3
+ * 声明阶段只验证冻结配置;按 Kernel 懒创建并复用运行时,不在模块加载时访问数据库或模型。
4
+ */
5
+ import { type Kernel, type Registry, type RuntimeDefinition } from '@yss123/cage-kernel';
6
+ import { AiRuntime } from './runtime.js';
7
+ import { type AiOptions } from './types.js';
8
+ export { AiRuntime } from './runtime.js';
9
+ export { chatModel, type ChatModelOptions } from './model.js';
10
+ export { responsesModel, type ResponsesModelOptions } from './responses.js';
11
+ export { managedModel, ModelManager } from './models.js';
12
+ export type { AiOptions, AiContextOptions, RunLimits, ModelProvider, ModelRequest, ModelResult, ModelMessage, ModelTool, ToolCall, } from './types.js';
13
+ export type { PageContext, AiRun, AiEvent, AiInteraction, AiMessageInput, AiSession, AiMemory, } from '@yss123/cage-ai-protocol';
14
+ /**
15
+ * 可注册的 AI 服务声明,校验唯一启用和模型引用,并按内核复用运行时。
16
+ */
17
+ export interface AiDefinition extends RuntimeDefinition {
18
+ /**
19
+ * 获取或创建绑定内核的 AiRuntime,生命周期由宿主管理。
20
+ */
21
+ service(kernel: Kernel): AiRuntime;
22
+ /**
23
+ * 校验扩展唯一性与审批模型引用,无效配置以 CAGE-AI-001 拒绝。
24
+ */
25
+ validate(registry: Registry): void;
26
+ }
27
+ /**
28
+ * 创建供 domain 顶层导出的 AI 服务声明,CLI、API 和 worker 从同一注册表取得能力、迁移与运行时。
29
+ * 复制并冻结模型映射、上下文和助理额度,校验模型引用、窗口、并发及超时边界;无效声明以 CAGE-AI-001 拒绝。
30
+ * service 按 Kernel 实例懒创建并缓存运行时,validate 再核对唯一启用和审批节点的模型引用。
31
+ * 声明阶段没有数据库或网络 IO;公开能力仍需管理员明确授予,启用声明不自动授权用户或连接真实模型。
32
+ */
33
+ export declare function ai(options: AiOptions): AiDefinition;
package/dist/index.js ADDED
@@ -0,0 +1,100 @@
1
+ /**
2
+ * AI 包公开入口。应用顶层 ai() 声明向注册表提供服务、能力和迁移,供 CLI/API/worker 一致使用。
3
+ * 声明阶段只验证冻结配置;按 Kernel 懒创建并复用运行时,不在模块加载时访问数据库或模型。
4
+ */
5
+ import { RUNTIME, MIGRATIONS, declError, } from '@yss123/cage-kernel';
6
+ import { AI_MIGRATION } from './schema.js';
7
+ import { AiRuntime } from './runtime.js';
8
+ import { DEFAULT_LIMITS } from './types.js';
9
+ import { MODEL_MIGRATION, MODEL_CAPABILITY } from './models.js';
10
+ import { PERSONALITY_MIGRATION, PERSONALITY_CAPABILITY } from './personalities.js';
11
+ import { CONTEXT_MIGRATION } from './context-schema.js';
12
+ import { EXECUTION_MIGRATION } from './execution-schema.js';
13
+ export { AiRuntime } from './runtime.js';
14
+ export { chatModel } from './model.js';
15
+ export { responsesModel } from './responses.js';
16
+ export { managedModel, ModelManager } from './models.js';
17
+ /**
18
+ * 创建供 domain 顶层导出的 AI 服务声明,CLI、API 和 worker 从同一注册表取得能力、迁移与运行时。
19
+ * 复制并冻结模型映射、上下文和助理额度,校验模型引用、窗口、并发及超时边界;无效声明以 CAGE-AI-001 拒绝。
20
+ * service 按 Kernel 实例懒创建并缓存运行时,validate 再核对唯一启用和审批节点的模型引用。
21
+ * 声明阶段没有数据库或网络 IO;公开能力仍需管理员明确授予,启用声明不自动授权用户或连接真实模型。
22
+ */
23
+ export function ai(options) {
24
+ options = {
25
+ ...options,
26
+ context: options.context && Object.freeze({ ...options.context }),
27
+ models: Object.freeze({ ...options.models }),
28
+ assistant: options.assistant &&
29
+ Object.freeze({ ...options.assistant, limits: Object.freeze({ ...options.assistant.limits }) }),
30
+ };
31
+ if (!Object.keys(options.models).length)
32
+ throw declError('CAGE-AI-001', '至少配置一个模型');
33
+ for (const provider of Object.values(options.models))
34
+ if (provider.contextWindowTokens !== undefined &&
35
+ (!Number.isSafeInteger(provider.contextWindowTokens) ||
36
+ provider.contextWindowTokens < 8192 ||
37
+ provider.contextWindowTokens > 2_000_000))
38
+ throw declError('CAGE-AI-001', 'contextWindowTokens 必须是 8192 至 2000000 之间的整数');
39
+ const limits = { ...DEFAULT_LIMITS, ...options.assistant?.limits };
40
+ for (const [key, value] of Object.entries(limits))
41
+ if (!Number.isSafeInteger(value) || value < (key === 'maxModelRetries' ? 0 : 1))
42
+ throw declError('CAGE-AI-001', `${key} 超出允许范围`);
43
+ for (const [key, value] of Object.entries(options.context ?? {}))
44
+ if (!Number.isSafeInteger(value) || value <= 0)
45
+ throw declError('CAGE-AI-001', `${key} 必须是正整数`);
46
+ if ((options.context?.maxTools ?? 128) > 128)
47
+ throw declError('CAGE-AI-001', 'maxTools 最多 128(包含通用工具)');
48
+ if ((limits.maxModelRetries ?? 2) > 8)
49
+ throw declError('CAGE-AI-001', 'maxModelRetries 最多 8 次');
50
+ if (options.assistant && !options.models[options.assistant.model])
51
+ throw declError('CAGE-AI-001', '助理引用的模型不存在');
52
+ for (const value of [options.maxConcurrentRuns ?? 2, options.maxQueuedPerUser ?? 8, options.delegationTtlMs ?? 1])
53
+ if (!Number.isSafeInteger(value) || value <= 0)
54
+ throw declError('CAGE-AI-001', '并发、队列与委托期限必须是正整数');
55
+ if ((options.maxConcurrentRuns ?? 2) > 32 || limits.timeoutMs > 300_000)
56
+ throw declError('CAGE-AI-001', '并发最多 32,单轮运行超时最多 300000 毫秒');
57
+ // 按内核实例缓存而非全局单例,避免不同应用/连接配置共享运行队列;弱引用不阻止已释放内核回收。
58
+ const services = new WeakMap();
59
+ return Object.freeze({
60
+ [RUNTIME]: true,
61
+ name: 'ai',
62
+ spec: {
63
+ models: Object.fromEntries(Object.entries(options.models).map(([name, value]) => [name, value.spec])),
64
+ assistant: options.assistant,
65
+ context: options.context,
66
+ maxConcurrentRuns: options.maxConcurrentRuns,
67
+ maxQueuedPerUser: options.maxQueuedPerUser,
68
+ delegationTtlMs: options.delegationTtlMs,
69
+ },
70
+ capabilities: [
71
+ { capability: 'Sys.ai.use', kind: 'system', description: '使用领域智能助理(业务权限仍单独校验)' },
72
+ { capability: MODEL_CAPABILITY, kind: 'system', description: '管理本租户 AI 模型连接与密钥' },
73
+ { capability: PERSONALITY_CAPABILITY, kind: 'system', description: '管理本租户助理性格、默认项及试聊' },
74
+ ],
75
+ [MIGRATIONS]: () => [AI_MIGRATION, MODEL_MIGRATION, PERSONALITY_MIGRATION, CONTEXT_MIGRATION, EXECUTION_MIGRATION],
76
+ service(kernel) {
77
+ let service = services.get(kernel);
78
+ if (!service) {
79
+ service = new AiRuntime(kernel, options);
80
+ services.set(kernel, service);
81
+ }
82
+ return service;
83
+ },
84
+ validate(registry) {
85
+ if (registry.extensions.filter((e) => e.kind === 'RUNTIME' && e.value.name === 'ai').length !== 1)
86
+ throw declError('CAGE-AI-001', '只能启用一个 AI 运行时');
87
+ // 容器内的 AI 仍须经过相同模型/预算检查;不能因放入条件或并行分支而遗漏启动期校验。
88
+ const leafSteps = (nodes) => nodes.flatMap(node => node.kind === 'when' ? leafSteps(node.steps)
89
+ : node.kind === 'parallel' ? node.branches.flatMap((branch) => leafSteps(branch.nodes)) : [node]);
90
+ for (const ext of registry.extensions.filter((e) => e.kind === 'ROUTE'))
91
+ for (const node of leafSteps(ext.value.nodes)) {
92
+ if (node.kind === 'ai' && !options.models[node.model])
93
+ throw declError('CAGE-AI-001', `AI 审批引用的模型 ${node.model} 未配置`);
94
+ if (node.kind === 'ai' && (node.limits?.timeoutMs ?? 1) > 300_000)
95
+ throw declError('CAGE-AI-001', '审批 timeoutMs 最多 300000 毫秒');
96
+ }
97
+ },
98
+ });
99
+ }
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}