lettactl 0.5.7 → 0.5.9
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/dist/commands/apply-template.d.ts +12 -0
- package/dist/commands/apply-template.d.ts.map +1 -0
- package/dist/commands/apply-template.js +118 -0
- package/dist/commands/apply-template.js.map +1 -0
- package/dist/commands/apply.d.ts.map +1 -1
- package/dist/commands/apply.js +42 -358
- package/dist/commands/apply.js.map +1 -1
- package/dist/lib/agent-manager.d.ts +0 -8
- package/dist/lib/agent-manager.d.ts.map +1 -1
- package/dist/lib/agent-manager.js +10 -58
- package/dist/lib/agent-manager.js.map +1 -1
- package/dist/lib/apply-helpers.d.ts +29 -0
- package/dist/lib/apply-helpers.d.ts.map +1 -0
- package/dist/lib/apply-helpers.js +224 -0
- package/dist/lib/apply-helpers.js.map +1 -0
- package/dist/lib/block-manager.d.ts +6 -29
- package/dist/lib/block-manager.d.ts.map +1 -1
- package/dist/lib/block-manager.js +76 -218
- package/dist/lib/block-manager.js.map +1 -1
- package/dist/lib/diff-analyzers.d.ts +17 -0
- package/dist/lib/diff-analyzers.d.ts.map +1 -0
- package/dist/lib/diff-analyzers.js +172 -0
- package/dist/lib/diff-analyzers.js.map +1 -0
- package/dist/lib/diff-applier.d.ts +27 -0
- package/dist/lib/diff-applier.d.ts.map +1 -0
- package/dist/lib/diff-applier.js +196 -0
- package/dist/lib/diff-applier.js.map +1 -0
- package/dist/lib/diff-engine.d.ts +0 -19
- package/dist/lib/diff-engine.d.ts.map +1 -1
- package/dist/lib/diff-engine.js +8 -359
- package/dist/lib/diff-engine.js.map +1 -1
- package/dist/lib/letta-client.d.ts +5 -0
- package/dist/lib/letta-client.d.ts.map +1 -1
- package/dist/lib/letta-client.js +3 -0
- package/dist/lib/letta-client.js.map +1 -1
- package/dist/utils/hash-utils.d.ts +9 -0
- package/dist/utils/hash-utils.d.ts.map +1 -0
- package/dist/utils/hash-utils.js +54 -0
- package/dist/utils/hash-utils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FleetParser } from '../lib/fleet-parser';
|
|
2
|
+
/**
|
|
3
|
+
* Template mode: apply a template config to all existing agents matching a glob pattern.
|
|
4
|
+
* Uses MERGE semantics - adds/updates resources but doesn't remove existing ones.
|
|
5
|
+
*/
|
|
6
|
+
export declare function applyTemplateMode(options: {
|
|
7
|
+
file: string;
|
|
8
|
+
match: string;
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
root?: string;
|
|
11
|
+
}, config: any, parser: FleetParser, command: any): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=apply-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-template.d.ts","sourceRoot":"","sources":["../../src/commands/apply-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASlD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACzE,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,GAAG,GACX,OAAO,CAAC,IAAI,CAAC,CA4Hf"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyTemplateMode = applyTemplateMode;
|
|
4
|
+
const letta_client_1 = require("../lib/letta-client");
|
|
5
|
+
const block_manager_1 = require("../lib/block-manager");
|
|
6
|
+
const diff_engine_1 = require("../lib/diff-engine");
|
|
7
|
+
const file_content_tracker_1 = require("../lib/file-content-tracker");
|
|
8
|
+
const output_formatter_1 = require("../lib/output-formatter");
|
|
9
|
+
const spinner_1 = require("../lib/spinner");
|
|
10
|
+
const minimatch_1 = require("minimatch");
|
|
11
|
+
/**
|
|
12
|
+
* Template mode: apply a template config to all existing agents matching a glob pattern.
|
|
13
|
+
* Uses MERGE semantics - adds/updates resources but doesn't remove existing ones.
|
|
14
|
+
*/
|
|
15
|
+
async function applyTemplateMode(options, config, parser, command) {
|
|
16
|
+
const verbose = command.parent?.opts().verbose || false;
|
|
17
|
+
const spinnerEnabled = (0, spinner_1.getSpinnerEnabled)(command);
|
|
18
|
+
const pattern = options.match;
|
|
19
|
+
const findSpinner = (0, spinner_1.createSpinner)(`Finding agents matching "${pattern}"...`, spinnerEnabled).start();
|
|
20
|
+
// Get all agents from server
|
|
21
|
+
const client = new letta_client_1.LettaClientWrapper();
|
|
22
|
+
const allAgentsResponse = await client.listAgents();
|
|
23
|
+
const allAgents = Array.isArray(allAgentsResponse)
|
|
24
|
+
? allAgentsResponse
|
|
25
|
+
: allAgentsResponse.items || [];
|
|
26
|
+
// Filter by glob pattern
|
|
27
|
+
const matchingAgents = allAgents.filter((agent) => (0, minimatch_1.minimatch)(agent.name, pattern));
|
|
28
|
+
if (matchingAgents.length === 0) {
|
|
29
|
+
findSpinner.fail(`No agents found matching pattern: ${pattern}`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
findSpinner.succeed(`Found ${matchingAgents.length} agents matching "${pattern}"`);
|
|
33
|
+
matchingAgents.forEach((a) => console.log(` - ${a.name}`));
|
|
34
|
+
if (options.dryRun) {
|
|
35
|
+
console.log('\nDry-run mode: no changes will be made');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Initialize managers
|
|
39
|
+
const blockManager = new block_manager_1.BlockManager(client);
|
|
40
|
+
const diffEngine = new diff_engine_1.DiffEngine(client, blockManager, parser.basePath);
|
|
41
|
+
const fileTracker = new file_content_tracker_1.FileContentTracker(parser.basePath, parser.storageBackend);
|
|
42
|
+
const createdFolders = new Map();
|
|
43
|
+
await blockManager.loadExistingBlocks();
|
|
44
|
+
// Process shared blocks from template
|
|
45
|
+
const sharedBlockIds = new Map();
|
|
46
|
+
if (config.shared_blocks?.length) {
|
|
47
|
+
const blockSpinner = (0, spinner_1.createSpinner)('Processing shared blocks...', spinnerEnabled).start();
|
|
48
|
+
for (const sharedBlock of config.shared_blocks) {
|
|
49
|
+
const blockId = await blockManager.getOrCreateSharedBlock(sharedBlock);
|
|
50
|
+
sharedBlockIds.set(sharedBlock.name, blockId);
|
|
51
|
+
if (verbose)
|
|
52
|
+
console.log(` ${sharedBlock.name} -> ${blockId}`);
|
|
53
|
+
}
|
|
54
|
+
blockSpinner.succeed(`Processed ${config.shared_blocks.length} shared blocks`);
|
|
55
|
+
}
|
|
56
|
+
// Get template agent config (first agent in config, or use top-level values)
|
|
57
|
+
const templateAgent = config.agents?.[0];
|
|
58
|
+
const templateTools = templateAgent?.tools || [];
|
|
59
|
+
const templateSharedBlocks = templateAgent?.shared_blocks || [];
|
|
60
|
+
// Generate tool source hashes and register tools
|
|
61
|
+
const toolSourceHashes = fileTracker.generateToolSourceHashes(templateTools, parser.toolConfigs);
|
|
62
|
+
const toolNameToId = await parser.registerRequiredTools(config, client, verbose, toolSourceHashes);
|
|
63
|
+
// Apply template to each matching agent
|
|
64
|
+
for (const existingAgent of matchingAgents) {
|
|
65
|
+
const agentSpinner = (0, spinner_1.createSpinner)(`Analyzing ${existingAgent.name}...`, spinnerEnabled).start();
|
|
66
|
+
try {
|
|
67
|
+
// Build desired config from template (no memoryBlocks - those are instance-specific)
|
|
68
|
+
const desiredConfig = {
|
|
69
|
+
systemPrompt: templateAgent?.system_prompt?.value || '',
|
|
70
|
+
tools: templateTools,
|
|
71
|
+
toolSourceHashes,
|
|
72
|
+
sharedBlocks: templateSharedBlocks,
|
|
73
|
+
};
|
|
74
|
+
// Create minimal AgentVersion for diff engine
|
|
75
|
+
const agentVersion = {
|
|
76
|
+
id: existingAgent.id,
|
|
77
|
+
name: existingAgent.name,
|
|
78
|
+
baseName: existingAgent.name,
|
|
79
|
+
configHashes: { overall: '', systemPrompt: '', tools: '', model: '', memoryBlocks: '', folders: '', sharedBlocks: '' },
|
|
80
|
+
version: 'latest',
|
|
81
|
+
lastUpdated: existingAgent.updated_at || new Date().toISOString()
|
|
82
|
+
};
|
|
83
|
+
// Generate update operations
|
|
84
|
+
const ops = await diffEngine.generateUpdateOperations(agentVersion, desiredConfig, toolNameToId, createdFolders, verbose, sharedBlockIds);
|
|
85
|
+
// MERGE semantics: clear toRemove arrays (don't remove existing resources)
|
|
86
|
+
if (ops.tools)
|
|
87
|
+
ops.tools.toRemove = [];
|
|
88
|
+
if (ops.blocks)
|
|
89
|
+
ops.blocks.toRemove = [];
|
|
90
|
+
if (ops.folders)
|
|
91
|
+
ops.folders.toDetach = [];
|
|
92
|
+
// Recalculate operation count after filtering
|
|
93
|
+
ops.operationCount = 0;
|
|
94
|
+
if (ops.updateFields)
|
|
95
|
+
ops.operationCount += Object.keys(ops.updateFields).length;
|
|
96
|
+
if (ops.tools)
|
|
97
|
+
ops.operationCount += ops.tools.toAdd.length + ops.tools.toUpdate.length;
|
|
98
|
+
if (ops.blocks)
|
|
99
|
+
ops.operationCount += ops.blocks.toAdd.length + ops.blocks.toUpdate.length;
|
|
100
|
+
if (ops.folders)
|
|
101
|
+
ops.operationCount += ops.folders.toAttach.length;
|
|
102
|
+
if (ops.operationCount === 0) {
|
|
103
|
+
agentSpinner.succeed(`${existingAgent.name}: already up to date`);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
agentSpinner.stop();
|
|
107
|
+
output_formatter_1.OutputFormatter.showAgentUpdateDiff(ops);
|
|
108
|
+
const updateSpinner = (0, spinner_1.createSpinner)(`Applying updates to ${existingAgent.name}...`, spinnerEnabled).start();
|
|
109
|
+
await diffEngine.applyUpdateOperations(existingAgent.id, ops, verbose);
|
|
110
|
+
updateSpinner.succeed(`${existingAgent.name}: updated successfully`);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
agentSpinner.fail(`${existingAgent.name}: ${error.message}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
console.log('\nTemplate apply completed');
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=apply-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-template.js","sourceRoot":"","sources":["../../src/commands/apply-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,EAAE,GAAG,iBAiL1I"}
|
package/dist/commands/apply.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.applyCommand = applyCommand;
|
|
37
4
|
const fleet_parser_1 = require("../lib/fleet-parser");
|
|
@@ -40,12 +7,10 @@ const block_manager_1 = require("../lib/block-manager");
|
|
|
40
7
|
const agent_manager_1 = require("../lib/agent-manager");
|
|
41
8
|
const diff_engine_1 = require("../lib/diff-engine");
|
|
42
9
|
const file_content_tracker_1 = require("../lib/file-content-tracker");
|
|
43
|
-
const output_formatter_1 = require("../lib/output-formatter");
|
|
44
10
|
const spinner_1 = require("../lib/spinner");
|
|
45
11
|
const storage_backend_1 = require("../lib/storage-backend");
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const path = __importStar(require("path"));
|
|
12
|
+
const apply_template_1 = require("./apply-template");
|
|
13
|
+
const apply_helpers_1 = require("../lib/apply-helpers");
|
|
49
14
|
async function applyCommand(options, command) {
|
|
50
15
|
const verbose = command.parent?.opts().verbose || false;
|
|
51
16
|
try {
|
|
@@ -78,7 +43,7 @@ async function applyCommand(options, command) {
|
|
|
78
43
|
console.log(`Found ${config.agents.length} agents in configuration`);
|
|
79
44
|
// Template mode: apply config to existing agents matching pattern
|
|
80
45
|
if (options.match) {
|
|
81
|
-
await applyTemplateMode({ ...options, match: options.match }, config, parser, command);
|
|
46
|
+
await (0, apply_template_1.applyTemplateMode)({ ...options, match: options.match }, config, parser, command);
|
|
82
47
|
return;
|
|
83
48
|
}
|
|
84
49
|
if (options.dryRun) {
|
|
@@ -97,25 +62,16 @@ async function applyCommand(options, command) {
|
|
|
97
62
|
const agentManager = new agent_manager_1.AgentManager(client);
|
|
98
63
|
const diffEngine = new diff_engine_1.DiffEngine(client, blockManager, parser.basePath);
|
|
99
64
|
const fileTracker = new file_content_tracker_1.FileContentTracker(parser.basePath, parser.storageBackend);
|
|
100
|
-
|
|
101
|
-
// Load existing resources for versioning
|
|
65
|
+
// Load existing resources
|
|
102
66
|
if (verbose)
|
|
103
67
|
console.log('Loading existing blocks...');
|
|
104
68
|
await blockManager.loadExistingBlocks();
|
|
105
69
|
if (verbose)
|
|
106
70
|
console.log('Loading existing agents...');
|
|
107
71
|
await agentManager.loadExistingAgents();
|
|
108
|
-
// Process shared blocks
|
|
109
|
-
const sharedBlockIds =
|
|
110
|
-
|
|
111
|
-
if (verbose)
|
|
112
|
-
console.log('Processing shared blocks...');
|
|
113
|
-
for (const sharedBlock of config.shared_blocks) {
|
|
114
|
-
const blockId = await blockManager.getOrCreateSharedBlock(sharedBlock);
|
|
115
|
-
sharedBlockIds.set(sharedBlock.name, blockId);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Generate tool source hashes for all tools in config
|
|
72
|
+
// Process shared blocks
|
|
73
|
+
const sharedBlockIds = await (0, apply_helpers_1.processSharedBlocks)(config, blockManager, verbose);
|
|
74
|
+
// Generate tool source hashes and register tools
|
|
119
75
|
const allToolNames = new Set();
|
|
120
76
|
for (const agent of config.agents) {
|
|
121
77
|
for (const toolName of agent.tools || []) {
|
|
@@ -123,69 +79,13 @@ async function applyCommand(options, command) {
|
|
|
123
79
|
}
|
|
124
80
|
}
|
|
125
81
|
const globalToolSourceHashes = fileTracker.generateToolSourceHashes(Array.from(allToolNames), parser.toolConfigs);
|
|
126
|
-
// Register required tools
|
|
127
82
|
if (verbose)
|
|
128
83
|
console.log('Registering tools...');
|
|
129
84
|
const toolNameToId = await parser.registerRequiredTools(config, client, verbose, globalToolSourceHashes);
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
const existingFolders = Array.isArray(foldersResponse) ? foldersResponse : foldersResponse.items || [];
|
|
135
|
-
for (const agent of config.agents) {
|
|
136
|
-
if (options.agent && !agent.name.includes(options.agent))
|
|
137
|
-
continue;
|
|
138
|
-
if (agent.folders) {
|
|
139
|
-
for (const folderConfig of agent.folders) {
|
|
140
|
-
if (createdFolders.has(folderConfig.name)) {
|
|
141
|
-
if (verbose)
|
|
142
|
-
console.log(`Using existing folder: ${folderConfig.name}`);
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
// Check if folder already exists
|
|
146
|
-
let folder = existingFolders.find((f) => f.name === folderConfig.name);
|
|
147
|
-
if (!folder) {
|
|
148
|
-
if (verbose)
|
|
149
|
-
console.log(`Creating folder: ${folderConfig.name}`);
|
|
150
|
-
folder = await client.createFolder({
|
|
151
|
-
name: folderConfig.name,
|
|
152
|
-
embedding: agent.embedding || "letta/letta-free"
|
|
153
|
-
});
|
|
154
|
-
console.log(`Created folder: ${folderConfig.name}`);
|
|
155
|
-
createdFolders.set(folderConfig.name, folder.id);
|
|
156
|
-
// Upload files only to newly created folders
|
|
157
|
-
if (verbose)
|
|
158
|
-
console.log(`Uploading ${folderConfig.files.length} files...`);
|
|
159
|
-
for (const filePath of folderConfig.files) {
|
|
160
|
-
try {
|
|
161
|
-
const resolvedPath = path.resolve(parser.basePath, filePath);
|
|
162
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
163
|
-
console.warn(`File not found, skipping: ${filePath}`);
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
if (verbose)
|
|
167
|
-
console.log(` Uploading ${filePath}...`);
|
|
168
|
-
const fileStream = fs.createReadStream(resolvedPath);
|
|
169
|
-
await client.uploadFileToFolder(fileStream, folder.id, path.basename(filePath));
|
|
170
|
-
if (verbose)
|
|
171
|
-
console.log(` Uploaded: ${filePath}`);
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
console.error(` Failed to upload ${filePath}:`, error.message);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
if (verbose)
|
|
180
|
-
console.log(`Using existing folder: ${folderConfig.name}`);
|
|
181
|
-
if (verbose)
|
|
182
|
-
console.log(' (Skipping file upload - files already exist)');
|
|
183
|
-
createdFolders.set(folderConfig.name, folder.id);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
// Create agents with memory blocks
|
|
85
|
+
// Process folders
|
|
86
|
+
const createdFolders = await (0, apply_helpers_1.processFolders)(config, client, parser, options, verbose);
|
|
87
|
+
// Process agents
|
|
88
|
+
const spinnerEnabled = (0, spinner_1.getSpinnerEnabled)(command);
|
|
189
89
|
if (verbose)
|
|
190
90
|
console.log('Processing agents...');
|
|
191
91
|
for (const agent of config.agents) {
|
|
@@ -199,177 +99,68 @@ async function applyCommand(options, command) {
|
|
|
199
99
|
console.log(` Folders: ${agent.folders?.length || 0}`);
|
|
200
100
|
}
|
|
201
101
|
try {
|
|
202
|
-
// Generate
|
|
102
|
+
// Generate hashes for change detection
|
|
203
103
|
const folderContentHashes = fileTracker.generateFolderFileHashes(agent.folders || []);
|
|
204
|
-
// Generate tool source code hashes for change detection
|
|
205
104
|
const toolSourceHashes = fileTracker.generateToolSourceHashes(agent.tools || [], parser.toolConfigs);
|
|
206
|
-
// Generate memory block file content hashes for change detection
|
|
207
105
|
const memoryBlockFileHashes = await fileTracker.generateMemoryBlockFileHashes(agent.memory_blocks || []);
|
|
208
|
-
//
|
|
209
|
-
const
|
|
106
|
+
// Build agent config
|
|
107
|
+
const agentConfig = {
|
|
210
108
|
systemPrompt: agent.system_prompt.value || '',
|
|
211
109
|
tools: agent.tools || [],
|
|
212
110
|
toolSourceHashes,
|
|
213
111
|
model: agent.llm_config?.model,
|
|
214
112
|
embedding: agent.embedding,
|
|
215
113
|
contextWindow: agent.llm_config?.context_window,
|
|
216
|
-
memoryBlocks: (agent.memory_blocks || []).map(block => ({
|
|
114
|
+
memoryBlocks: (agent.memory_blocks || []).map((block) => ({
|
|
217
115
|
name: block.name,
|
|
218
116
|
description: block.description,
|
|
219
117
|
limit: block.limit,
|
|
220
118
|
value: block.value || ''
|
|
221
119
|
})),
|
|
222
120
|
memoryBlockFileHashes,
|
|
223
|
-
folders: (agent.folders || []).map(folder => ({
|
|
121
|
+
folders: (agent.folders || []).map((folder) => ({
|
|
224
122
|
name: folder.name,
|
|
225
123
|
files: folder.files,
|
|
226
124
|
fileContentHashes: folderContentHashes.get(folder.name) || {}
|
|
227
125
|
})),
|
|
228
126
|
sharedBlocks: agent.shared_blocks || []
|
|
229
|
-
}
|
|
127
|
+
};
|
|
128
|
+
// Check if agent exists
|
|
129
|
+
const { agentName, shouldCreate, existingAgent } = await agentManager.getOrCreateAgentName(agent.name, agentConfig, verbose);
|
|
230
130
|
if (!shouldCreate && existingAgent) {
|
|
231
|
-
//
|
|
232
|
-
const agentConfig = {
|
|
233
|
-
systemPrompt: agent.system_prompt.value || '',
|
|
234
|
-
tools: agent.tools || [],
|
|
235
|
-
toolSourceHashes,
|
|
236
|
-
model: agent.llm_config?.model,
|
|
237
|
-
embedding: agent.embedding,
|
|
238
|
-
contextWindow: agent.llm_config?.context_window,
|
|
239
|
-
memoryBlocks: (agent.memory_blocks || []).map(block => ({
|
|
240
|
-
name: block.name,
|
|
241
|
-
description: block.description,
|
|
242
|
-
limit: block.limit,
|
|
243
|
-
value: block.value || ''
|
|
244
|
-
})),
|
|
245
|
-
memoryBlockFileHashes,
|
|
246
|
-
folders: (agent.folders || []).map(folder => ({
|
|
247
|
-
name: folder.name,
|
|
248
|
-
files: folder.files,
|
|
249
|
-
fileContentHashes: folderContentHashes.get(folder.name) || {}
|
|
250
|
-
})),
|
|
251
|
-
sharedBlocks: agent.shared_blocks || []
|
|
252
|
-
};
|
|
253
|
-
// Check if any granular changes are needed
|
|
131
|
+
// Check if changes needed
|
|
254
132
|
const changes = agentManager.getConfigChanges(existingAgent, agentConfig);
|
|
255
133
|
if (!changes.hasChanges) {
|
|
256
134
|
console.log(`Agent ${agent.name} already exists and is up to date`);
|
|
257
135
|
continue;
|
|
258
136
|
}
|
|
259
|
-
//
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const updateSpinner = (0, spinner_1.createSpinner)(`Applying updates to ${agent.name}...`, spinnerEnabled).start();
|
|
269
|
-
await diffEngine.applyUpdateOperations(existingAgent.id, updateOperations, verbose);
|
|
270
|
-
// Update registry with new hashes
|
|
271
|
-
agentManager.updateRegistry(existingAgent.name, agentConfig, existingAgent.id);
|
|
272
|
-
updateSpinner.succeed(`Agent ${agent.name} updated successfully (conversation history preserved)`);
|
|
273
|
-
}
|
|
274
|
-
catch (error) {
|
|
275
|
-
spinner.fail(`Failed to update agent ${agent.name}`);
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
// Collect all block IDs (shared + agent-specific)
|
|
281
|
-
const blockIds = [];
|
|
282
|
-
// Add shared blocks for this agent
|
|
283
|
-
if (agent.shared_blocks) {
|
|
284
|
-
for (const sharedBlockName of agent.shared_blocks) {
|
|
285
|
-
const sharedBlockId = sharedBlockIds.get(sharedBlockName);
|
|
286
|
-
if (sharedBlockId) {
|
|
287
|
-
blockIds.push(sharedBlockId);
|
|
288
|
-
if (verbose)
|
|
289
|
-
console.log(` Using shared block: ${sharedBlockName}`);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
console.warn(` Shared block not found: ${sharedBlockName}`);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// Create agent-specific memory blocks
|
|
297
|
-
if (agent.memory_blocks) {
|
|
298
|
-
for (const block of agent.memory_blocks) {
|
|
299
|
-
if (verbose)
|
|
300
|
-
console.log(` Processing memory block: ${block.name}`);
|
|
301
|
-
const blockId = await blockManager.getOrCreateAgentBlock(block, agent.name);
|
|
302
|
-
blockIds.push(blockId);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
// Create agent
|
|
306
|
-
const creationSpinner = (0, spinner_1.createSpinner)(`Creating agent ${agentName}...`, (0, spinner_1.getSpinnerEnabled)(command)).start();
|
|
307
|
-
try {
|
|
308
|
-
// Resolve tool names to IDs
|
|
309
|
-
const toolIds = [];
|
|
310
|
-
if (agent.tools) {
|
|
311
|
-
for (const toolName of agent.tools) {
|
|
312
|
-
const toolId = toolNameToId.get(toolName);
|
|
313
|
-
if (toolId) {
|
|
314
|
-
toolIds.push(toolId);
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
console.warn(` Tool not found: ${toolName}`);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
const createdAgent = await client.createAgent({
|
|
322
|
-
name: agentName,
|
|
323
|
-
model: agent.llm_config?.model || "google_ai/gemini-2.5-pro",
|
|
324
|
-
embedding: agent.embedding || "letta/letta-free",
|
|
325
|
-
system: agent.system_prompt.value || '',
|
|
326
|
-
block_ids: blockIds,
|
|
327
|
-
context_window_limit: agent.llm_config?.context_window || 64000
|
|
137
|
+
// Update existing agent
|
|
138
|
+
await (0, apply_helpers_1.updateExistingAgent)(agent, existingAgent, agentConfig, {
|
|
139
|
+
diffEngine,
|
|
140
|
+
agentManager,
|
|
141
|
+
toolNameToId,
|
|
142
|
+
createdFolders,
|
|
143
|
+
sharedBlockIds,
|
|
144
|
+
spinnerEnabled,
|
|
145
|
+
verbose
|
|
328
146
|
});
|
|
329
|
-
// Attach tools after agent creation (same as update path)
|
|
330
|
-
for (const toolId of toolIds) {
|
|
331
|
-
if (verbose)
|
|
332
|
-
console.log(` Attaching tool: ${toolId}`);
|
|
333
|
-
await client.attachToolToAgent(createdAgent.id, toolId);
|
|
334
|
-
}
|
|
335
|
-
// Update agent registry with new agent
|
|
336
|
-
agentManager.updateRegistry(agentName, {
|
|
337
|
-
systemPrompt: agent.system_prompt.value || '',
|
|
338
|
-
tools: agent.tools || [],
|
|
339
|
-
model: agent.llm_config?.model,
|
|
340
|
-
embedding: agent.embedding,
|
|
341
|
-
contextWindow: agent.llm_config?.context_window,
|
|
342
|
-
memoryBlocks: (agent.memory_blocks || []).map(block => ({
|
|
343
|
-
name: block.name,
|
|
344
|
-
description: block.description,
|
|
345
|
-
limit: block.limit,
|
|
346
|
-
value: block.value || ''
|
|
347
|
-
})),
|
|
348
|
-
folders: agent.folders || [],
|
|
349
|
-
sharedBlocks: agent.shared_blocks || []
|
|
350
|
-
}, createdAgent.id);
|
|
351
|
-
// Attach folders to agent
|
|
352
|
-
if (agent.folders) {
|
|
353
|
-
for (const folderConfig of agent.folders) {
|
|
354
|
-
const folderId = createdFolders.get(folderConfig.name);
|
|
355
|
-
if (folderId) {
|
|
356
|
-
if (verbose)
|
|
357
|
-
console.log(` Attaching folder ${folderConfig.name}`);
|
|
358
|
-
await client.attachFolderToAgent(createdAgent.id, folderId);
|
|
359
|
-
if (verbose)
|
|
360
|
-
console.log(` Folder attached`);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
creationSpinner.succeed(`Agent ${agentName} created successfully`);
|
|
365
147
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
148
|
+
else {
|
|
149
|
+
// Create new agent
|
|
150
|
+
await (0, apply_helpers_1.createNewAgent)(agent, agentName, {
|
|
151
|
+
client,
|
|
152
|
+
blockManager,
|
|
153
|
+
agentManager,
|
|
154
|
+
toolNameToId,
|
|
155
|
+
createdFolders,
|
|
156
|
+
sharedBlockIds,
|
|
157
|
+
spinnerEnabled,
|
|
158
|
+
verbose
|
|
159
|
+
});
|
|
369
160
|
}
|
|
370
161
|
}
|
|
371
162
|
catch (error) {
|
|
372
|
-
console.error(`Failed to
|
|
163
|
+
console.error(`Failed to process agent ${agent.name}:`, error.message);
|
|
373
164
|
throw error;
|
|
374
165
|
}
|
|
375
166
|
}
|
|
@@ -380,111 +171,4 @@ async function applyCommand(options, command) {
|
|
|
380
171
|
process.exit(1);
|
|
381
172
|
}
|
|
382
173
|
}
|
|
383
|
-
/**
|
|
384
|
-
* Template mode: apply a template config to all existing agents matching a glob pattern.
|
|
385
|
-
* Uses MERGE semantics - adds/updates resources but doesn't remove existing ones.
|
|
386
|
-
*/
|
|
387
|
-
async function applyTemplateMode(options, config, parser, command) {
|
|
388
|
-
const verbose = command.parent?.opts().verbose || false;
|
|
389
|
-
const spinnerEnabled = (0, spinner_1.getSpinnerEnabled)(command);
|
|
390
|
-
const pattern = options.match;
|
|
391
|
-
const findSpinner = (0, spinner_1.createSpinner)(`Finding agents matching "${pattern}"...`, spinnerEnabled).start();
|
|
392
|
-
// Get all agents from server
|
|
393
|
-
const client = new letta_client_1.LettaClientWrapper();
|
|
394
|
-
const allAgentsResponse = await client.listAgents();
|
|
395
|
-
const allAgents = Array.isArray(allAgentsResponse)
|
|
396
|
-
? allAgentsResponse
|
|
397
|
-
: allAgentsResponse.items || [];
|
|
398
|
-
// Filter by glob pattern
|
|
399
|
-
const matchingAgents = allAgents.filter((agent) => (0, minimatch_1.minimatch)(agent.name, pattern));
|
|
400
|
-
if (matchingAgents.length === 0) {
|
|
401
|
-
findSpinner.fail(`No agents found matching pattern: ${pattern}`);
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
findSpinner.succeed(`Found ${matchingAgents.length} agents matching "${pattern}"`);
|
|
405
|
-
matchingAgents.forEach((a) => console.log(` - ${a.name}`));
|
|
406
|
-
if (options.dryRun) {
|
|
407
|
-
console.log('\nDry-run mode: no changes will be made');
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
// Initialize managers
|
|
411
|
-
const blockManager = new block_manager_1.BlockManager(client);
|
|
412
|
-
const diffEngine = new diff_engine_1.DiffEngine(client, blockManager, parser.basePath);
|
|
413
|
-
const fileTracker = new file_content_tracker_1.FileContentTracker(parser.basePath, parser.storageBackend);
|
|
414
|
-
const createdFolders = new Map();
|
|
415
|
-
await blockManager.loadExistingBlocks();
|
|
416
|
-
// Process shared blocks from template
|
|
417
|
-
const sharedBlockIds = new Map();
|
|
418
|
-
if (config.shared_blocks?.length) {
|
|
419
|
-
const blockSpinner = (0, spinner_1.createSpinner)('Processing shared blocks...', spinnerEnabled).start();
|
|
420
|
-
for (const sharedBlock of config.shared_blocks) {
|
|
421
|
-
const blockId = await blockManager.getOrCreateSharedBlock(sharedBlock);
|
|
422
|
-
sharedBlockIds.set(sharedBlock.name, blockId);
|
|
423
|
-
if (verbose)
|
|
424
|
-
console.log(` ${sharedBlock.name} -> ${blockId}`);
|
|
425
|
-
}
|
|
426
|
-
blockSpinner.succeed(`Processed ${config.shared_blocks.length} shared blocks`);
|
|
427
|
-
}
|
|
428
|
-
// Get template agent config (first agent in config, or use top-level values)
|
|
429
|
-
const templateAgent = config.agents?.[0];
|
|
430
|
-
const templateTools = templateAgent?.tools || [];
|
|
431
|
-
const templateSharedBlocks = templateAgent?.shared_blocks || [];
|
|
432
|
-
// Generate tool source hashes and register tools
|
|
433
|
-
const toolSourceHashes = fileTracker.generateToolSourceHashes(templateTools, parser.toolConfigs);
|
|
434
|
-
const toolNameToId = await parser.registerRequiredTools(config, client, verbose, toolSourceHashes);
|
|
435
|
-
// Apply template to each matching agent
|
|
436
|
-
for (const existingAgent of matchingAgents) {
|
|
437
|
-
const agentSpinner = (0, spinner_1.createSpinner)(`Analyzing ${existingAgent.name}...`, spinnerEnabled).start();
|
|
438
|
-
try {
|
|
439
|
-
// Build desired config from template (no memoryBlocks - those are instance-specific)
|
|
440
|
-
const desiredConfig = {
|
|
441
|
-
systemPrompt: templateAgent?.system_prompt?.value || '',
|
|
442
|
-
tools: templateTools,
|
|
443
|
-
toolSourceHashes,
|
|
444
|
-
sharedBlocks: templateSharedBlocks,
|
|
445
|
-
};
|
|
446
|
-
// Create minimal AgentVersion for diff engine
|
|
447
|
-
const agentVersion = {
|
|
448
|
-
id: existingAgent.id,
|
|
449
|
-
name: existingAgent.name,
|
|
450
|
-
baseName: existingAgent.name,
|
|
451
|
-
configHashes: { overall: '', systemPrompt: '', tools: '', model: '', memoryBlocks: '', folders: '', sharedBlocks: '' },
|
|
452
|
-
version: 'latest',
|
|
453
|
-
lastUpdated: existingAgent.updated_at || new Date().toISOString()
|
|
454
|
-
};
|
|
455
|
-
// Generate update operations
|
|
456
|
-
const ops = await diffEngine.generateUpdateOperations(agentVersion, desiredConfig, toolNameToId, createdFolders, verbose, sharedBlockIds);
|
|
457
|
-
// MERGE semantics: clear toRemove arrays (don't remove existing resources)
|
|
458
|
-
if (ops.tools)
|
|
459
|
-
ops.tools.toRemove = [];
|
|
460
|
-
if (ops.blocks)
|
|
461
|
-
ops.blocks.toRemove = [];
|
|
462
|
-
if (ops.folders)
|
|
463
|
-
ops.folders.toDetach = [];
|
|
464
|
-
// Recalculate operation count after filtering
|
|
465
|
-
ops.operationCount = 0;
|
|
466
|
-
if (ops.updateFields)
|
|
467
|
-
ops.operationCount += Object.keys(ops.updateFields).length;
|
|
468
|
-
if (ops.tools)
|
|
469
|
-
ops.operationCount += ops.tools.toAdd.length + ops.tools.toUpdate.length;
|
|
470
|
-
if (ops.blocks)
|
|
471
|
-
ops.operationCount += ops.blocks.toAdd.length + ops.blocks.toUpdate.length;
|
|
472
|
-
if (ops.folders)
|
|
473
|
-
ops.operationCount += ops.folders.toAttach.length;
|
|
474
|
-
if (ops.operationCount === 0) {
|
|
475
|
-
agentSpinner.succeed(`${existingAgent.name}: already up to date`);
|
|
476
|
-
continue;
|
|
477
|
-
}
|
|
478
|
-
agentSpinner.stop();
|
|
479
|
-
output_formatter_1.OutputFormatter.showAgentUpdateDiff(ops);
|
|
480
|
-
const updateSpinner = (0, spinner_1.createSpinner)(`Applying updates to ${existingAgent.name}...`, spinnerEnabled).start();
|
|
481
|
-
await diffEngine.applyUpdateOperations(existingAgent.id, ops, verbose);
|
|
482
|
-
updateSpinner.succeed(`${existingAgent.name}: updated successfully`);
|
|
483
|
-
}
|
|
484
|
-
catch (error) {
|
|
485
|
-
agentSpinner.fail(`${existingAgent.name}: ${error.message}`);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
console.log('\nTemplate apply completed');
|
|
489
|
-
}
|
|
490
174
|
//# sourceMappingURL=apply.js.map
|