@memoryblock/plugin-agents 0.1.0-beta → 0.1.1-beta
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/README.md +35 -0
- package/package.json +48 -7
- package/LICENSE +0 -21
- package/src/index.ts +0 -10
- package/src/tools/create-agent.ts +0 -84
- package/src/tools/list-agents.ts +0 -50
- package/src/tools/query-agent.ts +0 -138
- package/tsconfig.json +0 -10
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @memoryblock/plugin-agents
|
|
2
|
+
|
|
3
|
+
Official plugin for orchestrating secondary AI agents in **memoryblock**.
|
|
4
|
+
|
|
5
|
+
This package handles:
|
|
6
|
+
- Agent delegation
|
|
7
|
+
- Task sub-routing
|
|
8
|
+
- Multi-agent hierarchical scaling
|
|
9
|
+
|
|
10
|
+
## The `memoryblock` Ecosystem
|
|
11
|
+
|
|
12
|
+
**memoryblock** is a highly modular system. Here are the official packages:
|
|
13
|
+
|
|
14
|
+
**The Core**
|
|
15
|
+
* [**memoryblock**](https://www.npmjs.com/package/memoryblock) - The core engine interface and types.
|
|
16
|
+
* [**@memoryblock/daemon**](https://www.npmjs.com/package/@memoryblock/daemon) - Background daemon manager.
|
|
17
|
+
* [**@memoryblock/api**](https://www.npmjs.com/package/@memoryblock/api) - Core REST and WebSocket API server.
|
|
18
|
+
|
|
19
|
+
**Integrations & Tooling**
|
|
20
|
+
* [**@memoryblock/adapters**](https://www.npmjs.com/package/@memoryblock/adapters) - LLM adapters (OpenAI, Anthropic, Bedrock, etc).
|
|
21
|
+
* [**@memoryblock/channels**](https://www.npmjs.com/package/@memoryblock/channels) - Communication channels (CLI, Telegram, Web).
|
|
22
|
+
* [**@memoryblock/tools**](https://www.npmjs.com/package/@memoryblock/tools) - Standard tool definitions and schemas.
|
|
23
|
+
* [**@memoryblock/locale**](https://www.npmjs.com/package/@memoryblock/locale) - Localization strings and formatting.
|
|
24
|
+
* [**@memoryblock/web**](https://www.npmjs.com/package/@memoryblock/web) - Front-end dashboard and Web UI.
|
|
25
|
+
|
|
26
|
+
**Plugins**
|
|
27
|
+
* [**@memoryblock/plugin-installer**](https://www.npmjs.com/package/@memoryblock/plugin-installer) - Plugin installer and registry manager.
|
|
28
|
+
* [**@memoryblock/plugin-agents**](https://www.npmjs.com/package/@memoryblock/plugin-agents) - Secondary AI agents orchestrator.
|
|
29
|
+
* [**@memoryblock/plugin-aws**](https://www.npmjs.com/package/@memoryblock/plugin-aws) - AWS integrations.
|
|
30
|
+
* [**@memoryblock/plugin-fetch-webpage**](https://www.npmjs.com/package/@memoryblock/plugin-fetch-webpage) - Web content fetching and parsing.
|
|
31
|
+
* [**@memoryblock/plugin-web-search**](https://www.npmjs.com/package/@memoryblock/plugin-web-search) - Web search capabilities.
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memoryblock/plugin-agents",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1-beta",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"description": "Official plugin for orchestrating secondary AI agents in memoryblock.",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/"
|
|
8
|
+
],
|
|
5
9
|
"main": "./dist/index.js",
|
|
6
10
|
"types": "./dist/index.d.ts",
|
|
7
11
|
"exports": {
|
|
@@ -10,12 +14,49 @@
|
|
|
10
14
|
"import": "./dist/index.js"
|
|
11
15
|
}
|
|
12
16
|
},
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"@memoryblock/tools": "0.1.0-beta",
|
|
15
|
-
"@memoryblock/adapters": "0.1.0-beta",
|
|
16
|
-
"memoryblock": "0.1.0-beta"
|
|
17
|
-
},
|
|
18
17
|
"scripts": {
|
|
19
18
|
"build": "tsc -p tsconfig.json"
|
|
20
|
-
}
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@memoryblock/tools": "^0.1.1-beta",
|
|
22
|
+
"@memoryblock/adapters": "^0.1.1-beta",
|
|
23
|
+
"memoryblock": "^0.1.1-beta"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"memoryblock",
|
|
27
|
+
"mblk",
|
|
28
|
+
"ai-agent",
|
|
29
|
+
"assistants",
|
|
30
|
+
"agents",
|
|
31
|
+
"automation",
|
|
32
|
+
"multi-agent",
|
|
33
|
+
"agentic-framework",
|
|
34
|
+
"plugin",
|
|
35
|
+
"autonomous",
|
|
36
|
+
"orchestration",
|
|
37
|
+
"multi-agents",
|
|
38
|
+
"openai",
|
|
39
|
+
"anthropic",
|
|
40
|
+
"gemini",
|
|
41
|
+
"groq",
|
|
42
|
+
"deepseek",
|
|
43
|
+
"ollama",
|
|
44
|
+
"chatgpt",
|
|
45
|
+
"bedrock",
|
|
46
|
+
"gpt"
|
|
47
|
+
],
|
|
48
|
+
"author": {
|
|
49
|
+
"name": "Ghazi",
|
|
50
|
+
"url": "https://mgks.dev"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/memoryblock-io/memoryblock.git"
|
|
55
|
+
},
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/memoryblock-io/memoryblock/issues"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://memoryblock.io",
|
|
60
|
+
"funding": "https://github.com/sponsors/mgks",
|
|
61
|
+
"license": "MIT"
|
|
21
62
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 memoryblock
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/src/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Tool } from '@memoryblock/tools';
|
|
2
|
-
import { createAgentTool } from './tools/create-agent.js';
|
|
3
|
-
import { listAgentsTool } from './tools/list-agents.js';
|
|
4
|
-
import { queryAgentTool } from './tools/query-agent.js';
|
|
5
|
-
|
|
6
|
-
export const tools: Tool[] = [
|
|
7
|
-
createAgentTool,
|
|
8
|
-
listAgentsTool,
|
|
9
|
-
queryAgentTool
|
|
10
|
-
];
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { createSchema } from '@memoryblock/tools';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { promises as fsp } from 'node:fs';
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
|
-
// @ts-ignore - workspace resolution cache issue
|
|
7
|
-
import { loadGlobalConfig, resolveBlocksDir, saveBlockConfig, BlockConfigSchema } from 'memoryblock';
|
|
8
|
-
|
|
9
|
-
export const createAgentTool = {
|
|
10
|
-
definition: {
|
|
11
|
-
name: 'create_agent',
|
|
12
|
-
description: 'Creates a new memoryblock sub-agent with a specific name, description, and model.',
|
|
13
|
-
parameters: createSchema({
|
|
14
|
-
name: { type: 'string', description: 'Agent identifier, lowercase alphanumeric and hyphens (e.g. "code-reviewer")' },
|
|
15
|
-
description: { type: 'string', description: 'What this agent is designed to do' },
|
|
16
|
-
model: { type: 'string', description: 'The LLM model to use. Defaults to bedrock but can be openai, gemini, or anthropic if api keys configured (e.g. "gpt-4o", "gemini-2.5-pro", "claude-3-5-sonnet-20241022").' }
|
|
17
|
-
}, ['name', 'description']),
|
|
18
|
-
requiresApproval: true
|
|
19
|
-
},
|
|
20
|
-
async execute(params: Record<string, unknown>) {
|
|
21
|
-
const { name, description, model = 'anthropic.claude-3-haiku-20240307-v1:0' } = params as { name: string, description: string, model?: string };
|
|
22
|
-
|
|
23
|
-
if (!/^[a-z0-9][a-z0-9-]{0,31}$/.test(name)) {
|
|
24
|
-
return { content: 'Invalid name format. Use lowercase letters, numbers, and hyphens (max 32 chars).', isError: true };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const globalConfig = await loadGlobalConfig();
|
|
29
|
-
const blocksDir = resolveBlocksDir(globalConfig);
|
|
30
|
-
const blockPath = join(blocksDir, name);
|
|
31
|
-
|
|
32
|
-
const exists = await fsp.stat(blockPath).then(() => true).catch(() => false);
|
|
33
|
-
if (exists) {
|
|
34
|
-
return { content: `Agent "${name}" already exists.`, isError: true };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
await fsp.mkdir(blockPath, { recursive: true });
|
|
38
|
-
|
|
39
|
-
// Determine provider natively based on common prefixes
|
|
40
|
-
let provider = 'bedrock';
|
|
41
|
-
if (model.includes('gpt-') || model.includes('o1-')) provider = 'openai';
|
|
42
|
-
if (model.includes('gemini-')) provider = 'gemini';
|
|
43
|
-
if (model.includes('claude-') && !model.includes('anthropic.')) provider = 'anthropic';
|
|
44
|
-
|
|
45
|
-
// Adopt default config with sandbox enabled
|
|
46
|
-
const config = BlockConfigSchema.parse({
|
|
47
|
-
name,
|
|
48
|
-
description,
|
|
49
|
-
adapter: {
|
|
50
|
-
...globalConfig.defaults.adapter,
|
|
51
|
-
provider,
|
|
52
|
-
model
|
|
53
|
-
},
|
|
54
|
-
goals: [description],
|
|
55
|
-
tools: {
|
|
56
|
-
enabled: ['*'],
|
|
57
|
-
searchProvider: 'brave',
|
|
58
|
-
sandbox: true // Sub-agents must be sandboxed natively
|
|
59
|
-
},
|
|
60
|
-
channel: { type: 'cli' },
|
|
61
|
-
permissions: {
|
|
62
|
-
scope: 'block',
|
|
63
|
-
allowShell: false,
|
|
64
|
-
allowNetwork: true,
|
|
65
|
-
maxTimeout: 120_000
|
|
66
|
-
},
|
|
67
|
-
memory: globalConfig.defaults.memory,
|
|
68
|
-
pulse: globalConfig.defaults.pulse
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
await saveBlockConfig(blockPath, config);
|
|
72
|
-
|
|
73
|
-
// Initial memory empty
|
|
74
|
-
await fsp.writeFile(join(blockPath, 'memory.md'), '# Memory\n\n(no memory yet)', 'utf8');
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
content: `Created sub-agent "${name}" successfully in sandboxed mode using ${provider}/${model}. You can now use query_agent to assign it tasks.`,
|
|
78
|
-
isError: false
|
|
79
|
-
};
|
|
80
|
-
} catch (err) {
|
|
81
|
-
return { content: `Failed to create agent: ${(err as Error).message}`, isError: true };
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
};
|
package/src/tools/list-agents.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { createSchema } from '@memoryblock/tools';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { promises as fsp } from 'node:fs';
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
|
-
// @ts-ignore - workspace resolution cache issue
|
|
7
|
-
import { loadGlobalConfig, resolveBlocksDir, loadBlockConfig } from 'memoryblock';
|
|
8
|
-
|
|
9
|
-
export const listAgentsTool = {
|
|
10
|
-
definition: {
|
|
11
|
-
name: 'list_agents',
|
|
12
|
-
description: 'Discovers available memoryblock sub-agents that can be queried or delegated tasks to.',
|
|
13
|
-
parameters: createSchema({}),
|
|
14
|
-
requiresApproval: false
|
|
15
|
-
},
|
|
16
|
-
async execute() {
|
|
17
|
-
try {
|
|
18
|
-
const globalConfig = await loadGlobalConfig();
|
|
19
|
-
const blocksDir = resolveBlocksDir(globalConfig);
|
|
20
|
-
const entries = await fsp.readdir(blocksDir, { withFileTypes: true });
|
|
21
|
-
|
|
22
|
-
const agents = [];
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
if (entry.isDirectory()) {
|
|
25
|
-
try {
|
|
26
|
-
const blockPath = join(blocksDir, entry.name);
|
|
27
|
-
const config = await loadBlockConfig(blockPath);
|
|
28
|
-
let status = 'UNKNOWN';
|
|
29
|
-
try {
|
|
30
|
-
const pulseRaw = await fsp.readFile(join(blockPath, 'pulse.json'), 'utf-8');
|
|
31
|
-
status = JSON.parse(pulseRaw).status;
|
|
32
|
-
} catch { /* ignore */ }
|
|
33
|
-
|
|
34
|
-
agents.push(`- **${config.name}**: ${config.description} (Status: ${status})`);
|
|
35
|
-
} catch {
|
|
36
|
-
// skip invalid blocks
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (agents.length === 0) return { content: 'No other agents found.', isError: false };
|
|
42
|
-
return {
|
|
43
|
-
content: `Available Agents:\n\n${agents.join('\n')}`,
|
|
44
|
-
isError: false
|
|
45
|
-
};
|
|
46
|
-
} catch (err) {
|
|
47
|
-
return { content: `Failed to list agents: ${(err as Error).message}`, isError: true };
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
package/src/tools/query-agent.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { createSchema, createDefaultRegistry } from '@memoryblock/tools';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { promises as fsp } from 'node:fs';
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
6
|
-
// @ts-ignore - workspace resolution cache issue
|
|
7
|
-
import {
|
|
8
|
-
loadGlobalConfig, resolveBlocksDir, loadBlockConfig, loadAuth,
|
|
9
|
-
Monitor
|
|
10
|
-
} from 'memoryblock';
|
|
11
|
-
|
|
12
|
-
// Quick inline OrchestratorChannel for interception
|
|
13
|
-
class OrchestratorChannel {
|
|
14
|
-
public readonly name = 'orchestrator';
|
|
15
|
-
private messageHandler: ((msg: any) => void) | null = null;
|
|
16
|
-
private resolveResponse: ((res: string) => void) | null = null;
|
|
17
|
-
private finalResponse = '';
|
|
18
|
-
|
|
19
|
-
onMessage(handler: (msg: any) => void) {
|
|
20
|
-
this.messageHandler = handler;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async send(msg: any) {
|
|
24
|
-
if (!msg.isSystem && msg.content) {
|
|
25
|
-
this.finalResponse = msg.content;
|
|
26
|
-
if (this.resolveResponse) {
|
|
27
|
-
this.resolveResponse(this.finalResponse);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async requestApproval() {
|
|
33
|
-
// Sub-agents auto-deny unapproved actions in orchestration
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async start() {}
|
|
38
|
-
async stop() {}
|
|
39
|
-
|
|
40
|
-
simulateUser(content: string) {
|
|
41
|
-
if (this.messageHandler) {
|
|
42
|
-
this.messageHandler({
|
|
43
|
-
blockName: 'orchestrator',
|
|
44
|
-
monitorName: 'orchestrator',
|
|
45
|
-
content,
|
|
46
|
-
isSystem: false,
|
|
47
|
-
timestamp: new Date().toISOString()
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
waitForResponse(): Promise<string> {
|
|
53
|
-
return new Promise(resolve => {
|
|
54
|
-
this.resolveResponse = resolve;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const queryAgentTool = {
|
|
60
|
-
definition: {
|
|
61
|
-
name: 'query_agent',
|
|
62
|
-
description: 'Delegates a task to a sub-agent. The orchestrator will pause until the sub-agent completes the request and returns its response.',
|
|
63
|
-
parameters: createSchema({
|
|
64
|
-
agent_name: { type: 'string', description: 'Name of the sub-agent to query.' },
|
|
65
|
-
prompt: { type: 'string', description: 'The objective, task, or question to delegate to the sub-agent.' }
|
|
66
|
-
}, ['agent_name', 'prompt']),
|
|
67
|
-
requiresApproval: true // Delegating tasks is a major action
|
|
68
|
-
},
|
|
69
|
-
async execute(params: Record<string, unknown>) {
|
|
70
|
-
const { agent_name, prompt } = params as { agent_name: string, prompt: string };
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
const globalConfig = await loadGlobalConfig();
|
|
74
|
-
const blockPath = join(resolveBlocksDir(globalConfig), agent_name);
|
|
75
|
-
|
|
76
|
-
const exists = await fsp.stat(blockPath).then(() => true).catch(() => false);
|
|
77
|
-
if (!exists) {
|
|
78
|
-
return { content: `Agent "${agent_name}" does not exist. Use create_agent first.`, isError: true };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const blockConfig = await loadBlockConfig(blockPath);
|
|
82
|
-
|
|
83
|
-
// Load adapter natively
|
|
84
|
-
const adapters = await import('@memoryblock/adapters');
|
|
85
|
-
let adapter: any;
|
|
86
|
-
const provider = blockConfig.adapter.provider || 'bedrock';
|
|
87
|
-
if (provider === 'openai') {
|
|
88
|
-
const auth = await loadAuth();
|
|
89
|
-
adapter = new adapters.OpenAIAdapter({
|
|
90
|
-
model: blockConfig.adapter.model,
|
|
91
|
-
apiKey: auth?.openai?.apiKey || process.env.OPENAI_API_KEY || '',
|
|
92
|
-
});
|
|
93
|
-
} else if (provider === 'gemini') {
|
|
94
|
-
const auth = await loadAuth();
|
|
95
|
-
adapter = new adapters.GeminiAdapter({
|
|
96
|
-
model: blockConfig.adapter.model,
|
|
97
|
-
apiKey: auth?.gemini?.apiKey || process.env.GEMINI_API_KEY || '',
|
|
98
|
-
});
|
|
99
|
-
} else {
|
|
100
|
-
adapter = new adapters.BedrockAdapter({
|
|
101
|
-
model: blockConfig.adapter.model,
|
|
102
|
-
region: blockConfig.adapter.region,
|
|
103
|
-
maxTokens: blockConfig.adapter.maxTokens,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const registry = createDefaultRegistry();
|
|
108
|
-
const channel = new OrchestratorChannel();
|
|
109
|
-
|
|
110
|
-
const monitor = new Monitor({
|
|
111
|
-
blockPath,
|
|
112
|
-
blockConfig,
|
|
113
|
-
adapter,
|
|
114
|
-
registry,
|
|
115
|
-
channel: channel as any
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Start monitor
|
|
119
|
-
await monitor.start();
|
|
120
|
-
|
|
121
|
-
// Push prompt
|
|
122
|
-
channel.simulateUser(prompt);
|
|
123
|
-
|
|
124
|
-
// Wait until the monitor emits a non-system message
|
|
125
|
-
const finalResponse = await channel.waitForResponse();
|
|
126
|
-
|
|
127
|
-
// Stop monitor cleanup
|
|
128
|
-
await monitor.stop();
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
content: `Response from ${agent_name}:\n\n${finalResponse}`,
|
|
132
|
-
isError: false
|
|
133
|
-
};
|
|
134
|
-
} catch (err) {
|
|
135
|
-
return { content: `Agent query failed: ${(err as Error).message}`, isError: true };
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
};
|