@bivy/bivy 0.18.11-staging.13 → 0.18.11-staging.15
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/bin/bivy.mjs +2 -1
- package/dist/run-tools.js +5 -2
- package/dist/server.js +15 -16
- package/package.json +1 -1
package/bin/bivy.mjs
CHANGED
|
@@ -2506,7 +2506,8 @@ async function cmdDelegate(args = []) {
|
|
|
2506
2506
|
if (!res.ok) throw new Error(data?.error || `HTTP ${res.status}`);
|
|
2507
2507
|
return data;
|
|
2508
2508
|
};
|
|
2509
|
-
|
|
2509
|
+
// needs_attention = parked by the machine's policy; it won't move on its own.
|
|
2510
|
+
const terminal = (run) => ["succeeded", "failed", "cancelled", "needs_attention"].includes(run?.status);
|
|
2510
2511
|
// The node caps one wait at 300s; loop until the child ends or our budget does.
|
|
2511
2512
|
const waitFor = async (runId, seconds) => {
|
|
2512
2513
|
const deadline = Date.now() + seconds * 1000;
|
package/dist/run-tools.js
CHANGED
|
@@ -12,6 +12,9 @@ export const RUN_TOOL_LIMITS = {
|
|
|
12
12
|
maxAnswer: 8_000,
|
|
13
13
|
};
|
|
14
14
|
const TERMINAL = new Set(["succeeded", "failed", "cancelled"]);
|
|
15
|
+
// Parked by the node's policy (usage limit, missing credentials): it won't
|
|
16
|
+
// progress without a person, so waiting ends there and the reason comes back.
|
|
17
|
+
const SETTLED = new Set([...TERMINAL, "needs_attention"]);
|
|
15
18
|
const STATUSES = new Set(["pending", "claimed", "running", "waiting", "needs_attention", "succeeded", "failed", "cancelled"]);
|
|
16
19
|
const SOURCE_PREFIX = "agent-delegation:v1:";
|
|
17
20
|
const bounded = (v, n) => typeof v === "string" && v ? v.slice(0, n) : undefined;
|
|
@@ -109,7 +112,7 @@ export class RunDelegationService {
|
|
|
109
112
|
if (!raw || provenance?.parentSessionId !== sessionId)
|
|
110
113
|
throw new Error("delegated Run not found");
|
|
111
114
|
const value = safeRun(raw, provenance);
|
|
112
|
-
if (
|
|
115
|
+
if (SETTLED.has(value.status) && this.backend.answer) {
|
|
113
116
|
// Best-effort: an unreachable machine still leaves status + references.
|
|
114
117
|
const answer = cached?.value.answer ?? await this.backend.answer(raw).catch(() => undefined);
|
|
115
118
|
if (answer)
|
|
@@ -155,7 +158,7 @@ export class RunDelegationService {
|
|
|
155
158
|
if (signal?.aborted)
|
|
156
159
|
throw signal.reason ?? new Error("wait cancelled; the child Run may still be running");
|
|
157
160
|
const result = await this.authorized(sessionId, runId, true);
|
|
158
|
-
if (
|
|
161
|
+
if (SETTLED.has(result.status))
|
|
159
162
|
return result;
|
|
160
163
|
if (this.now() >= deadline)
|
|
161
164
|
return { ...result, timedOut: true, wait: { timedOut: true, childContinues: true } };
|
package/dist/server.js
CHANGED
|
@@ -4667,11 +4667,7 @@ async function runIssueTaskInner(cfg, issue, source, overrides = {}) {
|
|
|
4667
4667
|
sessionNamer.setSessionName(record, issueSessionTitle(issue));
|
|
4668
4668
|
// Best-effort model selection for runtimes that support it (e.g. claude-code, pi).
|
|
4669
4669
|
if (directives.model && typeof record.session.setModel === "function") {
|
|
4670
|
-
|
|
4671
|
-
assertSessionModel(record, directives.model);
|
|
4672
|
-
await record.session.setModel("", directives.model);
|
|
4673
|
-
}
|
|
4674
|
-
catch { }
|
|
4670
|
+
await applyRequestedModel(record, { provider: "", id: directives.model });
|
|
4675
4671
|
}
|
|
4676
4672
|
if (!record.worktree)
|
|
4677
4673
|
throw new Error("worktree was not created for the issue session");
|
|
@@ -5361,6 +5357,13 @@ async function delegationAnswer(sessionId) {
|
|
|
5361
5357
|
}
|
|
5362
5358
|
return undefined;
|
|
5363
5359
|
}
|
|
5360
|
+
/** A delegated task's first line, bounded, as its child session's title. */
|
|
5361
|
+
function delegatedSessionTitle(instructions) {
|
|
5362
|
+
const line = instructions?.split(/\r?\n/).map((l) => l.trim()).find(Boolean);
|
|
5363
|
+
if (!line)
|
|
5364
|
+
return undefined;
|
|
5365
|
+
return line.length > 80 ? `${line.slice(0, 79).trimEnd()}…` : line;
|
|
5366
|
+
}
|
|
5364
5367
|
/** Text of the most recent user message in a session's transcript, if any. */
|
|
5365
5368
|
function lastUserMessageText(record) {
|
|
5366
5369
|
const messages = record.session.getMessages();
|
|
@@ -5515,12 +5518,8 @@ async function executeWorkItem(item, report, signal) {
|
|
|
5515
5518
|
approvalMode: safety.approval,
|
|
5516
5519
|
});
|
|
5517
5520
|
sessionNamer.setSessionName(record, `${issue.identifier}: ${issue.title}`);
|
|
5518
|
-
if (item.model)
|
|
5519
|
-
|
|
5520
|
-
await record.session.setModel("", item.model);
|
|
5521
|
-
}
|
|
5522
|
-
catch { }
|
|
5523
|
-
}
|
|
5521
|
+
if (item.model)
|
|
5522
|
+
await applyRequestedModel(record, { provider: "", id: item.model });
|
|
5524
5523
|
await report({ output: { sessionId: record.id, branch }, events: [{ at: new Date().toISOString(), kind: "branch", summary: "Linear issue working branch and session created.", ref: branch, url: issue.url }] });
|
|
5525
5524
|
await runSessionTurn(record, buildLinearTaskPrompt(issue, item.body), signal);
|
|
5526
5525
|
if (signal.aborted)
|
|
@@ -5594,13 +5593,13 @@ async function executeWorkItem(item, report, signal) {
|
|
|
5594
5593
|
// sends after the Run is mistaken for the Session's first naming prompt (the
|
|
5595
5594
|
// internal Run turn does not pass through the interactive prompt handler), so
|
|
5596
5595
|
// rows named after the Run suddenly become "status", "continue", etc.
|
|
5597
|
-
|
|
5596
|
+
// A delegated child's queue title is generic ("Delegated Run": the task is
|
|
5597
|
+
// sealed, the queue never sees it). Name it after the task itself, which
|
|
5598
|
+
// only this machine can read, so it's recognizable in the session list.
|
|
5599
|
+
sessionNamer.setSessionName(record, delegatedProvenance ? delegatedSessionTitle(item.body) ?? item.title : item.title);
|
|
5598
5600
|
persistSessionMetadata(record);
|
|
5599
5601
|
if (item.model) {
|
|
5600
|
-
|
|
5601
|
-
await record.session.setModel("", item.model);
|
|
5602
|
-
}
|
|
5603
|
-
catch { }
|
|
5602
|
+
await applyRequestedModel(record, { provider: "", id: item.model });
|
|
5604
5603
|
}
|
|
5605
5604
|
// Record the session id with the control plane BEFORE the (potentially long)
|
|
5606
5605
|
// turn runs, not just after it completes. A machine restart mid-turn must leave
|
package/package.json
CHANGED