@zhin.js/agent 0.0.0 → 0.0.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.
- package/CHANGELOG.md +8 -0
- package/README.md +226 -0
- package/lib/agent.d.ts +9 -7
- package/lib/agent.d.ts.map +1 -1
- package/lib/agent.js +63 -29
- package/lib/agent.js.map +1 -1
- package/lib/bootstrap.js +1 -1
- package/lib/bootstrap.js.map +1 -1
- package/lib/builtin-tools.d.ts.map +1 -1
- package/lib/builtin-tools.js +34 -31
- package/lib/builtin-tools.js.map +1 -1
- package/lib/compaction.js +1 -1
- package/lib/compaction.js.map +1 -1
- package/lib/context-manager.js +1 -1
- package/lib/context-manager.js.map +1 -1
- package/lib/conversation-memory.d.ts +11 -0
- package/lib/conversation-memory.d.ts.map +1 -1
- package/lib/conversation-memory.js +39 -1
- package/lib/conversation-memory.js.map +1 -1
- package/lib/cron-engine.d.ts.map +1 -1
- package/lib/cron-engine.js +5 -3
- package/lib/cron-engine.js.map +1 -1
- package/lib/follow-up.js +1 -1
- package/lib/follow-up.js.map +1 -1
- package/lib/hooks.js +1 -1
- package/lib/hooks.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/init/create-zhin-agent.d.ts +3 -0
- package/lib/init/create-zhin-agent.d.ts.map +1 -0
- package/lib/init/create-zhin-agent.js +127 -0
- package/lib/init/create-zhin-agent.js.map +1 -0
- package/lib/init/register-ai-service.d.ts +7 -0
- package/lib/init/register-ai-service.d.ts.map +1 -0
- package/lib/init/register-ai-service.js +42 -0
- package/lib/init/register-ai-service.js.map +1 -0
- package/lib/init/register-ai-trigger.d.ts +7 -0
- package/lib/init/register-ai-trigger.d.ts.map +1 -0
- package/lib/init/register-ai-trigger.js +163 -0
- package/lib/init/register-ai-trigger.js.map +1 -0
- package/lib/init/register-builtin-tools.d.ts +3 -0
- package/lib/init/register-builtin-tools.d.ts.map +1 -0
- package/lib/init/register-builtin-tools.js +179 -0
- package/lib/init/register-builtin-tools.js.map +1 -0
- package/lib/init/register-db-models.d.ts +2 -0
- package/lib/init/register-db-models.d.ts.map +1 -0
- package/lib/init/register-db-models.js +28 -0
- package/lib/init/register-db-models.js.map +1 -0
- package/lib/init/register-db-upgrade.d.ts +10 -0
- package/lib/init/register-db-upgrade.d.ts.map +1 -0
- package/lib/init/register-db-upgrade.js +67 -0
- package/lib/init/register-db-upgrade.js.map +1 -0
- package/lib/init/register-management-tools.d.ts +6 -0
- package/lib/init/register-management-tools.d.ts.map +1 -0
- package/lib/init/register-management-tools.js +68 -0
- package/lib/init/register-management-tools.js.map +1 -0
- package/lib/init/register-message-recorder.d.ts +3 -0
- package/lib/init/register-message-recorder.d.ts.map +1 -0
- package/lib/init/register-message-recorder.js +27 -0
- package/lib/init/register-message-recorder.js.map +1 -0
- package/lib/init/register-tool-service.d.ts +2 -0
- package/lib/init/register-tool-service.d.ts.map +1 -0
- package/lib/init/register-tool-service.js +9 -0
- package/lib/init/register-tool-service.js.map +1 -0
- package/lib/init/shared-refs.d.ts +14 -0
- package/lib/init/shared-refs.d.ts.map +1 -0
- package/lib/init/shared-refs.js +7 -0
- package/lib/init/shared-refs.js.map +1 -0
- package/lib/init/types.d.ts +15 -0
- package/lib/init/types.d.ts.map +1 -0
- package/lib/init/types.js +7 -0
- package/lib/init/types.js.map +1 -0
- package/lib/init.d.ts +14 -17
- package/lib/init.d.ts.map +1 -1
- package/lib/init.js +34 -670
- package/lib/init.js.map +1 -1
- package/lib/rate-limiter.js +1 -1
- package/lib/rate-limiter.js.map +1 -1
- package/lib/service.js +2 -2
- package/lib/service.js.map +1 -1
- package/lib/session.d.ts +7 -0
- package/lib/session.d.ts.map +1 -1
- package/lib/session.js +26 -4
- package/lib/session.js.map +1 -1
- package/lib/storage.d.ts +68 -0
- package/lib/storage.d.ts.map +1 -0
- package/lib/storage.js +105 -0
- package/lib/storage.js.map +1 -0
- package/lib/subagent.js +1 -1
- package/lib/subagent.js.map +1 -1
- package/lib/tools.d.ts.map +1 -1
- package/lib/tools.js +8 -9
- package/lib/tools.js.map +1 -1
- package/lib/user-profile.js +1 -1
- package/lib/user-profile.js.map +1 -1
- package/lib/zhin-agent/builtin-tools.js.map +1 -1
- package/lib/zhin-agent/config.d.ts +1 -1
- package/lib/zhin-agent/config.d.ts.map +1 -1
- package/lib/zhin-agent/config.js.map +1 -1
- package/lib/zhin-agent/index.js +1 -1
- package/lib/zhin-agent/index.js.map +1 -1
- package/lib/zhin-agent/tool-collector.js +3 -3
- package/lib/zhin-agent/tool-collector.js.map +1 -1
- package/package.json +4 -3
- package/src/agent.ts +53 -30
- package/src/bootstrap.ts +1 -1
- package/src/builtin-tools.ts +44 -40
- package/src/compaction.ts +1 -1
- package/src/context-manager.ts +1 -1
- package/src/conversation-memory.ts +43 -1
- package/src/cron-engine.ts +5 -3
- package/src/follow-up.ts +1 -1
- package/src/hooks.ts +1 -1
- package/src/index.ts +10 -0
- package/src/init/create-zhin-agent.ts +133 -0
- package/src/init/register-ai-service.ts +53 -0
- package/src/init/register-ai-trigger.ts +179 -0
- package/src/init/register-builtin-tools.ts +177 -0
- package/src/init/register-db-models.ts +31 -0
- package/src/init/register-db-upgrade.ts +77 -0
- package/src/init/register-management-tools.ts +71 -0
- package/src/init/register-message-recorder.ts +31 -0
- package/src/init/register-tool-service.ts +9 -0
- package/src/init/shared-refs.ts +20 -0
- package/src/init/types.ts +18 -0
- package/src/init.ts +35 -735
- package/src/rate-limiter.ts +1 -1
- package/src/service.ts +4 -4
- package/src/session.ts +26 -4
- package/src/storage.ts +135 -0
- package/src/subagent.ts +1 -1
- package/src/tools.ts +7 -10
- package/src/user-profile.ts +1 -1
- package/src/zhin-agent/builtin-tools.ts +2 -2
- package/src/zhin-agent/config.ts +3 -3
- package/src/zhin-agent/index.ts +1 -1
- package/src/zhin-agent/tool-collector.ts +8 -8
package/src/rate-limiter.ts
CHANGED
package/src/service.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 统一管理多个模型提供商,提供会话和 Agent 能力
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { Logger } from '@zhin.js/
|
|
6
|
+
import { Logger } from '@zhin.js/core';
|
|
7
7
|
import type { Plugin, Tool, ToolContext, AITriggerConfig } from '@zhin.js/core';
|
|
8
8
|
import type {
|
|
9
9
|
AIProvider,
|
|
@@ -224,12 +224,12 @@ ${preExecutedData ? `\n已自动获取的数据:${preExecutedData}\n` : ''}
|
|
|
224
224
|
const agentTool: AgentTool = {
|
|
225
225
|
name: tool.name,
|
|
226
226
|
description: tool.description,
|
|
227
|
-
parameters: tool.parameters
|
|
228
|
-
execute: tool.execute,
|
|
227
|
+
parameters: tool.parameters,
|
|
228
|
+
execute: async (args) => tool.execute(args),
|
|
229
229
|
};
|
|
230
230
|
if (tool.tags?.length) agentTool.tags = tool.tags;
|
|
231
231
|
if (tool.permissionLevel) agentTool.permissionLevel = AIService.PERM_MAP[tool.permissionLevel] ?? 0;
|
|
232
|
-
if (
|
|
232
|
+
if (tool.keywords?.length) agentTool.keywords = tool.keywords;
|
|
233
233
|
return agentTool;
|
|
234
234
|
}
|
|
235
235
|
|
package/src/session.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - 更长的上下文记忆能力
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import { Logger } from '@zhin.js/
|
|
12
|
+
import { Logger } from '@zhin.js/core';
|
|
13
13
|
import type { ChatMessage, SessionConfig, Session } from '@zhin.js/core';
|
|
14
14
|
|
|
15
15
|
const logger = new Logger(null, 'AI-Session');
|
|
@@ -192,14 +192,17 @@ export class DatabaseSessionManager implements ISessionManager {
|
|
|
192
192
|
private saveTimer?: ReturnType<typeof setTimeout>;
|
|
193
193
|
private model: any; // 数据库模型
|
|
194
194
|
|
|
195
|
+
/** 内存缓存上限,超出时淘汰最久未访问的条目 */
|
|
196
|
+
private static readonly MAX_CACHE_SIZE = 2000;
|
|
197
|
+
|
|
195
198
|
constructor(
|
|
196
199
|
model: any,
|
|
197
200
|
config: { maxHistory?: number; expireMs?: number } = {}
|
|
198
201
|
) {
|
|
199
202
|
this.model = model;
|
|
200
203
|
this.config = {
|
|
201
|
-
maxHistory: config.maxHistory ?? 200,
|
|
202
|
-
expireMs: config.expireMs ?? 7 * 24 * 60 * 60 * 1000,
|
|
204
|
+
maxHistory: config.maxHistory ?? 200,
|
|
205
|
+
expireMs: config.expireMs ?? 7 * 24 * 60 * 60 * 1000,
|
|
203
206
|
};
|
|
204
207
|
|
|
205
208
|
// 定期清理过期会话(每小时)
|
|
@@ -286,7 +289,6 @@ export class DatabaseSessionManager implements ISessionManager {
|
|
|
286
289
|
session = await this.loadSession(sessionId) ?? undefined;
|
|
287
290
|
|
|
288
291
|
if (!session) {
|
|
289
|
-
// 创建新会话
|
|
290
292
|
session = {
|
|
291
293
|
id: sessionId,
|
|
292
294
|
config: config || { provider: 'openai' },
|
|
@@ -296,6 +298,11 @@ export class DatabaseSessionManager implements ISessionManager {
|
|
|
296
298
|
};
|
|
297
299
|
}
|
|
298
300
|
|
|
301
|
+
this.evictCacheIfNeeded();
|
|
302
|
+
this.cache.set(sessionId, session);
|
|
303
|
+
} else {
|
|
304
|
+
// LRU: 重新插入以更新 Map 的迭代顺序
|
|
305
|
+
this.cache.delete(sessionId);
|
|
299
306
|
this.cache.set(sessionId, session);
|
|
300
307
|
}
|
|
301
308
|
|
|
@@ -305,6 +312,21 @@ export class DatabaseSessionManager implements ISessionManager {
|
|
|
305
312
|
return session;
|
|
306
313
|
}
|
|
307
314
|
|
|
315
|
+
/**
|
|
316
|
+
* 当缓存超过上限时,淘汰最久未访问的条目。
|
|
317
|
+
* 利用 Map 的插入顺序(最旧的在前)。
|
|
318
|
+
*/
|
|
319
|
+
private evictCacheIfNeeded(): void {
|
|
320
|
+
while (this.cache.size >= DatabaseSessionManager.MAX_CACHE_SIZE) {
|
|
321
|
+
const oldest = this.cache.keys().next().value;
|
|
322
|
+
if (oldest !== undefined) {
|
|
323
|
+
this.cache.delete(oldest);
|
|
324
|
+
} else {
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
308
330
|
async has(sessionId: string): Promise<boolean> {
|
|
309
331
|
if (this.cache.has(sessionId)) {
|
|
310
332
|
return true;
|
package/src/storage.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StorageBackend — Unified storage abstraction layer
|
|
3
|
+
*
|
|
4
|
+
* Provides a common interface for AI sub-systems (session, context, memory,
|
|
5
|
+
* user profile, follow-up) to switch between in-memory and database backends
|
|
6
|
+
* without changing business logic.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const backend = new MemoryStorageBackend<MyRecord>();
|
|
10
|
+
* // ... later, when DB is ready:
|
|
11
|
+
* const dbBackend = new DatabaseStorageBackend<MyRecord>(model, { keyField: 'session_id' });
|
|
12
|
+
* service.upgradeBackend(dbBackend);
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export interface StorageBackend<T extends Record<string, any>> {
|
|
16
|
+
get(key: string): Promise<T | null>;
|
|
17
|
+
set(key: string, value: T): Promise<void>;
|
|
18
|
+
delete(key: string): Promise<boolean>;
|
|
19
|
+
list(filter?: Partial<T>): Promise<T[]>;
|
|
20
|
+
clear(): Promise<void>;
|
|
21
|
+
readonly type: 'memory' | 'database';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* In-memory storage backend.
|
|
26
|
+
*/
|
|
27
|
+
export class MemoryStorageBackend<T extends Record<string, any>> implements StorageBackend<T> {
|
|
28
|
+
readonly type = 'memory' as const;
|
|
29
|
+
private data = new Map<string, T>();
|
|
30
|
+
|
|
31
|
+
async get(key: string): Promise<T | null> {
|
|
32
|
+
return this.data.get(key) ?? null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async set(key: string, value: T): Promise<void> {
|
|
36
|
+
this.data.set(key, value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async delete(key: string): Promise<boolean> {
|
|
40
|
+
return this.data.delete(key);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async list(filter?: Partial<T>): Promise<T[]> {
|
|
44
|
+
const all = Array.from(this.data.values());
|
|
45
|
+
if (!filter) return all;
|
|
46
|
+
return all.filter(item => {
|
|
47
|
+
for (const [k, v] of Object.entries(filter)) {
|
|
48
|
+
if (item[k] !== v) return false;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async clear(): Promise<void> {
|
|
55
|
+
this.data.clear();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Database model interface aligned with @zhin.js/database's RelatedModel API.
|
|
61
|
+
*/
|
|
62
|
+
export interface DbModel {
|
|
63
|
+
select(...fields: string[]): any;
|
|
64
|
+
create(data: Record<string, any>): Promise<any>;
|
|
65
|
+
update(data: Partial<any>): any;
|
|
66
|
+
delete(condition: Record<string, any>): any;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Database-backed storage backend.
|
|
71
|
+
*/
|
|
72
|
+
export class DatabaseStorageBackend<T extends Record<string, any>> implements StorageBackend<T> {
|
|
73
|
+
readonly type = 'database' as const;
|
|
74
|
+
|
|
75
|
+
constructor(
|
|
76
|
+
private model: DbModel,
|
|
77
|
+
private options: {
|
|
78
|
+
/** The field name used as lookup key (e.g. 'session_id', 'user_id') */
|
|
79
|
+
keyField: string;
|
|
80
|
+
},
|
|
81
|
+
) {}
|
|
82
|
+
|
|
83
|
+
async get(key: string): Promise<T | null> {
|
|
84
|
+
const rows: T[] = await this.model
|
|
85
|
+
.select()
|
|
86
|
+
.where({ [this.options.keyField]: key });
|
|
87
|
+
return rows[0] ?? null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async set(key: string, value: T): Promise<void> {
|
|
91
|
+
const existing = await this.get(key);
|
|
92
|
+
if (existing) {
|
|
93
|
+
await this.model
|
|
94
|
+
.update(value)
|
|
95
|
+
.where({ [this.options.keyField]: key });
|
|
96
|
+
} else {
|
|
97
|
+
await this.model.create({ ...value, [this.options.keyField]: key });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async delete(key: string): Promise<boolean> {
|
|
102
|
+
try {
|
|
103
|
+
await this.model.delete({ [this.options.keyField]: key });
|
|
104
|
+
return true;
|
|
105
|
+
} catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async list(filter?: Partial<T>): Promise<T[]> {
|
|
111
|
+
if (filter) {
|
|
112
|
+
return this.model.select().where(filter);
|
|
113
|
+
}
|
|
114
|
+
return this.model.select();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async clear(): Promise<void> {
|
|
118
|
+
const all = await this.list();
|
|
119
|
+
for (const item of all) {
|
|
120
|
+
const key = (item as Record<string, unknown>)[this.options.keyField] as string | undefined;
|
|
121
|
+
if (key) await this.delete(key);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Helper to create a swappable backend ref.
|
|
128
|
+
* Call `swap(newBackend)` to atomically upgrade from memory to database.
|
|
129
|
+
*/
|
|
130
|
+
export function createSwappableBackend<T extends Record<string, any>>(
|
|
131
|
+
initial: StorageBackend<T>,
|
|
132
|
+
): { backend: StorageBackend<T>; swap: (next: StorageBackend<T>) => void } {
|
|
133
|
+
const ref = { backend: initial, swap: (next: StorageBackend<T>) => { ref.backend = next; } };
|
|
134
|
+
return ref;
|
|
135
|
+
}
|
package/src/subagent.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { randomUUID } from 'crypto';
|
|
12
|
-
import { Logger } from '@zhin.js/
|
|
12
|
+
import { Logger } from '@zhin.js/core';
|
|
13
13
|
import type { AIProvider, AgentTool } from '@zhin.js/core';
|
|
14
14
|
import { createAgent } from './agent.js';
|
|
15
15
|
import type { ZhinAgentConfig } from './zhin-agent/config.js';
|
package/src/tools.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 内置工具集合 - 使用 ZhinTool 类定义
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ZhinTool, type Tool } from '@zhin.js/core';
|
|
6
|
+
import { ZhinTool, type Tool, evaluate, execute } from '@zhin.js/core';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* 计算器工具
|
|
@@ -16,7 +16,6 @@ export const calculatorTool = new ZhinTool('calculator')
|
|
|
16
16
|
.param('expression', { type: 'string', description: '数学表达式,例如 "2 + 3 * 4" 或 "sqrt(16)"' }, true)
|
|
17
17
|
.execute(async ({ expression }) => {
|
|
18
18
|
try {
|
|
19
|
-
// 安全的数学表达式求值
|
|
20
19
|
const sanitized = (expression as string)
|
|
21
20
|
.replace(/[^0-9+\-*/().^eEsincosqrtabspowlogxMathPI\s]/g, '')
|
|
22
21
|
.replace(/\bsqrt\b/g, 'Math.sqrt')
|
|
@@ -30,7 +29,8 @@ export const calculatorTool = new ZhinTool('calculator')
|
|
|
30
29
|
.replace(/\bE\b(?![0-9])/g, 'Math.E')
|
|
31
30
|
.replace(/\^/g, '**');
|
|
32
31
|
|
|
33
|
-
const result =
|
|
32
|
+
const result = evaluate(sanitized, { Math });
|
|
33
|
+
if (result === undefined) return { error: '无法计算表达式', expression };
|
|
34
34
|
return { result, expression };
|
|
35
35
|
} catch (error) {
|
|
36
36
|
return { error: '无法计算表达式', expression };
|
|
@@ -104,13 +104,10 @@ export const codeRunnerTool = new ZhinTool('run_code')
|
|
|
104
104
|
.param('code', { type: 'string', description: 'JavaScript 代码' }, true)
|
|
105
105
|
.execute(async ({ code }) => {
|
|
106
106
|
try {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return (function() { ${code} })();
|
|
112
|
-
`)();
|
|
113
|
-
|
|
107
|
+
const sandbox = {
|
|
108
|
+
console: { log: (...args: unknown[]) => args.map(String).join(' ') },
|
|
109
|
+
};
|
|
110
|
+
const result = execute(code as string, sandbox);
|
|
114
111
|
return {
|
|
115
112
|
success: true,
|
|
116
113
|
result: result !== undefined ? String(result) : 'undefined',
|
package/src/user-profile.ts
CHANGED
|
@@ -147,7 +147,7 @@ export function createScheduleFollowUpTool(
|
|
|
147
147
|
const botId = context.botId || '';
|
|
148
148
|
const senderId = context.senderId || '';
|
|
149
149
|
const sceneId = context.sceneId || '';
|
|
150
|
-
const sceneType =
|
|
150
|
+
const sceneType = context.message?.$channel?.type || 'private';
|
|
151
151
|
|
|
152
152
|
return {
|
|
153
153
|
name: 'schedule_followup',
|
|
@@ -208,7 +208,7 @@ export function createSpawnTaskTool(
|
|
|
208
208
|
const botId = context.botId || '';
|
|
209
209
|
const senderId = context.senderId || '';
|
|
210
210
|
const sceneId = context.sceneId || '';
|
|
211
|
-
const sceneType =
|
|
211
|
+
const sceneType = context.message?.$channel?.type || 'private';
|
|
212
212
|
|
|
213
213
|
return {
|
|
214
214
|
name: 'spawn_task',
|
package/src/zhin-agent/config.ts
CHANGED
|
@@ -25,7 +25,7 @@ export function inferModelSize(modelName: string): ModelSizeHint {
|
|
|
25
25
|
* Priority: explicit config > model name inference.
|
|
26
26
|
*/
|
|
27
27
|
export function resolveModelSize(config: Required<ZhinAgentConfig>, modelName: string): ModelSizeHint {
|
|
28
|
-
if (config.modelSizeHint && config.modelSizeHint !==
|
|
28
|
+
if (config.modelSizeHint && (config.modelSizeHint as string) !== '') return config.modelSizeHint as ModelSizeHint;
|
|
29
29
|
return inferModelSize(modelName);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -80,7 +80,7 @@ export interface ZhinAgentConfig {
|
|
|
80
80
|
maxSubagentIterations?: number;
|
|
81
81
|
subagentTools?: string[];
|
|
82
82
|
/** 模型大小提示,影响技能指令截断长度。留空则根据模型名自动推断 */
|
|
83
|
-
modelSizeHint?: 'small' | 'medium' | 'large';
|
|
83
|
+
modelSizeHint?: '' | 'small' | 'medium' | 'large';
|
|
84
84
|
/** 技能指令最大字符数(覆盖 modelSizeHint 推断值) */
|
|
85
85
|
skillInstructionMaxChars?: number;
|
|
86
86
|
}
|
|
@@ -108,6 +108,6 @@ export const DEFAULT_CONFIG: Required<ZhinAgentConfig> = {
|
|
|
108
108
|
execAsk: false,
|
|
109
109
|
maxSubagentIterations: 15,
|
|
110
110
|
subagentTools: [],
|
|
111
|
-
modelSizeHint: ''
|
|
111
|
+
modelSizeHint: '',
|
|
112
112
|
skillInstructionMaxChars: 0,
|
|
113
113
|
};
|
package/src/zhin-agent/index.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* 12. 多模态输入:图片/音频直接传给视觉模型
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { Logger } from '@zhin.js/
|
|
19
|
+
import { Logger } from '@zhin.js/core';
|
|
20
20
|
import type { Tool, ToolContext, SkillFeature, AIProvider, AgentTool, ChatMessage, ContentPart } from '@zhin.js/core';
|
|
21
21
|
import { createAgent } from '../agent.js';
|
|
22
22
|
import { SessionManager, createMemorySessionManager } from '../session.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ZhinAgent 工具收集 — 两级过滤 (Skill → Tool) + 技能支持工具注入
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { Logger } from '@zhin.js/
|
|
5
|
+
import { Logger } from '@zhin.js/core';
|
|
6
6
|
import type { Tool, ToolContext, SkillFeature } from '@zhin.js/core';
|
|
7
7
|
import type { AgentTool } from '@zhin.js/core';
|
|
8
8
|
import { Agent } from '../agent.js';
|
|
@@ -22,7 +22,7 @@ export function toAgentTool(tool: Tool, context?: ToolContext): AgentTool {
|
|
|
22
22
|
contextKey: string;
|
|
23
23
|
paramType: string;
|
|
24
24
|
}> = [];
|
|
25
|
-
let cleanParameters:
|
|
25
|
+
let cleanParameters: AgentTool['parameters'] = tool.parameters;
|
|
26
26
|
|
|
27
27
|
if (context && tool.parameters?.properties) {
|
|
28
28
|
const props = tool.parameters.properties as Record<string, any>;
|
|
@@ -30,7 +30,7 @@ export function toAgentTool(tool: Tool, context?: ToolContext): AgentTool {
|
|
|
30
30
|
const filteredRequired: string[] = [];
|
|
31
31
|
|
|
32
32
|
for (const [key, schema] of Object.entries(props)) {
|
|
33
|
-
if (schema.contextKey && (context as
|
|
33
|
+
if (schema.contextKey && (context as Record<string, unknown>)[schema.contextKey] != null) {
|
|
34
34
|
contextInjections.push({
|
|
35
35
|
paramName: key,
|
|
36
36
|
contextKey: schema.contextKey,
|
|
@@ -56,12 +56,12 @@ export function toAgentTool(tool: Tool, context?: ToolContext): AgentTool {
|
|
|
56
56
|
const at: AgentTool = {
|
|
57
57
|
name: tool.name,
|
|
58
58
|
description: tool.description,
|
|
59
|
-
parameters: cleanParameters
|
|
59
|
+
parameters: cleanParameters,
|
|
60
60
|
execute: context
|
|
61
|
-
? (args: Record<string, any>) => {
|
|
61
|
+
? async (args: Record<string, any>) => {
|
|
62
62
|
const enrichedArgs = { ...args };
|
|
63
63
|
for (const { paramName, contextKey, paramType } of contextInjections) {
|
|
64
|
-
let value = (context as
|
|
64
|
+
let value = (context as Record<string, unknown>)[contextKey];
|
|
65
65
|
if (paramType === 'number' && typeof value === 'string') {
|
|
66
66
|
value = Number(value);
|
|
67
67
|
} else if (paramType === 'string' && typeof value !== 'string') {
|
|
@@ -71,13 +71,13 @@ export function toAgentTool(tool: Tool, context?: ToolContext): AgentTool {
|
|
|
71
71
|
}
|
|
72
72
|
return originalExecute(enrichedArgs, context);
|
|
73
73
|
}
|
|
74
|
-
: originalExecute,
|
|
74
|
+
: async (args: Record<string, any>) => originalExecute(args),
|
|
75
75
|
};
|
|
76
76
|
if (tool.tags?.length) at.tags = tool.tags;
|
|
77
77
|
if (tool.keywords?.length) at.keywords = tool.keywords;
|
|
78
78
|
if (tool.permissionLevel) at.permissionLevel = PERM_MAP[tool.permissionLevel] ?? 0;
|
|
79
79
|
if (tool.preExecutable) at.preExecutable = true;
|
|
80
|
-
if (
|
|
80
|
+
if (tool.kind) at.kind = tool.kind;
|
|
81
81
|
return at;
|
|
82
82
|
}
|
|
83
83
|
|