@bivy/bivy 0.18.11-staging.14 → 0.18.11-staging.16

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 CHANGED
@@ -2466,7 +2466,7 @@ async function cmdSuggest(args = []) {
2466
2466
  // self-contained task from this session to another agent, optionally on another
2467
2467
  // account machine, and get its answer back. Agent-agnostic — any agent with a
2468
2468
  // shell can call it — and meant for when the user asks for another agent/machine.
2469
- const DELEGATE_USAGE = `Usage: bivy delegate "<task>" [--agent <id>] [--machine <name>] [--model <model>] [--repo owner/repo] [--wait [seconds]] [--json]
2469
+ const DELEGATE_USAGE = `Usage: bivy delegate "<task>" [--agent <id>] [--machine <name>] [--model <model>] [--repo owner/repo] [--approval never|risky|always|autonomous] [--sandbox <tier>] [--wait [seconds]] [--json]
2470
2470
  bivy delegate "<task>" --to <agent>[@<machine>],<agent>[@<machine>],… [--wait [seconds]]
2471
2471
  bivy delegate machines [--json]
2472
2472
  bivy delegate status <run-id> [--json]
@@ -2480,7 +2480,12 @@ to several agents/machines at once (up to 3) so the results can be compared.
2480
2480
 
2481
2481
  async function cmdDelegate(args = []) {
2482
2482
  if (!args.length || args.some((a) => a === "-h" || a === "--help")) { console.log(DELEGATE_USAGE); return; }
2483
- const flagsWithValue = new Set(["--session", "--agent", "--machine", "--model", "--repo", "--timeout", "--to"]);
2483
+ const flagsWithValue = new Set(["--session", "--agent", "--machine", "--model", "--repo", "--timeout", "--to", "--approval", "--sandbox"]);
2484
+ // Children inherit this session's approval/sandbox unless set here.
2485
+ const safetyFlags = () => {
2486
+ const safety = { approval: flag("--approval"), sandbox: flag("--sandbox") };
2487
+ return safety.approval || safety.sandbox ? { safety } : {};
2488
+ };
2484
2489
  const flag = (name) => {
2485
2490
  const i = args.indexOf(name);
2486
2491
  return i >= 0 && i + 1 < args.length ? args[i + 1] : undefined;
@@ -2556,7 +2561,7 @@ async function cmdDelegate(args = []) {
2556
2561
  const group = `fanout-${Date.now().toString(36)}`;
2557
2562
  const runs = [];
2558
2563
  for (const target of targets) {
2559
- runs.push({ target, run: await call("", { instructions, agent: target.agent, machine: target.machine, model: flag("--model"), repo: flag("--repo"), group }) });
2564
+ runs.push({ target, run: await call("", { instructions, agent: target.agent, machine: target.machine, model: flag("--model"), repo: flag("--repo"), ...safetyFlags(), group }) });
2560
2565
  }
2561
2566
  if (waitIndex < 0) {
2562
2567
  if (json) console.log(JSON.stringify(runs.map((r) => r.run), null, 2));
@@ -2569,7 +2574,7 @@ async function cmdDelegate(args = []) {
2569
2574
  return;
2570
2575
  }
2571
2576
  const agent = flag("--agent");
2572
- const started = await call("", { instructions, agent: agent ? governedChatAgentId(agent) : undefined, machine: flag("--machine"), model: flag("--model"), repo: flag("--repo") });
2577
+ const started = await call("", { instructions, agent: agent ? governedChatAgentId(agent) : undefined, machine: flag("--machine"), model: flag("--model"), repo: flag("--repo"), ...safetyFlags() });
2573
2578
  if (waitIndex < 0) {
2574
2579
  if (!json) console.log(`Delegated as run ${started.runId} (${started.status}). Follow it with 'bivy delegate wait ${started.runId}'.`);
2575
2580
  else print(started);
package/dist/run-tools.js CHANGED
@@ -135,7 +135,9 @@ export class RunDelegationService {
135
135
  const existing = expectedSource ? recent.find((r) => r.source === expectedSource) : undefined;
136
136
  if (existing)
137
137
  return safeRun(existing, provenance);
138
- const active = recent.filter((r) => parseDelegationSource(r.source)?.parentSessionId === sessionId && !TERMINAL.has(r.status)).length;
138
+ // A parked child (needs_attention) runs nothing until a person acts, so it
139
+ // doesn't hold one of the parent's concurrent slots.
140
+ const active = recent.filter((r) => parseDelegationSource(r.source)?.parentSessionId === sessionId && !SETTLED.has(r.status)).length;
139
141
  if (active >= RUN_TOOL_LIMITS.maxConcurrentChildren)
140
142
  throw new Error(`concurrent child Run limit (${RUN_TOOL_LIMITS.maxConcurrentChildren}) reached`);
141
143
  const raw = await this.backend.start(sessionId, input, provenance);
package/dist/server.js CHANGED
@@ -527,7 +527,7 @@ const runDelegation = new RunDelegationService({
527
527
  throw error;
528
528
  }
529
529
  },
530
- start: async (_sessionId, input, provenance) => {
530
+ start: async (sessionId, input, provenance) => {
531
531
  const machine = input.machine?.trim() || identity.name;
532
532
  const nodes = await delegatedRunRequest("/nodes");
533
533
  const target = Array.isArray(nodes) ? nodes.find((node) => node && typeof node === "object" && node.name === machine) : undefined;
@@ -553,8 +553,12 @@ const runDelegation = new RunDelegationService({
553
553
  node: machine,
554
554
  runtimeId: input.agent,
555
555
  model: input.model,
556
- approvalMode: input.safety?.approval,
557
- sandbox: input.safety?.sandbox,
556
+ // A child acts for the same user in the same context as its parent, so
557
+ // it inherits the parent session's safety unless the caller set one. The
558
+ // queue's own default ("risky" with nobody to approve) denied ordinary
559
+ // commands, leaving children that could only describe what they'd do.
560
+ approvalMode: input.safety?.approval ?? openSessions.get(sessionId)?.approvalMode,
561
+ sandbox: input.safety?.sandbox ?? openSessions.get(sessionId)?.sandbox,
558
562
  maxAttempts: input.safety?.maxAttempts ?? 2,
559
563
  idempotencyKey: input.idempotencyKey,
560
564
  parentSessionId: provenance.parentSessionId,
@@ -5357,6 +5361,13 @@ async function delegationAnswer(sessionId) {
5357
5361
  }
5358
5362
  return undefined;
5359
5363
  }
5364
+ /** A delegated task's first line, bounded, as its child session's title. */
5365
+ function delegatedSessionTitle(instructions) {
5366
+ const line = instructions?.split(/\r?\n/).map((l) => l.trim()).find(Boolean);
5367
+ if (!line)
5368
+ return undefined;
5369
+ return line.length > 80 ? `${line.slice(0, 79).trimEnd()}…` : line;
5370
+ }
5360
5371
  /** Text of the most recent user message in a session's transcript, if any. */
5361
5372
  function lastUserMessageText(record) {
5362
5373
  const messages = record.session.getMessages();
@@ -5586,7 +5597,10 @@ async function executeWorkItem(item, report, signal) {
5586
5597
  // sends after the Run is mistaken for the Session's first naming prompt (the
5587
5598
  // internal Run turn does not pass through the interactive prompt handler), so
5588
5599
  // rows named after the Run suddenly become "status", "continue", etc.
5589
- sessionNamer.setSessionName(record, item.title);
5600
+ // A delegated child's queue title is generic ("Delegated Run": the task is
5601
+ // sealed, the queue never sees it). Name it after the task itself, which
5602
+ // only this machine can read, so it's recognizable in the session list.
5603
+ sessionNamer.setSessionName(record, delegatedProvenance ? delegatedSessionTitle(item.body) ?? item.title : item.title);
5590
5604
  persistSessionMetadata(record);
5591
5605
  if (item.model) {
5592
5606
  await applyRequestedModel(record, { provider: "", id: item.model });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.18.11-staging.14",
3
+ "version": "0.18.11-staging.16",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",