@guildai/cli 0.6.1 → 0.6.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/dist/commands/agent/publish.js +13 -53
- package/dist/commands/agent/save.js +14 -50
- package/dist/commands/chat.js +4 -4
- package/dist/lib/session-polling.js +1 -1
- package/dist/lib/version-helpers.d.ts +15 -0
- package/dist/lib/version-helpers.js +83 -0
- package/dist/mcp/tools.js +1 -1
- package/package.json +1 -1
|
@@ -4,8 +4,8 @@ import { Command } from 'commander';
|
|
|
4
4
|
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
5
|
import { getAgentId, resolveAgentRef } from '../../lib/agent-helpers.js';
|
|
6
6
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
7
|
-
import { pollUntilComplete } from '../../lib/polling.js';
|
|
8
7
|
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
+
import { waitForValidation, waitForPublish } from '../../lib/version-helpers.js';
|
|
9
9
|
export function createAgentPublishCommand() {
|
|
10
10
|
const cmd = new Command('publish');
|
|
11
11
|
cmd
|
|
@@ -37,71 +37,31 @@ export function createAgentPublishCommand() {
|
|
|
37
37
|
process.exit(1);
|
|
38
38
|
}
|
|
39
39
|
// Check validation status before attempting publish
|
|
40
|
-
let validationStatus = versionToPublish.validation_status;
|
|
41
40
|
let currentVersion = versionToPublish;
|
|
41
|
+
const validationStatus = currentVersion.validation_status;
|
|
42
42
|
if (validationStatus === 'PENDING' || validationStatus === 'RUNNING') {
|
|
43
43
|
if (options.wait) {
|
|
44
|
-
|
|
45
|
-
const result = await pollUntilComplete({
|
|
46
|
-
resourceId: versionToPublish.id,
|
|
47
|
-
endpoint: `/versions/${versionToPublish.id}`,
|
|
48
|
-
isComplete: (response) => response.validation_status !== 'PENDING' &&
|
|
49
|
-
response.validation_status !== 'RUNNING',
|
|
50
|
-
message: 'Waiting for validation to complete...',
|
|
51
|
-
successMessage: 'Validation complete',
|
|
52
|
-
timeoutMessage: 'Validation timed out',
|
|
53
|
-
maxAttempts: 120, // 2 minutes
|
|
54
|
-
delayMs: 1000,
|
|
55
|
-
});
|
|
56
|
-
if (!result.success || !result.response) {
|
|
57
|
-
output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
|
|
58
|
-
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
currentVersion = result.response;
|
|
61
|
-
validationStatus = currentVersion.validation_status;
|
|
62
|
-
// Re-check validation status after waiting - will be handled below
|
|
63
|
-
// by the main validation check
|
|
44
|
+
currentVersion = await waitForValidation(currentVersion.id, output);
|
|
64
45
|
}
|
|
65
46
|
else {
|
|
66
|
-
output.error('Cannot publish: validation is still in progress', `Validation status: ${validationStatus === 'PENDING' ? 'Waiting to start' : 'Running'}\n\
|
|
47
|
+
output.error('Cannot publish: validation is still in progress', `Validation status: ${validationStatus === 'PENDING' ? 'Waiting to start' : 'Running'}\n\nOptions:\n • Wait for validation: guild agent publish --wait\n • Check status: guild agent versions`);
|
|
67
48
|
process.exit(1);
|
|
68
49
|
}
|
|
69
50
|
}
|
|
70
|
-
if (validationStatus === 'FAILED') {
|
|
71
|
-
|
|
72
|
-
let failureDetails = '';
|
|
73
|
-
try {
|
|
74
|
-
const stepsResponse = await client.get(`/versions/${currentVersion.id}/validation/steps`);
|
|
75
|
-
const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
|
|
76
|
-
if (failedSteps.length > 0) {
|
|
77
|
-
const stepMessages = failedSteps.map((step) => {
|
|
78
|
-
let msg = `Step "${step.name}" failed:`;
|
|
79
|
-
if (step.content) {
|
|
80
|
-
msg += `\n ${step.content}`;
|
|
81
|
-
}
|
|
82
|
-
return msg;
|
|
83
|
-
});
|
|
84
|
-
failureDetails = stepMessages.join('\n\n');
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
failureDetails =
|
|
88
|
-
'No failed steps found. Check validation logs for details.';
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
// If we can't fetch steps, just show generic message
|
|
93
|
-
failureDetails = 'Could not fetch validation details.';
|
|
94
|
-
}
|
|
95
|
-
output.error('Cannot publish: validation failed', `${failureDetails}\n\nFix the issues, then save a new version:\n guild agent save --message "Fix validation errors"`);
|
|
51
|
+
else if (validationStatus === 'FAILED') {
|
|
52
|
+
output.error('Cannot publish: validation failed', 'Fix the issues, then save a new version:\n guild agent save --message "Fix validation errors"');
|
|
96
53
|
process.exit(1);
|
|
97
54
|
}
|
|
98
|
-
// Note: version_number is only set after validation extracts it from package.json,
|
|
99
|
-
// and only enforced at publish time (drafts don't require versions)
|
|
100
55
|
// Publish version
|
|
101
|
-
await client.post(`/versions/${currentVersion.id}/publish`, {});
|
|
56
|
+
currentVersion = await client.post(`/versions/${currentVersion.id}/publish`, {});
|
|
57
|
+
if (options.wait && currentVersion.status !== 'PUBLISHED') {
|
|
58
|
+
currentVersion = await waitForPublish(currentVersion.id, output);
|
|
59
|
+
}
|
|
102
60
|
const details = {
|
|
103
61
|
agent: `${currentVersion.agent?.name || config?.name || agentId}${config ? '' : ` (${agentId})`}`,
|
|
104
|
-
status:
|
|
62
|
+
status: currentVersion.status === 'PUBLISHED'
|
|
63
|
+
? 'DRAFT → PUBLISHED'
|
|
64
|
+
: 'DRAFT → PUBLISHING',
|
|
105
65
|
};
|
|
106
66
|
if (currentVersion.version_number) {
|
|
107
67
|
details.version = currentVersion.version_number;
|
|
@@ -9,7 +9,7 @@ import * as fs from 'fs/promises';
|
|
|
9
9
|
import * as path from 'path';
|
|
10
10
|
import { getAuthenticatedUrl } from '../../lib/auth.js';
|
|
11
11
|
import { runGit, GitError, formatGitError } from '../../lib/git.js';
|
|
12
|
-
import {
|
|
12
|
+
import { waitForValidation, waitForPublish } from '../../lib/version-helpers.js';
|
|
13
13
|
export function createAgentSaveCommand() {
|
|
14
14
|
const cmd = new Command('save');
|
|
15
15
|
cmd
|
|
@@ -255,58 +255,18 @@ export function createAgentSaveCommand() {
|
|
|
255
255
|
version_type: 'COMMITTED',
|
|
256
256
|
});
|
|
257
257
|
output.progress(`✓ Created version (${version.id})`);
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
// If --wait or --publish, wait for validation to complete
|
|
261
|
-
if (shouldWait) {
|
|
262
|
-
const pollResult = await pollUntilComplete({
|
|
263
|
-
resourceId: version.id,
|
|
264
|
-
endpoint: `/versions/${version.id}`,
|
|
265
|
-
isComplete: (response) => response.validation_status !== 'PENDING' &&
|
|
266
|
-
response.validation_status !== 'RUNNING',
|
|
267
|
-
message: 'Waiting for validation to complete...',
|
|
268
|
-
successMessage: 'Validation complete',
|
|
269
|
-
timeoutMessage: 'Validation timed out',
|
|
270
|
-
maxAttempts: 120, // 2 minutes
|
|
271
|
-
delayMs: 1000,
|
|
272
|
-
});
|
|
273
|
-
if (!pollResult.success || !pollResult.response) {
|
|
274
|
-
output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
|
|
275
|
-
process.exit(1);
|
|
276
|
-
}
|
|
277
|
-
version = pollResult.response;
|
|
278
|
-
// Check validation status
|
|
279
|
-
if (version.validation_status === 'FAILED') {
|
|
280
|
-
let failureDetails = '';
|
|
281
|
-
// Fetch validation steps to show the actual error
|
|
282
|
-
try {
|
|
283
|
-
const stepsResponse = await client.get(`/versions/${version.id}/validation/steps`);
|
|
284
|
-
const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
|
|
285
|
-
if (failedSteps.length > 0) {
|
|
286
|
-
const stepMessages = failedSteps.map((step) => step.content
|
|
287
|
-
? `Step "${step.name}" failed: ${step.content}`
|
|
288
|
-
: `Step "${step.name}" failed`);
|
|
289
|
-
failureDetails = stepMessages.join('\n');
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
failureDetails =
|
|
293
|
-
'No failed steps found. Check validation logs for details.';
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
catch {
|
|
297
|
-
failureDetails = 'Could not fetch validation details.';
|
|
298
|
-
}
|
|
299
|
-
failureDetails +=
|
|
300
|
-
'\n\nFix the issues, commit, and save a new version:\n git add . && git commit -m "Fix validation errors"\n guild agent save';
|
|
301
|
-
output.error('Validation failed', failureDetails);
|
|
302
|
-
process.exit(1);
|
|
303
|
-
}
|
|
258
|
+
if (options.wait) {
|
|
259
|
+
version = await waitForValidation(version.id, output);
|
|
304
260
|
}
|
|
305
|
-
// If --publish and validation passed, publish the version
|
|
306
261
|
if (options.publish) {
|
|
307
262
|
output.progress('Validation passed, publishing...');
|
|
308
263
|
version = await client.post(`/versions/${version.id}/publish`, {});
|
|
309
|
-
|
|
264
|
+
if (options.wait && version.status !== 'PUBLISHED') {
|
|
265
|
+
version = await waitForPublish(version.id, output);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
output.progress('✓ Published');
|
|
269
|
+
}
|
|
310
270
|
}
|
|
311
271
|
output.progress('');
|
|
312
272
|
output.progress('Version details:');
|
|
@@ -317,10 +277,14 @@ export function createAgentSaveCommand() {
|
|
|
317
277
|
output.progress(` Published at: ${version.published_at}`);
|
|
318
278
|
}
|
|
319
279
|
output.progress(` Summary: ${version.summary}`);
|
|
320
|
-
if (options.publish) {
|
|
280
|
+
if (options.publish && version.status === 'PUBLISHED') {
|
|
321
281
|
output.progress('');
|
|
322
282
|
output.progress('Version is now published and available in the catalog.');
|
|
323
283
|
}
|
|
284
|
+
else if (options.publish) {
|
|
285
|
+
output.progress('');
|
|
286
|
+
output.progress('Publish is in progress. Use --wait to wait for completion.');
|
|
287
|
+
}
|
|
324
288
|
else {
|
|
325
289
|
output.progress('');
|
|
326
290
|
output.progress('To publish this version:');
|
package/dist/commands/chat.js
CHANGED
|
@@ -485,9 +485,9 @@ function ChatUIWithConnection({ initialPrompt, version: _version, versionId: _ve
|
|
|
485
485
|
isPollingTasks.current = false;
|
|
486
486
|
}
|
|
487
487
|
};
|
|
488
|
-
// Poll immediately and then every
|
|
488
|
+
// Poll immediately and then every 2 seconds
|
|
489
489
|
pollTasks();
|
|
490
|
-
const interval = setInterval(pollTasks,
|
|
490
|
+
const interval = setInterval(pollTasks, 2000);
|
|
491
491
|
return () => {
|
|
492
492
|
clearInterval(interval);
|
|
493
493
|
};
|
|
@@ -684,7 +684,7 @@ function ChatUIWithConnection({ initialPrompt, version: _version, versionId: _ve
|
|
|
684
684
|
isPolling.current = false;
|
|
685
685
|
}
|
|
686
686
|
};
|
|
687
|
-
pollInterval.current = setInterval(poll,
|
|
687
|
+
pollInterval.current = setInterval(poll, 2000);
|
|
688
688
|
poll();
|
|
689
689
|
return () => {
|
|
690
690
|
if (pollInterval.current) {
|
|
@@ -972,7 +972,7 @@ export function createChatCommand() {
|
|
|
972
972
|
// Timeout after 5 minutes of INACTIVITY (no new messages)
|
|
973
973
|
// Agent initialization can take 1-2 minutes with no events
|
|
974
974
|
const inactivityTimeoutMs = 300000; // 5 minutes
|
|
975
|
-
const pollIntervalMs =
|
|
975
|
+
const pollIntervalMs = 2000;
|
|
976
976
|
const maxInactivityAttempts = inactivityTimeoutMs / pollIntervalMs;
|
|
977
977
|
let lastSeenEventId;
|
|
978
978
|
const allEvents = [];
|
|
@@ -46,7 +46,7 @@ export async function pollForResponse(client, sessionId, afterEventId, maxWaitTi
|
|
|
46
46
|
if (lastAgentRuntimeDone !== null) {
|
|
47
47
|
return { response: lastAgentRuntimeDone, lastEventId: fromId };
|
|
48
48
|
}
|
|
49
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
50
50
|
}
|
|
51
51
|
return { response: null, lastEventId: fromId };
|
|
52
52
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { OutputWriter } from './output.js';
|
|
2
|
+
import type { AgentVersion } from './api-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Poll until a version's validation completes, then check the result.
|
|
5
|
+
* Exits the process on timeout or validation failure.
|
|
6
|
+
* Returns the updated version on success.
|
|
7
|
+
*/
|
|
8
|
+
export declare function waitForValidation(versionId: string, output: OutputWriter): Promise<AgentVersion>;
|
|
9
|
+
/**
|
|
10
|
+
* Poll until a version's publish completes (PUBLISHING → PUBLISHED).
|
|
11
|
+
* Exits the process on timeout or failure.
|
|
12
|
+
* Returns the updated version on success.
|
|
13
|
+
*/
|
|
14
|
+
export declare function waitForPublish(versionId: string, output: OutputWriter): Promise<AgentVersion>;
|
|
15
|
+
//# sourceMappingURL=version-helpers.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { GuildAPIClient } from './api-client.js';
|
|
4
|
+
import { pollUntilComplete } from './polling.js';
|
|
5
|
+
/**
|
|
6
|
+
* Poll until a version's validation completes, then check the result.
|
|
7
|
+
* Exits the process on timeout or validation failure.
|
|
8
|
+
* Returns the updated version on success.
|
|
9
|
+
*/
|
|
10
|
+
export async function waitForValidation(versionId, output) {
|
|
11
|
+
const pollResult = await pollUntilComplete({
|
|
12
|
+
resourceId: versionId,
|
|
13
|
+
endpoint: `/versions/${versionId}`,
|
|
14
|
+
isComplete: (response) => response.validation_status !== 'PENDING' &&
|
|
15
|
+
response.validation_status !== 'RUNNING',
|
|
16
|
+
message: 'Waiting for validation to complete...',
|
|
17
|
+
successMessage: 'Validation complete',
|
|
18
|
+
timeoutMessage: 'Validation timed out',
|
|
19
|
+
maxAttempts: 120,
|
|
20
|
+
delayMs: 1000,
|
|
21
|
+
});
|
|
22
|
+
if (!pollResult.success || !pollResult.response) {
|
|
23
|
+
output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const version = pollResult.response;
|
|
27
|
+
if (version.validation_status === 'FAILED') {
|
|
28
|
+
const details = await fetchValidationFailureDetails(version.id);
|
|
29
|
+
output.error('Validation failed', details);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
return version;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Fetch validation step details for a failed version.
|
|
36
|
+
*/
|
|
37
|
+
async function fetchValidationFailureDetails(versionId) {
|
|
38
|
+
const client = new GuildAPIClient();
|
|
39
|
+
let failureDetails = '';
|
|
40
|
+
try {
|
|
41
|
+
const stepsResponse = await client.get(`/versions/${versionId}/validation/steps`);
|
|
42
|
+
const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
|
|
43
|
+
if (failedSteps.length > 0) {
|
|
44
|
+
failureDetails = failedSteps
|
|
45
|
+
.map((step) => step.content
|
|
46
|
+
? `Step "${step.name}" failed: ${step.content}`
|
|
47
|
+
: `Step "${step.name}" failed`)
|
|
48
|
+
.join('\n');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
failureDetails = 'No failed steps found. Check validation logs for details.';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
failureDetails = 'Could not fetch validation details.';
|
|
56
|
+
}
|
|
57
|
+
failureDetails +=
|
|
58
|
+
'\n\nFix the issues, then save a new version:\n guild agent save --message "Fix validation errors"';
|
|
59
|
+
return failureDetails;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Poll until a version's publish completes (PUBLISHING → PUBLISHED).
|
|
63
|
+
* Exits the process on timeout or failure.
|
|
64
|
+
* Returns the updated version on success.
|
|
65
|
+
*/
|
|
66
|
+
export async function waitForPublish(versionId, output) {
|
|
67
|
+
const pollResult = await pollUntilComplete({
|
|
68
|
+
resourceId: versionId,
|
|
69
|
+
endpoint: `/versions/${versionId}`,
|
|
70
|
+
isComplete: (response) => response.status === 'PUBLISHED' || response.status === 'FAILED',
|
|
71
|
+
message: 'Waiting for publish to complete...',
|
|
72
|
+
successMessage: 'Published',
|
|
73
|
+
timeoutMessage: 'Publish timed out',
|
|
74
|
+
maxAttempts: 60,
|
|
75
|
+
delayMs: 1000,
|
|
76
|
+
});
|
|
77
|
+
if (!pollResult.success || pollResult.response?.status !== 'PUBLISHED') {
|
|
78
|
+
output.error('Publish did not complete in time', 'Check status manually:\n guild agent versions');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
return pollResult.response;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=version-helpers.js.map
|
package/dist/mcp/tools.js
CHANGED
|
@@ -4,7 +4,7 @@ import { z } from 'zod';
|
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
// Constants
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
|
-
const POLL_INTERVAL_MS =
|
|
7
|
+
const POLL_INTERVAL_MS = 2000;
|
|
8
8
|
const POLL_TIMEOUT_MS = 120_000;
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
10
|
// Helpers
|