amalgm 0.1.83 → 0.1.84
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/package.json +1 -1
- package/runtime/scripts/amalgm-mcp/agent-config/schema.js +1 -1
- package/runtime/scripts/amalgm-mcp/tests/agents-source-of-truth.test.js +42 -0
- package/runtime/scripts/chat-core/auth.js +7 -9
- package/runtime/scripts/chat-core/contract.js +1 -1
- package/runtime/scripts/chat-core/tests/auth.test.js +15 -24
package/package.json
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
|
|
5
5
|
const CONFIG_VERSION = 1;
|
|
6
|
-
const DEFAULT_RUNTIME_HOME_LAYOUT = 'legacy';
|
|
7
6
|
const PER_AGENT_RUNTIME_HOME_LAYOUT = 'per-agent';
|
|
7
|
+
const DEFAULT_RUNTIME_HOME_LAYOUT = PER_AGENT_RUNTIME_HOME_LAYOUT;
|
|
8
8
|
const {
|
|
9
9
|
normalizeLoadout,
|
|
10
10
|
uniqueStrings,
|
|
@@ -17,6 +17,8 @@ const {
|
|
|
17
17
|
resolveAgent,
|
|
18
18
|
updateAgent,
|
|
19
19
|
} = require('../agents/store');
|
|
20
|
+
const agentsRest = require('../agents/rest');
|
|
21
|
+
const { getAgentConfig } = require('../agent-config/store');
|
|
20
22
|
|
|
21
23
|
test.after(() => {
|
|
22
24
|
closeLocalDb();
|
|
@@ -78,3 +80,43 @@ test('custom agent auth and model settings survive normalization', () => {
|
|
|
78
80
|
assert.deepEqual(agent.loadout, { toolIds: ['tool.search'] });
|
|
79
81
|
assert.equal(Object.prototype.hasOwnProperty.call(agent, 'tools'), false);
|
|
80
82
|
});
|
|
83
|
+
|
|
84
|
+
function captureSendJson() {
|
|
85
|
+
const response = {};
|
|
86
|
+
return {
|
|
87
|
+
response,
|
|
88
|
+
sendJson(status, payload) {
|
|
89
|
+
response.status = status;
|
|
90
|
+
response.payload = payload;
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
test('agents create REST preserves caller id and creates per-agent config', async () => {
|
|
96
|
+
const agentId = 'custom-first-class-ui-agent';
|
|
97
|
+
const { response, sendJson } = captureSendJson();
|
|
98
|
+
|
|
99
|
+
await agentsRest.handleCreate({
|
|
100
|
+
id: agentId,
|
|
101
|
+
name: 'First Class UI Agent',
|
|
102
|
+
baseHarnessId: 'codex',
|
|
103
|
+
baseModelId: 'openai/gpt-5.5',
|
|
104
|
+
authMethod: 'amalgm',
|
|
105
|
+
config: {
|
|
106
|
+
version: 1,
|
|
107
|
+
agentId,
|
|
108
|
+
instructions: 'Use the per-agent home.',
|
|
109
|
+
skills: [],
|
|
110
|
+
loadout: { toolIds: [] },
|
|
111
|
+
hooks: [],
|
|
112
|
+
subagents: [],
|
|
113
|
+
},
|
|
114
|
+
}, sendJson);
|
|
115
|
+
|
|
116
|
+
assert.equal(response.status, 200);
|
|
117
|
+
assert.equal(response.payload.agent.id, agentId);
|
|
118
|
+
assert.equal(resolveAgent(agentId).id, agentId);
|
|
119
|
+
assert.equal(response.payload.agent.config.agentId, agentId);
|
|
120
|
+
assert.equal(response.payload.agent.config.runtimeHomeLayout, 'per-agent');
|
|
121
|
+
assert.equal(getAgentConfig(agentId).runtimeHomeLayout, 'per-agent');
|
|
122
|
+
});
|
|
@@ -111,15 +111,13 @@ function providerAuthIdentity(harness) {
|
|
|
111
111
|
|
|
112
112
|
function runtimeHome({ amalgmDir, harness, agentConfigId, runtimeHomeLayout }) {
|
|
113
113
|
const harnessHome = path.join(amalgmDir, 'cli-homes', safePathSegment(harness));
|
|
114
|
-
if (runtimeHomeLayout === '
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
return path.join(harnessHome, 'home');
|
|
114
|
+
if (runtimeHomeLayout === 'legacy') return path.join(harnessHome, 'home');
|
|
115
|
+
return path.join(
|
|
116
|
+
harnessHome,
|
|
117
|
+
'agents',
|
|
118
|
+
safePathSegment(agentConfigId || harness),
|
|
119
|
+
'home',
|
|
120
|
+
);
|
|
123
121
|
}
|
|
124
122
|
|
|
125
123
|
function providerAuthFingerprint(harness) {
|
|
@@ -410,7 +410,7 @@ function createContract(payload, options = {}) {
|
|
|
410
410
|
|| payloadChatAgent?.customAgentId,
|
|
411
411
|
) || harness;
|
|
412
412
|
const agentConfig = normalizeAgentConfig(payload.agentConfig || { agentId: agentConfigId });
|
|
413
|
-
const runtimeHomeLayout =
|
|
413
|
+
const runtimeHomeLayout = 'per-agent';
|
|
414
414
|
const auth = authEnvelope({
|
|
415
415
|
harness,
|
|
416
416
|
authMethod,
|
|
@@ -7,10 +7,11 @@ const path = require('node:path');
|
|
|
7
7
|
const test = require('node:test');
|
|
8
8
|
const { authEnvelope, runtimeEnv } = require('../auth');
|
|
9
9
|
|
|
10
|
-
test('codex
|
|
10
|
+
test('codex uses one stable per-agent CLI home across auth methods', () => {
|
|
11
11
|
const amalgmDir = fs.mkdtempSync(path.join(os.tmpdir(), 'amalgm-auth-test-'));
|
|
12
12
|
fs.writeFileSync(path.join(amalgmDir, '.amalgm-credentials'), 'OPENAI_API_KEY=sk-test\n');
|
|
13
13
|
try {
|
|
14
|
+
const agentConfigId = 'debugging-agent';
|
|
14
15
|
const first = authEnvelope({
|
|
15
16
|
harness: 'codex',
|
|
16
17
|
authMethod: 'amalgm',
|
|
@@ -20,6 +21,7 @@ test('codex keeps legacy CLI home unless per-agent layout is explicit', () => {
|
|
|
20
21
|
proxyBaseUrl: 'https://proxy.example.test',
|
|
21
22
|
amalgmDir,
|
|
22
23
|
userId: 'user-123',
|
|
24
|
+
agentConfigId,
|
|
23
25
|
});
|
|
24
26
|
const second = authEnvelope({
|
|
25
27
|
harness: 'codex',
|
|
@@ -30,6 +32,7 @@ test('codex keeps legacy CLI home unless per-agent layout is explicit', () => {
|
|
|
30
32
|
proxyBaseUrl: 'https://proxy.example.test',
|
|
31
33
|
amalgmDir,
|
|
32
34
|
userId: 'user-123',
|
|
35
|
+
agentConfigId,
|
|
33
36
|
});
|
|
34
37
|
const third = authEnvelope({
|
|
35
38
|
harness: 'codex',
|
|
@@ -37,6 +40,7 @@ test('codex keeps legacy CLI home unless per-agent layout is explicit', () => {
|
|
|
37
40
|
sessionId: 'session-three',
|
|
38
41
|
amalgmDir,
|
|
39
42
|
userId: 'user-123',
|
|
43
|
+
agentConfigId,
|
|
40
44
|
});
|
|
41
45
|
const otherAgent = authEnvelope({
|
|
42
46
|
harness: 'codex',
|
|
@@ -49,31 +53,18 @@ test('codex keeps legacy CLI home unless per-agent layout is explicit', () => {
|
|
|
49
53
|
userId: 'user-123',
|
|
50
54
|
agentConfigId: 'agent-two',
|
|
51
55
|
});
|
|
52
|
-
const perAgent = authEnvelope({
|
|
53
|
-
harness: 'codex',
|
|
54
|
-
authMethod: 'provider_auth',
|
|
55
|
-
sessionId: 'session-five',
|
|
56
|
-
proxyToken: 'proxy-token-three',
|
|
57
|
-
localBaseUrl: 'http://127.0.0.1:8084',
|
|
58
|
-
proxyBaseUrl: 'https://proxy.example.test',
|
|
59
|
-
amalgmDir,
|
|
60
|
-
userId: 'user-123',
|
|
61
|
-
agentConfigId: 'agent-two',
|
|
62
|
-
runtimeHomeLayout: 'per-agent',
|
|
63
|
-
});
|
|
64
56
|
assert.notEqual(first.tokenFingerprint, second.tokenFingerprint);
|
|
65
57
|
assert.equal(first.runtimeHome, second.runtimeHome);
|
|
66
58
|
assert.equal(second.runtimeHome, third.runtimeHome);
|
|
67
|
-
assert.equal(first.runtimeHome, path.join(amalgmDir, 'cli-homes', 'codex', 'home'));
|
|
68
|
-
assert.equal(otherAgent.runtimeHome,
|
|
69
|
-
assert.
|
|
70
|
-
assert.notEqual(first.runtimeHome, perAgent.runtimeHome);
|
|
59
|
+
assert.equal(first.runtimeHome, path.join(amalgmDir, 'cli-homes', 'codex', 'agents', agentConfigId, 'home'));
|
|
60
|
+
assert.equal(otherAgent.runtimeHome, path.join(amalgmDir, 'cli-homes', 'codex', 'agents', 'agent-two', 'home'));
|
|
61
|
+
assert.notEqual(first.runtimeHome, otherAgent.runtimeHome);
|
|
71
62
|
} finally {
|
|
72
63
|
fs.rmSync(amalgmDir, { recursive: true, force: true });
|
|
73
64
|
}
|
|
74
65
|
});
|
|
75
66
|
|
|
76
|
-
test('opencode
|
|
67
|
+
test('opencode uses one stable per-agent CLI home across auth methods', () => {
|
|
77
68
|
const first = authEnvelope({
|
|
78
69
|
harness: 'opencode',
|
|
79
70
|
authMethod: 'amalgm',
|
|
@@ -98,15 +89,15 @@ test('opencode always uses one canonical CLI home across auth methods and token
|
|
|
98
89
|
|
|
99
90
|
assert.notEqual(first.tokenFingerprint, second.tokenFingerprint);
|
|
100
91
|
assert.equal(first.runtimeHome, second.runtimeHome);
|
|
101
|
-
assert.equal(first.runtimeHome, '/tmp/amalgm-test/cli-homes/opencode/home');
|
|
92
|
+
assert.equal(first.runtimeHome, '/tmp/amalgm-test/cli-homes/opencode/agents/opencode/home');
|
|
102
93
|
assert.equal(env.HOME, first.runtimeHome);
|
|
103
94
|
assert.equal(env.OPENCODE_HOME, first.runtimeHome);
|
|
104
95
|
assert.equal(env.OPENCODE_CONFIG_DIR, first.runtimeHome);
|
|
105
|
-
assert.equal(env.XDG_CONFIG_HOME, '/tmp/amalgm-test/cli-homes/opencode/home/.config');
|
|
106
|
-
assert.equal(env.XDG_DATA_HOME, '/tmp/amalgm-test/cli-homes/opencode/home/.local/share');
|
|
96
|
+
assert.equal(env.XDG_CONFIG_HOME, '/tmp/amalgm-test/cli-homes/opencode/agents/opencode/home/.config');
|
|
97
|
+
assert.equal(env.XDG_DATA_HOME, '/tmp/amalgm-test/cli-homes/opencode/agents/opencode/home/.local/share');
|
|
107
98
|
});
|
|
108
99
|
|
|
109
|
-
test('claude
|
|
100
|
+
test('claude uses one stable per-agent CLI home', () => {
|
|
110
101
|
const envelope = authEnvelope({
|
|
111
102
|
harness: 'claude_code',
|
|
112
103
|
authMethod: 'provider_auth',
|
|
@@ -114,7 +105,7 @@ test('claude always uses one canonical CLI home', () => {
|
|
|
114
105
|
amalgmDir: '/tmp/amalgm-test',
|
|
115
106
|
});
|
|
116
107
|
|
|
117
|
-
assert.equal(envelope.runtimeHome, '/tmp/amalgm-test/cli-homes/claude_code/home');
|
|
108
|
+
assert.equal(envelope.runtimeHome, '/tmp/amalgm-test/cli-homes/claude_code/agents/claude_code/home');
|
|
118
109
|
|
|
119
110
|
const env = runtimeEnv({
|
|
120
111
|
harness: 'claude_code',
|
|
@@ -146,5 +137,5 @@ test('provided CLI home path cannot move an agent off its canonical home', () =>
|
|
|
146
137
|
authProfileId: 'manual-profile',
|
|
147
138
|
});
|
|
148
139
|
|
|
149
|
-
assert.equal(envelope.runtimeHome, '/tmp/amalgm-test/cli-homes/codex/home');
|
|
140
|
+
assert.equal(envelope.runtimeHome, '/tmp/amalgm-test/cli-homes/codex/agents/codex/home');
|
|
150
141
|
});
|