@commonlyai/cli 0.1.172 → 0.1.173
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 +14 -4
- package/package.json +1 -1
- package/src/commands/agent.js +12 -6
- package/src/lib/handoff-memory.js +0 -23
package/README.md
CHANGED
|
@@ -33,11 +33,21 @@ Keep active-instance precedence separate from the newest-match fallback; back-to
|
|
|
33
33
|
A hosted agent's local handoff card includes `--memory-from <hosted-agent>` and
|
|
34
34
|
`--memory-instance <hosted-instance>` on the attach command. After login, attach
|
|
35
35
|
copies that source's long-term memory into the local identity before returning
|
|
36
|
-
its runnable configuration.
|
|
37
|
-
|
|
36
|
+
its runnable configuration. The source and target must belong to the logged-in
|
|
37
|
+
owner. No hosted runtime credential is moved.
|
|
38
38
|
|
|
39
39
|
This is a snapshot, not a shared identity or continuing synchronization. Attach
|
|
40
40
|
refuses to replace different existing local memory or copy into a non-private
|
|
41
|
-
long-term section.
|
|
42
|
-
|
|
41
|
+
long-term section. The install request completes memory authorization and the
|
|
42
|
+
revision-checked copy before joining the pod, creating an installation or posting
|
|
43
|
+
a greeting. A refused copy leaves those effects absent (an existing installation
|
|
44
|
+
is preserved). A later identity-creation or pod-join refusal can leave the copied
|
|
45
|
+
memory without an installation; retries recognize the snapshot as already copied.
|
|
46
|
+
The server claims the registry name before copying. On copy failure it releases
|
|
47
|
+
only the new, unchanged claim when no installation uses it; a claim touched by
|
|
48
|
+
another in-flight handoff is retained. Memory is not rolled back across later
|
|
49
|
+
identity or pod-join operations. Correct the error and
|
|
50
|
+
retry before running the local agent.
|
|
51
|
+
The CLI checks server support before publishing or installing; deploy the backend
|
|
52
|
+
with install-time handoff support before distributing the updated CLI. A retry resumes only your matching active local installation,
|
|
43
53
|
without changing its configuration or scopes. Repeating a copy with identical memory is safe.
|
package/package.json
CHANGED
package/src/commands/agent.js
CHANGED
|
@@ -22,7 +22,6 @@ import { createHash } from 'crypto';
|
|
|
22
22
|
|
|
23
23
|
import { requireSeatModel } from '../lib/adapters/seat-model.js';
|
|
24
24
|
import { createClient } from '../lib/api.js';
|
|
25
|
-
import { copyHandoffMemory } from '../lib/handoff-memory.js';
|
|
26
25
|
import {
|
|
27
26
|
buildSpawnId,
|
|
28
27
|
createSpawnCredentialLease,
|
|
@@ -987,6 +986,13 @@ export const performAttach = async ({
|
|
|
987
986
|
// server via legacy normalization).
|
|
988
987
|
const runtimeType = adapter.runtimeType || adapter.name;
|
|
989
988
|
|
|
989
|
+
if (memoryFrom) {
|
|
990
|
+
const capability = await client.get('/api/registry/install/memory-handoff');
|
|
991
|
+
if (capability?.installTimeMemoryHandoff !== true) {
|
|
992
|
+
throw new Error('Server does not support install-time memory handoff; upgrade the server before attaching');
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
990
996
|
// Idempotent publish — already-published is expected and fine. Install will
|
|
991
997
|
// surface the real error if the manifest is truly unusable.
|
|
992
998
|
try {
|
|
@@ -1010,7 +1016,9 @@ export const performAttach = async ({
|
|
|
1010
1016
|
// on config.environment so cross-driver implementations can realize it
|
|
1011
1017
|
// server-side without re-reading the user's file.
|
|
1012
1018
|
const installResult = await client.post('/api/registry/install', {
|
|
1013
|
-
...(memoryFrom ? {
|
|
1019
|
+
...(memoryFrom ? {
|
|
1020
|
+
resumeExisting: true, memoryFrom: { agentName: memoryFrom, instanceId: memoryInstance },
|
|
1021
|
+
} : {}),
|
|
1014
1022
|
agentName,
|
|
1015
1023
|
podId,
|
|
1016
1024
|
displayName: displayName || agentName,
|
|
@@ -1034,10 +1042,8 @@ export const performAttach = async ({
|
|
|
1034
1042
|
const instanceId = installation.instanceId || 'default';
|
|
1035
1043
|
|
|
1036
1044
|
if (memoryFrom) {
|
|
1037
|
-
const memoryCopy =
|
|
1038
|
-
|
|
1039
|
-
targetAgentName: installation.agentName, targetInstanceId: instanceId,
|
|
1040
|
-
});
|
|
1045
|
+
const memoryCopy = installResult.memoryCopy;
|
|
1046
|
+
if (!memoryCopy) throw new Error('Server does not support install-time memory handoff; upgrade the server before attaching');
|
|
1041
1047
|
log(memoryCopy.reason === 'source-empty'
|
|
1042
1048
|
? 'hosted agent has no long-term memory to copy'
|
|
1043
1049
|
: 'hosted long-term memory is present in the local agent');
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/** Copy only long-term memory using the logged-in owner's revision-checked API. */
|
|
2
|
-
export const copyHandoffMemory = async (client, {
|
|
3
|
-
sourceAgentName, sourceInstanceId = 'default', targetAgentName, targetInstanceId = 'default',
|
|
4
|
-
}) => {
|
|
5
|
-
const endpoint = (name, instance) => `/api/agent-memory/${encodeURIComponent(name)}/${encodeURIComponent(instance)}/editable`;
|
|
6
|
-
const source = await client.get(endpoint(sourceAgentName, sourceInstanceId));
|
|
7
|
-
const content = source?.sections?.long_term?.content;
|
|
8
|
-
if (typeof content !== 'string') throw new Error('Hosted memory response is missing long_term content');
|
|
9
|
-
if (!content) return { copied: false, reason: 'source-empty' };
|
|
10
|
-
const targetPath = endpoint(targetAgentName, targetInstanceId);
|
|
11
|
-
const target = await client.get(targetPath);
|
|
12
|
-
const prior = target?.sections?.long_term;
|
|
13
|
-
if (typeof prior?.content !== 'string') throw new Error('Local memory response is missing long_term content');
|
|
14
|
-
if (prior.visibility !== 'private') throw new Error('Local long-term memory must be private before copying hosted memory');
|
|
15
|
-
if (prior.content === content) return { copied: false, reason: 'already-copied' };
|
|
16
|
-
if (prior.content) throw new Error('Local agent already has different memory; choose a new local name');
|
|
17
|
-
// A concurrent first write wins rather than being overwritten by this copy.
|
|
18
|
-
await client.patch(`${targetPath}/long_term`, {
|
|
19
|
-
copyFrom: { agentName: sourceAgentName, instanceId: sourceInstanceId },
|
|
20
|
-
expectedUpdatedAt: prior.updatedAt ?? null,
|
|
21
|
-
});
|
|
22
|
-
return { copied: true };
|
|
23
|
-
};
|