mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-10-22 16:35:20 +08:00
* fix(box): retain outbox files when export fails * test(box): retain ownership evidence in CI logs * test(box): exercise LocalAgent export repair through real runtime and Docker Co-authored-by: multica-agent <[email protected]> * fix(box): complete bounded outbox recovery contract * feat(box): export explicitly selected files Co-authored-by: multica-agent <[email protected]> * test(box): exercise explicit export on real Docker Co-authored-by: multica-agent <[email protected]> * test(box): verify explicit exports with live model and Docker Co-authored-by: multica-agent <[email protected]> * fix(box): align explicit export SDK and integration contracts * docs(box): describe selected-file export contract --------- Co-authored-by: HaiYangBG1 <[email protected]> Co-authored-by: Chin Rock <[email protected]> Co-authored-by: multica-agent <[email protected]>
70 lines
3.9 KiB
Markdown
70 lines
3.9 KiB
Markdown
# Explicit Box file export
|
|
|
|
A Runner calls `ctx.export_box_files(paths)` with a non-empty list of normalized
|
|
absolute paths inside its bound sandbox. The run's outbox is the recommended place
|
|
for deliverables. Writing a file alone does not deliver it; LocalAgent exposes an
|
|
`export_box_files` model tool and performs no final directory scan.
|
|
|
|
Core validates every selected file before registering any new handles. Missing,
|
|
unreadable, non-regular or symlinked paths, exceeded quotas and malformed runtime
|
|
responses fail the whole batch and retain its files. The selected-file reader runs
|
|
inside the existing Box with its original configuration and Workspace/generation
|
|
fencing. It opens directories and files without following symlinks and uses
|
|
nonblocking opens to avoid hanging on FIFOs.
|
|
|
|
The existing limits remain: 20 files and 50 MiB per call, 10 MiB per file, and
|
|
100 files / 50 MiB cumulatively per run. Raw SDK stdout is capped at 1 MiB per
|
|
stream including base64/JSON overhead, so transport may reject a batch below its
|
|
nominal file quotas. Only explicit SDK clipping notices are classified as
|
|
truncation; ordinary invalid JSON is not guessed to be a size failure. Quota
|
|
errors include the threshold, known actual value or lower bound, sandbox paths,
|
|
retention state and suggested action.
|
|
|
|
Successful acceptance returns opaque run-scoped handles and removes only selected
|
|
files whose content still matches the accepted bytes. Unselected files remain.
|
|
Cleanup failure is a warning on accepted handles; it must not cause duplicate
|
|
registration or delivery. Re-reading unchanged retained files reuses their IDs;
|
|
changed content or distinct source paths produces distinct handles. Already
|
|
submitted IDs are never returned for another delivery.
|
|
|
|
`message.completed.file_ids` attaches accepted files to automatic Pipeline output.
|
|
Explicit Agent replies use `ctx.reply_files()`. Platform-send failure after Core
|
|
acceptance terminates LocalAgent rather than regenerating or resending possibly
|
|
already-delivered files. Model export retries use ordinary paired tool-call
|
|
messages within the original tool/context/deadline budgets. There is no separate
|
|
two-attempt completion recovery loop. Streaming text already sent cannot be
|
|
retracted. Retention lasts only within the existing Box/run lifetime; expiry and
|
|
startup cleanup remain in effect.
|
|
|
|
## Coordinated dependency
|
|
|
|
This API requires the matching Core, LocalAgent and SDK implementation. The current
|
|
Core and LocalAgent uv locks pin SDK commit
|
|
`b300830b0e5339e7989be237efa811bedf761d55` from SDK PR #180. Published SDK 0.7.4 and
|
|
0.7.13 do not include the paths argument. LocalAgent rejects an older Runtime SDK
|
|
before preparing its file tool. Maintainers must coordinate the SDK release and
|
|
Runtime upgrade before release deployment.
|
|
|
|
The internal directory-collection helpers retain their strict bounded reads and
|
|
host-permission fallback; they do not define the explicit Runner export API.
|
|
|
|
## Regression checks
|
|
|
|
```bash
|
|
uv run --no-sync pytest tests/unit_tests/box -q
|
|
uv run --no-sync pytest tests/integration_tests/box/test_outbox_export.py -v -s
|
|
LANGBOT_LEGACY_PLUGIN_ROOT=/path/to/pinned/plugins uv run --no-sync pytest --required-suite local_agent -q
|
|
```
|
|
|
|
The Docker integration records uid/gid/mode, checks exact bytes from root-owned
|
|
0600 output using a non-root Core on Linux, verifies Box reuse and rejects
|
|
cross-run handle reuse. The required LocalAgent suite uses the integrity-checked
|
|
plugin source in `tests/fixtures/legacy_plugin_identity_sources.json`; Core,
|
|
Runtime, SQLite and Docker are real while the model and faults are scripted.
|
|
Cases cover selection, repair, streaming, tool-budget exhaustion, cleanup retry,
|
|
invalid response, timeout, real-ledger cancellation and no implicit export.
|
|
|
|
The opt-in `test_live_explicit_export.py` additionally needs dedicated
|
|
`BOX_LIVE_API_KEY` and `BOX_LIVE_MODEL` configuration. Its absence is a skip,
|
|
not evidence of a live-model acceptance run.
|