@agentrix/agentrix-run 0.6.0 → 0.8.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 +120 -16
- package/dist/index.mjs +121 -17
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -8,17 +8,21 @@ const DEFAULT_WAIT_TIMEOUT_SECONDS = 1800;
|
|
|
8
8
|
const DEFAULT_AGENTRIX_BASE_URL = "https://agentrix.xmz.ai";
|
|
9
9
|
function usage() {
|
|
10
10
|
return [
|
|
11
|
-
"Usage: agentrix-run --agent <agent> --prompt <prompt> [options]",
|
|
11
|
+
"Usage: agentrix-run (--agent <agent> | --resume <task-id>) --prompt <prompt> [options]",
|
|
12
12
|
"",
|
|
13
13
|
"Options:",
|
|
14
14
|
" --title <text>",
|
|
15
15
|
" --allow-filesystem-agent",
|
|
16
|
+
" --resume <task-id>",
|
|
16
17
|
" --repo <json>",
|
|
17
18
|
" --output-schema <json>",
|
|
18
19
|
" --ref <ref>",
|
|
19
20
|
" --sha <sha>",
|
|
20
21
|
" --base-ref <ref>",
|
|
21
22
|
" --head-ref <ref>",
|
|
23
|
+
" --head-sha <sha>",
|
|
24
|
+
" --checkout-ref <ref>",
|
|
25
|
+
" --checkout-sha <sha>",
|
|
22
26
|
" --branch-name <name>",
|
|
23
27
|
" --pr-number <number>",
|
|
24
28
|
" --issue-number <number>",
|
|
@@ -181,6 +185,10 @@ function parseArgs(argv) {
|
|
|
181
185
|
case "--allow-filesystem-agent":
|
|
182
186
|
options.allowFilesystemAgent = true;
|
|
183
187
|
break;
|
|
188
|
+
case "--resume":
|
|
189
|
+
options.resumeTaskId = requireValue(argv, index, arg);
|
|
190
|
+
index += 1;
|
|
191
|
+
break;
|
|
184
192
|
case "--title":
|
|
185
193
|
options.title = requireValue(argv, index, arg);
|
|
186
194
|
index += 1;
|
|
@@ -213,6 +221,18 @@ function parseArgs(argv) {
|
|
|
213
221
|
options.headRef = requireValue(argv, index, arg);
|
|
214
222
|
index += 1;
|
|
215
223
|
break;
|
|
224
|
+
case "--head-sha":
|
|
225
|
+
options.headSha = requireValue(argv, index, arg);
|
|
226
|
+
index += 1;
|
|
227
|
+
break;
|
|
228
|
+
case "--checkout-ref":
|
|
229
|
+
options.checkoutRef = requireValue(argv, index, arg);
|
|
230
|
+
index += 1;
|
|
231
|
+
break;
|
|
232
|
+
case "--checkout-sha":
|
|
233
|
+
options.checkoutSha = requireValue(argv, index, arg);
|
|
234
|
+
index += 1;
|
|
235
|
+
break;
|
|
216
236
|
case "--branch-name":
|
|
217
237
|
options.branchName = requireValue(argv, index, arg);
|
|
218
238
|
index += 1;
|
|
@@ -268,12 +288,15 @@ function parseArgs(argv) {
|
|
|
268
288
|
throw new Error(`Unknown argument: ${arg}`);
|
|
269
289
|
}
|
|
270
290
|
}
|
|
271
|
-
if (!options.agent.trim()) {
|
|
291
|
+
if (!options.resumeTaskId && !options.agent.trim()) {
|
|
272
292
|
throw new Error("--agent is required");
|
|
273
293
|
}
|
|
274
294
|
if (!options.prompt.trim()) {
|
|
275
295
|
throw new Error("--prompt is required");
|
|
276
296
|
}
|
|
297
|
+
if (options.resumeTaskId !== void 0 && !options.resumeTaskId.trim()) {
|
|
298
|
+
throw new Error("--resume must be a non-empty task ID");
|
|
299
|
+
}
|
|
277
300
|
return options;
|
|
278
301
|
}
|
|
279
302
|
function normalizeRef(value) {
|
|
@@ -317,6 +340,15 @@ function optionalPositiveInt(value) {
|
|
|
317
340
|
const parsed = Number.parseInt(value, 10);
|
|
318
341
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
319
342
|
}
|
|
343
|
+
function firstEnv(...names) {
|
|
344
|
+
for (const name of names) {
|
|
345
|
+
const value = process.env[name];
|
|
346
|
+
if (value) {
|
|
347
|
+
return value;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return void 0;
|
|
351
|
+
}
|
|
320
352
|
function readBooleanEnv(name) {
|
|
321
353
|
const value = process.env[name]?.trim().toLowerCase();
|
|
322
354
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
@@ -359,6 +391,7 @@ function detectGithub() {
|
|
|
359
391
|
sha: process.env.GITHUB_SHA,
|
|
360
392
|
baseRef: process.env.GITHUB_BASE_REF || getNestedString(payload, "pull_request", "base", "ref"),
|
|
361
393
|
headRef: process.env.GITHUB_HEAD_REF || getNestedString(payload, "pull_request", "head", "ref"),
|
|
394
|
+
headSha: getNestedString(payload, "pull_request", "head", "sha"),
|
|
362
395
|
prNumber: getNestedNumber(payload, "pull_request", "number"),
|
|
363
396
|
issueNumber: getNestedNumber(payload, "issue", "number")
|
|
364
397
|
},
|
|
@@ -383,19 +416,24 @@ function detectGitlab() {
|
|
|
383
416
|
name: repository.name
|
|
384
417
|
},
|
|
385
418
|
git: {
|
|
386
|
-
ref:
|
|
387
|
-
sha:
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
419
|
+
ref: firstEnv("GITLAB_BRIDGE_REF_NAME", "CI_COMMIT_REF_NAME"),
|
|
420
|
+
sha: firstEnv(
|
|
421
|
+
"GITLAB_BRIDGE_HEAD_SHA",
|
|
422
|
+
"GITLAB_BRIDGE_WORKFLOW_RUN_SHA",
|
|
423
|
+
"CI_COMMIT_SHA"
|
|
424
|
+
),
|
|
425
|
+
baseRef: firstEnv("GITLAB_BRIDGE_BASE_REF", "CI_MERGE_REQUEST_TARGET_BRANCH_NAME"),
|
|
426
|
+
headRef: firstEnv("GITLAB_BRIDGE_HEAD_REF", "CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"),
|
|
427
|
+
headSha: firstEnv("GITLAB_BRIDGE_HEAD_SHA", "CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"),
|
|
428
|
+
prNumber: optionalPositiveInt(firstEnv("GITLAB_BRIDGE_PR_NUMBER", "CI_MERGE_REQUEST_IID")),
|
|
429
|
+
issueNumber: optionalPositiveInt(firstEnv("GITLAB_BRIDGE_ISSUE_NUMBER", "AGENTRIX_ISSUE_NUMBER"))
|
|
392
430
|
},
|
|
393
431
|
context: {
|
|
394
432
|
ciProvider: "gitlab_ci",
|
|
395
|
-
eventName:
|
|
396
|
-
eventAction: process.env.
|
|
433
|
+
eventName: firstEnv("GITLAB_BRIDGE_EVENT_NAME", "CI_PIPELINE_SOURCE"),
|
|
434
|
+
eventAction: process.env.GITLAB_BRIDGE_EVENT_ACTION,
|
|
397
435
|
jobUrl: process.env.CI_JOB_URL,
|
|
398
|
-
runUrl:
|
|
436
|
+
runUrl: firstEnv("GITLAB_BRIDGE_WORKFLOW_RUN_URL", "CI_PIPELINE_URL")
|
|
399
437
|
}
|
|
400
438
|
};
|
|
401
439
|
}
|
|
@@ -431,6 +469,9 @@ function buildRequest(options, detected) {
|
|
|
431
469
|
sha: options.sha ?? detected.git?.sha,
|
|
432
470
|
baseRef: options.baseRef ?? detected.git?.baseRef,
|
|
433
471
|
headRef: options.headRef ?? detected.git?.headRef,
|
|
472
|
+
headSha: options.headSha ?? detected.git?.headSha,
|
|
473
|
+
checkoutRef: options.checkoutRef ?? detected.git?.checkoutRef,
|
|
474
|
+
checkoutSha: options.checkoutSha ?? detected.git?.checkoutSha,
|
|
434
475
|
branchName: options.branchName || process.env.AGENTRIX_BRANCH_NAME,
|
|
435
476
|
prNumber: options.prNumber ?? detected.git?.prNumber,
|
|
436
477
|
issueNumber: options.issueNumber ?? detected.git?.issueNumber
|
|
@@ -441,10 +482,10 @@ function buildRequest(options, detected) {
|
|
|
441
482
|
},
|
|
442
483
|
context: detected.context?.ciProvider ? {
|
|
443
484
|
ciProvider: detected.context.ciProvider,
|
|
444
|
-
eventName:
|
|
445
|
-
eventAction:
|
|
485
|
+
eventName: detected.context.eventName,
|
|
486
|
+
eventAction: detected.context.eventAction,
|
|
446
487
|
jobUrl: process.env.AGENTRIX_JOB_URL || detected.context.jobUrl,
|
|
447
|
-
runUrl:
|
|
488
|
+
runUrl: detected.context.runUrl,
|
|
448
489
|
payload: detected.context.payload
|
|
449
490
|
} : void 0,
|
|
450
491
|
metadata: Object.keys(options.metadata).length > 0 ? options.metadata : void 0
|
|
@@ -483,6 +524,36 @@ async function createRun(baseUrl, apiKey, request) {
|
|
|
483
524
|
const response = await requestJson("POST", `${baseUrl}/v1/ci/runs`, apiKey, request);
|
|
484
525
|
return shared.CreateCiRunResponseSchema.parse(response);
|
|
485
526
|
}
|
|
527
|
+
function createPromptMessage(text) {
|
|
528
|
+
return {
|
|
529
|
+
type: "user",
|
|
530
|
+
message: {
|
|
531
|
+
role: "user",
|
|
532
|
+
content: text.trim()
|
|
533
|
+
},
|
|
534
|
+
parent_tool_use_id: null,
|
|
535
|
+
session_id: ""
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
function buildResumeMessageRequest(options) {
|
|
539
|
+
return {
|
|
540
|
+
message: createPromptMessage(options.prompt),
|
|
541
|
+
target: "agent",
|
|
542
|
+
senderType: "human",
|
|
543
|
+
senderId: "agentrix-run",
|
|
544
|
+
senderName: "agentrix-run",
|
|
545
|
+
responseMode: options.responseMode
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
async function sendResumeMessage(baseUrl, apiKey, taskId, request) {
|
|
549
|
+
const response = await requestJson(
|
|
550
|
+
"POST",
|
|
551
|
+
`${baseUrl}/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
552
|
+
apiKey,
|
|
553
|
+
request
|
|
554
|
+
);
|
|
555
|
+
return shared.SendTaskMessageResponseSchema.parse(response);
|
|
556
|
+
}
|
|
486
557
|
function exitCodeForStatus(status) {
|
|
487
558
|
return status === "completed" ? 0 : 1;
|
|
488
559
|
}
|
|
@@ -567,12 +638,12 @@ function parseSseBlock(block) {
|
|
|
567
638
|
data: JSON.parse(dataText)
|
|
568
639
|
};
|
|
569
640
|
}
|
|
570
|
-
async function
|
|
641
|
+
async function streamRunRequest(baseUrl, apiKey, path, request, deadline) {
|
|
571
642
|
const timeoutMs = Math.max(deadline - Date.now(), 1);
|
|
572
643
|
const controller = new AbortController();
|
|
573
644
|
const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
|
|
574
645
|
try {
|
|
575
|
-
const response = await fetch(`${baseUrl}
|
|
646
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
576
647
|
method: "POST",
|
|
577
648
|
headers: {
|
|
578
649
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -640,11 +711,44 @@ async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
|
640
711
|
clearTimeout(timeoutHandle);
|
|
641
712
|
}
|
|
642
713
|
}
|
|
714
|
+
async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
715
|
+
return streamRunRequest(baseUrl, apiKey, "/v1/ci/runs", request, deadline);
|
|
716
|
+
}
|
|
717
|
+
async function resumeRunStream(baseUrl, apiKey, taskId, request, deadline) {
|
|
718
|
+
return streamRunRequest(
|
|
719
|
+
baseUrl,
|
|
720
|
+
apiKey,
|
|
721
|
+
`/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
722
|
+
request,
|
|
723
|
+
deadline
|
|
724
|
+
);
|
|
725
|
+
}
|
|
643
726
|
async function main(argv = process.argv.slice(2)) {
|
|
644
727
|
const options = parseArgs(argv);
|
|
645
728
|
const detected = detectCiContext();
|
|
646
729
|
const baseUrl = resolveBaseUrl(options);
|
|
647
730
|
const apiKey = resolveApiKey(options);
|
|
731
|
+
if (options.resumeTaskId) {
|
|
732
|
+
const taskId = options.resumeTaskId.trim();
|
|
733
|
+
const request2 = buildResumeMessageRequest(options);
|
|
734
|
+
if (options.responseMode === "async") {
|
|
735
|
+
const response = await sendResumeMessage(baseUrl, apiKey, taskId, request2);
|
|
736
|
+
if (!response.run) {
|
|
737
|
+
throw new Error("Server did not return CI run metadata for resumed task");
|
|
738
|
+
}
|
|
739
|
+
writeAsyncResultFile(options.resultFile, response.run);
|
|
740
|
+
printStandardFields({
|
|
741
|
+
runId: response.run.runId,
|
|
742
|
+
status: response.run.status,
|
|
743
|
+
detailUrl: response.run.detailUrl
|
|
744
|
+
});
|
|
745
|
+
return 0;
|
|
746
|
+
}
|
|
747
|
+
const deadline2 = ensureWaitDeadline(options);
|
|
748
|
+
const finalStatus2 = await resumeRunStream(baseUrl, apiKey, taskId, request2, deadline2);
|
|
749
|
+
writeResultFile(options.resultFile, finalStatus2);
|
|
750
|
+
return exitCodeForStatus(finalStatus2.status);
|
|
751
|
+
}
|
|
648
752
|
const request = buildRequest(options, detected);
|
|
649
753
|
if (options.responseMode === "async") {
|
|
650
754
|
const run = await createRun(baseUrl, apiKey, request);
|
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
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
6
|
const DEFAULT_AGENTRIX_BASE_URL = "https://agentrix.xmz.ai";
|
|
7
7
|
function usage() {
|
|
8
8
|
return [
|
|
9
|
-
"Usage: agentrix-run --agent <agent> --prompt <prompt> [options]",
|
|
9
|
+
"Usage: agentrix-run (--agent <agent> | --resume <task-id>) --prompt <prompt> [options]",
|
|
10
10
|
"",
|
|
11
11
|
"Options:",
|
|
12
12
|
" --title <text>",
|
|
13
13
|
" --allow-filesystem-agent",
|
|
14
|
+
" --resume <task-id>",
|
|
14
15
|
" --repo <json>",
|
|
15
16
|
" --output-schema <json>",
|
|
16
17
|
" --ref <ref>",
|
|
17
18
|
" --sha <sha>",
|
|
18
19
|
" --base-ref <ref>",
|
|
19
20
|
" --head-ref <ref>",
|
|
21
|
+
" --head-sha <sha>",
|
|
22
|
+
" --checkout-ref <ref>",
|
|
23
|
+
" --checkout-sha <sha>",
|
|
20
24
|
" --branch-name <name>",
|
|
21
25
|
" --pr-number <number>",
|
|
22
26
|
" --issue-number <number>",
|
|
@@ -179,6 +183,10 @@ function parseArgs(argv) {
|
|
|
179
183
|
case "--allow-filesystem-agent":
|
|
180
184
|
options.allowFilesystemAgent = true;
|
|
181
185
|
break;
|
|
186
|
+
case "--resume":
|
|
187
|
+
options.resumeTaskId = requireValue(argv, index, arg);
|
|
188
|
+
index += 1;
|
|
189
|
+
break;
|
|
182
190
|
case "--title":
|
|
183
191
|
options.title = requireValue(argv, index, arg);
|
|
184
192
|
index += 1;
|
|
@@ -211,6 +219,18 @@ function parseArgs(argv) {
|
|
|
211
219
|
options.headRef = requireValue(argv, index, arg);
|
|
212
220
|
index += 1;
|
|
213
221
|
break;
|
|
222
|
+
case "--head-sha":
|
|
223
|
+
options.headSha = requireValue(argv, index, arg);
|
|
224
|
+
index += 1;
|
|
225
|
+
break;
|
|
226
|
+
case "--checkout-ref":
|
|
227
|
+
options.checkoutRef = requireValue(argv, index, arg);
|
|
228
|
+
index += 1;
|
|
229
|
+
break;
|
|
230
|
+
case "--checkout-sha":
|
|
231
|
+
options.checkoutSha = requireValue(argv, index, arg);
|
|
232
|
+
index += 1;
|
|
233
|
+
break;
|
|
214
234
|
case "--branch-name":
|
|
215
235
|
options.branchName = requireValue(argv, index, arg);
|
|
216
236
|
index += 1;
|
|
@@ -266,12 +286,15 @@ function parseArgs(argv) {
|
|
|
266
286
|
throw new Error(`Unknown argument: ${arg}`);
|
|
267
287
|
}
|
|
268
288
|
}
|
|
269
|
-
if (!options.agent.trim()) {
|
|
289
|
+
if (!options.resumeTaskId && !options.agent.trim()) {
|
|
270
290
|
throw new Error("--agent is required");
|
|
271
291
|
}
|
|
272
292
|
if (!options.prompt.trim()) {
|
|
273
293
|
throw new Error("--prompt is required");
|
|
274
294
|
}
|
|
295
|
+
if (options.resumeTaskId !== void 0 && !options.resumeTaskId.trim()) {
|
|
296
|
+
throw new Error("--resume must be a non-empty task ID");
|
|
297
|
+
}
|
|
275
298
|
return options;
|
|
276
299
|
}
|
|
277
300
|
function normalizeRef(value) {
|
|
@@ -315,6 +338,15 @@ function optionalPositiveInt(value) {
|
|
|
315
338
|
const parsed = Number.parseInt(value, 10);
|
|
316
339
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
317
340
|
}
|
|
341
|
+
function firstEnv(...names) {
|
|
342
|
+
for (const name of names) {
|
|
343
|
+
const value = process.env[name];
|
|
344
|
+
if (value) {
|
|
345
|
+
return value;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return void 0;
|
|
349
|
+
}
|
|
318
350
|
function readBooleanEnv(name) {
|
|
319
351
|
const value = process.env[name]?.trim().toLowerCase();
|
|
320
352
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
@@ -357,6 +389,7 @@ function detectGithub() {
|
|
|
357
389
|
sha: process.env.GITHUB_SHA,
|
|
358
390
|
baseRef: process.env.GITHUB_BASE_REF || getNestedString(payload, "pull_request", "base", "ref"),
|
|
359
391
|
headRef: process.env.GITHUB_HEAD_REF || getNestedString(payload, "pull_request", "head", "ref"),
|
|
392
|
+
headSha: getNestedString(payload, "pull_request", "head", "sha"),
|
|
360
393
|
prNumber: getNestedNumber(payload, "pull_request", "number"),
|
|
361
394
|
issueNumber: getNestedNumber(payload, "issue", "number")
|
|
362
395
|
},
|
|
@@ -381,19 +414,24 @@ function detectGitlab() {
|
|
|
381
414
|
name: repository.name
|
|
382
415
|
},
|
|
383
416
|
git: {
|
|
384
|
-
ref:
|
|
385
|
-
sha:
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
417
|
+
ref: firstEnv("GITLAB_BRIDGE_REF_NAME", "CI_COMMIT_REF_NAME"),
|
|
418
|
+
sha: firstEnv(
|
|
419
|
+
"GITLAB_BRIDGE_HEAD_SHA",
|
|
420
|
+
"GITLAB_BRIDGE_WORKFLOW_RUN_SHA",
|
|
421
|
+
"CI_COMMIT_SHA"
|
|
422
|
+
),
|
|
423
|
+
baseRef: firstEnv("GITLAB_BRIDGE_BASE_REF", "CI_MERGE_REQUEST_TARGET_BRANCH_NAME"),
|
|
424
|
+
headRef: firstEnv("GITLAB_BRIDGE_HEAD_REF", "CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"),
|
|
425
|
+
headSha: firstEnv("GITLAB_BRIDGE_HEAD_SHA", "CI_MERGE_REQUEST_SOURCE_BRANCH_SHA"),
|
|
426
|
+
prNumber: optionalPositiveInt(firstEnv("GITLAB_BRIDGE_PR_NUMBER", "CI_MERGE_REQUEST_IID")),
|
|
427
|
+
issueNumber: optionalPositiveInt(firstEnv("GITLAB_BRIDGE_ISSUE_NUMBER", "AGENTRIX_ISSUE_NUMBER"))
|
|
390
428
|
},
|
|
391
429
|
context: {
|
|
392
430
|
ciProvider: "gitlab_ci",
|
|
393
|
-
eventName:
|
|
394
|
-
eventAction: process.env.
|
|
431
|
+
eventName: firstEnv("GITLAB_BRIDGE_EVENT_NAME", "CI_PIPELINE_SOURCE"),
|
|
432
|
+
eventAction: process.env.GITLAB_BRIDGE_EVENT_ACTION,
|
|
395
433
|
jobUrl: process.env.CI_JOB_URL,
|
|
396
|
-
runUrl:
|
|
434
|
+
runUrl: firstEnv("GITLAB_BRIDGE_WORKFLOW_RUN_URL", "CI_PIPELINE_URL")
|
|
397
435
|
}
|
|
398
436
|
};
|
|
399
437
|
}
|
|
@@ -429,6 +467,9 @@ function buildRequest(options, detected) {
|
|
|
429
467
|
sha: options.sha ?? detected.git?.sha,
|
|
430
468
|
baseRef: options.baseRef ?? detected.git?.baseRef,
|
|
431
469
|
headRef: options.headRef ?? detected.git?.headRef,
|
|
470
|
+
headSha: options.headSha ?? detected.git?.headSha,
|
|
471
|
+
checkoutRef: options.checkoutRef ?? detected.git?.checkoutRef,
|
|
472
|
+
checkoutSha: options.checkoutSha ?? detected.git?.checkoutSha,
|
|
432
473
|
branchName: options.branchName || process.env.AGENTRIX_BRANCH_NAME,
|
|
433
474
|
prNumber: options.prNumber ?? detected.git?.prNumber,
|
|
434
475
|
issueNumber: options.issueNumber ?? detected.git?.issueNumber
|
|
@@ -439,10 +480,10 @@ function buildRequest(options, detected) {
|
|
|
439
480
|
},
|
|
440
481
|
context: detected.context?.ciProvider ? {
|
|
441
482
|
ciProvider: detected.context.ciProvider,
|
|
442
|
-
eventName:
|
|
443
|
-
eventAction:
|
|
483
|
+
eventName: detected.context.eventName,
|
|
484
|
+
eventAction: detected.context.eventAction,
|
|
444
485
|
jobUrl: process.env.AGENTRIX_JOB_URL || detected.context.jobUrl,
|
|
445
|
-
runUrl:
|
|
486
|
+
runUrl: detected.context.runUrl,
|
|
446
487
|
payload: detected.context.payload
|
|
447
488
|
} : void 0,
|
|
448
489
|
metadata: Object.keys(options.metadata).length > 0 ? options.metadata : void 0
|
|
@@ -481,6 +522,36 @@ async function createRun(baseUrl, apiKey, request) {
|
|
|
481
522
|
const response = await requestJson("POST", `${baseUrl}/v1/ci/runs`, apiKey, request);
|
|
482
523
|
return CreateCiRunResponseSchema.parse(response);
|
|
483
524
|
}
|
|
525
|
+
function createPromptMessage(text) {
|
|
526
|
+
return {
|
|
527
|
+
type: "user",
|
|
528
|
+
message: {
|
|
529
|
+
role: "user",
|
|
530
|
+
content: text.trim()
|
|
531
|
+
},
|
|
532
|
+
parent_tool_use_id: null,
|
|
533
|
+
session_id: ""
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
function buildResumeMessageRequest(options) {
|
|
537
|
+
return {
|
|
538
|
+
message: createPromptMessage(options.prompt),
|
|
539
|
+
target: "agent",
|
|
540
|
+
senderType: "human",
|
|
541
|
+
senderId: "agentrix-run",
|
|
542
|
+
senderName: "agentrix-run",
|
|
543
|
+
responseMode: options.responseMode
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
async function sendResumeMessage(baseUrl, apiKey, taskId, request) {
|
|
547
|
+
const response = await requestJson(
|
|
548
|
+
"POST",
|
|
549
|
+
`${baseUrl}/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
550
|
+
apiKey,
|
|
551
|
+
request
|
|
552
|
+
);
|
|
553
|
+
return SendTaskMessageResponseSchema.parse(response);
|
|
554
|
+
}
|
|
484
555
|
function exitCodeForStatus(status) {
|
|
485
556
|
return status === "completed" ? 0 : 1;
|
|
486
557
|
}
|
|
@@ -565,12 +636,12 @@ function parseSseBlock(block) {
|
|
|
565
636
|
data: JSON.parse(dataText)
|
|
566
637
|
};
|
|
567
638
|
}
|
|
568
|
-
async function
|
|
639
|
+
async function streamRunRequest(baseUrl, apiKey, path, request, deadline) {
|
|
569
640
|
const timeoutMs = Math.max(deadline - Date.now(), 1);
|
|
570
641
|
const controller = new AbortController();
|
|
571
642
|
const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
|
|
572
643
|
try {
|
|
573
|
-
const response = await fetch(`${baseUrl}
|
|
644
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
574
645
|
method: "POST",
|
|
575
646
|
headers: {
|
|
576
647
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -638,11 +709,44 @@ async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
|
638
709
|
clearTimeout(timeoutHandle);
|
|
639
710
|
}
|
|
640
711
|
}
|
|
712
|
+
async function createRunStream(baseUrl, apiKey, request, deadline) {
|
|
713
|
+
return streamRunRequest(baseUrl, apiKey, "/v1/ci/runs", request, deadline);
|
|
714
|
+
}
|
|
715
|
+
async function resumeRunStream(baseUrl, apiKey, taskId, request, deadline) {
|
|
716
|
+
return streamRunRequest(
|
|
717
|
+
baseUrl,
|
|
718
|
+
apiKey,
|
|
719
|
+
`/v1/tasks/${encodeURIComponent(taskId)}/send-message`,
|
|
720
|
+
request,
|
|
721
|
+
deadline
|
|
722
|
+
);
|
|
723
|
+
}
|
|
641
724
|
async function main(argv = process.argv.slice(2)) {
|
|
642
725
|
const options = parseArgs(argv);
|
|
643
726
|
const detected = detectCiContext();
|
|
644
727
|
const baseUrl = resolveBaseUrl(options);
|
|
645
728
|
const apiKey = resolveApiKey(options);
|
|
729
|
+
if (options.resumeTaskId) {
|
|
730
|
+
const taskId = options.resumeTaskId.trim();
|
|
731
|
+
const request2 = buildResumeMessageRequest(options);
|
|
732
|
+
if (options.responseMode === "async") {
|
|
733
|
+
const response = await sendResumeMessage(baseUrl, apiKey, taskId, request2);
|
|
734
|
+
if (!response.run) {
|
|
735
|
+
throw new Error("Server did not return CI run metadata for resumed task");
|
|
736
|
+
}
|
|
737
|
+
writeAsyncResultFile(options.resultFile, response.run);
|
|
738
|
+
printStandardFields({
|
|
739
|
+
runId: response.run.runId,
|
|
740
|
+
status: response.run.status,
|
|
741
|
+
detailUrl: response.run.detailUrl
|
|
742
|
+
});
|
|
743
|
+
return 0;
|
|
744
|
+
}
|
|
745
|
+
const deadline2 = ensureWaitDeadline(options);
|
|
746
|
+
const finalStatus2 = await resumeRunStream(baseUrl, apiKey, taskId, request2, deadline2);
|
|
747
|
+
writeResultFile(options.resultFile, finalStatus2);
|
|
748
|
+
return exitCodeForStatus(finalStatus2.status);
|
|
749
|
+
}
|
|
646
750
|
const request = buildRequest(options, detected);
|
|
647
751
|
if (options.responseMode === "async") {
|
|
648
752
|
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.8.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.41.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": ">=20",
|