@kynver-app/runtime 0.1.76 → 0.1.77

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.
@@ -0,0 +1,10 @@
1
+ import type { HarnessWorkerRecord } from "./status.js";
2
+ /**
3
+ * A finished worker whose completion POST was recorded but did not advance the
4
+ * linked AgentTask (structural blocker or rejected outcome) must be eligible for
5
+ * idempotent completion replay on later pipeline ticks — not skipped as "already
6
+ * acknowledged".
7
+ */
8
+ export declare function shouldReplayHarnessCompletion(worker: HarnessWorkerRecord): boolean;
9
+ /** Terminal ack with no structural reason to replay completion to AgentOS. */
10
+ export declare function hasTerminalCompletionAck(worker: HarnessWorkerRecord): boolean;
package/dist/index.js CHANGED
@@ -1863,7 +1863,9 @@ function computeWorkerStatus(worker, options = {}) {
1863
1863
  finalResult,
1864
1864
  error,
1865
1865
  changedFiles,
1866
- gitAncestry
1866
+ gitAncestry,
1867
+ instructionPolicyFingerprint: worker.instructionPolicyFingerprint ?? null,
1868
+ instructionPolicyEvidence: worker.instructionPolicyEvidence ?? null
1867
1869
  };
1868
1870
  }
1869
1871
  function isFinishedWorkerStatus(status) {
@@ -3670,6 +3672,21 @@ function persistCompletionAck(worker, runId, fields) {
3670
3672
  saveWorker(runId, worker);
3671
3673
  }
3672
3674
 
3675
+ // src/completion-replay.ts
3676
+ function trimBlocker(value) {
3677
+ if (typeof value !== "string") return null;
3678
+ const trimmed = value.trim();
3679
+ return trimmed.length ? trimmed : null;
3680
+ }
3681
+ function shouldReplayHarnessCompletion(worker) {
3682
+ if (trimBlocker(worker.completionBlocker)) return true;
3683
+ if (worker.completionOutcome === "rejected") return true;
3684
+ return false;
3685
+ }
3686
+ function hasTerminalCompletionAck(worker) {
3687
+ return hasCompletionAck(worker) && !shouldReplayHarnessCompletion(worker);
3688
+ }
3689
+
3673
3690
  // src/worker-ops.ts
3674
3691
  import path17 from "node:path";
3675
3692
 
@@ -4488,7 +4505,7 @@ async function tryCompleteWorker(args) {
4488
4505
  return { ok: true, skipped: true, reason: "worker-not-finished" };
4489
4506
  }
4490
4507
  const forceReplay = args.force === true || args.force === "true";
4491
- if (!forceReplay && hasCompletionAck(worker)) {
4508
+ if (!forceReplay && hasTerminalCompletionAck(worker)) {
4492
4509
  return {
4493
4510
  ok: true,
4494
4511
  skipped: true,
@@ -4880,7 +4897,7 @@ async function autoCompleteWorker(raw) {
4880
4897
  reason: "worker has no agentOsId/taskId \u2014 nothing to attribute completion to"
4881
4898
  };
4882
4899
  }
4883
- if (hasCompletionAck(worker)) {
4900
+ if (hasTerminalCompletionAck(worker)) {
4884
4901
  return {
4885
4902
  worker: worker.name,
4886
4903
  runId: worker.runId,
@@ -4893,7 +4910,7 @@ async function autoCompleteWorker(raw) {
4893
4910
  const startMs = Date.now();
4894
4911
  while (true) {
4895
4912
  worker = loadWorker(args.run, args.name);
4896
- if (hasCompletionAck(worker)) {
4913
+ if (hasTerminalCompletionAck(worker)) {
4897
4914
  return {
4898
4915
  worker: worker.name,
4899
4916
  runId: worker.runId,
@@ -6192,7 +6209,23 @@ async function dispatchRun(args) {
6192
6209
  for (const decision of result.started) {
6193
6210
  shouldContinueDispatch = await spawnClaimed(decision) && shouldContinueDispatch;
6194
6211
  }
6195
- skipped.push(...result.skipped ?? []);
6212
+ skipped.push(
6213
+ ...result.skipped ?? []
6214
+ );
6215
+ if (exactTargetMode) {
6216
+ for (const skipDecision of skipped) {
6217
+ const taskId = String(skipDecision.task.id);
6218
+ if (!exactTargetIds.has(taskId)) continue;
6219
+ outcomes.push({
6220
+ taskId,
6221
+ started: false,
6222
+ error: `exact_target_not_started:${skipDecision.skipReason}`,
6223
+ skipReason: skipDecision.skipReason,
6224
+ detail: skipDecision.reason ?? null,
6225
+ requestedTargetTaskIds: [...exactTargetIds]
6226
+ });
6227
+ }
6228
+ }
6196
6229
  if (exactTargetMode) shouldContinueDispatch = false;
6197
6230
  while (shouldContinueDispatch && outcomes.length < cappedStarts) {
6198
6231
  if (exactTargetMode) break;
@@ -8931,6 +8964,24 @@ async function runPipelineDispatch(args, slots) {
8931
8964
  };
8932
8965
  }
8933
8966
 
8967
+ // src/pipeline-exact-targets.ts
8968
+ function operatorExactTargetTaskIds(operatorTick) {
8969
+ if (!operatorTick || typeof operatorTick !== "object") return [];
8970
+ const body = operatorTick;
8971
+ const raw = body.response?.dispatch?.exactTargetTaskIds;
8972
+ if (!Array.isArray(raw)) return [];
8973
+ const seen = /* @__PURE__ */ new Set();
8974
+ const out = [];
8975
+ for (const value of raw) {
8976
+ if (typeof value !== "string") continue;
8977
+ const id = value.trim();
8978
+ if (!id || seen.has(id)) continue;
8979
+ seen.add(id);
8980
+ out.push(id);
8981
+ }
8982
+ return out;
8983
+ }
8984
+
8934
8985
  // src/pipeline-max-starts.ts
8935
8986
  function operatorDispatchFromTick(operatorTick) {
8936
8987
  const body = operatorTick;
@@ -9090,7 +9141,7 @@ async function completeFinishedWorkers(runId, args) {
9090
9141
  void 0
9091
9142
  );
9092
9143
  if (!worker?.taskId || worker.localOnly) continue;
9093
- if (hasCompletionAck(worker)) {
9144
+ if (hasTerminalCompletionAck(worker)) {
9094
9145
  outcomes.push({ worker: name, ok: true, taskId: worker.taskId ?? null, skipped: true });
9095
9146
  continue;
9096
9147
  }
@@ -9159,24 +9210,50 @@ async function runPipelineTick(args) {
9159
9210
  let maxStarts = maxStartsAdvice.maxStarts;
9160
9211
  const sweep = await sweepRun({ run: runId, agentOsId, pipeline: true, ...args });
9161
9212
  let dispatch = null;
9162
- if (execute && maxStarts > 0) {
9163
- dispatch = await runPipelineDispatch(
9213
+ let startedCount = 0;
9214
+ const exactTargetTaskIds = operatorExactTargetTaskIds(operatorTick);
9215
+ let remainingStarts = maxStarts;
9216
+ if (execute && remainingStarts > 0 && exactTargetTaskIds.length > 0) {
9217
+ const exactBudget = Math.min(remainingStarts, exactTargetTaskIds.length);
9218
+ const exact = await runPipelineDispatch(
9219
+ {
9220
+ ...args,
9221
+ run: runId,
9222
+ agentOsId,
9223
+ targetTaskIds: exactTargetTaskIds.join(",")
9224
+ },
9225
+ exactBudget
9226
+ );
9227
+ const exactStarted = countDispatchStarts(exact);
9228
+ startedCount += exactStarted;
9229
+ remainingStarts = Math.max(0, remainingStarts - exactStarted);
9230
+ dispatch = { exactTargetTaskIds, exact, startedCount };
9231
+ }
9232
+ if (execute && remainingStarts > 0) {
9233
+ const broad = await runPipelineDispatch(
9164
9234
  {
9165
9235
  ...args,
9166
9236
  run: runId,
9167
9237
  agentOsId
9168
9238
  },
9169
- maxStarts
9239
+ remainingStarts
9170
9240
  );
9171
- } else {
9172
- dispatch = {
9173
- ok: true,
9174
- skipped: true,
9175
- reason: execute ? dispatchResourceGate.reason ?? "no slots or queued work" : "execute disabled",
9176
- maxStarts: 0
9177
- };
9241
+ const broadStarted = countDispatchStarts(broad);
9242
+ startedCount += broadStarted;
9243
+ dispatch = dispatch && typeof dispatch === "object" ? { ...dispatch, broad, startedCount } : broad;
9244
+ } else if (!execute || maxStarts <= 0) {
9245
+ if (!dispatch) {
9246
+ dispatch = {
9247
+ ok: true,
9248
+ skipped: true,
9249
+ reason: execute ? dispatchResourceGate.reason ?? "no slots or queued work" : "execute disabled",
9250
+ maxStarts: 0,
9251
+ ...exactTargetTaskIds.length ? { exactTargetTaskIds, exactOnly: true } : {}
9252
+ };
9253
+ }
9254
+ } else if (dispatch && typeof dispatch === "object") {
9255
+ dispatch = { ...dispatch, broadSkipped: true, startedCount };
9178
9256
  }
9179
- const startedCount = dispatch?.startedCount ?? 0;
9180
9257
  const idle = !maxStartsAdvice.underutilized && maxStarts === 0 && completedWorkers.length === 0 && startedCount === 0;
9181
9258
  return {
9182
9259
  runId,