@amalgm/agents 0.1.1 → 0.1.3
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/PURPOSE.md +12 -2
- package/README.md +34 -0
- package/dist/bin/rest.js +7 -2
- package/dist/bundles/create.d.ts +13 -0
- package/dist/bundles/create.js +125 -0
- package/dist/bundles/graph-records.d.ts +10 -0
- package/dist/bundles/graph-records.js +61 -0
- package/dist/bundles/graph.d.ts +6 -0
- package/dist/bundles/graph.js +121 -0
- package/dist/bundles/install.d.ts +6 -0
- package/dist/bundles/install.js +64 -0
- package/dist/bundles/types.d.ts +97 -0
- package/dist/bundles/types.js +1 -0
- package/dist/bundles/util.d.ts +14 -0
- package/dist/bundles/util.js +56 -0
- package/dist/bundles/validate.d.ts +2 -0
- package/dist/bundles/validate.js +92 -0
- package/dist/config/import.d.ts +14 -0
- package/dist/config/import.js +59 -0
- package/dist/config/native.d.ts +2 -0
- package/dist/config/native.js +179 -0
- package/dist/config/schema.d.ts +3 -0
- package/dist/config/schema.js +135 -0
- package/dist/config/store.d.ts +9 -0
- package/dist/config/store.js +56 -0
- package/dist/config/types.d.ts +55 -0
- package/dist/config/types.js +1 -0
- package/dist/http/bundle-routes.d.ts +2 -0
- package/dist/http/bundle-routes.js +67 -0
- package/dist/http/config-routes.d.ts +2 -0
- package/dist/http/config-routes.js +46 -0
- package/dist/http/server.js +5 -1
- package/dist/http-types.d.ts +5 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +9 -0
- package/dist/mcp/server.js +1 -1
- package/docs/ENGINE_INTEGRATION.md +3 -3
- package/docs/REST.md +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createAgentBundle } from '../bundles/create.js';
|
|
2
|
+
import { installAgentBundle } from '../bundles/install.js';
|
|
3
|
+
import { BUNDLE_KIND, BUNDLE_SCHEMA_VERSION } from '../bundles/util.js';
|
|
4
|
+
import { scanInstalledSkills } from '../skills/scanner.js';
|
|
5
|
+
function ids(...values) {
|
|
6
|
+
const result = [];
|
|
7
|
+
for (const value of values) {
|
|
8
|
+
if (typeof value === 'string' && value.trim())
|
|
9
|
+
result.push(value.trim());
|
|
10
|
+
if (Array.isArray(value))
|
|
11
|
+
value.forEach((item) => {
|
|
12
|
+
if (typeof item === 'string' && item.trim())
|
|
13
|
+
result.push(item.trim());
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return [...new Set(result)];
|
|
17
|
+
}
|
|
18
|
+
export async function routeAgentBundles(context) {
|
|
19
|
+
const [resource, action, child] = context.path;
|
|
20
|
+
if (resource !== 'agent-bundles')
|
|
21
|
+
return false;
|
|
22
|
+
if (!action && context.method === 'GET') {
|
|
23
|
+
context.json(200, {
|
|
24
|
+
kind: BUNDLE_KIND,
|
|
25
|
+
schemaVersion: BUNDLE_SCHEMA_VERSION,
|
|
26
|
+
available: { agents: context.agents.listAgents().map((agent) => ({
|
|
27
|
+
id: agent.id, name: agent.definition.name, description: agent.definition.description,
|
|
28
|
+
})) },
|
|
29
|
+
});
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
if (child || context.method !== 'POST')
|
|
33
|
+
return false;
|
|
34
|
+
const body = await context.body();
|
|
35
|
+
try {
|
|
36
|
+
if (action === 'preview') {
|
|
37
|
+
const installedSkills = scanInstalledSkills({ ...context.skillRoots, includeContent: true }).skills;
|
|
38
|
+
const result = await createAgentBundle(context.agents, {
|
|
39
|
+
agentIds: ids(body.agent_id, body.agent_ids),
|
|
40
|
+
automationIds: ids(body.automation_id, body.automation_ids),
|
|
41
|
+
appIds: ids(body.app_id, body.app_ids),
|
|
42
|
+
toolIds: ids(body.tool_id, body.tool_ids),
|
|
43
|
+
}, { ...(context.bundlePort ? { port: context.bundlePort } : {}), installedSkills });
|
|
44
|
+
context.json(200, { ok: true, ...result });
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (action === 'install') {
|
|
48
|
+
if (!body.bundle) {
|
|
49
|
+
context.json(400, { error: 'bundle is required' });
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
const authRef = typeof body.auth_ref === 'string' ? body.auth_ref
|
|
53
|
+
: typeof body.authMethod === 'string' ? body.authMethod : undefined;
|
|
54
|
+
const result = await installAgentBundle(context.agents, body.bundle, {
|
|
55
|
+
...(context.bundlePort ? { port: context.bundlePort } : {}),
|
|
56
|
+
...(authRef ? { authRef } : {}),
|
|
57
|
+
});
|
|
58
|
+
context.json(200, result);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
context.json(400, { error: error instanceof Error ? error.message : 'Bundle operation failed' });
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isObject } from '../json.js';
|
|
2
|
+
import { importAgentConfig } from '../config/import.js';
|
|
3
|
+
import { configFromAgent, listAgentConfigs, updateAgentConfig } from '../config/store.js';
|
|
4
|
+
function agentId(body) {
|
|
5
|
+
return typeof body.agent_id === 'string' ? body.agent_id.trim() : '';
|
|
6
|
+
}
|
|
7
|
+
export async function routeAgentConfig(context) {
|
|
8
|
+
const [resource, action, child] = context.path;
|
|
9
|
+
if (resource !== 'agent-config')
|
|
10
|
+
return false;
|
|
11
|
+
if (!action && context.method === 'GET') {
|
|
12
|
+
context.json(200, { configs: listAgentConfigs(context.agents) });
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (child || context.method !== 'POST')
|
|
16
|
+
return false;
|
|
17
|
+
const body = await context.body();
|
|
18
|
+
const id = agentId(body);
|
|
19
|
+
if (!id) {
|
|
20
|
+
context.json(400, { error: 'agent_id is required' });
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const agent = context.agents.getAgent(id);
|
|
24
|
+
if (!agent) {
|
|
25
|
+
context.json(404, { error: `Agent not found: ${id}` });
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (action === 'get') {
|
|
29
|
+
context.json(200, { config: configFromAgent(agent) });
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
if (action === 'update') {
|
|
33
|
+
const config = isObject(body.config) ? body.config : {};
|
|
34
|
+
context.json(200, { ok: true, config: updateAgentConfig(context.agents, id, config).config });
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (action === 'import-native') {
|
|
38
|
+
const result = importAgentConfig(context.agents, id, {
|
|
39
|
+
...(context.nativeHomeDir ? { homeDir: context.nativeHomeDir } : {}),
|
|
40
|
+
replace: body.replace === true,
|
|
41
|
+
});
|
|
42
|
+
context.json(200, { ok: true, ...result });
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
package/dist/http/server.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
2
|
import { Agents } from '../agents.js';
|
|
3
3
|
import { asAgentError } from '../errors.js';
|
|
4
|
+
import { routeAgentConfig } from './config-routes.js';
|
|
5
|
+
import { routeAgentBundles } from './bundle-routes.js';
|
|
4
6
|
import { routeAgents } from './agent-routes.js';
|
|
5
7
|
import { guardRequest, readJson, sendJson } from './request.js';
|
|
6
8
|
import { routeSessions } from './session-routes.js';
|
|
@@ -44,10 +46,12 @@ export function createRestServer(options = {}) {
|
|
|
44
46
|
path,
|
|
45
47
|
url,
|
|
46
48
|
skillRoots: options.skillRoots || {},
|
|
49
|
+
...(options.nativeHomeDir ? { nativeHomeDir: options.nativeHomeDir } : {}),
|
|
50
|
+
...(options.bundlePort ? { bundlePort: options.bundlePort } : {}),
|
|
47
51
|
body: () => readJson(request, bodyLimit),
|
|
48
52
|
json: (status, value) => sendJson(response, status, value),
|
|
49
53
|
};
|
|
50
|
-
if (await routeSkills(context))
|
|
54
|
+
if (await routeAgentBundles(context) || await routeAgentConfig(context) || await routeSkills(context))
|
|
51
55
|
return;
|
|
52
56
|
if (path.shift() !== 'v1') {
|
|
53
57
|
sendJson(response, 404, { error: { code: 'not_found', message: 'Route not found.' } });
|
package/dist/http-types.d.ts
CHANGED
|
@@ -3,11 +3,14 @@ import type { AddressInfo } from 'node:net';
|
|
|
3
3
|
import type { Agents } from './agents.js';
|
|
4
4
|
import type { AgentsOptions } from './types.js';
|
|
5
5
|
import type { SkillRootOptions } from './skills/roots.js';
|
|
6
|
+
import type { AgentBundlePort } from './bundles/types.js';
|
|
6
7
|
export interface RestServerOptions extends AgentsOptions {
|
|
7
8
|
agents?: Agents;
|
|
8
9
|
token?: string;
|
|
9
10
|
bodyLimitBytes?: number;
|
|
10
11
|
skillRoots?: SkillRootOptions;
|
|
12
|
+
nativeHomeDir?: string;
|
|
13
|
+
bundlePort?: AgentBundlePort;
|
|
11
14
|
}
|
|
12
15
|
export interface RestServer {
|
|
13
16
|
agents: Agents;
|
|
@@ -21,6 +24,8 @@ export interface RouteContext {
|
|
|
21
24
|
path: string[];
|
|
22
25
|
url: URL;
|
|
23
26
|
skillRoots: SkillRootOptions;
|
|
27
|
+
nativeHomeDir?: string;
|
|
28
|
+
bundlePort?: AgentBundlePort;
|
|
24
29
|
body(): Promise<Record<string, unknown>>;
|
|
25
30
|
json(status: number, value: unknown): void;
|
|
26
31
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,3 +8,15 @@ export { buildCanonicalSkillRoots, classifySkillRoot } from './skills/roots.js';
|
|
|
8
8
|
export type { SkillRootClassification, SkillRootOptions } from './skills/roots.js';
|
|
9
9
|
export { parseSkillFrontmatter, scanInstalledSkills } from './skills/scanner.js';
|
|
10
10
|
export type { InstalledSkill, SkillScanOptions } from './skills/scanner.js';
|
|
11
|
+
export { normalizeAgentConfig, stableConfigId } from './config/schema.js';
|
|
12
|
+
export { configFromAgent, listAgentConfigs, updateAgentConfig } from './config/store.js';
|
|
13
|
+
export { importAgentConfig } from './config/import.js';
|
|
14
|
+
export { importNativeConfig } from './config/native.js';
|
|
15
|
+
export type * from './config/types.js';
|
|
16
|
+
export { createAgentBundle } from './bundles/create.js';
|
|
17
|
+
export type { CreateBundleOptions } from './bundles/create.js';
|
|
18
|
+
export { installAgentBundle } from './bundles/install.js';
|
|
19
|
+
export { buildBundleGraph } from './bundles/graph.js';
|
|
20
|
+
export { validateAgentBundle } from './bundles/validate.js';
|
|
21
|
+
export { BUNDLE_KIND, BUNDLE_SCHEMA_VERSION } from './bundles/util.js';
|
|
22
|
+
export type * from './bundles/types.js';
|
package/dist/index.js
CHANGED
|
@@ -5,3 +5,12 @@ export { definitionHash, normalizeDefinition, patchDefinition } from './definiti
|
|
|
5
5
|
export { messageText, normalizeMessage } from './messages.js';
|
|
6
6
|
export { buildCanonicalSkillRoots, classifySkillRoot } from './skills/roots.js';
|
|
7
7
|
export { parseSkillFrontmatter, scanInstalledSkills } from './skills/scanner.js';
|
|
8
|
+
export { normalizeAgentConfig, stableConfigId } from './config/schema.js';
|
|
9
|
+
export { configFromAgent, listAgentConfigs, updateAgentConfig } from './config/store.js';
|
|
10
|
+
export { importAgentConfig } from './config/import.js';
|
|
11
|
+
export { importNativeConfig } from './config/native.js';
|
|
12
|
+
export { createAgentBundle } from './bundles/create.js';
|
|
13
|
+
export { installAgentBundle } from './bundles/install.js';
|
|
14
|
+
export { buildBundleGraph } from './bundles/graph.js';
|
|
15
|
+
export { validateAgentBundle } from './bundles/validate.js';
|
|
16
|
+
export { BUNDLE_KIND, BUNDLE_SCHEMA_VERSION } from './bundles/util.js';
|
package/dist/mcp/server.js
CHANGED
|
@@ -16,7 +16,7 @@ export function createMcpServer(options = {}) {
|
|
|
16
16
|
return {
|
|
17
17
|
protocolVersion: message.params?.protocolVersion || '2024-11-05',
|
|
18
18
|
capabilities: { tools: { listChanged: false } },
|
|
19
|
-
serverInfo: { name: 'amalgm-agents', version: '0.1.
|
|
19
|
+
serverInfo: { name: 'amalgm-agents', version: '0.1.3' },
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
if (message.method === 'ping')
|
|
@@ -18,9 +18,9 @@ that domain.
|
|
|
18
18
|
| credential adapter | `authRef` resolver inside drivers |
|
|
19
19
|
| Supabase Chat session creation | Chat/cloud adapter observing Agents events |
|
|
20
20
|
|
|
21
|
-
Agent
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
Agent bundle-v2 graph and agent install laws live here. Engine supplies the
|
|
22
|
+
`AgentBundlePort` that exports and installs apps, automations, and tools through
|
|
23
|
+
their public SDKs; neither side imports another product's store.
|
|
24
24
|
|
|
25
25
|
## Required driver adapter
|
|
26
26
|
|
package/docs/REST.md
CHANGED
|
@@ -10,6 +10,31 @@ token receives the kernel's canonical 401 from `@amalgm/core/transport`,
|
|
|
10
10
|
compared in constant time. `/healthz` is a minimal unauthenticated liveness
|
|
11
11
|
response. JSON bodies default to a 512 KB limit.
|
|
12
12
|
|
|
13
|
+
## Agent configuration
|
|
14
|
+
|
|
15
|
+
| Method | Path | Result |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `GET` | `/agent-config` | List normalized configs from live agent revisions |
|
|
18
|
+
| `POST` | `/agent-config/get` | Read `{ agent_id }` |
|
|
19
|
+
| `POST` | `/agent-config/update` | Atomically apply `{ agent_id, config }` |
|
|
20
|
+
| `POST` | `/agent-config/import-native` | Import safe native fields for `{ agent_id, replace? }` |
|
|
21
|
+
|
|
22
|
+
Set `nativeHomeDir` when embedding the server or `--native-home`/
|
|
23
|
+
`AMALGM_NATIVE_HOME` with the REST binary. Native import intentionally ignores
|
|
24
|
+
auth files, secrets, and MCP server configuration.
|
|
25
|
+
|
|
26
|
+
## Agent bundles
|
|
27
|
+
|
|
28
|
+
| Method | Path | Result |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `GET` | `/agent-bundles` | Read bundle-v2 capability and available agent heads |
|
|
31
|
+
| `POST` | `/agent-bundles/preview` | Export requested agent/app/automation/tool heads |
|
|
32
|
+
| `POST` | `/agent-bundles/install` | Validate and install `{ bundle, auth_ref? }` |
|
|
33
|
+
|
|
34
|
+
Embedding hosts inject `bundlePort` for resources owned by Apps, Automations,
|
|
35
|
+
and Toolbox. Agent-only bundles need no port. Bundles with external resources
|
|
36
|
+
fail explicitly when the owner port is absent.
|
|
37
|
+
|
|
13
38
|
## Agents
|
|
14
39
|
|
|
15
40
|
| Method | Path | Result |
|