feat(alexandria): collect and send per-call feedback tokens

Merged
NI
3d ago
+741-3

Adds per-call feedback tokens so Alexandria ratings are attributed to the calls they are about.

  • Alexandria call results can carry a feedbackToken. The CLI keeps up to 20 of them for 24 hours in its config directory (deduped, written atomically, mode 0600, scoped to the API key) and prints a short Feedback ref c3: provider/capability line to stderr per call. JSON output is unchanged and still contains the token as returned.
  • firecrawl alexandria feedback sends the stored tokens, so the overall rating covers the calls in the session, and clears them after a successful submission. Repeatable --call-rating <ref>=<good|partial|bad> rates individual calls by ref; repeatable --token <token> passes tokens explicitly for scripted use (replacing the stored ones). An unknown ref fails before anything is sent.
  • rejectedTokens from the API is shown in the output. With no stored tokens the request body is unchanged.

Tests

Store (dedupe, cap, TTL, scoping, file mode, write failures), recording and ref printing, sending, clearing, call ratings, explicit tokens, unknown refs, rejected tokens and argument parsing.

Open in Capy


Summary by cubic

Adds per-call feedback tokens so Alexandria ratings are attributed to the calls they are about.

  • Alexandria call results can carry a feedbackToken; the CLI stores up to 20 per API key for 24 hours in its config directory (deduped, written atomically with mode 0600, updates serialized across processes) and prints a Feedback ref cN: provider/capability line to stderr per call. Tokens from the firecrawl provider are not stored, missing results are ignored, and JSON output is unchanged and still contains the token as returned.
  • firecrawl alexandria feedback sends the stored tokens so the session rating covers those calls, and clears the stored ones it sent after a successful submission. Repeatable --call-rating <ref>=<good|partial|bad> rates individual calls by ref; repeatable --token <token> passes tokens explicitly, replacing the stored ones and scoping refs to those tokens. An unknown ref fails before anything is sent; rejectedTokens from the API is shown in the output. With no stored tokens, the request body is unchanged. Expired tokens are pruned from disk on read.