@orchagent/cli 0.3.91 → 0.3.93
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/diff-format.js +300 -0
- package/dist/commands/diff.js +2 -129
- package/dist/commands/health.js +90 -7
- package/dist/commands/index.js +4 -0
- package/dist/commands/init-wizard.js +129 -64
- package/dist/commands/init.js +71 -1
- package/dist/commands/publish.js +74 -66
- package/dist/commands/run.js +107 -29
- package/dist/commands/scaffold.js +213 -0
- package/dist/commands/schedule.js +40 -3
- package/dist/commands/templates/cron-job.js +259 -0
- package/dist/commands/update.js +46 -9
- package/dist/commands/validate.js +264 -0
- package/dist/lib/scaffold-orchestration.js +237 -0
- package/dist/lib/validate.js +478 -0
- package/package.json +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dependencyRef = dependencyRef;
|
|
4
|
+
exports.validateScaffoldAgentName = validateScaffoldAgentName;
|
|
5
|
+
exports.dedupeOrchestrationDependencies = dedupeOrchestrationDependencies;
|
|
6
|
+
exports.buildOrchestrationCustomTools = buildOrchestrationCustomTools;
|
|
7
|
+
exports.buildOrchestrationManifest = buildOrchestrationManifest;
|
|
8
|
+
exports.buildOrchestrationPrompt = buildOrchestrationPrompt;
|
|
9
|
+
exports.buildOrchestrationSchema = buildOrchestrationSchema;
|
|
10
|
+
const BUILTIN_TOOL_NAMES = new Set([
|
|
11
|
+
'bash',
|
|
12
|
+
'read_file',
|
|
13
|
+
'write_file',
|
|
14
|
+
'list_files',
|
|
15
|
+
'submit_result',
|
|
16
|
+
]);
|
|
17
|
+
const DEFAULT_MAX_TURNS = 25;
|
|
18
|
+
const DEFAULT_TIMEOUT_MS = 180000;
|
|
19
|
+
const DEFAULT_PER_CALL_DOWNSTREAM_CAP = 50;
|
|
20
|
+
function dependencyId(dep) {
|
|
21
|
+
return `${dep.org}/${dep.name}`;
|
|
22
|
+
}
|
|
23
|
+
function dependencyRef(dep) {
|
|
24
|
+
return `${dependencyId(dep)}@${dep.version}`;
|
|
25
|
+
}
|
|
26
|
+
function sanitizeToolToken(value) {
|
|
27
|
+
const token = value
|
|
28
|
+
.trim()
|
|
29
|
+
.toLowerCase()
|
|
30
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
31
|
+
.replace(/^_+|_+$/g, '');
|
|
32
|
+
return token || 'dependency';
|
|
33
|
+
}
|
|
34
|
+
function defaultToolInputSchema() {
|
|
35
|
+
return {
|
|
36
|
+
type: 'object',
|
|
37
|
+
description: 'JSON payload forwarded to the dependency agent',
|
|
38
|
+
additionalProperties: true,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function normalizeToolInputSchema(inputSchema) {
|
|
42
|
+
if (!inputSchema || typeof inputSchema !== 'object' || Array.isArray(inputSchema)) {
|
|
43
|
+
return defaultToolInputSchema();
|
|
44
|
+
}
|
|
45
|
+
return inputSchema;
|
|
46
|
+
}
|
|
47
|
+
function summarizeDependencyDescription(dep) {
|
|
48
|
+
const prefix = `Call ${dependencyRef(dep)}`;
|
|
49
|
+
const raw = dep.description?.trim();
|
|
50
|
+
if (!raw)
|
|
51
|
+
return prefix;
|
|
52
|
+
const compact = raw.replace(/\s+/g, ' ');
|
|
53
|
+
if (compact.length <= 140)
|
|
54
|
+
return `${prefix}: ${compact}`;
|
|
55
|
+
return `${prefix}: ${compact.slice(0, 137)}...`;
|
|
56
|
+
}
|
|
57
|
+
function nextUniqueToolName(dep, usedNames) {
|
|
58
|
+
const candidates = [
|
|
59
|
+
`call_${sanitizeToolToken(dep.name)}`,
|
|
60
|
+
`call_${sanitizeToolToken(dep.org)}_${sanitizeToolToken(dep.name)}`,
|
|
61
|
+
];
|
|
62
|
+
for (const candidate of candidates) {
|
|
63
|
+
if (!usedNames.has(candidate) && !BUILTIN_TOOL_NAMES.has(candidate)) {
|
|
64
|
+
usedNames.add(candidate);
|
|
65
|
+
return candidate;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
let suffix = 2;
|
|
69
|
+
const stablePrefix = `call_${sanitizeToolToken(dep.org)}_${sanitizeToolToken(dep.name)}`;
|
|
70
|
+
while (true) {
|
|
71
|
+
const candidate = `${stablePrefix}_${suffix}`;
|
|
72
|
+
if (!usedNames.has(candidate) && !BUILTIN_TOOL_NAMES.has(candidate)) {
|
|
73
|
+
usedNames.add(candidate);
|
|
74
|
+
return candidate;
|
|
75
|
+
}
|
|
76
|
+
suffix += 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function defaultMaxHops(depCount) {
|
|
80
|
+
return Math.max(2, Math.min(8, depCount + 1));
|
|
81
|
+
}
|
|
82
|
+
function validateScaffoldAgentName(name) {
|
|
83
|
+
const errors = [];
|
|
84
|
+
const trimmed = name.trim();
|
|
85
|
+
const nameRegex = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
86
|
+
if (trimmed.length < 2 || trimmed.length > 50) {
|
|
87
|
+
errors.push('Agent name must be 2-50 characters');
|
|
88
|
+
}
|
|
89
|
+
if (trimmed !== trimmed.toLowerCase()) {
|
|
90
|
+
errors.push('Agent name must be lowercase');
|
|
91
|
+
}
|
|
92
|
+
if (trimmed.length > 1 && !nameRegex.test(trimmed)) {
|
|
93
|
+
errors.push('Agent name must contain only lowercase letters, numbers, and hyphens, and must start/end with a letter or number');
|
|
94
|
+
}
|
|
95
|
+
if (trimmed.includes('--')) {
|
|
96
|
+
errors.push('Agent name must not contain consecutive hyphens');
|
|
97
|
+
}
|
|
98
|
+
return errors;
|
|
99
|
+
}
|
|
100
|
+
function dedupeOrchestrationDependencies(dependencies) {
|
|
101
|
+
const deduped = [];
|
|
102
|
+
const duplicates = [];
|
|
103
|
+
const byId = new Map();
|
|
104
|
+
const versionsById = new Map();
|
|
105
|
+
for (const dep of dependencies) {
|
|
106
|
+
const id = dependencyId(dep);
|
|
107
|
+
const existing = byId.get(id);
|
|
108
|
+
if (!existing) {
|
|
109
|
+
byId.set(id, dep);
|
|
110
|
+
deduped.push(dep);
|
|
111
|
+
versionsById.set(id, new Set([dep.version]));
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
versionsById.get(id)?.add(dep.version);
|
|
115
|
+
if (existing.version === dep.version) {
|
|
116
|
+
duplicates.push(dependencyRef(dep));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const conflicts = [];
|
|
120
|
+
for (const [id, versions] of versionsById.entries()) {
|
|
121
|
+
if (versions.size > 1) {
|
|
122
|
+
conflicts.push({ id, versions: [...versions].sort() });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { dependencies: deduped, duplicates, conflicts };
|
|
126
|
+
}
|
|
127
|
+
function buildOrchestrationCustomTools(dependencies) {
|
|
128
|
+
const usedNames = new Set();
|
|
129
|
+
return dependencies.map((dep) => {
|
|
130
|
+
return {
|
|
131
|
+
name: nextUniqueToolName(dep, usedNames),
|
|
132
|
+
description: summarizeDependencyDescription(dep),
|
|
133
|
+
input_schema: normalizeToolInputSchema(dep.inputSchema),
|
|
134
|
+
command: `python3 /home/user/helpers/orch_call.py ${dependencyRef(dep)}`,
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function buildOrchestrationManifest(args) {
|
|
139
|
+
const maxTurns = args.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
140
|
+
const timeoutMs = args.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
141
|
+
const maxHops = args.maxHops ?? defaultMaxHops(args.dependencies.length);
|
|
142
|
+
const perCallDownstreamCap = args.perCallDownstreamCap ?? DEFAULT_PER_CALL_DOWNSTREAM_CAP;
|
|
143
|
+
return {
|
|
144
|
+
name: args.name,
|
|
145
|
+
type: 'agent',
|
|
146
|
+
description: `Managed-loop orchestrator that coordinates ${args.dependencies.length} dependency agents`,
|
|
147
|
+
run_mode: 'on_demand',
|
|
148
|
+
tags: ['orchestration'],
|
|
149
|
+
supported_providers: ['any'],
|
|
150
|
+
required_secrets: [],
|
|
151
|
+
max_turns: maxTurns,
|
|
152
|
+
custom_tools: args.customTools,
|
|
153
|
+
// Keep loop in sync with top-level compatibility fields for local + cloud parity.
|
|
154
|
+
loop: {
|
|
155
|
+
max_turns: maxTurns,
|
|
156
|
+
custom_tools: args.customTools,
|
|
157
|
+
},
|
|
158
|
+
manifest: {
|
|
159
|
+
manifest_version: 1,
|
|
160
|
+
dependencies: args.dependencies.map((dep) => ({
|
|
161
|
+
id: `${dep.org}/${dep.name}`,
|
|
162
|
+
version: dep.version,
|
|
163
|
+
})),
|
|
164
|
+
max_hops: maxHops,
|
|
165
|
+
timeout_ms: timeoutMs,
|
|
166
|
+
per_call_downstream_cap: perCallDownstreamCap,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function buildOrchestrationPrompt(args) {
|
|
171
|
+
const toolLines = args.customTools.map((tool, idx) => {
|
|
172
|
+
const dep = args.dependencies[idx];
|
|
173
|
+
const description = dep.description?.trim() ? ` — ${dep.description.trim()}` : '';
|
|
174
|
+
return `- \`${tool.name}\` -> \`${dependencyRef(dep)}\`${description}`;
|
|
175
|
+
});
|
|
176
|
+
return [
|
|
177
|
+
`You are ${args.name}, an orchestration agent that delegates work to specialist dependency agents.`,
|
|
178
|
+
'',
|
|
179
|
+
'Primary objective:',
|
|
180
|
+
'- Use the dependency tools to solve the incoming task with accurate, well-structured results.',
|
|
181
|
+
'',
|
|
182
|
+
'Available dependency tools:',
|
|
183
|
+
...toolLines,
|
|
184
|
+
'',
|
|
185
|
+
'Operating rules:',
|
|
186
|
+
'1. Prefer the dependency tools over ad-hoc bash implementations when a dependency can handle the task.',
|
|
187
|
+
'2. Pass only relevant fields to each tool call; do not invent required fields.',
|
|
188
|
+
'3. Chain tool calls when needed and reconcile conflicting outputs before finalizing.',
|
|
189
|
+
'4. If a dependency fails, retry once with corrected input; if still failing, return a clear partial result with the failure reason.',
|
|
190
|
+
'5. Always finish by calling submit_result with output that matches schema.json.',
|
|
191
|
+
'',
|
|
192
|
+
'Input template:',
|
|
193
|
+
'- `{{task}}`: the user task you must complete.',
|
|
194
|
+
'',
|
|
195
|
+
'Use concise, factual language in the final response.',
|
|
196
|
+
'',
|
|
197
|
+
].join('\n');
|
|
198
|
+
}
|
|
199
|
+
function buildOrchestrationSchema() {
|
|
200
|
+
return {
|
|
201
|
+
input: {
|
|
202
|
+
type: 'object',
|
|
203
|
+
properties: {
|
|
204
|
+
task: {
|
|
205
|
+
type: 'string',
|
|
206
|
+
description: 'Task to delegate across dependency agents',
|
|
207
|
+
},
|
|
208
|
+
context: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
description: 'Optional context payload forwarded to dependency tools as needed',
|
|
211
|
+
additionalProperties: true,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
required: ['task'],
|
|
215
|
+
},
|
|
216
|
+
output: {
|
|
217
|
+
type: 'object',
|
|
218
|
+
properties: {
|
|
219
|
+
result: {
|
|
220
|
+
type: 'string',
|
|
221
|
+
description: 'Final synthesized answer for the task',
|
|
222
|
+
},
|
|
223
|
+
used_tools: {
|
|
224
|
+
type: 'array',
|
|
225
|
+
items: { type: 'string' },
|
|
226
|
+
description: 'Dependency tool names used to produce the result',
|
|
227
|
+
},
|
|
228
|
+
notes: {
|
|
229
|
+
type: 'array',
|
|
230
|
+
items: { type: 'string' },
|
|
231
|
+
description: 'Warnings, fallbacks, or caveats encountered during orchestration',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
required: ['result', 'used_tools'],
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|