Skip to content

feat(commonly): commonly_read_attachment β€” one-shot file read tool#5

Merged
samxu01 merged 1 commit intorebase-2026.3.29from
feat/commonly-read-attachment
May 7, 2026
Merged

feat(commonly): commonly_read_attachment β€” one-shot file read tool#5
samxu01 merged 1 commit intorebase-2026.3.29from
feat/commonly-read-attachment

Conversation

@samxu01
Copy link
Copy Markdown

@samxu01 samxu01 commented May 7, 2026

Summary

  • Adds commonly_read_attachment(fileName, maxChars?) tool to the commonly extension
  • Format-aware extraction: officecli for docx/xlsx/pptx, pdftotext for pdf, raw utf-8 for md/txt/csv/json/etc., markitdown fallback for everything else
  • Eliminates the 4-step curl + extract reasoning chain agents had to write inline when consuming attached files

Why

Agents had no first-class way to consume files attached in chat. The [[upload:fileName|...]] directive in commonly_get_messages output gave them the ObjectStore key, but extracting text required: spot the directive, curl the file, pick the right extractor binary, parse output. Models routinely skipped this and ignored attachments.

Defensive details

  • fileName regex ^[a-zA-Z0-9_.-]+\.[a-zA-Z0-9]+$ + .. ban prevents path-traversal / URL-injection
  • 25 MB hard cap mirrors the upload route
  • Bearer token sent defensively for the upcoming signed-URL flip (ADR-002 Phase 1b)
  • Temp dir cleaned up in finally regardless of extractor outcome

Test plan

  • pnpm tsgo β€” tools.ts compiles clean (pre-existing errors in other files are unrelated)
  • pnpm check β€” tools.ts lints clean
  • Live smoke: have an agent in dev cluster call commonly_read_attachment on 1778103164116-632900841.docx (real preview-demo.docx); expect text extraction with mammoth-equivalent fidelity

Agents had no first-class way to consume files attached in chat. The
[[upload:fileName|...]] directive in `commonly_get_messages` output
gave them the ObjectStore key, but extracting text required a 4-step
reasoning chain: spot the directive, curl the file, pick the right
extractor binary, parse output. Models routinely skipped this and
ignored attachments.

This tool wraps the chain in a single call. Format-aware extraction:
- .docx / .xlsx / .pptx β†’ `officecli view text` (already on PATH)
- .pdf                  β†’ `pdftotext -layout`
- .md / .txt / .csv / .json / .yaml / .xml / .html / .log β†’ raw utf-8
- everything else       β†’ `markitdown` fallback

Returns structured `{ ok, fileName, extractor, sizeBytes, totalChars,
truncated, text }`. Caller can pass `maxChars` (clamped to [1000,
64000]; default 16000) to bound output. Truncation marker preserved
so the model sees what was cut.

Defensive details:
- fileName must match `^[a-zA-Z0-9_.-]+\.[a-zA-Z0-9]+$` and forbid
  `..` β€” can't be tricked into fetching `/etc/passwd` or arbitrary
  URLs.
- 25 MB hard cap mirrors the upload route.
- Sends `Authorization: Bearer ${COMMONLY_API_TOKEN}` defensively
  even though `/api/uploads/:fileName` is public-read today (ADR-002
  Phase 1) β€” pre-positions us for the signed-URL flip.
- Temp dir is cleaned up in `finally` regardless of extractor outcome.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@samxu01 samxu01 merged commit ae3235c into rebase-2026.3.29 May 7, 2026
2 of 9 checks passed
@samxu01 samxu01 deleted the feat/commonly-read-attachment branch May 7, 2026 04:50
samxu01 added a commit to Team-Commonly/commonly that referenced this pull request May 7, 2026
…ad_attachment tool

Picks up Team-Commonly/openclaw#5 β€” adds commonly_read_attachment to the
commonly extension's tool surface. One-shot file read for any attached
file in chat, format-aware (officecli / pdftotext / raw utf-8 / markitdown
fallback). Replaces the 4-step curl-and-extract reasoning chain agents
had to write inline.

The dev-time `-dirty` annotation in the submodule is from an unrelated
ADR-012 WIP (channel.ts + events.ts) someone else has open in this
worktree; the recorded SHA itself is clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant