@agentrix/agentrix-run 0.5.0 → 0.7.0
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/index.cjs +78 -9
- package/dist/index.mjs +79 -10
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -5,13 +5,15 @@ var shared = require('@agentrix/shared');
|
|
|
5
5
|
|
|
6
6
|
const DEFAULT_RESPONSE_MODE = "stream";
|
|
7
7
|
const DEFAULT_WAIT_TIMEOUT_SECONDS = 1800;
|
|
8
|
+
const DEFAULT_AGENTRIX_BASE_URL = "https://agentrix.xmz.ai";
|
|
8
9
|
function usage() {
|
|
9
10
|
return [
|
|
10
|
-
"Usage: agentrix-run --agent <agent> --prompt <prompt> [options]",
|
|
11
|
+
"Usage: agentrix-run (--agent <agent> | --resume <task-id>) --prompt <prompt> [options]",
|
|
11
12
|
"",
|
|
12
13
|
"Options:",
|
|
13
14
|
" --title <text>",
|
|
14
15
|
" --allow-filesystem-agent",
|
|
16
|
+
" --resume <task-id>",
|
|
15
17
|
" --repo <json>",
|
|
16
18
|
" --output-schema <json>",
|
|
17
19
|
" --ref <ref>",
|
|
@@ -26,7 +28,7 @@ function usage() {
|
|
|
26
28
|
" --capability-profile <name>",
|
|
27
29
|
" --runner-id <cloud-id|machine-id>",
|
|
28
30
|
" --result-file <path>",
|
|
29
|
-
|
|
31
|
+
` --base-url <url> (default: ${DEFAULT_AGENTRIX_BASE_URL})`,
|
|
30
32
|
" --api-key <api-key>",
|
|
31
33
|
" --metadata <key=value>",
|
|
32
34
|
" --help"
|
|
@@ -180,6 +182,10 @@ function parseArgs(argv) {
|
|
|
180
182
|
case "--allow-filesystem-agent":
|
|
181
183
|
options.allowFilesystemAgent = true;
|
|
182
184
|
break;
|
|
185
|
+
case "--resume":
|
|
186
|
+
options.resumeTaskId = requireValue(argv, index, arg);
|
|
187
|
+
index += 1;
|
|
188
|
+
break;
|
|
183
189
|
case "--title":
|
|
184
190
|
options.title = requireValue(argv, index, arg);
|
|
185
191
|
index += 1;
|
|
@@ -267,12 +273,15 @@ function parseArgs(argv) {
|
|
|
267
273
|
throw new Error(`Unknown argument: ${arg}`);
|
|
268
274
|
}
|
|
269
275
|
}
|
|
270
|
-
if (!options.agent.trim()) {
|
|
276
|
+
if (!options.resumeTaskId && !options.agent.trim()) {
|
|
271
277
|
throw new Error("--agent is required");
|
|
272
278
|
}
|
|
273
279
|
if (!options.prompt.trim()) {
|
|
274
280
|
throw new Error("--prompt is required");
|
|
275
281
|
}
|
|
282
|
+
if (options.resumeTaskId !== void 0 && !options.resumeTaskId.trim()) {
|
|
283
|
+
throw new Error("--resume must be a non-empty task ID");
|
|
284
|
+
}
|
|
276
285
|
return options;
|
|
277
286
|
}
|
|
278
287
|
function normalizeRef(value) {
|
|
@@ -451,10 +460,7 @@ function buildRequest(options, detected) {
|
|
|
451
460
|
return shared.CreateCiRunRequestSchema.parse(request);
|
|
452
461
|
}
|
|
453
462
|
function resolveBaseUrl(options) {
|
|
454
|
-
const value = options.baseUrl || process.env.AGENTRIX_BASE_URL;
|
|
455
|
-
if (!value) {
|
|
456
|
-
throw new Error("Missing --base-url and AGENTRIX_BASE_URL");
|
|
457
|
-
}
|
|
463
|
+
const value = options.baseUrl || process.env.AGENTRIX_BASE_URL || DEFAULT_AGENTRIX_BASE_URL;
|
|
458
464
|
return value.replace(/\/+$/, "");
|
|
459
465
|
}
|
|
460
466
|
function resolveApiKey(options) {
|
|
@@ -485,6 +491,36 @@ async function createRun(baseUrl, apiKey, request) {
|
|
|
485
491
|
const response = await requestJson("POST", `${baseUrl}/v1/ci/runs`, apiKey, request);
|
|
486
492
|
return shared.CreateCiRunResponseSchema.parse(response);
|
|
487
493
|
}
|
|
494
|
+
function createPromptMessage(text) {
|
|
495
|
+
return {
|
|
496
|
+
type: "user",
|
|
497
|
+
message: {
|
|
498
|
+
role: "user",
|
|
499
|
+
content: text.trim()
|
|
500
|
+
},
|
|
501
|
+
parent_tool_use_id: null,
|
|
502
|
+
session_id: ""
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
function buildResumeMessageRequest(options) {
|
|
506
|
+
return {
|
|
507
|
+
message: createPromptMessage(options.prompt),
|
|
508
|
+
target: "agent",
|
|
509
|
+
senderType: "human",
|
|
510
|
+
senderId: "agentrix-run",
|
|
511
|
+
senderName: "agentrix-run",
|
|
512
|
+
responseMode: options.responseMode
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
async function sendResumeMessage(baseUrl, apiKey, taskId, request) {
|
|
516
|
+
const response = await requestJson(
|
|
517
|
+
"POST",
|
|
518
|
+
`${baseUrl}/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
519
|
+
apiKey,
|
|
520
|
+
request
|
|
521
|
+
);
|
|
522
|
+
return shared.SendTaskMessageResponseSchema.parse(response);
|
|
523
|
+
}
|
|
488
524
|
function exitCodeForStatus(status) {
|
|
489
525
|
return status === "completed" ? 0 : 1;
|
|
490
526
|
}
|
|
@@ -569,12 +605,12 @@ function parseSseBlock(block) {
|
|
|
569
605
|
data: JSON.parse(dataText)
|
|
570
606
|
};
|
|
571
607
|
}
|
|
572
|
-
async function
|
|
608
|
+
async function streamRunRequest(baseUrl, apiKey, path, request, deadline) {
|
|
573
609
|
const timeoutMs = Math.max(deadline - Date.now(), 1);
|
|
574
610
|
const controller = new AbortController();
|
|
575
611
|
const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
|
|
576
612
|
try {
|
|
577
|
-
const response = await fetch(`${baseUrl}
|
|
613
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
578
614
|
method: "POST",
|
|
579
615
|
headers: {
|
|
580
616
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -642,11 +678,44 @@ async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
|
642
678
|
clearTimeout(timeoutHandle);
|
|
643
679
|
}
|
|
644
680
|
}
|
|
681
|
+
async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
682
|
+
return streamRunRequest(baseUrl, apiKey, "/v1/ci/runs", request, deadline);
|
|
683
|
+
}
|
|
684
|
+
async function resumeRunStream(baseUrl, apiKey, taskId, request, deadline) {
|
|
685
|
+
return streamRunRequest(
|
|
686
|
+
baseUrl,
|
|
687
|
+
apiKey,
|
|
688
|
+
`/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
689
|
+
request,
|
|
690
|
+
deadline
|
|
691
|
+
);
|
|
692
|
+
}
|
|
645
693
|
async function main(argv = process.argv.slice(2)) {
|
|
646
694
|
const options = parseArgs(argv);
|
|
647
695
|
const detected = detectCiContext();
|
|
648
696
|
const baseUrl = resolveBaseUrl(options);
|
|
649
697
|
const apiKey = resolveApiKey(options);
|
|
698
|
+
if (options.resumeTaskId) {
|
|
699
|
+
const taskId = options.resumeTaskId.trim();
|
|
700
|
+
const request2 = buildResumeMessageRequest(options);
|
|
701
|
+
if (options.responseMode === "async") {
|
|
702
|
+
const response = await sendResumeMessage(baseUrl, apiKey, taskId, request2);
|
|
703
|
+
if (!response.run) {
|
|
704
|
+
throw new Error("Server did not return CI run metadata for resumed task");
|
|
705
|
+
}
|
|
706
|
+
writeAsyncResultFile(options.resultFile, response.run);
|
|
707
|
+
printStandardFields({
|
|
708
|
+
runId: response.run.runId,
|
|
709
|
+
status: response.run.status,
|
|
710
|
+
detailUrl: response.run.detailUrl
|
|
711
|
+
});
|
|
712
|
+
return 0;
|
|
713
|
+
}
|
|
714
|
+
const deadline2 = ensureWaitDeadline(options);
|
|
715
|
+
const finalStatus2 = await resumeRunStream(baseUrl, apiKey, taskId, request2, deadline2);
|
|
716
|
+
writeResultFile(options.resultFile, finalStatus2);
|
|
717
|
+
return exitCodeForStatus(finalStatus2.status);
|
|
718
|
+
}
|
|
650
719
|
const request = buildRequest(options, detected);
|
|
651
720
|
if (options.responseMode === "async") {
|
|
652
721
|
const run = await createRun(baseUrl, apiKey, request);
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { writeFileSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { CreateCiRunRequestSchema, CiRunStatusResponseSchema, CreateCiRunResponseSchema } from '@agentrix/shared';
|
|
2
|
+
import { CreateCiRunRequestSchema, CiRunStatusResponseSchema, SendTaskMessageResponseSchema, CreateCiRunResponseSchema } from '@agentrix/shared';
|
|
3
3
|
|
|
4
4
|
const DEFAULT_RESPONSE_MODE = "stream";
|
|
5
5
|
const DEFAULT_WAIT_TIMEOUT_SECONDS = 1800;
|
|
6
|
+
const DEFAULT_AGENTRIX_BASE_URL = "https://agentrix.xmz.ai";
|
|
6
7
|
function usage() {
|
|
7
8
|
return [
|
|
8
|
-
"Usage: agentrix-run --agent <agent> --prompt <prompt> [options]",
|
|
9
|
+
"Usage: agentrix-run (--agent <agent> | --resume <task-id>) --prompt <prompt> [options]",
|
|
9
10
|
"",
|
|
10
11
|
"Options:",
|
|
11
12
|
" --title <text>",
|
|
12
13
|
" --allow-filesystem-agent",
|
|
14
|
+
" --resume <task-id>",
|
|
13
15
|
" --repo <json>",
|
|
14
16
|
" --output-schema <json>",
|
|
15
17
|
" --ref <ref>",
|
|
@@ -24,7 +26,7 @@ function usage() {
|
|
|
24
26
|
" --capability-profile <name>",
|
|
25
27
|
" --runner-id <cloud-id|machine-id>",
|
|
26
28
|
" --result-file <path>",
|
|
27
|
-
|
|
29
|
+
` --base-url <url> (default: ${DEFAULT_AGENTRIX_BASE_URL})`,
|
|
28
30
|
" --api-key <api-key>",
|
|
29
31
|
" --metadata <key=value>",
|
|
30
32
|
" --help"
|
|
@@ -178,6 +180,10 @@ function parseArgs(argv) {
|
|
|
178
180
|
case "--allow-filesystem-agent":
|
|
179
181
|
options.allowFilesystemAgent = true;
|
|
180
182
|
break;
|
|
183
|
+
case "--resume":
|
|
184
|
+
options.resumeTaskId = requireValue(argv, index, arg);
|
|
185
|
+
index += 1;
|
|
186
|
+
break;
|
|
181
187
|
case "--title":
|
|
182
188
|
options.title = requireValue(argv, index, arg);
|
|
183
189
|
index += 1;
|
|
@@ -265,12 +271,15 @@ function parseArgs(argv) {
|
|
|
265
271
|
throw new Error(`Unknown argument: ${arg}`);
|
|
266
272
|
}
|
|
267
273
|
}
|
|
268
|
-
if (!options.agent.trim()) {
|
|
274
|
+
if (!options.resumeTaskId && !options.agent.trim()) {
|
|
269
275
|
throw new Error("--agent is required");
|
|
270
276
|
}
|
|
271
277
|
if (!options.prompt.trim()) {
|
|
272
278
|
throw new Error("--prompt is required");
|
|
273
279
|
}
|
|
280
|
+
if (options.resumeTaskId !== void 0 && !options.resumeTaskId.trim()) {
|
|
281
|
+
throw new Error("--resume must be a non-empty task ID");
|
|
282
|
+
}
|
|
274
283
|
return options;
|
|
275
284
|
}
|
|
276
285
|
function normalizeRef(value) {
|
|
@@ -449,10 +458,7 @@ function buildRequest(options, detected) {
|
|
|
449
458
|
return CreateCiRunRequestSchema.parse(request);
|
|
450
459
|
}
|
|
451
460
|
function resolveBaseUrl(options) {
|
|
452
|
-
const value = options.baseUrl || process.env.AGENTRIX_BASE_URL;
|
|
453
|
-
if (!value) {
|
|
454
|
-
throw new Error("Missing --base-url and AGENTRIX_BASE_URL");
|
|
455
|
-
}
|
|
461
|
+
const value = options.baseUrl || process.env.AGENTRIX_BASE_URL || DEFAULT_AGENTRIX_BASE_URL;
|
|
456
462
|
return value.replace(/\/+$/, "");
|
|
457
463
|
}
|
|
458
464
|
function resolveApiKey(options) {
|
|
@@ -483,6 +489,36 @@ async function createRun(baseUrl, apiKey, request) {
|
|
|
483
489
|
const response = await requestJson("POST", `${baseUrl}/v1/ci/runs`, apiKey, request);
|
|
484
490
|
return CreateCiRunResponseSchema.parse(response);
|
|
485
491
|
}
|
|
492
|
+
function createPromptMessage(text) {
|
|
493
|
+
return {
|
|
494
|
+
type: "user",
|
|
495
|
+
message: {
|
|
496
|
+
role: "user",
|
|
497
|
+
content: text.trim()
|
|
498
|
+
},
|
|
499
|
+
parent_tool_use_id: null,
|
|
500
|
+
session_id: ""
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function buildResumeMessageRequest(options) {
|
|
504
|
+
return {
|
|
505
|
+
message: createPromptMessage(options.prompt),
|
|
506
|
+
target: "agent",
|
|
507
|
+
senderType: "human",
|
|
508
|
+
senderId: "agentrix-run",
|
|
509
|
+
senderName: "agentrix-run",
|
|
510
|
+
responseMode: options.responseMode
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
async function sendResumeMessage(baseUrl, apiKey, taskId, request) {
|
|
514
|
+
const response = await requestJson(
|
|
515
|
+
"POST",
|
|
516
|
+
`${baseUrl}/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
517
|
+
apiKey,
|
|
518
|
+
request
|
|
519
|
+
);
|
|
520
|
+
return SendTaskMessageResponseSchema.parse(response);
|
|
521
|
+
}
|
|
486
522
|
function exitCodeForStatus(status) {
|
|
487
523
|
return status === "completed" ? 0 : 1;
|
|
488
524
|
}
|
|
@@ -567,12 +603,12 @@ function parseSseBlock(block) {
|
|
|
567
603
|
data: JSON.parse(dataText)
|
|
568
604
|
};
|
|
569
605
|
}
|
|
570
|
-
async function
|
|
606
|
+
async function streamRunRequest(baseUrl, apiKey, path, request, deadline) {
|
|
571
607
|
const timeoutMs = Math.max(deadline - Date.now(), 1);
|
|
572
608
|
const controller = new AbortController();
|
|
573
609
|
const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
|
|
574
610
|
try {
|
|
575
|
-
const response = await fetch(`${baseUrl}
|
|
611
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
576
612
|
method: "POST",
|
|
577
613
|
headers: {
|
|
578
614
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -640,11 +676,44 @@ async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
|
640
676
|
clearTimeout(timeoutHandle);
|
|
641
677
|
}
|
|
642
678
|
}
|
|
679
|
+
async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
680
|
+
return streamRunRequest(baseUrl, apiKey, "/v1/ci/runs", request, deadline);
|
|
681
|
+
}
|
|
682
|
+
async function resumeRunStream(baseUrl, apiKey, taskId, request, deadline) {
|
|
683
|
+
return streamRunRequest(
|
|
684
|
+
baseUrl,
|
|
685
|
+
apiKey,
|
|
686
|
+
`/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
687
|
+
request,
|
|
688
|
+
deadline
|
|
689
|
+
);
|
|
690
|
+
}
|
|
643
691
|
async function main(argv = process.argv.slice(2)) {
|
|
644
692
|
const options = parseArgs(argv);
|
|
645
693
|
const detected = detectCiContext();
|
|
646
694
|
const baseUrl = resolveBaseUrl(options);
|
|
647
695
|
const apiKey = resolveApiKey(options);
|
|
696
|
+
if (options.resumeTaskId) {
|
|
697
|
+
const taskId = options.resumeTaskId.trim();
|
|
698
|
+
const request2 = buildResumeMessageRequest(options);
|
|
699
|
+
if (options.responseMode === "async") {
|
|
700
|
+
const response = await sendResumeMessage(baseUrl, apiKey, taskId, request2);
|
|
701
|
+
if (!response.run) {
|
|
702
|
+
throw new Error("Server did not return CI run metadata for resumed task");
|
|
703
|
+
}
|
|
704
|
+
writeAsyncResultFile(options.resultFile, response.run);
|
|
705
|
+
printStandardFields({
|
|
706
|
+
runId: response.run.runId,
|
|
707
|
+
status: response.run.status,
|
|
708
|
+
detailUrl: response.run.detailUrl
|
|
709
|
+
});
|
|
710
|
+
return 0;
|
|
711
|
+
}
|
|
712
|
+
const deadline2 = ensureWaitDeadline(options);
|
|
713
|
+
const finalStatus2 = await resumeRunStream(baseUrl, apiKey, taskId, request2, deadline2);
|
|
714
|
+
writeResultFile(options.resultFile, finalStatus2);
|
|
715
|
+
return exitCodeForStatus(finalStatus2.status);
|
|
716
|
+
}
|
|
648
717
|
const request = buildRequest(options, detected);
|
|
649
718
|
if (options.responseMode === "async") {
|
|
650
719
|
const run = await createRun(baseUrl, apiKey, request);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentrix/agentrix-run",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Native CI submit-and-observe wrapper for Agentrix",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"prepublishOnly": "yarn build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@agentrix/shared": "^2.
|
|
35
|
+
"@agentrix/shared": "^2.40.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": ">=20",
|