@amalgm/agents 0.2.1 → 0.2.2
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 +25 -24
- package/README.md +21 -47
- package/dist/agents.d.ts +4 -26
- package/dist/agents.js +4 -87
- package/dist/bin/mcp.js +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +2 -13
- package/dist/cli/open.d.ts +1 -1
- package/dist/cli/open.js +1 -5
- package/dist/cli/run.js +3 -8
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +0 -2
- package/dist/http/server.js +1 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/mcp/agent-tools.js +1 -1
- package/dist/mcp/tools.js +1 -2
- package/dist/rows.d.ts +1 -4
- package/dist/rows.js +0 -39
- package/dist/schema.js +53 -101
- package/dist/types.d.ts +0 -106
- package/docs/ARCHITECTURE.md +21 -33
- package/docs/CLI.md +3 -43
- package/docs/DATA_MODEL.md +7 -46
- package/docs/DEFINITIONS.md +4 -4
- package/docs/ENGINE_INTEGRATION.md +9 -71
- package/docs/MCP.md +3 -19
- package/docs/REST.md +14 -97
- package/docs/SDK.md +12 -61
- package/docs/SECURITY.md +6 -35
- package/docs/SHELL_INTEGRATION.md +29 -0
- package/examples/basic.ts +8 -22
- package/package.json +2 -2
- package/skills/amalgm-agents/SKILL.md +231 -20
- package/skills/amalgm-agents/agents/openai.yaml +2 -2
- package/dist/cli/session-commands.d.ts +0 -4
- package/dist/cli/session-commands.js +0 -54
- package/dist/drivers.d.ts +0 -4
- package/dist/drivers.js +0 -25
- package/dist/event-store.d.ts +0 -13
- package/dist/event-store.js +0 -50
- package/dist/http/session-routes.d.ts +0 -2
- package/dist/http/session-routes.js +0 -67
- package/dist/http/stream.d.ts +0 -3
- package/dist/http/stream.js +0 -30
- package/dist/mcp/session-tools.d.ts +0 -3
- package/dist/mcp/session-tools.js +0 -81
- package/dist/messages.d.ts +0 -3
- package/dist/messages.js +0 -56
- package/dist/runtime.d.ts +0 -29
- package/dist/runtime.js +0 -176
- package/dist/session-store.d.ts +0 -15
- package/dist/session-store.js +0 -83
- package/dist/turn-store.d.ts +0 -31
- package/dist/turn-store.js +0 -164
- package/docs/DRIVERS.md +0 -72
package/dist/schema.js
CHANGED
|
@@ -1,31 +1,56 @@
|
|
|
1
|
-
const SCHEMA_VERSION =
|
|
2
|
-
|
|
1
|
+
const SCHEMA_VERSION = 3;
|
|
2
|
+
const REGISTRY_SCHEMA = `
|
|
3
|
+
CREATE TABLE agents (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
current_revision_id TEXT,
|
|
6
|
+
current_revision_number INTEGER NOT NULL DEFAULT 0,
|
|
7
|
+
created_at TEXT NOT NULL,
|
|
8
|
+
updated_at TEXT NOT NULL,
|
|
9
|
+
deleted_at TEXT
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CREATE TABLE agent_revisions (
|
|
13
|
+
id TEXT PRIMARY KEY,
|
|
14
|
+
agent_id TEXT NOT NULL REFERENCES agents(id),
|
|
15
|
+
revision_number INTEGER NOT NULL,
|
|
16
|
+
definition_hash TEXT NOT NULL,
|
|
17
|
+
definition_json TEXT NOT NULL,
|
|
18
|
+
created_at TEXT NOT NULL,
|
|
19
|
+
UNIQUE(agent_id, revision_number)
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
CREATE INDEX agent_revisions_agent_idx
|
|
23
|
+
ON agent_revisions(agent_id, revision_number DESC);
|
|
24
|
+
`;
|
|
25
|
+
function upgradeRegistry(database, current) {
|
|
3
26
|
database.pragma('foreign_keys = OFF');
|
|
4
27
|
try {
|
|
28
|
+
database.exec('BEGIN IMMEDIATE');
|
|
29
|
+
if (current === 1) {
|
|
30
|
+
database.exec(`
|
|
31
|
+
CREATE TABLE agent_revisions_next (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
agent_id TEXT NOT NULL REFERENCES agents(id),
|
|
34
|
+
revision_number INTEGER NOT NULL,
|
|
35
|
+
definition_hash TEXT NOT NULL,
|
|
36
|
+
definition_json TEXT NOT NULL,
|
|
37
|
+
created_at TEXT NOT NULL,
|
|
38
|
+
UNIQUE(agent_id, revision_number)
|
|
39
|
+
);
|
|
40
|
+
INSERT INTO agent_revisions_next
|
|
41
|
+
(id, agent_id, revision_number, definition_hash, definition_json, created_at)
|
|
42
|
+
SELECT id, agent_id, revision_number, definition_hash, definition_json, created_at
|
|
43
|
+
FROM agent_revisions;
|
|
44
|
+
DROP TABLE agent_revisions;
|
|
45
|
+
ALTER TABLE agent_revisions_next RENAME TO agent_revisions;
|
|
46
|
+
CREATE INDEX agent_revisions_agent_idx
|
|
47
|
+
ON agent_revisions(agent_id, revision_number DESC);
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
5
50
|
database.exec(`
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
id TEXT PRIMARY KEY,
|
|
10
|
-
agent_id TEXT NOT NULL REFERENCES agents(id),
|
|
11
|
-
revision_number INTEGER NOT NULL,
|
|
12
|
-
definition_hash TEXT NOT NULL,
|
|
13
|
-
definition_json TEXT NOT NULL,
|
|
14
|
-
created_at TEXT NOT NULL,
|
|
15
|
-
UNIQUE(agent_id, revision_number)
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
INSERT INTO agent_revisions_next
|
|
19
|
-
(id, agent_id, revision_number, definition_hash, definition_json, created_at)
|
|
20
|
-
SELECT id, agent_id, revision_number, definition_hash, definition_json, created_at
|
|
21
|
-
FROM agent_revisions;
|
|
22
|
-
|
|
23
|
-
DROP TABLE agent_revisions;
|
|
24
|
-
ALTER TABLE agent_revisions_next RENAME TO agent_revisions;
|
|
25
|
-
|
|
26
|
-
CREATE INDEX agent_revisions_agent_idx
|
|
27
|
-
ON agent_revisions(agent_id, revision_number DESC);
|
|
28
|
-
|
|
51
|
+
DROP TABLE IF EXISTS session_events;
|
|
52
|
+
DROP TABLE IF EXISTS turns;
|
|
53
|
+
DROP TABLE IF EXISTS sessions;
|
|
29
54
|
PRAGMA user_version = ${SCHEMA_VERSION};
|
|
30
55
|
COMMIT;
|
|
31
56
|
`);
|
|
@@ -46,82 +71,9 @@ export function migrate(database) {
|
|
|
46
71
|
}
|
|
47
72
|
if (current === SCHEMA_VERSION)
|
|
48
73
|
return;
|
|
49
|
-
if (current
|
|
50
|
-
|
|
74
|
+
if (current > 0) {
|
|
75
|
+
upgradeRegistry(database, current);
|
|
51
76
|
return;
|
|
52
77
|
}
|
|
53
|
-
database.exec(
|
|
54
|
-
CREATE TABLE agents (
|
|
55
|
-
id TEXT PRIMARY KEY,
|
|
56
|
-
current_revision_id TEXT,
|
|
57
|
-
current_revision_number INTEGER NOT NULL DEFAULT 0,
|
|
58
|
-
created_at TEXT NOT NULL,
|
|
59
|
-
updated_at TEXT NOT NULL,
|
|
60
|
-
deleted_at TEXT
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
CREATE TABLE agent_revisions (
|
|
64
|
-
id TEXT PRIMARY KEY,
|
|
65
|
-
agent_id TEXT NOT NULL REFERENCES agents(id),
|
|
66
|
-
revision_number INTEGER NOT NULL,
|
|
67
|
-
definition_hash TEXT NOT NULL,
|
|
68
|
-
definition_json TEXT NOT NULL,
|
|
69
|
-
created_at TEXT NOT NULL,
|
|
70
|
-
UNIQUE(agent_id, revision_number)
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
CREATE TABLE sessions (
|
|
74
|
-
id TEXT PRIMARY KEY,
|
|
75
|
-
agent_id TEXT NOT NULL REFERENCES agents(id),
|
|
76
|
-
agent_revision_id TEXT NOT NULL REFERENCES agent_revisions(id),
|
|
77
|
-
agent_revision_number INTEGER NOT NULL,
|
|
78
|
-
status TEXT NOT NULL CHECK(status IN ('active', 'archived')),
|
|
79
|
-
driver_session_id TEXT,
|
|
80
|
-
metadata_json TEXT NOT NULL,
|
|
81
|
-
created_at TEXT NOT NULL,
|
|
82
|
-
updated_at TEXT NOT NULL,
|
|
83
|
-
archived_at TEXT
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
CREATE TABLE turns (
|
|
87
|
-
id TEXT PRIMARY KEY,
|
|
88
|
-
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
89
|
-
idempotency_key TEXT NOT NULL,
|
|
90
|
-
status TEXT NOT NULL CHECK(status IN (
|
|
91
|
-
'queued', 'running', 'cancelling', 'completed', 'failed', 'cancelled', 'interrupted'
|
|
92
|
-
)),
|
|
93
|
-
input_json TEXT NOT NULL,
|
|
94
|
-
result_json TEXT,
|
|
95
|
-
error_json TEXT,
|
|
96
|
-
created_at TEXT NOT NULL,
|
|
97
|
-
started_at TEXT,
|
|
98
|
-
completed_at TEXT,
|
|
99
|
-
UNIQUE(session_id, idempotency_key)
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
CREATE TABLE session_events (
|
|
103
|
-
id TEXT PRIMARY KEY,
|
|
104
|
-
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
105
|
-
turn_id TEXT REFERENCES turns(id),
|
|
106
|
-
sequence INTEGER NOT NULL,
|
|
107
|
-
type TEXT NOT NULL,
|
|
108
|
-
data_json TEXT NOT NULL,
|
|
109
|
-
created_at TEXT NOT NULL,
|
|
110
|
-
UNIQUE(session_id, sequence)
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
CREATE INDEX agent_revisions_agent_idx
|
|
114
|
-
ON agent_revisions(agent_id, revision_number DESC);
|
|
115
|
-
CREATE INDEX sessions_agent_idx
|
|
116
|
-
ON sessions(agent_id, updated_at DESC);
|
|
117
|
-
CREATE INDEX turns_session_idx
|
|
118
|
-
ON turns(session_id, created_at ASC);
|
|
119
|
-
CREATE UNIQUE INDEX turns_one_active_per_session_idx
|
|
120
|
-
ON turns(session_id)
|
|
121
|
-
WHERE status IN ('queued', 'running', 'cancelling');
|
|
122
|
-
CREATE INDEX session_events_session_idx
|
|
123
|
-
ON session_events(session_id, sequence ASC);
|
|
124
|
-
|
|
125
|
-
PRAGMA user_version = ${SCHEMA_VERSION};
|
|
126
|
-
`);
|
|
78
|
+
database.exec(`${REGISTRY_SCHEMA}\nPRAGMA user_version = ${SCHEMA_VERSION};`);
|
|
127
79
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -63,114 +63,8 @@ export interface AgentRecord {
|
|
|
63
63
|
updatedAt: string;
|
|
64
64
|
deletedAt: string | null;
|
|
65
65
|
}
|
|
66
|
-
export type SessionStatus = 'active' | 'archived';
|
|
67
|
-
export type TurnStatus = 'queued' | 'running' | 'cancelling' | 'completed' | 'failed' | 'cancelled' | 'interrupted';
|
|
68
|
-
export interface TextPart {
|
|
69
|
-
type: 'text';
|
|
70
|
-
text: string;
|
|
71
|
-
}
|
|
72
|
-
export interface ReferencePart {
|
|
73
|
-
type: 'reference';
|
|
74
|
-
uri: string;
|
|
75
|
-
name: string | null;
|
|
76
|
-
mediaType: string | null;
|
|
77
|
-
}
|
|
78
|
-
export interface DataPart {
|
|
79
|
-
type: 'data';
|
|
80
|
-
name: string;
|
|
81
|
-
data: JsonValue;
|
|
82
|
-
}
|
|
83
|
-
export type AgentPart = TextPart | ReferencePart | DataPart;
|
|
84
|
-
export type MessageRole = 'user' | 'assistant' | 'system';
|
|
85
|
-
export interface AgentMessage {
|
|
86
|
-
role: MessageRole;
|
|
87
|
-
parts: AgentPart[];
|
|
88
|
-
}
|
|
89
|
-
export interface AgentSession {
|
|
90
|
-
id: string;
|
|
91
|
-
agentId: string;
|
|
92
|
-
agentRevisionId: string;
|
|
93
|
-
agentRevision: number;
|
|
94
|
-
status: SessionStatus;
|
|
95
|
-
driverSessionId: string | null;
|
|
96
|
-
metadata: JsonObject;
|
|
97
|
-
createdAt: string;
|
|
98
|
-
updatedAt: string;
|
|
99
|
-
archivedAt: string | null;
|
|
100
|
-
}
|
|
101
|
-
export interface AgentTurn {
|
|
102
|
-
id: string;
|
|
103
|
-
sessionId: string;
|
|
104
|
-
idempotencyKey: string;
|
|
105
|
-
status: TurnStatus;
|
|
106
|
-
input: AgentMessage;
|
|
107
|
-
result: JsonObject | null;
|
|
108
|
-
error: AgentFailure | null;
|
|
109
|
-
createdAt: string;
|
|
110
|
-
startedAt: string | null;
|
|
111
|
-
completedAt: string | null;
|
|
112
|
-
}
|
|
113
|
-
export interface AgentFailure {
|
|
114
|
-
code: string;
|
|
115
|
-
message: string;
|
|
116
|
-
details: JsonObject;
|
|
117
|
-
}
|
|
118
|
-
export interface SessionEvent {
|
|
119
|
-
id: string;
|
|
120
|
-
sessionId: string;
|
|
121
|
-
turnId: string | null;
|
|
122
|
-
sequence: number;
|
|
123
|
-
type: string;
|
|
124
|
-
data: JsonObject;
|
|
125
|
-
createdAt: string;
|
|
126
|
-
}
|
|
127
|
-
export interface DriverEvent {
|
|
128
|
-
type: string;
|
|
129
|
-
data: JsonObject;
|
|
130
|
-
}
|
|
131
|
-
export interface DriverRunRequest {
|
|
132
|
-
agent: AgentRevision;
|
|
133
|
-
session: AgentSession;
|
|
134
|
-
turn: AgentTurn;
|
|
135
|
-
history: AgentMessage[];
|
|
136
|
-
input: AgentMessage;
|
|
137
|
-
driverSessionId: string | null;
|
|
138
|
-
}
|
|
139
|
-
export interface DriverRunResult {
|
|
140
|
-
message?: AgentMessage;
|
|
141
|
-
driverSessionId?: string;
|
|
142
|
-
metadata?: JsonObject;
|
|
143
|
-
}
|
|
144
|
-
export interface DriverRunContext {
|
|
145
|
-
signal: AbortSignal;
|
|
146
|
-
emit(event: DriverEvent): SessionEvent;
|
|
147
|
-
}
|
|
148
|
-
export interface AgentDriver {
|
|
149
|
-
id: string;
|
|
150
|
-
run(request: DriverRunRequest, context: DriverRunContext): Promise<DriverRunResult | void>;
|
|
151
|
-
}
|
|
152
66
|
export interface AgentsOptions {
|
|
153
67
|
stateDir?: string;
|
|
154
68
|
databasePath?: string;
|
|
155
|
-
drivers?: AgentDriver[];
|
|
156
|
-
maxInputBytes?: number;
|
|
157
|
-
maxEventBytes?: number;
|
|
158
|
-
turnTimeoutMs?: number;
|
|
159
69
|
now?: () => string;
|
|
160
70
|
}
|
|
161
|
-
export interface StartSessionInput {
|
|
162
|
-
agentId: string;
|
|
163
|
-
revisionId?: string;
|
|
164
|
-
sessionId?: string;
|
|
165
|
-
metadata?: JsonObject;
|
|
166
|
-
}
|
|
167
|
-
export interface SendInput {
|
|
168
|
-
message: string | AgentMessage;
|
|
169
|
-
idempotencyKey?: string;
|
|
170
|
-
}
|
|
171
|
-
export interface EnqueuedTurn {
|
|
172
|
-
turn: AgentTurn;
|
|
173
|
-
completion: Promise<AgentTurn>;
|
|
174
|
-
duplicate: boolean;
|
|
175
|
-
}
|
|
176
|
-
export type EventListener = (event: SessionEvent) => void;
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -2,27 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## Ownership
|
|
4
4
|
|
|
5
|
-
The Agents service owns
|
|
5
|
+
The Agents service owns three facts:
|
|
6
6
|
|
|
7
7
|
1. which agent identities exist;
|
|
8
|
-
2. the immutable revisions of each identity;
|
|
9
|
-
3. which
|
|
10
|
-
4. the ordered turns and events inside each session.
|
|
8
|
+
2. the immutable revisions of each identity; and
|
|
9
|
+
3. which installed agents and Agent Home descriptors are available locally.
|
|
11
10
|
|
|
12
11
|
Everything else crosses an adapter boundary.
|
|
13
12
|
|
|
14
13
|
```text
|
|
15
14
|
SDK
|
|
16
15
|
│
|
|
17
|
-
CLI ───┐ │ ┌─── REST
|
|
16
|
+
CLI ───┐ │ ┌─── REST
|
|
18
17
|
├── Agents ───┤
|
|
19
18
|
MCP ───┘ │ └─── Engine adapter
|
|
20
19
|
│
|
|
21
|
-
|
|
22
|
-
│
|
|
23
|
-
AgentDriver
|
|
24
|
-
┌──────┼──────┐
|
|
25
|
-
Codex Claude custom
|
|
20
|
+
SQLite registry
|
|
26
21
|
```
|
|
27
22
|
|
|
28
23
|
CLI, MCP, REST, and Engine never write SQLite directly. `Agents` is the
|
|
@@ -32,15 +27,17 @@ public service; the stores below it are implementation details.
|
|
|
32
27
|
|
|
33
28
|
| Product | Owns | Agents keeps |
|
|
34
29
|
|---|---|---|
|
|
35
|
-
| Chat |
|
|
30
|
+
| Chat | conversations, prepared execution, turns, streams, persistence, reconnect, usage, interrupt | exact agent revision selection |
|
|
36
31
|
| Tools | tools, actions, drivers, loadouts | opaque tool/action ids |
|
|
37
32
|
| Skills | skill content and installation | opaque skill ids |
|
|
38
33
|
| Credentials | secret material and authorization | opaque `authRef` |
|
|
39
|
-
|
|
|
40
|
-
| Agents |
|
|
34
|
+
| Shell | native harness processes, auth, machine effects, exact SDK composition | resolved revision projection |
|
|
35
|
+
| Agents | identities, installations, Agent Home descriptors, immutable revisions | canonical registry records |
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
A Chat conversation is executable history. It names one Agents installation
|
|
38
|
+
and the exact immutable revision used by each prepared execution. Agents never
|
|
39
|
+
imports Chat and Chat never imports the Agents store; Shell composes their
|
|
40
|
+
public capabilities through an explicit resolver.
|
|
44
41
|
|
|
45
42
|
## Mutation path
|
|
46
43
|
|
|
@@ -49,25 +46,16 @@ merges a typed patch into the current definition and compares its canonical
|
|
|
49
46
|
hash with the current revision. Equal content is idempotent; changed content
|
|
50
47
|
appends a revision and moves the identity's current pointer.
|
|
51
48
|
|
|
52
|
-
Deleting an agent sets `deleted_at`. It does not delete revisions or
|
|
49
|
+
Deleting an agent sets `deleted_at`. It does not delete immutable revisions or
|
|
50
|
+
Chat conversations that already name them.
|
|
53
51
|
The id cannot be recreated accidentally.
|
|
54
52
|
|
|
55
|
-
##
|
|
56
|
-
|
|
57
|
-
1. A caller starts a session; the current revision id is copied onto it.
|
|
58
|
-
2. A turn and its input event commit in one transaction.
|
|
59
|
-
3. The turn becomes `running` before its driver is invoked.
|
|
60
|
-
4. Driver events commit to the ordered event ledger before subscribers see them.
|
|
61
|
-
5. The driver returns a message, opaque native session id, and metadata.
|
|
62
|
-
6. The turn reaches exactly one terminal state.
|
|
63
|
-
|
|
64
|
-
One session serializes turns. Different sessions can execute concurrently.
|
|
53
|
+
## Resolution path
|
|
65
54
|
|
|
66
|
-
|
|
55
|
+
1. A caller selects an installed agent identity.
|
|
56
|
+
2. Agents returns the requested immutable revision, or the current revision
|
|
57
|
+
when no revision was requested.
|
|
58
|
+
3. Shell projects that revision into Chat's execution-preparation resolver.
|
|
59
|
+
4. Chat freezes the resolved facts before accepting a turn.
|
|
67
60
|
|
|
68
|
-
|
|
69
|
-
streaming, and resume rules. Baking them into storage would couple every user
|
|
70
|
-
of the SDK to Engine. `AgentDriver` receives a complete immutable revision and
|
|
71
|
-
ordered history, then emits durable events. Engine can reuse its current
|
|
72
|
-
chat-core adapters behind this interface; standalone users can provide their
|
|
73
|
-
own drivers.
|
|
61
|
+
Agents ends at this resolution result. Chat is the only execution path.
|
package/docs/CLI.md
CHANGED
|
@@ -3,18 +3,6 @@
|
|
|
3
3
|
The CLI prints JSON to stdout and errors to stderr. It shares the SDK database;
|
|
4
4
|
there is no CLI-specific registry.
|
|
5
5
|
|
|
6
|
-
## Global options
|
|
7
|
-
|
|
8
|
-
| Option | Meaning |
|
|
9
|
-
|---|---|
|
|
10
|
-
| `--state-dir <path>` | Override the Agents state directory |
|
|
11
|
-
| `--drivers <a.js,b.js>` | Load compiled driver modules |
|
|
12
|
-
| `--help` | Print command help |
|
|
13
|
-
|
|
14
|
-
`AMALGM_AGENT_DRIVERS` supplies the same comma-separated driver list.
|
|
15
|
-
|
|
16
|
-
## Agent commands
|
|
17
|
-
|
|
18
6
|
```bash
|
|
19
7
|
amalgm-agents agent list [--include-deleted]
|
|
20
8
|
amalgm-agents agent show <id> [--include-deleted]
|
|
@@ -23,39 +11,11 @@ amalgm-agents agent update <id> <patch.json>
|
|
|
23
11
|
amalgm-agents agent delete <id>
|
|
24
12
|
```
|
|
25
13
|
|
|
26
|
-
|
|
27
|
-
[Definitions](./DEFINITIONS.md).
|
|
14
|
+
Global options are `--state-dir <path>` and `--help`.
|
|
28
15
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
amalgm-agents session list [--agent <id>] [--include-archived]
|
|
33
|
-
amalgm-agents session start <agent-id> [--id <id>] [--revision <revision-id>]
|
|
34
|
-
amalgm-agents session show <id>
|
|
35
|
-
amalgm-agents session events <id> [--after <sequence>]
|
|
36
|
-
amalgm-agents session send <id> <message> [--key <idempotency-key>]
|
|
37
|
-
amalgm-agents session cancel <id>
|
|
38
|
-
amalgm-agents session archive <id>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`session show` returns the session, turns, and event ledger together.
|
|
42
|
-
|
|
43
|
-
## Talk shortcut
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
amalgm-agents talk <agent-id> <message> \
|
|
47
|
-
[--session <session-id>] [--key <idempotency-key>] [--background]
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Without `--session`, the command starts one. Foreground waits for a terminal
|
|
51
|
-
turn; background returns the accepted turn immediately.
|
|
52
|
-
|
|
53
|
-
## Servers
|
|
16
|
+
The REST CLI binds loopback by default:
|
|
54
17
|
|
|
55
18
|
```bash
|
|
56
19
|
amalgm-agents-rest --host 127.0.0.1 --port 4317 --token "$TOKEN"
|
|
57
|
-
amalgm-agents-mcp --state-dir ./state
|
|
20
|
+
amalgm-agents-mcp --state-dir ./state
|
|
58
21
|
```
|
|
59
|
-
|
|
60
|
-
The REST CLI binds loopback by default. Use a bearer token before deliberately
|
|
61
|
-
binding to any shared interface.
|
package/docs/DATA_MODEL.md
CHANGED
|
@@ -1,56 +1,17 @@
|
|
|
1
|
-
# Persistence
|
|
1
|
+
# Persistence
|
|
2
2
|
|
|
3
3
|
The default database is `agents.db` inside the state directory resolved by
|
|
4
|
-
`@amalgm/core/identity`: `
|
|
5
|
-
`$
|
|
6
|
-
`~/.amalgm/users/local/agents`. Set `stateDir` or `databasePath` to relocate
|
|
7
|
-
it directly.
|
|
4
|
+
`@amalgm/core/identity`: `AMALGAM_AGENTS_DIR` verbatim when set, otherwise
|
|
5
|
+
`$AMALGAM_DIR/agents`, otherwise `~/.amalgm/users/local/agents`.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
The registry has two tables:
|
|
10
8
|
|
|
11
9
|
| Table | Role |
|
|
12
10
|
|---|---|
|
|
13
11
|
| `agents` | stable identity, current revision pointer, tombstone |
|
|
14
12
|
| `agent_revisions` | immutable normalized definitions |
|
|
15
|
-
| `sessions` | pinned revision and opaque driver session id |
|
|
16
|
-
| `turns` | accepted input and execution outcome |
|
|
17
|
-
| `session_events` | ordered append-only execution observations |
|
|
18
|
-
|
|
19
|
-
Foreign keys prevent orphan sessions, turns, and events. SQLite WAL mode and a
|
|
20
|
-
five-second busy timeout support multiple read-oriented surfaces while one
|
|
21
|
-
service owns mutations.
|
|
22
13
|
|
|
23
14
|
Repeating the current definition is idempotent. Returning to content used by
|
|
24
|
-
an earlier revision creates a new revision number
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## Turn states
|
|
28
|
-
|
|
29
|
-
```text
|
|
30
|
-
queued → running → completed
|
|
31
|
-
├──→ failed
|
|
32
|
-
├──→ cancelling → cancelled
|
|
33
|
-
└──→ interrupted
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
`queued`, `running`, and `cancelling` are non-terminal. At service startup they
|
|
37
|
-
become `interrupted`, because the previous process may have completed external
|
|
38
|
-
side effects before dying. The service never guesses and never automatically
|
|
39
|
-
replays uncertain work.
|
|
40
|
-
|
|
41
|
-
## Idempotency
|
|
42
|
-
|
|
43
|
-
`idempotencyKey` is unique within a session. Repeating a key returns its
|
|
44
|
-
existing turn and does not invoke the driver again. Callers should derive it
|
|
45
|
-
from their durable request identity instead of generating a new value on every
|
|
46
|
-
retry.
|
|
47
|
-
|
|
48
|
-
## Events
|
|
49
|
-
|
|
50
|
-
Every event receives the next integer sequence within its session. SSE first
|
|
51
|
-
reads committed events after the requested sequence, then subscribes to newly
|
|
52
|
-
committed events. Reconnecting with the last SSE id therefore closes the gap
|
|
53
|
-
without polling or losing events.
|
|
54
|
-
|
|
55
|
-
Events are facts, not mutable projections. User interfaces derive streaming
|
|
56
|
-
text, messages, tool activity, and status from the ledger.
|
|
15
|
+
an earlier revision creates a new revision number, keeping the definition
|
|
16
|
+
timeline complete and append-only. Conversations and turns are stored only by
|
|
17
|
+
Chat.
|
package/docs/DEFINITIONS.md
CHANGED
|
@@ -37,13 +37,13 @@ products.
|
|
|
37
37
|
|
|
38
38
|
`id` is a stable machine identity: 1–128 lowercase letters, numbers, dots,
|
|
39
39
|
underscores, or hyphens. Renaming `name` never changes it. Deleted ids remain
|
|
40
|
-
reserved so
|
|
40
|
+
reserved so recorded revision identities cannot be reused.
|
|
41
41
|
|
|
42
42
|
## Revisions
|
|
43
43
|
|
|
44
44
|
The normalized complete definition is hashed. An edit with equal content keeps
|
|
45
45
|
the current revision. Any changed field creates a new immutable revision.
|
|
46
|
-
|
|
46
|
+
Chat records the exact revision selected for every prepared execution.
|
|
47
47
|
|
|
48
48
|
## PATCH behavior
|
|
49
49
|
|
|
@@ -61,5 +61,5 @@ authoritative and de-duplicated. Set nullable fields such as `model` or
|
|
|
61
61
|
- `resources.skills` and `resources.files` are resolved by the host.
|
|
62
62
|
- `resources.subagents` describes intended relationships; the host still
|
|
63
63
|
authorizes every agent-to-agent call.
|
|
64
|
-
- `driver.config` is non-secret
|
|
65
|
-
|
|
64
|
+
- `driver.config` is non-secret harness configuration interpreted only by
|
|
65
|
+
Chat's host runtime.
|
|
@@ -1,74 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Historical Engine integration
|
|
2
2
|
|
|
3
|
-
Engine
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Amalgm Engine is deprecated. Its former agent registry, configuration, talk,
|
|
4
|
+
REST, and MCP implementations are reference evidence for migrations and
|
|
5
|
+
parity only. They are not active execution or persistence authorities and are
|
|
6
|
+
never a fallback beside Shell.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Agents now owns identities, installations, immutable revisions, and portable
|
|
9
|
+
bundles. Chat owns conversations and turns. Shell resolves exact Agents
|
|
10
|
+
revisions into prepared Chat executions through the public packages.
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|---|---|
|
|
11
|
-
| `amalgm-mcp/agents/store.js` agent rows | `AgentStore` through `Agents` |
|
|
12
|
-
| `amalgm-mcp/agent-config/*` normalized config | immutable agent definitions |
|
|
13
|
-
| `amalgm-mcp/agents/talk.js` durable sessions and logs | Agents sessions, turns, events |
|
|
14
|
-
| `amalgm-mcp/agents/tools.js` | packaged MCP tools |
|
|
15
|
-
| `amalgm-mcp/agents/rest.js` and route wiring | packaged REST adapter |
|
|
16
|
-
| `chat-core` native runtime execution | Engine-supplied `AgentDriver` implementations |
|
|
17
|
-
| Toolbox lookup and MCP resolution | `@amalgm/tools` adapter inside drivers |
|
|
18
|
-
| credential adapter | `authRef` resolver inside drivers |
|
|
19
|
-
| Supabase Chat session creation | Chat/cloud adapter observing Agents events |
|
|
20
|
-
|
|
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
|
-
|
|
25
|
-
## Required driver adapter
|
|
26
|
-
|
|
27
|
-
Engine should implement one driver per native harness identity (`codex`,
|
|
28
|
-
`claude_code`, `opencode`, `pi`, and others). A driver translates the immutable
|
|
29
|
-
revision into chat-core's runtime envelope, resolves `authRef`, projects the
|
|
30
|
-
Toolbox loadout, forwards normalized streaming events, and returns the native
|
|
31
|
-
session id for continuation.
|
|
32
|
-
|
|
33
|
-
Drivers must not write Agents SQLite or invent another conversation log.
|
|
34
|
-
|
|
35
|
-
## Chat boundary
|
|
36
|
-
|
|
37
|
-
Engine may associate an Agents session id with a Chat record. Chat owns title,
|
|
38
|
-
participants, layout, read state, and cloud presentation. Agents owns pinned
|
|
39
|
-
revision, accepted inputs, driver execution, and events. Synchronization is an
|
|
40
|
-
adapter subscribed to committed Agents events; neither database is imported by
|
|
41
|
-
the other product.
|
|
42
|
-
|
|
43
|
-
## One-time migration
|
|
44
|
-
|
|
45
|
-
1. Stop the legacy agent mutation and talk surfaces.
|
|
46
|
-
2. Read each legacy agent plus its `agent_config` as one complete definition.
|
|
47
|
-
3. Map `baseHarnessId` to `driver.id`, model fields to `model`, auth mode to an
|
|
48
|
-
`authRef`, and legacy loadout ids to `toolbox.toolIds`.
|
|
49
|
-
4. Create missing agents and update existing agents through `Agents`.
|
|
50
|
-
5. Import local conversation JSONL as archived sessions only when its agent and
|
|
51
|
-
chronological message identity are unambiguous; otherwise retain it as a
|
|
52
|
-
legacy read-only export.
|
|
53
|
-
6. Start packaged REST and MCP adapters behind Engine's existing authenticated
|
|
54
|
-
routes.
|
|
55
|
-
7. Enable native drivers and verify continuation against real harness sessions.
|
|
56
|
-
8. Delete the legacy registry, config, talk, REST, and MCP implementations only
|
|
57
|
-
after parity and rollback checks pass.
|
|
58
|
-
|
|
59
|
-
Migration must be idempotent. Record the source identity and migration version
|
|
60
|
-
outside agent metadata or in a namespaced metadata field; never manufacture a
|
|
61
|
-
new revision on equal reruns.
|
|
62
|
-
|
|
63
|
-
## Integration tests
|
|
64
|
-
|
|
65
|
-
Before switchover, run:
|
|
66
|
-
|
|
67
|
-
- legacy agent create/update/delete through the UI against `Agents`;
|
|
68
|
-
- a session created on revision 1, followed by an agent edit and continuation;
|
|
69
|
-
- native resume after Engine restart;
|
|
70
|
-
- Toolbox loadout enforcement through `@amalgm/tools`;
|
|
71
|
-
- provider authentication failure without credential persistence in Agents;
|
|
72
|
-
- agent-to-agent background calls and cancellation;
|
|
73
|
-
- Chat projection without Chat becoming the session source of truth; and
|
|
74
|
-
- one-time migration twice with byte-for-byte equal resulting definitions.
|
|
12
|
+
See [SHELL_INTEGRATION.md](./SHELL_INTEGRATION.md) for the active boundary.
|
package/docs/MCP.md
CHANGED
|
@@ -3,22 +3,6 @@
|
|
|
3
3
|
`amalgm-agents-mcp` is the standalone stdio server. `createMcpServer` from
|
|
4
4
|
`@amalgm/agents/mcp` embeds the same server.
|
|
5
5
|
|
|
6
|
-
It exposes
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|---|---|
|
|
10
|
-
| `agents_list` | List persistent agents |
|
|
11
|
-
| `agents_get` | Inspect one agent |
|
|
12
|
-
| `agents_create` | Create an agent |
|
|
13
|
-
| `agents_update` | Edit an agent |
|
|
14
|
-
| `agents_delete` | Delete an agent while retaining session history |
|
|
15
|
-
| `agents_get_conversation` | Inspect a durable agent session |
|
|
16
|
-
| `talk_to_agent` | Start or continue an agent session |
|
|
17
|
-
|
|
18
|
-
`talk_to_agent` accepts the legacy `agent`, `conversation_id`, `description`,
|
|
19
|
-
and `prompt` fields. `agent_id`, `session_id`, and structured `message` are
|
|
20
|
-
also accepted. It returns `conversation_id` as the durable Agents session ID,
|
|
21
|
-
not a Chat ID. Use `run_in_background` for long work.
|
|
22
|
-
|
|
23
|
-
All handlers call the injected `Agents` service. MCP contains no second
|
|
24
|
-
registry, transcript, execution engine, or routing subsystem.
|
|
6
|
+
It exposes five registry tools: `agents_list`, `agents_get`, `agents_create`,
|
|
7
|
+
`agents_update`, and `agents_delete`. Their handlers call the injected
|
|
8
|
+
`Agents` service; MCP contains no second registry and no conversation runtime.
|