opc-agent 1.4.0 → 2.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 +25 -0
- package/README.md +91 -32
- package/dist/channels/email.d.ts +32 -26
- package/dist/channels/email.js +239 -62
- package/dist/channels/feishu.d.ts +21 -6
- package/dist/channels/feishu.js +225 -126
- package/dist/channels/telegram.d.ts +30 -9
- package/dist/channels/telegram.js +125 -33
- package/dist/channels/websocket.d.ts +46 -3
- package/dist/channels/websocket.js +306 -37
- package/dist/channels/wechat.d.ts +33 -13
- package/dist/channels/wechat.js +229 -42
- package/dist/cli.js +1127 -19
- package/dist/core/a2a.d.ts +17 -0
- package/dist/core/a2a.js +43 -1
- package/dist/core/agent.d.ts +39 -0
- package/dist/core/agent.js +228 -3
- package/dist/core/runtime.d.ts +7 -0
- package/dist/core/runtime.js +205 -2
- package/dist/core/sandbox.d.ts +26 -0
- package/dist/core/sandbox.js +117 -0
- package/dist/core/scheduler.d.ts +52 -0
- package/dist/core/scheduler.js +168 -0
- package/dist/core/subagent.d.ts +28 -0
- package/dist/core/subagent.js +65 -0
- package/dist/core/workflow-graph.d.ts +93 -0
- package/dist/core/workflow-graph.js +247 -0
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.js +134 -0
- package/dist/doctor.d.ts +15 -0
- package/dist/doctor.js +183 -0
- package/dist/eval/index.d.ts +65 -0
- package/dist/eval/index.js +191 -0
- package/dist/index.d.ts +37 -6
- package/dist/index.js +75 -3
- package/dist/plugins/content-filter.d.ts +7 -0
- package/dist/plugins/content-filter.js +25 -0
- package/dist/plugins/index.d.ts +42 -0
- package/dist/plugins/index.js +108 -2
- package/dist/plugins/logger.d.ts +6 -0
- package/dist/plugins/logger.js +20 -0
- package/dist/plugins/rate-limiter.d.ts +7 -0
- package/dist/plugins/rate-limiter.js +35 -0
- package/dist/protocols/a2a/client.d.ts +25 -0
- package/dist/protocols/a2a/client.js +115 -0
- package/dist/protocols/a2a/index.d.ts +6 -0
- package/dist/protocols/a2a/index.js +12 -0
- package/dist/protocols/a2a/server.d.ts +41 -0
- package/dist/protocols/a2a/server.js +295 -0
- package/dist/protocols/a2a/types.d.ts +91 -0
- package/dist/protocols/a2a/types.js +15 -0
- package/dist/protocols/a2a/utils.d.ts +6 -0
- package/dist/protocols/a2a/utils.js +47 -0
- package/dist/protocols/agui/client.d.ts +10 -0
- package/dist/protocols/agui/client.js +75 -0
- package/dist/protocols/agui/index.d.ts +4 -0
- package/dist/protocols/agui/index.js +25 -0
- package/dist/protocols/agui/server.d.ts +37 -0
- package/dist/protocols/agui/server.js +191 -0
- package/dist/protocols/agui/types.d.ts +107 -0
- package/dist/protocols/agui/types.js +17 -0
- package/dist/protocols/index.d.ts +2 -0
- package/dist/protocols/index.js +19 -0
- package/dist/protocols/mcp/agent-tools.d.ts +11 -0
- package/dist/protocols/mcp/agent-tools.js +129 -0
- package/dist/protocols/mcp/index.d.ts +5 -0
- package/dist/protocols/mcp/index.js +11 -0
- package/dist/protocols/mcp/server.d.ts +31 -0
- package/dist/protocols/mcp/server.js +248 -0
- package/dist/protocols/mcp/types.d.ts +92 -0
- package/dist/protocols/mcp/types.js +17 -0
- package/dist/providers/index.d.ts +5 -1
- package/dist/providers/index.js +16 -9
- package/dist/publish/index.d.ts +45 -0
- package/dist/publish/index.js +350 -0
- package/dist/schema/oad.d.ts +859 -67
- package/dist/schema/oad.js +47 -3
- package/dist/security/approval.d.ts +36 -0
- package/dist/security/approval.js +113 -0
- package/dist/security/index.d.ts +4 -0
- package/dist/security/index.js +8 -0
- package/dist/security/keys.d.ts +16 -0
- package/dist/security/keys.js +117 -0
- package/dist/skills/auto-learn.d.ts +28 -0
- package/dist/skills/auto-learn.js +257 -0
- package/dist/studio/server.d.ts +63 -0
- package/dist/studio/server.js +625 -0
- package/dist/studio-ui/index.html +662 -0
- package/dist/telemetry/index.d.ts +93 -0
- package/dist/telemetry/index.js +285 -0
- package/dist/tools/builtin/datetime.d.ts +3 -0
- package/dist/tools/builtin/datetime.js +44 -0
- package/dist/tools/builtin/file.d.ts +3 -0
- package/dist/tools/builtin/file.js +151 -0
- package/dist/tools/builtin/index.d.ts +15 -0
- package/dist/tools/builtin/index.js +30 -0
- package/dist/tools/builtin/shell.d.ts +3 -0
- package/dist/tools/builtin/shell.js +43 -0
- package/dist/tools/builtin/web.d.ts +3 -0
- package/dist/tools/builtin/web.js +37 -0
- package/dist/tools/mcp-client.d.ts +24 -0
- package/dist/tools/mcp-client.js +119 -0
- package/package.json +5 -3
- package/scripts/install.ps1 +31 -0
- package/scripts/install.sh +40 -0
- package/src/channels/email.ts +351 -177
- package/src/channels/feishu.ts +349 -236
- package/src/channels/telegram.ts +212 -90
- package/src/channels/websocket.ts +399 -87
- package/src/channels/wechat.ts +329 -149
- package/src/cli.ts +1201 -20
- package/src/core/a2a.ts +60 -0
- package/src/core/agent.ts +420 -152
- package/src/core/runtime.ts +174 -0
- package/src/core/sandbox.ts +143 -0
- package/src/core/scheduler.ts +187 -0
- package/src/core/subagent.ts +98 -0
- package/src/core/workflow-graph.ts +365 -0
- package/src/daemon.ts +96 -0
- package/src/doctor.ts +156 -0
- package/src/eval/index.ts +211 -0
- package/src/eval/suites/basic.json +16 -0
- package/src/eval/suites/memory.json +12 -0
- package/src/eval/suites/safety.json +14 -0
- package/src/index.ts +65 -6
- package/src/plugins/content-filter.ts +23 -0
- package/src/plugins/index.ts +133 -2
- package/src/plugins/logger.ts +18 -0
- package/src/plugins/rate-limiter.ts +38 -0
- package/src/protocols/a2a/client.ts +132 -0
- package/src/protocols/a2a/index.ts +8 -0
- package/src/protocols/a2a/server.ts +333 -0
- package/src/protocols/a2a/types.ts +88 -0
- package/src/protocols/a2a/utils.ts +50 -0
- package/src/protocols/agui/client.ts +83 -0
- package/src/protocols/agui/index.ts +4 -0
- package/src/protocols/agui/server.ts +218 -0
- package/src/protocols/agui/types.ts +153 -0
- package/src/protocols/index.ts +2 -0
- package/src/protocols/mcp/agent-tools.ts +134 -0
- package/src/protocols/mcp/index.ts +8 -0
- package/src/protocols/mcp/server.ts +262 -0
- package/src/protocols/mcp/types.ts +69 -0
- package/src/providers/index.ts +354 -339
- package/src/publish/index.ts +376 -0
- package/src/schema/oad.ts +204 -154
- package/src/security/approval.ts +131 -0
- package/src/security/index.ts +3 -0
- package/src/security/keys.ts +87 -0
- package/src/skills/auto-learn.ts +262 -0
- package/src/studio/server.ts +629 -0
- package/src/studio-ui/index.html +662 -0
- package/src/telemetry/index.ts +324 -0
- package/src/tools/builtin/datetime.ts +41 -0
- package/src/tools/builtin/file.ts +107 -0
- package/src/tools/builtin/index.ts +28 -0
- package/src/tools/builtin/shell.ts +43 -0
- package/src/tools/builtin/web.ts +35 -0
- package/src/tools/mcp-client.ts +131 -0
- package/src/types/agent-workstation.d.ts +2 -0
- package/tests/a2a-protocol.test.ts +285 -0
- package/tests/agui-protocol.test.ts +246 -0
- package/tests/auto-learn.test.ts +105 -0
- package/tests/builtin-tools.test.ts +83 -0
- package/tests/channels/discord.test.ts +79 -0
- package/tests/channels/email.test.ts +148 -0
- package/tests/channels/feishu.test.ts +123 -0
- package/tests/channels/telegram.test.ts +129 -0
- package/tests/channels/websocket.test.ts +53 -0
- package/tests/channels/wechat.test.ts +170 -0
- package/tests/chat-cli.test.ts +160 -0
- package/tests/cli.test.ts +46 -0
- package/tests/daemon.test.ts +135 -0
- package/tests/deepbrain-wire.test.ts +234 -0
- package/tests/doctor.test.ts +38 -0
- package/tests/eval.test.ts +173 -0
- package/tests/init-role.test.ts +124 -0
- package/tests/mcp-client.test.ts +92 -0
- package/tests/mcp-server.test.ts +178 -0
- package/tests/plugin-a2a-enhanced.test.ts +230 -0
- package/tests/publish.test.ts +231 -0
- package/tests/scheduler.test.ts +200 -0
- package/tests/security-enhanced.test.ts +233 -0
- package/tests/skill-learner.test.ts +161 -0
- package/tests/studio.test.ts +229 -0
- package/tests/subagent.test.ts +193 -0
- package/tests/telegram-discord.test.ts +60 -0
- package/tests/telemetry.test.ts +186 -0
- package/tests/tools/builtin-extended.test.ts +138 -0
- package/tests/workflow-graph.test.ts +279 -0
- package/tutorial/customer-service-agent/README.md +612 -0
- package/tutorial/customer-service-agent/SOUL.md +26 -0
- package/tutorial/customer-service-agent/agent.yaml +63 -0
- package/tutorial/customer-service-agent/package.json +19 -0
- package/tutorial/customer-service-agent/src/index.ts +69 -0
- package/tutorial/customer-service-agent/src/skills/faq.ts +27 -0
- package/tutorial/customer-service-agent/src/skills/ticket.ts +22 -0
- package/tutorial/customer-service-agent/tsconfig.json +14 -0
package/dist/core/a2a.d.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import { Room } from './room';
|
|
3
3
|
import type { IAgent } from './types';
|
|
4
|
+
export interface AgentCard {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
capabilities: string[];
|
|
8
|
+
endpoint?: string;
|
|
9
|
+
handler?: (message: string) => Promise<string>;
|
|
10
|
+
}
|
|
11
|
+
export declare class AgentCardRegistry {
|
|
12
|
+
private cards;
|
|
13
|
+
private logger;
|
|
14
|
+
register(card: AgentCard): void;
|
|
15
|
+
unregister(name: string): void;
|
|
16
|
+
get(name: string): AgentCard | undefined;
|
|
17
|
+
find(query: string): AgentCard[];
|
|
18
|
+
send(agentName: string, message: string): Promise<string>;
|
|
19
|
+
list(): AgentCard[];
|
|
20
|
+
}
|
|
4
21
|
export interface AgentCapability {
|
|
5
22
|
name: string;
|
|
6
23
|
description: string;
|
package/dist/core/a2a.js
CHANGED
|
@@ -1,9 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AgentRegistry = void 0;
|
|
3
|
+
exports.AgentRegistry = exports.AgentCardRegistry = void 0;
|
|
4
4
|
const events_1 = require("events");
|
|
5
5
|
const room_1 = require("./room");
|
|
6
6
|
const logger_1 = require("./logger");
|
|
7
|
+
class AgentCardRegistry {
|
|
8
|
+
cards = new Map();
|
|
9
|
+
logger = new logger_1.Logger('a2a:cards');
|
|
10
|
+
register(card) {
|
|
11
|
+
this.cards.set(card.name, card);
|
|
12
|
+
this.logger.info('AgentCard registered', { name: card.name });
|
|
13
|
+
}
|
|
14
|
+
unregister(name) {
|
|
15
|
+
this.cards.delete(name);
|
|
16
|
+
}
|
|
17
|
+
get(name) {
|
|
18
|
+
return this.cards.get(name);
|
|
19
|
+
}
|
|
20
|
+
find(query) {
|
|
21
|
+
const lower = query.toLowerCase();
|
|
22
|
+
return Array.from(this.cards.values()).filter(a => a.name.toLowerCase().includes(lower) ||
|
|
23
|
+
a.description.toLowerCase().includes(lower) ||
|
|
24
|
+
a.capabilities.some(c => c.toLowerCase().includes(lower)));
|
|
25
|
+
}
|
|
26
|
+
async send(agentName, message) {
|
|
27
|
+
const agent = this.cards.get(agentName);
|
|
28
|
+
if (!agent)
|
|
29
|
+
throw new Error(`Agent '${agentName}' not found`);
|
|
30
|
+
if (agent.handler) {
|
|
31
|
+
return agent.handler(message);
|
|
32
|
+
}
|
|
33
|
+
else if (agent.endpoint) {
|
|
34
|
+
const res = await fetch(agent.endpoint, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { 'Content-Type': 'application/json' },
|
|
37
|
+
body: JSON.stringify({ message }),
|
|
38
|
+
});
|
|
39
|
+
const data = await res.json();
|
|
40
|
+
return data.response || data.content || '';
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`Agent '${agentName}' has no handler or endpoint`);
|
|
43
|
+
}
|
|
44
|
+
list() {
|
|
45
|
+
return Array.from(this.cards.values());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.AgentCardRegistry = AgentCardRegistry;
|
|
7
49
|
// ── Agent Registry ──────────────────────────────────────────
|
|
8
50
|
class AgentRegistry extends events_1.EventEmitter {
|
|
9
51
|
registrations = new Map();
|
package/dist/core/agent.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import type { AgentState, IAgent, IChannel, ISkill, Message, MemoryStore } from './types';
|
|
3
3
|
import { type LLMProvider } from '../providers';
|
|
4
|
+
import { SkillLearner } from '../skills/auto-learn';
|
|
5
|
+
import type { MCPTool } from '../tools/mcp';
|
|
6
|
+
import { MCPToolRegistry } from '../tools/mcp';
|
|
7
|
+
import { type SubAgentConfig, type SubAgentResult } from './subagent';
|
|
8
|
+
import { Tracer } from '../telemetry';
|
|
4
9
|
export declare class BaseAgent extends EventEmitter implements IAgent {
|
|
5
10
|
readonly name: string;
|
|
6
11
|
private _state;
|
|
@@ -10,6 +15,14 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
|
|
|
10
15
|
private _provider;
|
|
11
16
|
private systemPrompt;
|
|
12
17
|
private historyLimit;
|
|
18
|
+
private toolRegistry;
|
|
19
|
+
private maxToolRounds;
|
|
20
|
+
private skillLearner?;
|
|
21
|
+
private autoLearnConfig;
|
|
22
|
+
private _subAgentManager?;
|
|
23
|
+
private longTermMemory?;
|
|
24
|
+
private longTermMemoryConfig;
|
|
25
|
+
private tracer?;
|
|
13
26
|
constructor(options: {
|
|
14
27
|
name: string;
|
|
15
28
|
systemPrompt?: string;
|
|
@@ -17,11 +30,33 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
|
|
|
17
30
|
model?: string;
|
|
18
31
|
memory?: MemoryStore;
|
|
19
32
|
historyLimit?: number;
|
|
33
|
+
skillsDir?: string;
|
|
34
|
+
learning?: {
|
|
35
|
+
autoSkillCreation?: boolean;
|
|
36
|
+
minConversationLength?: number;
|
|
37
|
+
improveOnUse?: boolean;
|
|
38
|
+
};
|
|
39
|
+
maxToolRounds?: number;
|
|
40
|
+
tracer?: Tracer;
|
|
20
41
|
});
|
|
42
|
+
setLongTermMemory(brain: any, config?: {
|
|
43
|
+
autoLearn?: boolean;
|
|
44
|
+
autoRecall?: boolean;
|
|
45
|
+
}): void;
|
|
46
|
+
getLongTermMemory(): any;
|
|
47
|
+
getLongTermMemoryConfig(): {
|
|
48
|
+
autoLearn: boolean;
|
|
49
|
+
autoRecall: boolean;
|
|
50
|
+
};
|
|
21
51
|
get state(): AgentState;
|
|
22
52
|
get provider(): LLMProvider;
|
|
23
53
|
getSystemPrompt(): string;
|
|
24
54
|
getMemory(): MemoryStore;
|
|
55
|
+
getSkillLearner(): SkillLearner | undefined;
|
|
56
|
+
getToolRegistry(): MCPToolRegistry;
|
|
57
|
+
getTracer(): Tracer | undefined;
|
|
58
|
+
setTracer(tracer: Tracer): void;
|
|
59
|
+
registerTool(tool: MCPTool): void;
|
|
25
60
|
private transition;
|
|
26
61
|
init(): Promise<void>;
|
|
27
62
|
start(): Promise<void>;
|
|
@@ -29,7 +64,11 @@ export declare class BaseAgent extends EventEmitter implements IAgent {
|
|
|
29
64
|
registerSkill(skill: ISkill): void;
|
|
30
65
|
bindChannel(channel: IChannel): void;
|
|
31
66
|
getChannels(): IChannel[];
|
|
67
|
+
private getSubAgentManager;
|
|
68
|
+
spawnSubAgent(config: SubAgentConfig): Promise<SubAgentResult>;
|
|
69
|
+
spawnParallel(configs: SubAgentConfig[]): Promise<SubAgentResult[]>;
|
|
32
70
|
handleMessage(message: Message): Promise<Message>;
|
|
71
|
+
private parseToolCall;
|
|
33
72
|
handleMessageStream(message: Message): AsyncIterable<string>;
|
|
34
73
|
private createResponse;
|
|
35
74
|
}
|
package/dist/core/agent.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.BaseAgent = void 0;
|
|
|
4
4
|
const events_1 = require("events");
|
|
5
5
|
const memory_1 = require("../memory");
|
|
6
6
|
const providers_1 = require("../providers");
|
|
7
|
+
const auto_learn_1 = require("../skills/auto-learn");
|
|
8
|
+
const mcp_1 = require("../tools/mcp");
|
|
9
|
+
const subagent_1 = require("./subagent");
|
|
7
10
|
class BaseAgent extends events_1.EventEmitter {
|
|
8
11
|
name;
|
|
9
12
|
_state = 'init';
|
|
@@ -13,6 +16,14 @@ class BaseAgent extends events_1.EventEmitter {
|
|
|
13
16
|
_provider;
|
|
14
17
|
systemPrompt;
|
|
15
18
|
historyLimit;
|
|
19
|
+
toolRegistry = new mcp_1.MCPToolRegistry();
|
|
20
|
+
maxToolRounds;
|
|
21
|
+
skillLearner;
|
|
22
|
+
autoLearnConfig;
|
|
23
|
+
_subAgentManager;
|
|
24
|
+
longTermMemory;
|
|
25
|
+
longTermMemoryConfig = { autoLearn: true, autoRecall: true };
|
|
26
|
+
tracer;
|
|
16
27
|
constructor(options) {
|
|
17
28
|
super();
|
|
18
29
|
this.name = options.name;
|
|
@@ -20,6 +31,31 @@ class BaseAgent extends events_1.EventEmitter {
|
|
|
20
31
|
this.memory = options.memory ?? new memory_1.InMemoryStore();
|
|
21
32
|
this._provider = (0, providers_1.createProvider)(options.provider ?? 'openai', options.model);
|
|
22
33
|
this.historyLimit = options.historyLimit ?? 50;
|
|
34
|
+
this.maxToolRounds = options.maxToolRounds ?? 10;
|
|
35
|
+
this.autoLearnConfig = {
|
|
36
|
+
enabled: options.learning?.autoSkillCreation !== false,
|
|
37
|
+
minConversationLength: options.learning?.minConversationLength ?? 3,
|
|
38
|
+
improveOnUse: options.learning?.improveOnUse !== false,
|
|
39
|
+
};
|
|
40
|
+
if (options.skillsDir) {
|
|
41
|
+
this.skillLearner = new auto_learn_1.SkillLearner(options.skillsDir);
|
|
42
|
+
}
|
|
43
|
+
this.tracer = options.tracer;
|
|
44
|
+
}
|
|
45
|
+
setLongTermMemory(brain, config) {
|
|
46
|
+
this.longTermMemory = brain;
|
|
47
|
+
if (config) {
|
|
48
|
+
this.longTermMemoryConfig = {
|
|
49
|
+
autoLearn: config.autoLearn !== false,
|
|
50
|
+
autoRecall: config.autoRecall !== false,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
getLongTermMemory() {
|
|
55
|
+
return this.longTermMemory;
|
|
56
|
+
}
|
|
57
|
+
getLongTermMemoryConfig() {
|
|
58
|
+
return this.longTermMemoryConfig;
|
|
23
59
|
}
|
|
24
60
|
get state() {
|
|
25
61
|
return this._state;
|
|
@@ -33,12 +69,30 @@ class BaseAgent extends events_1.EventEmitter {
|
|
|
33
69
|
getMemory() {
|
|
34
70
|
return this.memory;
|
|
35
71
|
}
|
|
72
|
+
getSkillLearner() {
|
|
73
|
+
return this.skillLearner;
|
|
74
|
+
}
|
|
75
|
+
getToolRegistry() {
|
|
76
|
+
return this.toolRegistry;
|
|
77
|
+
}
|
|
78
|
+
getTracer() {
|
|
79
|
+
return this.tracer;
|
|
80
|
+
}
|
|
81
|
+
setTracer(tracer) {
|
|
82
|
+
this.tracer = tracer;
|
|
83
|
+
}
|
|
84
|
+
registerTool(tool) {
|
|
85
|
+
this.toolRegistry.register(tool);
|
|
86
|
+
}
|
|
36
87
|
transition(to) {
|
|
37
88
|
const from = this._state;
|
|
38
89
|
this._state = to;
|
|
39
90
|
this.emit('state:change', from, to);
|
|
40
91
|
}
|
|
41
92
|
async init() {
|
|
93
|
+
if (this.skillLearner) {
|
|
94
|
+
await this.skillLearner.loadLearnedSkills();
|
|
95
|
+
}
|
|
42
96
|
this.transition('ready');
|
|
43
97
|
}
|
|
44
98
|
async start() {
|
|
@@ -66,10 +120,59 @@ class BaseAgent extends events_1.EventEmitter {
|
|
|
66
120
|
getChannels() {
|
|
67
121
|
return this.channels;
|
|
68
122
|
}
|
|
123
|
+
getSubAgentManager() {
|
|
124
|
+
if (!this._subAgentManager) {
|
|
125
|
+
this._subAgentManager = new subagent_1.SubAgentManager();
|
|
126
|
+
}
|
|
127
|
+
return this._subAgentManager;
|
|
128
|
+
}
|
|
129
|
+
async spawnSubAgent(config) {
|
|
130
|
+
return this.getSubAgentManager().spawn(config, this._provider);
|
|
131
|
+
}
|
|
132
|
+
async spawnParallel(configs) {
|
|
133
|
+
return this.getSubAgentManager().spawnParallel(configs, this._provider);
|
|
134
|
+
}
|
|
69
135
|
async handleMessage(message) {
|
|
70
136
|
this.emit('message:in', message);
|
|
137
|
+
// Start root span if tracer is configured
|
|
138
|
+
let rootSpan;
|
|
139
|
+
if (this.tracer) {
|
|
140
|
+
rootSpan = this.tracer.startSpan('handleMessage', {
|
|
141
|
+
kind: 'server',
|
|
142
|
+
attributes: {
|
|
143
|
+
'message.channel': message.metadata?.channel || 'unknown',
|
|
144
|
+
'message.sender': message.metadata?.sender || 'unknown',
|
|
145
|
+
'message.length': message.content.length,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
this.tracer.increment('agent.messages.total', 1, { agent: this.name });
|
|
149
|
+
}
|
|
71
150
|
const sessionId = message.metadata?.sessionId ?? 'default';
|
|
72
151
|
await this.memory.addMessage(sessionId, message);
|
|
152
|
+
// === Recall from long-term memory ===
|
|
153
|
+
let memoryContext = '';
|
|
154
|
+
if (this.longTermMemory && this.longTermMemoryConfig.autoRecall) {
|
|
155
|
+
let memorySpan;
|
|
156
|
+
if (this.tracer && rootSpan) {
|
|
157
|
+
memorySpan = this.tracer.startSpan('memory.recall', { parent: rootSpan, kind: 'client' });
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const recalled = await this.longTermMemory.recall(message.content);
|
|
161
|
+
if (recalled && (Array.isArray(recalled) ? recalled.length > 0 : true)) {
|
|
162
|
+
memoryContext = '\n\n[Relevant memories]\n' +
|
|
163
|
+
(Array.isArray(recalled)
|
|
164
|
+
? recalled.map((r) => typeof r === 'string' ? r : r.content || r.compiled_truth || '').join('\n')
|
|
165
|
+
: String(recalled));
|
|
166
|
+
}
|
|
167
|
+
if (this.tracer && memorySpan)
|
|
168
|
+
this.tracer.endSpan(memorySpan, 'ok');
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
if (this.tracer && memorySpan)
|
|
172
|
+
this.tracer.endSpan(memorySpan, 'error');
|
|
173
|
+
// Silent fail — don't break chat if memory fails
|
|
174
|
+
}
|
|
175
|
+
}
|
|
73
176
|
const context = {
|
|
74
177
|
agentName: this.name,
|
|
75
178
|
sessionId,
|
|
@@ -93,13 +196,135 @@ class BaseAgent extends events_1.EventEmitter {
|
|
|
93
196
|
this.emit('error', err instanceof Error ? err : new Error(String(err)));
|
|
94
197
|
}
|
|
95
198
|
}
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
199
|
+
// Check if a learned skill matches — prepend instructions to system prompt
|
|
200
|
+
let effectiveSystemPrompt = this.systemPrompt;
|
|
201
|
+
// Inject long-term memory context
|
|
202
|
+
if (memoryContext) {
|
|
203
|
+
effectiveSystemPrompt = effectiveSystemPrompt + memoryContext;
|
|
204
|
+
}
|
|
205
|
+
const matchedSkill = this.skillLearner?.matchSkill(message.content);
|
|
206
|
+
if (matchedSkill) {
|
|
207
|
+
matchedSkill.usageCount++;
|
|
208
|
+
matchedSkill.lastUsed = new Date();
|
|
209
|
+
effectiveSystemPrompt = `[Learned Skill: ${matchedSkill.name}]\n${matchedSkill.instructions}\n\n${this.systemPrompt}`;
|
|
210
|
+
this.emit('skill:matched', matchedSkill);
|
|
211
|
+
if (this.tracer && rootSpan) {
|
|
212
|
+
this.tracer.addEvent(rootSpan, 'skill.matched', { 'skill.name': matchedSkill.name });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Fall back to LLM with tool use loop
|
|
216
|
+
const tools = this.toolRegistry.list();
|
|
217
|
+
const llmMessages = [...context.messages];
|
|
218
|
+
let finalResponse = '';
|
|
219
|
+
for (let round = 0; round <= this.maxToolRounds; round++) {
|
|
220
|
+
let llmSpan;
|
|
221
|
+
if (this.tracer && rootSpan) {
|
|
222
|
+
llmSpan = this.tracer.startSpan('llm.chat', {
|
|
223
|
+
parent: rootSpan,
|
|
224
|
+
kind: 'client',
|
|
225
|
+
attributes: { 'llm.round': round },
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
const llmResponse = await this._provider.chat(llmMessages, effectiveSystemPrompt, { tools: tools.length > 0 ? tools : undefined });
|
|
229
|
+
if (this.tracer && llmSpan) {
|
|
230
|
+
llmSpan.attributes['llm.response.length'] = llmResponse.length;
|
|
231
|
+
this.tracer.endSpan(llmSpan, 'ok');
|
|
232
|
+
}
|
|
233
|
+
const toolCall = this.parseToolCall(llmResponse);
|
|
234
|
+
if (!toolCall || tools.length === 0 || round === this.maxToolRounds) {
|
|
235
|
+
finalResponse = llmResponse;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
// Execute tool
|
|
239
|
+
let toolSpan;
|
|
240
|
+
if (this.tracer && rootSpan) {
|
|
241
|
+
toolSpan = this.tracer.startSpan('tool.execute', {
|
|
242
|
+
parent: rootSpan,
|
|
243
|
+
kind: 'internal',
|
|
244
|
+
attributes: { 'tool.name': toolCall.name },
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
const toolResult = await this.toolRegistry.execute(toolCall.name, toolCall.arguments, context);
|
|
248
|
+
this.emit('tool:execute', toolCall.name, toolResult);
|
|
249
|
+
if (this.tracer && toolSpan) {
|
|
250
|
+
toolSpan.attributes['tool.result.length'] = toolResult.content?.length || 0;
|
|
251
|
+
this.tracer.endSpan(toolSpan, 'ok');
|
|
252
|
+
}
|
|
253
|
+
// Add tool call and result to messages for next round
|
|
254
|
+
llmMessages.push({
|
|
255
|
+
id: `tool_call_${Date.now()}`,
|
|
256
|
+
role: 'assistant',
|
|
257
|
+
content: llmResponse,
|
|
258
|
+
timestamp: Date.now(),
|
|
259
|
+
});
|
|
260
|
+
llmMessages.push({
|
|
261
|
+
id: `tool_result_${Date.now()}`,
|
|
262
|
+
role: 'user',
|
|
263
|
+
content: `[Tool Result for ${toolCall.name}]: ${toolResult.content}`,
|
|
264
|
+
timestamp: Date.now(),
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const response = this.createResponse(finalResponse, message);
|
|
99
268
|
await this.memory.addMessage(sessionId, response);
|
|
100
269
|
this.emit('message:out', response);
|
|
270
|
+
// End root telemetry span
|
|
271
|
+
if (this.tracer && rootSpan) {
|
|
272
|
+
rootSpan.attributes['response.length'] = finalResponse.length;
|
|
273
|
+
this.tracer.endSpan(rootSpan, 'ok');
|
|
274
|
+
this.tracer.histogram('agent.message.duration', rootSpan.endTime - rootSpan.startTime, { agent: this.name });
|
|
275
|
+
}
|
|
276
|
+
// === Learn from interaction ===
|
|
277
|
+
if (this.longTermMemory && this.longTermMemoryConfig.autoLearn) {
|
|
278
|
+
try {
|
|
279
|
+
await this.longTermMemory.learn(`User: ${message.content}\nAssistant: ${finalResponse}`, { tags: ['conversation', message.metadata?.channel || 'unknown'] });
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// Silent fail
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// After response, check if we should learn a skill
|
|
286
|
+
if (this.skillLearner &&
|
|
287
|
+
this.autoLearnConfig.enabled &&
|
|
288
|
+
context.messages.length >= this.autoLearnConfig.minConversationLength) {
|
|
289
|
+
this.skillLearner
|
|
290
|
+
.analyzeForSkillCreation(context.messages, this._provider)
|
|
291
|
+
.then(async (learnedSkill) => {
|
|
292
|
+
if (learnedSkill) {
|
|
293
|
+
await this.skillLearner.saveSkill(learnedSkill);
|
|
294
|
+
this.emit('skill:learned', learnedSkill);
|
|
295
|
+
}
|
|
296
|
+
})
|
|
297
|
+
.catch(() => { });
|
|
298
|
+
}
|
|
299
|
+
// Improve matched skill after use
|
|
300
|
+
if (matchedSkill && this.skillLearner && this.autoLearnConfig.improveOnUse) {
|
|
301
|
+
this.skillLearner
|
|
302
|
+
.improveSkill(matchedSkill, context.messages, this._provider)
|
|
303
|
+
.then(() => this.skillLearner.saveSkill(matchedSkill))
|
|
304
|
+
.catch(() => { });
|
|
305
|
+
}
|
|
101
306
|
return response;
|
|
102
307
|
}
|
|
308
|
+
parseToolCall(response) {
|
|
309
|
+
try {
|
|
310
|
+
const parsed = JSON.parse(response);
|
|
311
|
+
if (parsed.tool_call)
|
|
312
|
+
return parsed.tool_call;
|
|
313
|
+
if (parsed.name && parsed.arguments !== undefined)
|
|
314
|
+
return parsed;
|
|
315
|
+
}
|
|
316
|
+
catch { /* not JSON */ }
|
|
317
|
+
const match = response.match(/<tool_call>\s*(\{[\s\S]*?\})\s*<\/tool_call>/);
|
|
318
|
+
if (match) {
|
|
319
|
+
try {
|
|
320
|
+
const parsed = JSON.parse(match[1]);
|
|
321
|
+
if (parsed.name)
|
|
322
|
+
return parsed;
|
|
323
|
+
}
|
|
324
|
+
catch { /* not valid JSON */ }
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
103
328
|
async *handleMessageStream(message) {
|
|
104
329
|
const sessionId = message.metadata?.sessionId ?? 'default';
|
|
105
330
|
await this.memory.addMessage(sessionId, message);
|
package/dist/core/runtime.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PluginManager } from '../plugins';
|
|
1
2
|
import { BaseAgent } from './agent';
|
|
2
3
|
import { Analytics } from '../analytics';
|
|
3
4
|
import type { OADDocument } from '../schema/oad';
|
|
@@ -11,6 +12,11 @@ export declare class AgentRuntime {
|
|
|
11
12
|
private shutdownHandlers;
|
|
12
13
|
private isShuttingDown;
|
|
13
14
|
private analytics;
|
|
15
|
+
private scheduler;
|
|
16
|
+
private pluginManager;
|
|
17
|
+
private brain;
|
|
18
|
+
private agentBrain;
|
|
19
|
+
private evolveScheduler;
|
|
14
20
|
loadConfig(filePath: string): Promise<OADDocument>;
|
|
15
21
|
setHistoryLimit(limit: number): void;
|
|
16
22
|
initialize(config?: OADDocument): Promise<BaseAgent>;
|
|
@@ -22,5 +28,6 @@ export declare class AgentRuntime {
|
|
|
22
28
|
getAgent(): BaseAgent | null;
|
|
23
29
|
getAnalytics(): Analytics;
|
|
24
30
|
getConfig(): OADDocument | null;
|
|
31
|
+
getPluginManager(): PluginManager;
|
|
25
32
|
}
|
|
26
33
|
//# sourceMappingURL=runtime.d.ts.map
|