@bowenqt/qiniu-ai-sdk 0.10.0 → 0.14.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.
Files changed (149) hide show
  1. package/README.md +225 -0
  2. package/dist/ai/agent-graph.d.ts +101 -0
  3. package/dist/ai/agent-graph.d.ts.map +1 -0
  4. package/dist/ai/agent-graph.js +322 -0
  5. package/dist/ai/agent-graph.js.map +1 -0
  6. package/dist/ai/agent-graph.mjs +318 -0
  7. package/dist/ai/generate-text.d.ts +58 -0
  8. package/dist/ai/generate-text.d.ts.map +1 -1
  9. package/dist/ai/generate-text.js +157 -0
  10. package/dist/ai/generate-text.js.map +1 -1
  11. package/dist/ai/generate-text.mjs +156 -0
  12. package/dist/ai/graph/checkpointer.d.ts +112 -0
  13. package/dist/ai/graph/checkpointer.d.ts.map +1 -0
  14. package/dist/ai/graph/checkpointer.js +131 -0
  15. package/dist/ai/graph/checkpointer.js.map +1 -0
  16. package/dist/ai/graph/checkpointer.mjs +126 -0
  17. package/dist/ai/graph/index.d.ts +13 -0
  18. package/dist/ai/graph/index.d.ts.map +1 -0
  19. package/dist/ai/graph/index.js +22 -0
  20. package/dist/ai/graph/index.js.map +1 -0
  21. package/dist/ai/graph/index.mjs +12 -0
  22. package/dist/ai/graph/postgres-checkpointer.d.ts +54 -0
  23. package/dist/ai/graph/postgres-checkpointer.d.ts.map +1 -0
  24. package/dist/ai/graph/postgres-checkpointer.js +134 -0
  25. package/dist/ai/graph/postgres-checkpointer.js.map +1 -0
  26. package/dist/ai/graph/postgres-checkpointer.mjs +130 -0
  27. package/dist/ai/graph/redis-checkpointer.d.ts +51 -0
  28. package/dist/ai/graph/redis-checkpointer.d.ts.map +1 -0
  29. package/dist/ai/graph/redis-checkpointer.js +124 -0
  30. package/dist/ai/graph/redis-checkpointer.js.map +1 -0
  31. package/dist/ai/graph/redis-checkpointer.mjs +120 -0
  32. package/dist/ai/graph/state-graph.d.ts +41 -0
  33. package/dist/ai/graph/state-graph.d.ts.map +1 -0
  34. package/dist/ai/graph/state-graph.js +149 -0
  35. package/dist/ai/graph/state-graph.js.map +1 -0
  36. package/dist/ai/graph/state-graph.mjs +144 -0
  37. package/dist/ai/graph/types.d.ts +41 -0
  38. package/dist/ai/graph/types.d.ts.map +1 -0
  39. package/dist/ai/graph/types.js +10 -0
  40. package/dist/ai/graph/types.js.map +1 -0
  41. package/dist/ai/graph/types.mjs +7 -0
  42. package/dist/ai/internal-types.d.ts +109 -0
  43. package/dist/ai/internal-types.d.ts.map +1 -0
  44. package/dist/ai/internal-types.js +28 -0
  45. package/dist/ai/internal-types.js.map +1 -0
  46. package/dist/ai/internal-types.mjs +23 -0
  47. package/dist/ai/nodes/execute-node.d.ts +27 -0
  48. package/dist/ai/nodes/execute-node.d.ts.map +1 -0
  49. package/dist/ai/nodes/execute-node.js +118 -0
  50. package/dist/ai/nodes/execute-node.js.map +1 -0
  51. package/dist/ai/nodes/execute-node.mjs +114 -0
  52. package/dist/ai/nodes/index.d.ts +8 -0
  53. package/dist/ai/nodes/index.d.ts.map +1 -0
  54. package/dist/ai/nodes/index.js +16 -0
  55. package/dist/ai/nodes/index.js.map +1 -0
  56. package/dist/ai/nodes/index.mjs +7 -0
  57. package/dist/ai/nodes/memory-node.d.ts +34 -0
  58. package/dist/ai/nodes/memory-node.d.ts.map +1 -0
  59. package/dist/ai/nodes/memory-node.js +164 -0
  60. package/dist/ai/nodes/memory-node.js.map +1 -0
  61. package/dist/ai/nodes/memory-node.mjs +158 -0
  62. package/dist/ai/nodes/predict-node.d.ts +42 -0
  63. package/dist/ai/nodes/predict-node.d.ts.map +1 -0
  64. package/dist/ai/nodes/predict-node.js +89 -0
  65. package/dist/ai/nodes/predict-node.js.map +1 -0
  66. package/dist/ai/nodes/predict-node.mjs +86 -0
  67. package/dist/ai/nodes/types.d.ts +44 -0
  68. package/dist/ai/nodes/types.d.ts.map +1 -0
  69. package/dist/ai/nodes/types.js +6 -0
  70. package/dist/ai/nodes/types.js.map +1 -0
  71. package/dist/ai/nodes/types.mjs +5 -0
  72. package/dist/index.d.ts +23 -0
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +80 -1
  75. package/dist/index.js.map +1 -1
  76. package/dist/index.mjs +34 -0
  77. package/dist/lib/otel-tracer.d.ts +47 -0
  78. package/dist/lib/otel-tracer.d.ts.map +1 -0
  79. package/dist/lib/otel-tracer.js +79 -0
  80. package/dist/lib/otel-tracer.js.map +1 -0
  81. package/dist/lib/otel-tracer.mjs +75 -0
  82. package/dist/lib/token-estimator.d.ts +62 -0
  83. package/dist/lib/token-estimator.d.ts.map +1 -0
  84. package/dist/lib/token-estimator.js +106 -0
  85. package/dist/lib/token-estimator.js.map +1 -0
  86. package/dist/lib/token-estimator.mjs +100 -0
  87. package/dist/lib/tool-registry.d.ts +103 -0
  88. package/dist/lib/tool-registry.d.ts.map +1 -0
  89. package/dist/lib/tool-registry.js +159 -0
  90. package/dist/lib/tool-registry.js.map +1 -0
  91. package/dist/lib/tool-registry.mjs +154 -0
  92. package/dist/lib/tracer.d.ts +85 -0
  93. package/dist/lib/tracer.d.ts.map +1 -0
  94. package/dist/lib/tracer.js +170 -0
  95. package/dist/lib/tracer.js.map +1 -0
  96. package/dist/lib/tracer.mjs +161 -0
  97. package/dist/lib/types.d.ts +11 -0
  98. package/dist/lib/types.d.ts.map +1 -1
  99. package/dist/modules/mcp/adapter.d.ts +23 -0
  100. package/dist/modules/mcp/adapter.d.ts.map +1 -0
  101. package/dist/modules/mcp/adapter.js +63 -0
  102. package/dist/modules/mcp/adapter.js.map +1 -0
  103. package/dist/modules/mcp/adapter.mjs +58 -0
  104. package/dist/modules/mcp/client.d.ts +75 -0
  105. package/dist/modules/mcp/client.d.ts.map +1 -0
  106. package/dist/modules/mcp/client.js +300 -0
  107. package/dist/modules/mcp/client.js.map +1 -0
  108. package/dist/modules/mcp/client.mjs +295 -0
  109. package/dist/modules/mcp/http-transport.d.ts +51 -0
  110. package/dist/modules/mcp/http-transport.d.ts.map +1 -0
  111. package/dist/modules/mcp/http-transport.js +146 -0
  112. package/dist/modules/mcp/http-transport.js.map +1 -0
  113. package/dist/modules/mcp/http-transport.mjs +141 -0
  114. package/dist/modules/mcp/index.d.ts +11 -0
  115. package/dist/modules/mcp/index.d.ts.map +1 -0
  116. package/dist/modules/mcp/index.js +34 -0
  117. package/dist/modules/mcp/index.js.map +1 -0
  118. package/dist/modules/mcp/index.mjs +14 -0
  119. package/dist/modules/mcp/oauth.d.ts +101 -0
  120. package/dist/modules/mcp/oauth.d.ts.map +1 -0
  121. package/dist/modules/mcp/oauth.js +347 -0
  122. package/dist/modules/mcp/oauth.js.map +1 -0
  123. package/dist/modules/mcp/oauth.mjs +304 -0
  124. package/dist/modules/mcp/token-store.d.ts +69 -0
  125. package/dist/modules/mcp/token-store.d.ts.map +1 -0
  126. package/dist/modules/mcp/token-store.js +174 -0
  127. package/dist/modules/mcp/token-store.js.map +1 -0
  128. package/dist/modules/mcp/token-store.mjs +135 -0
  129. package/dist/modules/mcp/types.d.ts +91 -0
  130. package/dist/modules/mcp/types.d.ts.map +1 -0
  131. package/dist/modules/mcp/types.js +14 -0
  132. package/dist/modules/mcp/types.js.map +1 -0
  133. package/dist/modules/mcp/types.mjs +11 -0
  134. package/dist/modules/skills/index.d.ts +7 -0
  135. package/dist/modules/skills/index.d.ts.map +1 -0
  136. package/dist/modules/skills/index.js +14 -0
  137. package/dist/modules/skills/index.js.map +1 -0
  138. package/dist/modules/skills/index.mjs +6 -0
  139. package/dist/modules/skills/loader.d.ts +51 -0
  140. package/dist/modules/skills/loader.d.ts.map +1 -0
  141. package/dist/modules/skills/loader.js +237 -0
  142. package/dist/modules/skills/loader.js.map +1 -0
  143. package/dist/modules/skills/loader.mjs +198 -0
  144. package/dist/modules/skills/types.d.ts +60 -0
  145. package/dist/modules/skills/types.d.ts.map +1 -0
  146. package/dist/modules/skills/types.js +20 -0
  147. package/dist/modules/skills/types.js.map +1 -0
  148. package/dist/modules/skills/types.mjs +17 -0
  149. package/package.json +4 -1
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * PostgreSQL Checkpointer implementation.
4
+ * Requires pg as a peer dependency.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Pool } from 'pg';
9
+ * import { PostgresCheckpointer } from '@bowenqt/qiniu-ai-sdk';
10
+ *
11
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
12
+ * const checkpointer = new PostgresCheckpointer(pool, { tableName: 'checkpoints' });
13
+ *
14
+ * // Create table (run once)
15
+ * await checkpointer.createTable();
16
+ * ```
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.PostgresCheckpointer = void 0;
20
+ /**
21
+ * PostgreSQL-based checkpointer.
22
+ * Uses pg-compatible client interface.
23
+ */
24
+ class PostgresCheckpointer {
25
+ constructor(client, config = {}) {
26
+ this.client = client;
27
+ this.tableName = config.tableName ?? 'qiniu_checkpoints';
28
+ this.schema = config.schema ?? 'public';
29
+ }
30
+ get table() {
31
+ return `"${this.schema}"."${this.tableName}"`;
32
+ }
33
+ /**
34
+ * Create the checkpoints table if it doesn't exist.
35
+ * Run this during application setup.
36
+ */
37
+ async createTable() {
38
+ await this.client.query(`
39
+ CREATE TABLE IF NOT EXISTS ${this.table} (
40
+ id TEXT PRIMARY KEY,
41
+ thread_id TEXT NOT NULL,
42
+ created_at BIGINT NOT NULL,
43
+ step_count INTEGER NOT NULL,
44
+ custom JSONB,
45
+ state JSONB NOT NULL,
46
+ created_at_ts TIMESTAMP DEFAULT NOW()
47
+ )
48
+ `);
49
+ await this.client.query(`
50
+ CREATE INDEX IF NOT EXISTS idx_${this.tableName}_thread_id
51
+ ON ${this.table} (thread_id)
52
+ `);
53
+ await this.client.query(`
54
+ CREATE INDEX IF NOT EXISTS idx_${this.tableName}_created_at
55
+ ON ${this.table} (created_at DESC)
56
+ `);
57
+ }
58
+ async save(threadId, state, custom) {
59
+ const id = `ckpt_${threadId}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
60
+ const createdAt = Date.now();
61
+ const metadata = {
62
+ id,
63
+ threadId,
64
+ createdAt,
65
+ stepCount: state.stepCount,
66
+ custom,
67
+ };
68
+ const serializedState = this.serializeState(state);
69
+ await this.client.query(`INSERT INTO ${this.table} (id, thread_id, created_at, step_count, custom, state)
70
+ VALUES ($1, $2, $3, $4, $5, $6)`, [id, threadId, createdAt, state.stepCount, JSON.stringify(custom ?? {}), JSON.stringify(serializedState)]);
71
+ return metadata;
72
+ }
73
+ async load(threadId) {
74
+ const result = await this.client.query(`SELECT id, thread_id, created_at, step_count, custom, state
75
+ FROM ${this.table}
76
+ WHERE thread_id = $1
77
+ ORDER BY created_at DESC
78
+ LIMIT 1`, [threadId]);
79
+ if (result.rows.length === 0)
80
+ return null;
81
+ const row = result.rows[0];
82
+ return {
83
+ metadata: {
84
+ id: row.id,
85
+ threadId: row.thread_id,
86
+ createdAt: Number(row.created_at),
87
+ stepCount: row.step_count,
88
+ custom: row.custom,
89
+ },
90
+ state: row.state,
91
+ };
92
+ }
93
+ async list(threadId) {
94
+ const result = await this.client.query(`SELECT id, thread_id, created_at, step_count, custom
95
+ FROM ${this.table}
96
+ WHERE thread_id = $1
97
+ ORDER BY created_at DESC`, [threadId]);
98
+ return result.rows.map(row => ({
99
+ id: row.id,
100
+ threadId: row.thread_id,
101
+ createdAt: Number(row.created_at),
102
+ stepCount: row.step_count,
103
+ custom: row.custom,
104
+ }));
105
+ }
106
+ async delete(checkpointId) {
107
+ const result = await this.client.query(`DELETE FROM ${this.table} WHERE id = $1`, [checkpointId]);
108
+ return result.rowCount === 1;
109
+ }
110
+ async clear(threadId) {
111
+ const result = await this.client.query(`DELETE FROM ${this.table} WHERE thread_id = $1`, [threadId]);
112
+ return result.rowCount ?? 0;
113
+ }
114
+ serializeState(state) {
115
+ return {
116
+ messages: state.messages.map(msg => ({
117
+ role: msg.role,
118
+ content: msg.content,
119
+ tool_calls: msg.tool_calls,
120
+ tool_call_id: msg.tool_call_id,
121
+ _meta: msg._meta,
122
+ })),
123
+ stepCount: state.stepCount,
124
+ maxSteps: state.maxSteps,
125
+ done: state.done,
126
+ output: state.output,
127
+ reasoning: state.reasoning,
128
+ finishReason: state.finishReason,
129
+ usage: state.usage,
130
+ };
131
+ }
132
+ }
133
+ exports.PostgresCheckpointer = PostgresCheckpointer;
134
+ //# sourceMappingURL=postgres-checkpointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-checkpointer.js","sourceRoot":"","sources":["../../../src/ai/graph/postgres-checkpointer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * PostgreSQL Checkpointer implementation.
3
+ * Requires pg as a peer dependency.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { Pool } from 'pg';
8
+ * import { PostgresCheckpointer } from '@bowenqt/qiniu-ai-sdk';
9
+ *
10
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
11
+ * const checkpointer = new PostgresCheckpointer(pool, { tableName: 'checkpoints' });
12
+ *
13
+ * // Create table (run once)
14
+ * await checkpointer.createTable();
15
+ * ```
16
+ */
17
+ /**
18
+ * PostgreSQL-based checkpointer.
19
+ * Uses pg-compatible client interface.
20
+ */
21
+ export class PostgresCheckpointer {
22
+ constructor(client, config = {}) {
23
+ this.client = client;
24
+ this.tableName = config.tableName ?? 'qiniu_checkpoints';
25
+ this.schema = config.schema ?? 'public';
26
+ }
27
+ get table() {
28
+ return `"${this.schema}"."${this.tableName}"`;
29
+ }
30
+ /**
31
+ * Create the checkpoints table if it doesn't exist.
32
+ * Run this during application setup.
33
+ */
34
+ async createTable() {
35
+ await this.client.query(`
36
+ CREATE TABLE IF NOT EXISTS ${this.table} (
37
+ id TEXT PRIMARY KEY,
38
+ thread_id TEXT NOT NULL,
39
+ created_at BIGINT NOT NULL,
40
+ step_count INTEGER NOT NULL,
41
+ custom JSONB,
42
+ state JSONB NOT NULL,
43
+ created_at_ts TIMESTAMP DEFAULT NOW()
44
+ )
45
+ `);
46
+ await this.client.query(`
47
+ CREATE INDEX IF NOT EXISTS idx_${this.tableName}_thread_id
48
+ ON ${this.table} (thread_id)
49
+ `);
50
+ await this.client.query(`
51
+ CREATE INDEX IF NOT EXISTS idx_${this.tableName}_created_at
52
+ ON ${this.table} (created_at DESC)
53
+ `);
54
+ }
55
+ async save(threadId, state, custom) {
56
+ const id = `ckpt_${threadId}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
57
+ const createdAt = Date.now();
58
+ const metadata = {
59
+ id,
60
+ threadId,
61
+ createdAt,
62
+ stepCount: state.stepCount,
63
+ custom,
64
+ };
65
+ const serializedState = this.serializeState(state);
66
+ await this.client.query(`INSERT INTO ${this.table} (id, thread_id, created_at, step_count, custom, state)
67
+ VALUES ($1, $2, $3, $4, $5, $6)`, [id, threadId, createdAt, state.stepCount, JSON.stringify(custom ?? {}), JSON.stringify(serializedState)]);
68
+ return metadata;
69
+ }
70
+ async load(threadId) {
71
+ const result = await this.client.query(`SELECT id, thread_id, created_at, step_count, custom, state
72
+ FROM ${this.table}
73
+ WHERE thread_id = $1
74
+ ORDER BY created_at DESC
75
+ LIMIT 1`, [threadId]);
76
+ if (result.rows.length === 0)
77
+ return null;
78
+ const row = result.rows[0];
79
+ return {
80
+ metadata: {
81
+ id: row.id,
82
+ threadId: row.thread_id,
83
+ createdAt: Number(row.created_at),
84
+ stepCount: row.step_count,
85
+ custom: row.custom,
86
+ },
87
+ state: row.state,
88
+ };
89
+ }
90
+ async list(threadId) {
91
+ const result = await this.client.query(`SELECT id, thread_id, created_at, step_count, custom
92
+ FROM ${this.table}
93
+ WHERE thread_id = $1
94
+ ORDER BY created_at DESC`, [threadId]);
95
+ return result.rows.map(row => ({
96
+ id: row.id,
97
+ threadId: row.thread_id,
98
+ createdAt: Number(row.created_at),
99
+ stepCount: row.step_count,
100
+ custom: row.custom,
101
+ }));
102
+ }
103
+ async delete(checkpointId) {
104
+ const result = await this.client.query(`DELETE FROM ${this.table} WHERE id = $1`, [checkpointId]);
105
+ return result.rowCount === 1;
106
+ }
107
+ async clear(threadId) {
108
+ const result = await this.client.query(`DELETE FROM ${this.table} WHERE thread_id = $1`, [threadId]);
109
+ return result.rowCount ?? 0;
110
+ }
111
+ serializeState(state) {
112
+ return {
113
+ messages: state.messages.map(msg => ({
114
+ role: msg.role,
115
+ content: msg.content,
116
+ tool_calls: msg.tool_calls,
117
+ tool_call_id: msg.tool_call_id,
118
+ _meta: msg._meta,
119
+ })),
120
+ stepCount: state.stepCount,
121
+ maxSteps: state.maxSteps,
122
+ done: state.done,
123
+ output: state.output,
124
+ reasoning: state.reasoning,
125
+ finishReason: state.finishReason,
126
+ usage: state.usage,
127
+ };
128
+ }
129
+ }
130
+ //# sourceMappingURL=postgres-checkpointer.js.map
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Redis Checkpointer implementation.
3
+ * Requires ioredis as a peer dependency.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import Redis from 'ioredis';
8
+ * import { RedisCheckpointer } from '@bowenqt/qiniu-ai-sdk';
9
+ *
10
+ * const redis = new Redis('redis://localhost:6379');
11
+ * const checkpointer = new RedisCheckpointer(redis, { prefix: 'myapp:' });
12
+ * ```
13
+ */
14
+ import type { AgentState } from '../internal-types';
15
+ import type { Checkpoint, CheckpointMetadata, Checkpointer } from './checkpointer';
16
+ /** Redis client interface (compatible with ioredis) */
17
+ export interface RedisClient {
18
+ set(key: string, value: string, exMode?: string, time?: number): Promise<'OK' | null>;
19
+ get(key: string): Promise<string | null>;
20
+ del(key: string | string[]): Promise<number>;
21
+ keys(pattern: string): Promise<string[]>;
22
+ smembers(key: string): Promise<string[]>;
23
+ sadd(key: string, ...members: string[]): Promise<number>;
24
+ srem(key: string, ...members: string[]): Promise<number>;
25
+ }
26
+ /** Redis checkpointer configuration */
27
+ export interface RedisCheckpointerConfig {
28
+ /** Key prefix (default: 'qiniu:checkpoint:') */
29
+ prefix?: string;
30
+ /** TTL in seconds (default: no expiry) */
31
+ ttlSeconds?: number;
32
+ }
33
+ /**
34
+ * Redis-based checkpointer.
35
+ * Uses ioredis-compatible client interface.
36
+ */
37
+ export declare class RedisCheckpointer implements Checkpointer {
38
+ private readonly redis;
39
+ private readonly prefix;
40
+ private readonly ttlSeconds?;
41
+ constructor(client: RedisClient, config?: RedisCheckpointerConfig);
42
+ private checkpointKey;
43
+ private threadKey;
44
+ save(threadId: string, state: AgentState, custom?: Record<string, unknown>): Promise<CheckpointMetadata>;
45
+ load(threadId: string): Promise<Checkpoint | null>;
46
+ list(threadId: string): Promise<CheckpointMetadata[]>;
47
+ delete(checkpointId: string): Promise<boolean>;
48
+ clear(threadId: string): Promise<number>;
49
+ private serializeState;
50
+ }
51
+ //# sourceMappingURL=redis-checkpointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-checkpointer.d.ts","sourceRoot":"","sources":["../../../src/ai/graph/redis-checkpointer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAwB,MAAM,gBAAgB,CAAC;AAEzG,uDAAuD;AACvD,MAAM,WAAW,WAAW;IACxB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACtF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5D;AAED,uCAAuC;AACvC,MAAM,WAAW,uBAAuB;IACpC,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAEzB,MAAM,EAAE,WAAW,EAAE,MAAM,GAAE,uBAA4B;IAMrE,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,SAAS;IAIX,IAAI,CACN,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,kBAAkB,CAAC;IA+BxB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAmBlD,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAerD,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW9C,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW9C,OAAO,CAAC,cAAc;CAkBzB"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * Redis Checkpointer implementation.
4
+ * Requires ioredis as a peer dependency.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import Redis from 'ioredis';
9
+ * import { RedisCheckpointer } from '@bowenqt/qiniu-ai-sdk';
10
+ *
11
+ * const redis = new Redis('redis://localhost:6379');
12
+ * const checkpointer = new RedisCheckpointer(redis, { prefix: 'myapp:' });
13
+ * ```
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.RedisCheckpointer = void 0;
17
+ /**
18
+ * Redis-based checkpointer.
19
+ * Uses ioredis-compatible client interface.
20
+ */
21
+ class RedisCheckpointer {
22
+ constructor(client, config = {}) {
23
+ this.redis = client;
24
+ this.prefix = config.prefix ?? 'qiniu:checkpoint:';
25
+ this.ttlSeconds = config.ttlSeconds;
26
+ }
27
+ checkpointKey(id) {
28
+ return `${this.prefix}data:${id}`;
29
+ }
30
+ threadKey(threadId) {
31
+ return `${this.prefix}thread:${threadId}`;
32
+ }
33
+ async save(threadId, state, custom) {
34
+ const id = `ckpt_${threadId}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
35
+ const metadata = {
36
+ id,
37
+ threadId,
38
+ createdAt: Date.now(),
39
+ stepCount: state.stepCount,
40
+ custom,
41
+ };
42
+ const checkpoint = {
43
+ metadata,
44
+ state: this.serializeState(state),
45
+ };
46
+ const key = this.checkpointKey(id);
47
+ const data = JSON.stringify(checkpoint);
48
+ if (this.ttlSeconds) {
49
+ await this.redis.set(key, data, 'EX', this.ttlSeconds);
50
+ }
51
+ else {
52
+ await this.redis.set(key, data);
53
+ }
54
+ // Add to thread index
55
+ await this.redis.sadd(this.threadKey(threadId), id);
56
+ return metadata;
57
+ }
58
+ async load(threadId) {
59
+ const ids = await this.redis.smembers(this.threadKey(threadId));
60
+ if (ids.length === 0)
61
+ return null;
62
+ let latest = null;
63
+ for (const id of ids) {
64
+ const data = await this.redis.get(this.checkpointKey(id));
65
+ if (data) {
66
+ const checkpoint = JSON.parse(data);
67
+ if (!latest || checkpoint.metadata.createdAt > latest.metadata.createdAt) {
68
+ latest = checkpoint;
69
+ }
70
+ }
71
+ }
72
+ return latest;
73
+ }
74
+ async list(threadId) {
75
+ const ids = await this.redis.smembers(this.threadKey(threadId));
76
+ const result = [];
77
+ for (const id of ids) {
78
+ const data = await this.redis.get(this.checkpointKey(id));
79
+ if (data) {
80
+ const checkpoint = JSON.parse(data);
81
+ result.push(checkpoint.metadata);
82
+ }
83
+ }
84
+ return result.sort((a, b) => b.createdAt - a.createdAt);
85
+ }
86
+ async delete(checkpointId) {
87
+ const data = await this.redis.get(this.checkpointKey(checkpointId));
88
+ if (!data)
89
+ return false;
90
+ const checkpoint = JSON.parse(data);
91
+ await this.redis.del(this.checkpointKey(checkpointId));
92
+ await this.redis.srem(this.threadKey(checkpoint.metadata.threadId), checkpointId);
93
+ return true;
94
+ }
95
+ async clear(threadId) {
96
+ const ids = await this.redis.smembers(this.threadKey(threadId));
97
+ if (ids.length === 0)
98
+ return 0;
99
+ const keys = ids.map(id => this.checkpointKey(id));
100
+ await this.redis.del(keys);
101
+ await this.redis.del(this.threadKey(threadId));
102
+ return ids.length;
103
+ }
104
+ serializeState(state) {
105
+ return {
106
+ messages: state.messages.map(msg => ({
107
+ role: msg.role,
108
+ content: msg.content,
109
+ tool_calls: msg.tool_calls,
110
+ tool_call_id: msg.tool_call_id,
111
+ _meta: msg._meta,
112
+ })),
113
+ stepCount: state.stepCount,
114
+ maxSteps: state.maxSteps,
115
+ done: state.done,
116
+ output: state.output,
117
+ reasoning: state.reasoning,
118
+ finishReason: state.finishReason,
119
+ usage: state.usage,
120
+ };
121
+ }
122
+ }
123
+ exports.RedisCheckpointer = RedisCheckpointer;
124
+ //# sourceMappingURL=redis-checkpointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-checkpointer.js","sourceRoot":"","sources":["../../../src/ai/graph/redis-checkpointer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Redis Checkpointer implementation.
3
+ * Requires ioredis as a peer dependency.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import Redis from 'ioredis';
8
+ * import { RedisCheckpointer } from '@bowenqt/qiniu-ai-sdk';
9
+ *
10
+ * const redis = new Redis('redis://localhost:6379');
11
+ * const checkpointer = new RedisCheckpointer(redis, { prefix: 'myapp:' });
12
+ * ```
13
+ */
14
+ /**
15
+ * Redis-based checkpointer.
16
+ * Uses ioredis-compatible client interface.
17
+ */
18
+ export class RedisCheckpointer {
19
+ constructor(client, config = {}) {
20
+ this.redis = client;
21
+ this.prefix = config.prefix ?? 'qiniu:checkpoint:';
22
+ this.ttlSeconds = config.ttlSeconds;
23
+ }
24
+ checkpointKey(id) {
25
+ return `${this.prefix}data:${id}`;
26
+ }
27
+ threadKey(threadId) {
28
+ return `${this.prefix}thread:${threadId}`;
29
+ }
30
+ async save(threadId, state, custom) {
31
+ const id = `ckpt_${threadId}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
32
+ const metadata = {
33
+ id,
34
+ threadId,
35
+ createdAt: Date.now(),
36
+ stepCount: state.stepCount,
37
+ custom,
38
+ };
39
+ const checkpoint = {
40
+ metadata,
41
+ state: this.serializeState(state),
42
+ };
43
+ const key = this.checkpointKey(id);
44
+ const data = JSON.stringify(checkpoint);
45
+ if (this.ttlSeconds) {
46
+ await this.redis.set(key, data, 'EX', this.ttlSeconds);
47
+ }
48
+ else {
49
+ await this.redis.set(key, data);
50
+ }
51
+ // Add to thread index
52
+ await this.redis.sadd(this.threadKey(threadId), id);
53
+ return metadata;
54
+ }
55
+ async load(threadId) {
56
+ const ids = await this.redis.smembers(this.threadKey(threadId));
57
+ if (ids.length === 0)
58
+ return null;
59
+ let latest = null;
60
+ for (const id of ids) {
61
+ const data = await this.redis.get(this.checkpointKey(id));
62
+ if (data) {
63
+ const checkpoint = JSON.parse(data);
64
+ if (!latest || checkpoint.metadata.createdAt > latest.metadata.createdAt) {
65
+ latest = checkpoint;
66
+ }
67
+ }
68
+ }
69
+ return latest;
70
+ }
71
+ async list(threadId) {
72
+ const ids = await this.redis.smembers(this.threadKey(threadId));
73
+ const result = [];
74
+ for (const id of ids) {
75
+ const data = await this.redis.get(this.checkpointKey(id));
76
+ if (data) {
77
+ const checkpoint = JSON.parse(data);
78
+ result.push(checkpoint.metadata);
79
+ }
80
+ }
81
+ return result.sort((a, b) => b.createdAt - a.createdAt);
82
+ }
83
+ async delete(checkpointId) {
84
+ const data = await this.redis.get(this.checkpointKey(checkpointId));
85
+ if (!data)
86
+ return false;
87
+ const checkpoint = JSON.parse(data);
88
+ await this.redis.del(this.checkpointKey(checkpointId));
89
+ await this.redis.srem(this.threadKey(checkpoint.metadata.threadId), checkpointId);
90
+ return true;
91
+ }
92
+ async clear(threadId) {
93
+ const ids = await this.redis.smembers(this.threadKey(threadId));
94
+ if (ids.length === 0)
95
+ return 0;
96
+ const keys = ids.map(id => this.checkpointKey(id));
97
+ await this.redis.del(keys);
98
+ await this.redis.del(this.threadKey(threadId));
99
+ return ids.length;
100
+ }
101
+ serializeState(state) {
102
+ return {
103
+ messages: state.messages.map(msg => ({
104
+ role: msg.role,
105
+ content: msg.content,
106
+ tool_calls: msg.tool_calls,
107
+ tool_call_id: msg.tool_call_id,
108
+ _meta: msg._meta,
109
+ })),
110
+ stepCount: state.stepCount,
111
+ maxSteps: state.maxSteps,
112
+ done: state.done,
113
+ output: state.output,
114
+ reasoning: state.reasoning,
115
+ finishReason: state.finishReason,
116
+ usage: state.usage,
117
+ };
118
+ }
119
+ }
120
+ //# sourceMappingURL=redis-checkpointer.js.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * StateGraph - LangGraph-inspired graph builder.
3
+ * Minimal implementation for Phase 1.
4
+ */
5
+ import type { NodeFunction, EdgeResolver, CompiledGraph, StateGraphConfig } from './types';
6
+ /** Maximum steps error */
7
+ export declare class MaxGraphStepsError extends Error {
8
+ readonly maxSteps: number;
9
+ constructor(maxSteps: number);
10
+ }
11
+ /**
12
+ * StateGraph builder for agent workflows.
13
+ */
14
+ export declare class StateGraph<S extends object> {
15
+ private config;
16
+ private nodes;
17
+ private edges;
18
+ private entryPoint;
19
+ constructor(config?: StateGraphConfig<S>);
20
+ /**
21
+ * Add a node to the graph.
22
+ */
23
+ addNode(name: string, fn: NodeFunction<S>): this;
24
+ /**
25
+ * Add an edge between nodes.
26
+ */
27
+ addEdge(from: string, to: string): this;
28
+ /**
29
+ * Add a conditional edge.
30
+ */
31
+ addConditionalEdge(from: string, resolver: EdgeResolver<S>): this;
32
+ /**
33
+ * Set the entry point.
34
+ */
35
+ setEntryPoint(name: string): this;
36
+ /**
37
+ * Compile the graph into an executable form.
38
+ */
39
+ compile(): CompiledGraph<S>;
40
+ }
41
+ //# sourceMappingURL=state-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-graph.d.ts","sourceRoot":"","sources":["../../../src/ai/graph/state-graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,YAAY,EACZ,YAAY,EAGZ,aAAa,EAEb,gBAAgB,EACnB,MAAM,SAAS,CAAC;AAGjB,0BAA0B;AAC1B,qBAAa,kBAAmB,SAAQ,KAAK;aACb,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;CAI/C;AAED;;GAEG;AACH,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM;IAKxB,OAAO,CAAC,MAAM;IAJ1B,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,UAAU,CAAuB;gBAErB,MAAM,GAAE,gBAAgB,CAAC,CAAC,CAAM;IAMpD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAWhD;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAKvC;;OAEG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAKjE;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKjC;;OAEG;IACH,OAAO,IAAI,aAAa,CAAC,CAAC,CAAC;CA8F9B"}