@botbotgo/agent-harness 0.0.83 → 0.0.84
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.83";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.83";
|
|
@@ -29,6 +29,7 @@ export declare class AgentHarnessRuntime {
|
|
|
29
29
|
private readonly concurrencyConfig;
|
|
30
30
|
private readonly workerId;
|
|
31
31
|
private activeRunSlots;
|
|
32
|
+
private pendingRunInsertionOrder;
|
|
32
33
|
private readonly pendingRunSlots;
|
|
33
34
|
private runtimeEventSequence;
|
|
34
35
|
private toPublicApprovalRecord;
|
|
@@ -90,6 +91,9 @@ export declare class AgentHarnessRuntime {
|
|
|
90
91
|
private finalizeCancelledRun;
|
|
91
92
|
private invokeWithHistory;
|
|
92
93
|
private buildPersistedRunRequest;
|
|
94
|
+
private normalizeRunPriority;
|
|
95
|
+
private resolvePersistedRunPriority;
|
|
96
|
+
private enqueuePendingRunSlot;
|
|
93
97
|
private executeQueuedRun;
|
|
94
98
|
private checkpointRefForState;
|
|
95
99
|
private finalizeContinuedRun;
|
package/dist/runtime/harness.js
CHANGED
|
@@ -46,6 +46,7 @@ export class AgentHarnessRuntime {
|
|
|
46
46
|
concurrencyConfig;
|
|
47
47
|
workerId = `worker-${createPersistentId()}`;
|
|
48
48
|
activeRunSlots = 0;
|
|
49
|
+
pendingRunInsertionOrder = 0;
|
|
49
50
|
pendingRunSlots = [];
|
|
50
51
|
runtimeEventSequence = 0;
|
|
51
52
|
toPublicApprovalRecord(approval) {
|
|
@@ -512,7 +513,7 @@ export class AgentHarnessRuntime {
|
|
|
512
513
|
throw error;
|
|
513
514
|
}
|
|
514
515
|
}
|
|
515
|
-
buildPersistedRunRequest(input, invocation) {
|
|
516
|
+
buildPersistedRunRequest(input, invocation, priority) {
|
|
516
517
|
const envelope = invocation.invocation ?? {
|
|
517
518
|
...(invocation.context ? { context: invocation.context } : {}),
|
|
518
519
|
...(invocation.state ? { inputs: invocation.state } : {}),
|
|
@@ -520,6 +521,7 @@ export class AgentHarnessRuntime {
|
|
|
520
521
|
};
|
|
521
522
|
return {
|
|
522
523
|
input: normalizeMessageContent(input),
|
|
524
|
+
priority: Number.isFinite(priority) ? Math.trunc(priority) : undefined,
|
|
523
525
|
invocation: envelope && Object.keys(envelope).length > 0
|
|
524
526
|
? {
|
|
525
527
|
...(envelope.context ? { context: envelope.context } : {}),
|
|
@@ -531,6 +533,48 @@ export class AgentHarnessRuntime {
|
|
|
531
533
|
savedAt: new Date().toISOString(),
|
|
532
534
|
};
|
|
533
535
|
}
|
|
536
|
+
normalizeRunPriority(priority) {
|
|
537
|
+
if (!Number.isFinite(priority)) {
|
|
538
|
+
return 0;
|
|
539
|
+
}
|
|
540
|
+
return Math.trunc(priority);
|
|
541
|
+
}
|
|
542
|
+
async resolvePersistedRunPriority(threadId, runId) {
|
|
543
|
+
const persisted = await this.persistence.getRunRequest(threadId, runId);
|
|
544
|
+
return this.normalizeRunPriority(persisted?.priority);
|
|
545
|
+
}
|
|
546
|
+
enqueuePendingRunSlot(entry) {
|
|
547
|
+
const previousPositions = new Map(this.pendingRunSlots
|
|
548
|
+
.filter((candidate) => Boolean(candidate.threadId && candidate.runId))
|
|
549
|
+
.map((candidate, index) => [candidate.runId, index + 1]));
|
|
550
|
+
const queuedEntry = {
|
|
551
|
+
...entry,
|
|
552
|
+
insertionOrder: this.pendingRunInsertionOrder++,
|
|
553
|
+
};
|
|
554
|
+
this.pendingRunSlots.push(queuedEntry);
|
|
555
|
+
this.pendingRunSlots.sort((left, right) => {
|
|
556
|
+
if (right.priority !== left.priority) {
|
|
557
|
+
return right.priority - left.priority;
|
|
558
|
+
}
|
|
559
|
+
return left.insertionOrder - right.insertionOrder;
|
|
560
|
+
});
|
|
561
|
+
return this.pendingRunSlots.flatMap((candidate, index) => {
|
|
562
|
+
if (!candidate.threadId || !candidate.runId) {
|
|
563
|
+
return [];
|
|
564
|
+
}
|
|
565
|
+
const previousPosition = previousPositions.get(candidate.runId);
|
|
566
|
+
const queuePosition = index + 1;
|
|
567
|
+
if (previousPosition === undefined || previousPosition === queuePosition) {
|
|
568
|
+
return [];
|
|
569
|
+
}
|
|
570
|
+
return [{
|
|
571
|
+
threadId: candidate.threadId,
|
|
572
|
+
runId: candidate.runId,
|
|
573
|
+
priority: candidate.priority,
|
|
574
|
+
queuePosition,
|
|
575
|
+
}];
|
|
576
|
+
});
|
|
577
|
+
}
|
|
534
578
|
async executeQueuedRun(binding, input, threadId, runId, agentId, options = {}) {
|
|
535
579
|
const previousState = options.previousState ?? "running";
|
|
536
580
|
const currentRun = await this.persistence.getRun(runId);
|
|
@@ -712,9 +756,9 @@ export class AgentHarnessRuntime {
|
|
|
712
756
|
}
|
|
713
757
|
await listener(value);
|
|
714
758
|
}
|
|
715
|
-
async acquireRunSlot(threadId, runId, activeState = "running") {
|
|
759
|
+
async acquireRunSlot(threadId, runId, activeState = "running", priority = 0) {
|
|
716
760
|
if (threadId && runId) {
|
|
717
|
-
await this.persistence.enqueueRun({ threadId, runId });
|
|
761
|
+
await this.persistence.enqueueRun({ threadId, runId, priority });
|
|
718
762
|
}
|
|
719
763
|
let stopHeartbeat = () => undefined;
|
|
720
764
|
const beginLease = async () => {
|
|
@@ -773,8 +817,50 @@ export class AgentHarnessRuntime {
|
|
|
773
817
|
void next?.activate();
|
|
774
818
|
};
|
|
775
819
|
}
|
|
820
|
+
const activateQueuedRun = async () => {
|
|
821
|
+
const currentRun = runId ? await this.persistence.getRun(runId) : null;
|
|
822
|
+
if (currentRun?.state === "cancelled") {
|
|
823
|
+
return "abort";
|
|
824
|
+
}
|
|
825
|
+
this.activeRunSlots += 1;
|
|
826
|
+
if (threadId && runId) {
|
|
827
|
+
await this.emit(threadId, runId, 4, "run.dequeued", {
|
|
828
|
+
queuePosition: 0,
|
|
829
|
+
activeRunCount: this.activeRunSlots,
|
|
830
|
+
maxConcurrentRuns,
|
|
831
|
+
priority,
|
|
832
|
+
});
|
|
833
|
+
await this.setRunStateAndEmit(threadId, runId, 5, activeState, {
|
|
834
|
+
previousState: "queued",
|
|
835
|
+
});
|
|
836
|
+
await beginLease();
|
|
837
|
+
}
|
|
838
|
+
return "activate";
|
|
839
|
+
};
|
|
776
840
|
if (threadId && runId) {
|
|
777
|
-
const
|
|
841
|
+
const slotAcquisition = new Promise((resolve, reject) => {
|
|
842
|
+
const displacedEntries = this.enqueuePendingRunSlot({
|
|
843
|
+
threadId,
|
|
844
|
+
runId,
|
|
845
|
+
priority,
|
|
846
|
+
activate: async () => {
|
|
847
|
+
try {
|
|
848
|
+
resolve(await activateQueuedRun());
|
|
849
|
+
}
|
|
850
|
+
catch (error) {
|
|
851
|
+
reject(error);
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
abort: () => resolve("abort"),
|
|
855
|
+
});
|
|
856
|
+
void Promise.all(displacedEntries.map((candidate) => this.emit(candidate.threadId, candidate.runId, 3, "run.queued", {
|
|
857
|
+
queuePosition: candidate.queuePosition,
|
|
858
|
+
activeRunCount: this.activeRunSlots,
|
|
859
|
+
maxConcurrentRuns,
|
|
860
|
+
priority: candidate.priority,
|
|
861
|
+
})));
|
|
862
|
+
});
|
|
863
|
+
const queuePosition = this.pendingRunSlots.findIndex((entry) => entry.runId === runId) + 1;
|
|
778
864
|
await this.setRunStateAndEmit(threadId, runId, 2, "queued", {
|
|
779
865
|
previousState: activeState,
|
|
780
866
|
});
|
|
@@ -782,37 +868,23 @@ export class AgentHarnessRuntime {
|
|
|
782
868
|
queuePosition,
|
|
783
869
|
activeRunCount: this.activeRunSlots,
|
|
784
870
|
maxConcurrentRuns,
|
|
871
|
+
priority,
|
|
785
872
|
});
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
});
|
|
802
|
-
await this.setRunStateAndEmit(threadId, runId, 5, activeState, {
|
|
803
|
-
previousState: "queued",
|
|
804
|
-
});
|
|
805
|
-
await beginLease();
|
|
806
|
-
}
|
|
807
|
-
resolve("activate");
|
|
808
|
-
}
|
|
809
|
-
catch (error) {
|
|
810
|
-
reject(error);
|
|
811
|
-
}
|
|
812
|
-
}, abort: () => resolve("abort") });
|
|
813
|
-
});
|
|
814
|
-
if (slotAcquisition === "abort") {
|
|
815
|
-
return async () => undefined;
|
|
873
|
+
const slotAcquisitionResult = await slotAcquisition;
|
|
874
|
+
if (slotAcquisitionResult === "abort") {
|
|
875
|
+
return async () => undefined;
|
|
876
|
+
}
|
|
877
|
+
let released = false;
|
|
878
|
+
return async () => {
|
|
879
|
+
if (released) {
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
released = true;
|
|
883
|
+
await releaseLease();
|
|
884
|
+
this.activeRunSlots = Math.max(0, this.activeRunSlots - 1);
|
|
885
|
+
const next = this.pendingRunSlots.shift();
|
|
886
|
+
void next?.activate();
|
|
887
|
+
};
|
|
816
888
|
}
|
|
817
889
|
let released = false;
|
|
818
890
|
return async () => {
|
|
@@ -923,14 +995,15 @@ export class AgentHarnessRuntime {
|
|
|
923
995
|
throw new Error(`Policy evaluation blocked agent ${selectedAgentId}: ${policyDecision.reasons.join(", ")}`);
|
|
924
996
|
}
|
|
925
997
|
const { threadId, runId } = await this.ensureThreadStarted(selectedAgentId, binding, options.input, options.threadId);
|
|
926
|
-
|
|
998
|
+
const priority = this.normalizeRunPriority(options.priority);
|
|
999
|
+
await this.persistence.saveRunRequest(threadId, runId, this.buildPersistedRunRequest(options.input, invocation, priority));
|
|
927
1000
|
await this.emitRunCreated(threadId, runId, {
|
|
928
1001
|
agentId: binding.agent.id,
|
|
929
1002
|
requestedAgentId: options.agentId ?? AUTO_AGENT_ID,
|
|
930
1003
|
selectedAgentId,
|
|
931
1004
|
executionMode: getBindingAdapterKind(binding),
|
|
932
1005
|
});
|
|
933
|
-
const releaseRunSlot = await this.acquireRunSlot(threadId, runId);
|
|
1006
|
+
const releaseRunSlot = await this.acquireRunSlot(threadId, runId, "running", priority);
|
|
934
1007
|
try {
|
|
935
1008
|
return await this.executeQueuedRun(binding, options.input, threadId, runId, selectedAgentId, {
|
|
936
1009
|
context: invocation.context,
|
|
@@ -965,7 +1038,8 @@ export class AgentHarnessRuntime {
|
|
|
965
1038
|
let emitted = false;
|
|
966
1039
|
let streamActivityObserved = false;
|
|
967
1040
|
const { threadId, runId } = await this.ensureThreadStarted(selectedAgentId, binding, options.input, options.threadId);
|
|
968
|
-
|
|
1041
|
+
const priority = this.normalizeRunPriority(options.priority);
|
|
1042
|
+
await this.persistence.saveRunRequest(threadId, runId, this.buildPersistedRunRequest(options.input, invocation, priority));
|
|
969
1043
|
yield { type: "event", event: await this.emitRunCreated(threadId, runId, {
|
|
970
1044
|
agentId: selectedAgentId,
|
|
971
1045
|
requestedAgentId: options.agentId ?? AUTO_AGENT_ID,
|
|
@@ -973,7 +1047,7 @@ export class AgentHarnessRuntime {
|
|
|
973
1047
|
input: options.input,
|
|
974
1048
|
state: "running",
|
|
975
1049
|
}) };
|
|
976
|
-
const releaseRunSlot = await this.acquireRunSlot(threadId, runId);
|
|
1050
|
+
const releaseRunSlot = await this.acquireRunSlot(threadId, runId, "running", priority);
|
|
977
1051
|
try {
|
|
978
1052
|
try {
|
|
979
1053
|
const priorHistory = await this.loadPriorHistory(threadId, runId);
|
|
@@ -1229,7 +1303,7 @@ export class AgentHarnessRuntime {
|
|
|
1229
1303
|
return this.finalizeCancelledRun(threadId, runId, thread.status, cancellation.reason);
|
|
1230
1304
|
}
|
|
1231
1305
|
await this.persistence.setRunState(threadId, runId, "resuming", `checkpoints/${threadId}/${runId}/cp-1`);
|
|
1232
|
-
const releaseRunSlot = await this.acquireRunSlot(threadId, runId, "resuming");
|
|
1306
|
+
const releaseRunSlot = await this.acquireRunSlot(threadId, runId, "resuming", await this.resolvePersistedRunPriority(threadId, runId));
|
|
1233
1307
|
try {
|
|
1234
1308
|
await this.persistence.saveRecoveryIntent(threadId, runId, {
|
|
1235
1309
|
kind: "approval-decision",
|
|
@@ -1410,7 +1484,7 @@ export class AgentHarnessRuntime {
|
|
|
1410
1484
|
});
|
|
1411
1485
|
continue;
|
|
1412
1486
|
}
|
|
1413
|
-
const releaseRunSlot = await this.acquireRunSlot(thread.threadId, thread.latestRunId);
|
|
1487
|
+
const releaseRunSlot = await this.acquireRunSlot(thread.threadId, thread.latestRunId, "running", this.normalizeRunPriority(request.priority));
|
|
1414
1488
|
try {
|
|
1415
1489
|
await this.executeQueuedRun(binding, request.input, thread.threadId, thread.latestRunId, runMeta.agentId, {
|
|
1416
1490
|
context: request.invocation?.context,
|
|
@@ -1453,7 +1527,7 @@ export class AgentHarnessRuntime {
|
|
|
1453
1527
|
await this.persistence.releaseRunClaim(thread.latestRunId);
|
|
1454
1528
|
continue;
|
|
1455
1529
|
}
|
|
1456
|
-
const releaseRunSlot = await this.acquireRunSlot(thread.threadId, thread.latestRunId, "running");
|
|
1530
|
+
const releaseRunSlot = await this.acquireRunSlot(thread.threadId, thread.latestRunId, "running", this.normalizeRunPriority(request.priority));
|
|
1457
1531
|
try {
|
|
1458
1532
|
await this.emit(thread.threadId, thread.latestRunId, 100, "run.resumed", {
|
|
1459
1533
|
resumeKind: "startup-running-recovery",
|