feat(agent): adopt AI SDK v7 — crash safety, context pruning, HITL approvals (#3362)

* docs(adr): propose agent AI SDK v7 adoption plan

* fix(ai): bind analyzeResume through aiService in service test

The test destructured analyzeResume as a named export that does not exist; main was red.

* test(agent): keep pure ai helpers real via spread-actual mock factory

* feat(agent): add run guards, patch version guard, run wall-clock timeout

* feat(agent): validate UI messages at the send boundary

* feat(agent): crash-safe draft-row persistence and server-side cancellation

* feat(agent): reap stale run claims at boot, on send, and on thread open

* feat(agent): fresh-document patch output and tiered context pruning

* feat(ai): shared agent tool contracts and message metadata schema

* feat(agent): add per-thread review-patches setting with update endpoint

* feat(agent): gate resume patches behind hmac-signed tool approval

* feat(agent): merge question answers and approval decisions before run claim

* feat(agent): approval ui with composed auto-send and fixture-driven tests

* feat(agent): usage metadata, tool activity cards, smoother streaming

* feat(agent): tool-call repair, input examples, structured step logging

* chore(i18n): translate new agent workspace strings across all locales

* fix(agent): gate stale-run draft cancellation on winning the claim clear

Snapshot streaming drafts before the conditional clear and skip the flip entirely when another reaper or a replacement run already cleared the claim. Also address review nits in eleven locale catalogs.

* fix(agent): flip reaped drafts only when their snapshotted state is unchanged

* fix(agent): address review findings across run lifecycle, context budget, and approval flow

- bind patches to the revision the model read via signed baseUpdatedAt
- claim the run before consuming a continuation; recorded-but-unexecuted approvals retry as pending continuations
- keep run ownership on stop() until cancellation persists; preserve the claim for the reaper when final persistence fails
- estimate tokens without serializing binary attachments (tokenx) and enforce the budget by dropping oldest whole turns
- mark crash-recovered patch results as snapshot boundaries; strip /data prefixes at execution time
- retry failed continuations without regenerate; mount a single AgentChat; disable response controls on read-only threads; freeze review toggle during runs (client+server)
- accumulate usage across continuations and match the SDK's nested usage shape; label-form token strings; reorderable source label; accessible note field; state-neutral web-search label

* chore(i18n): translate revised agent strings across all locales

* fix(agent): harden baseUpdatedAt validation and address review follow-ups

- bundle tokenx in the server runtime dependencies (e2e boot failure)
- strict ISO schema for baseUpdatedAt plus loud executor rejection of unparseable values
- it-IT source label consistency (Fonte)
- prove penultimate-turn retention in the context pruning test

* chore(deps): exempt tokenx from knip for the externalized server bundle
This commit is contained in:
Amruth Pillai
2026-08-20 08:06:53 +02:00
committed by GitHub
parent dbbab6fd76
commit c8081ac2fe
95 changed files with 14919 additions and 497 deletions
+103 -3
View File
@@ -543,6 +543,14 @@ msgstr "Sol·licitada"
msgid "Applied on"
msgstr "Aplicat a"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Approve"
msgstr "Aprova"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Approved — waiting for the agent…"
msgstr "Aprovat — esperant l'agent…"
#: src/libs/locale.ts
msgid "Arabic"
msgstr "Àrab"
@@ -1462,6 +1470,14 @@ msgstr "Sestà suprimint la clau API..."
msgid "Deleting your resume..."
msgstr "Sestà suprimint el currículum..."
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Denied — waiting for the agent…"
msgstr "Denegat — esperant l'agent…"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Deny"
msgstr "Denega"
#: src/libs/resume/ats.ts
msgid "Describe what you did so the entry contributes keywords for matching."
msgstr "Descriu què has fet perquè l'entrada aporti paraules clau per a la coincidència."
@@ -1530,6 +1546,10 @@ msgstr "Donar"
msgid "Donate to Reactive Resume"
msgstr "Fes una donació a Reactive Resume"
#: src/routes/agent/-components/tool-part-card.tsx
msgid "Done"
msgstr "Fet"
#. Action button to download two-factor backup codes as a text file
#. Primary action in the builder header to open resume download options
#: src/dialogs/auth/enable-two-factor.tsx
@@ -1642,6 +1662,10 @@ msgstr "Edita el contingut en mode de pantalla completa"
msgid "Edit date"
msgstr "Edita la data"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Edit declined"
msgstr "Edició rebutjada"
#. Resume card context menu action to edit resume metadata
#. Resume card dropdown action to edit resume metadata
#: src/routes/builder/$resumeId/-components/header.tsx
@@ -1837,6 +1861,10 @@ msgstr "Exporta el teu currículum a PDF a l'instant, sense esperes ni demores."
msgid "Exported pipeline-flow.png"
msgstr "S'ha exportat el flux de la canonada.png"
#: src/routes/agent/-components/tool-part-card.tsx
msgid "Failed"
msgstr "Ha fallat"
#: src/routes/builder/$resumeId/-sidebar/right/sections/resume-analysis.tsx
msgid "Failed to analyze resume."
msgstr "S'ha fallat l'anàlisi del currículum."
@@ -1967,6 +1995,10 @@ msgstr "S'ha fallat la desactivació del proveïdor. Torni a provar."
msgid "Failed to update provider."
msgstr "No s'ha pogut actualitzar el proveïdor."
#: src/routes/agent/-components/agent-chat.tsx
msgid "Failed to update thread settings."
msgstr "No s'ha pogut actualitzar la configuració del fil."
#. Fallback toast when changing account password fails
#: src/dialogs/auth/change-password.tsx
msgid "Failed to update your password. Please try again."
@@ -3153,6 +3185,14 @@ msgstr "Routador obert"
msgid "opens in new tab"
msgstr "sobre en una pestanya nova"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Optional note for the agent"
msgstr "Nota opcional per a l'agent"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Optional note for the agent…"
msgstr "Nota opcional per a l'agent…"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Optionally, set a password so that only people with the password can view your resume through the link."
msgstr "Opcionalment, estableix una contrasenya perquè només les persones que la tinguin puguin veure el currículum mitjançant lenllaç."
@@ -3499,6 +3539,10 @@ msgstr "Publicacions"
msgid "Publisher"
msgstr "Editor"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Raw JSON"
msgstr "JSON en brut"
#: src/features/applications/components/application-ai-copilot.tsx
msgid "Re-score"
msgstr "Torna a puntuar"
@@ -3546,10 +3590,18 @@ msgstr "Currículum reactiu v<0>{__APP_VERSION__}</0>"
msgid "Reactive Resume v4 (JSON)"
msgstr "Reactive Resume v4 (JSON)"
#: src/routes/agent/-components/tool-part-card.tsx
msgid "Read an attachment"
msgstr "Ha llegit un adjunt"
#: src/features/resume/stylesheet/editor.tsx
msgid "Read the Applying Custom Styles guide."
msgstr "Llegiu la guia Aplicació d'estils personalitzats."
#: src/routes/agent/-components/tool-part-card.tsx
msgid "Read the resume"
msgstr "Ha llegit el currículum"
#: src/features/applications/components/application-form-sheet.tsx
msgid "Reading the posting…"
msgstr "S'està llegint l'oferta…"
@@ -3700,8 +3752,8 @@ msgid "Restore"
msgstr "Restaurar"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Restore the resume to before this patch? This will roll back this patch and any patches applied after it."
msgstr "Voleu restaurar el currículum anterior a aquest pegat? Això reverteix aquest pegat i qualsevol pegat aplicat després."
msgid "Restore the resume to before this patch?"
msgstr "Vols restaurar el currículum a l'estat anterior a aquest pegat?"
#: src/routes/builder/$resumeId/-components/version-history.tsx
msgid "Restore this version?"
@@ -3726,6 +3778,10 @@ msgstr "Anàlisi del currículum completada."
msgid "Resume content"
msgstr "Reprendre el contingut"
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Resume edit"
msgstr "Edició del currículum"
#: src/features/applications/components/application-detail-sheet.tsx
msgid "Resume file"
msgstr "Fitxer de currículum"
@@ -3754,10 +3810,18 @@ msgstr "Currículums"
msgid "Retry"
msgstr "Torna-ho a intentar"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Review edits"
msgstr "Revisa les edicions"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Review the resume against a job description and ask me questions before changing uncertain sections."
msgstr "Revisa el currículum en relació amb la descripció del lloc de treball i fes-me preguntes abans de canviar les seccions incertes."
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Review this edit"
msgstr "Revisa aquesta edició"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Rework the summary so it targets a senior engineering manager role without sounding generic."
msgstr "Reelabora el resum perquè s'adreci a un rol de gerent sènior d'enginyeria sense que sembli genèric."
@@ -3798,6 +3862,10 @@ msgstr "Rotació"
msgid "Run your first analysis to get a scorecard, strengths, and prioritized suggestions."
msgstr "Executa la teva primera anàlisi per obtenir un quadre de comandament, els punts forts i suggeriments prioritzats."
#: src/routes/agent/-components/tool-part-card.tsx
msgid "Running…"
msgstr "S'està executant…"
#: src/libs/locale.ts
msgid "Russian"
msgstr "Rus"
@@ -4253,6 +4321,15 @@ msgstr "Font"
msgid "Source Code"
msgstr "Codi font"
#. placeholder {0}: operation.from
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "Source: {0}"
msgstr "Font: {0}"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Sources"
msgstr "Fonts"
#: src/routes/builder/$resumeId/-sidebar/right/sections/page.tsx
msgid "Spacing (Horizontal)"
msgstr "Espaiat (horitzontal)"
@@ -4604,6 +4681,10 @@ msgstr "No s'ha pogut obrir aquest assistent."
msgid "This date will not be read correctly."
msgstr "Aquesta data no es llegirà correctament."
#: src/routes/agent/-components/patch-approval-card.tsx
msgid "This edit request can no longer be answered."
msgstr "Aquesta sol·licitud d'edició ja no es pot respondre."
#: src/libs/resume/ats.ts
msgid "This email address will not be recognized."
msgstr "Aquesta adreça de correu electrònic no serà reconeguda."
@@ -4712,6 +4793,10 @@ msgstr "Això t'ajudarà a identificar-la més endavant, si tens previst tenir d
msgid "This will remove all items from this section."
msgstr "Això eliminarà tots els elements d'aquesta secció."
#: src/routes/agent/-components/agent-chat.tsx
msgid "This will roll back this patch and any patches applied after it."
msgstr "Això desfarà aquest pegat i tots els pegats aplicats després."
#: src/routes/agent/-components/agent-chat.tsx
#: src/routes/agent/-components/thread-sidebar.tsx
msgid "Thread actions"
@@ -4794,6 +4879,18 @@ msgstr "Canvia la barra lateral dreta"
msgid "Toggle threads"
msgstr "Activa/desactiva els fils"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Tokens: {threadTokenTotal}"
msgstr "Tokens: {threadTokenTotal}"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Tokens: {total}"
msgstr "Tokens: {total}"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Tokens: {total} ({cached} cached)"
msgstr "Tokens: {total} ({cached} en memòria cau)"
#: src/features/applications/components/application-form-sheet.tsx
msgid "Track a job you're applying to and link the resume you sent."
msgstr "Fes un seguiment de la feina a la qual estàs sol·licitant i enllaça el currículum que has enviat."
@@ -5213,6 +5310,10 @@ msgstr "No hem pogut detectar el format automàticament. Trieu-lo a dalt."
msgid "We couldn't find that page"
msgstr "No hem pogut trobar aquesta pàgina"
#: src/routes/agent/-components/tool-part-card.tsx
msgid "Web search"
msgstr "Cerca web"
#: src/dialogs/resume/sections/award.tsx
#: src/dialogs/resume/sections/certification.tsx
#: src/dialogs/resume/sections/education.tsx
@@ -5445,4 +5546,3 @@ msgstr "Allunya"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulú"