Skip to content

[Payment due @cretadn22] Make a new agent a full co-pilot of its creator#94602

Merged
puneetlath merged 4 commits into
mainfrom
yuwen-651811-agent-copilot
Jul 6, 2026
Merged

[Payment due @cretadn22] Make a new agent a full co-pilot of its creator#94602
puneetlath merged 4 commits into
mainfrom
yuwen-651811-agent-copilot

Conversation

@yuwenmemon

@yuwenmemon yuwenmemon commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@puneetlath please review

Explanation of Change

When you create an agent from Settings > Agents, it's now sent as a full co-pilot of your account so it can act on your behalf without you adding it as a co-pilot by hand. The create screen also says this up front, so the relationship is clear before you create the agent.

Needs the backend pieces to take effect: Auth #22504 and Web-Expensify #54103 (deploy Auth, then Web, then this).

Fixed Issues

$ https://github.com/Expensify/Expensify/issues/651811
PROPOSAL: N/A

Tests

  1. Go to Settings > Agents > New agent.
  2. Verify the note above the "Create agent" button says the agent will be added as a full copilot of your account so it can act on your behalf.
  3. Create the agent.
  4. Go to Settings > Security > Copilot: Delegated access and verify the new agent is listed as a copilot that can access your account.
  • Verify that no errors appear in the JS console

Offline tests

Agent creation is optimistic, so the same steps work offline and reconcile once you're back online.

QA Steps

Same as tests.

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

@OSBotify

Copy link
Copy Markdown
Contributor

🦜 Polyglot Parrot! 🦜

Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues:

View the translation diff
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 22e1904cb15..cac520ff07b 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -2846,7 +2846,7 @@ ${amount} für ${merchant} – ${date}`,
         defaultAgentName: (displayName: string) => `Agent*in von ${displayName}`,
         defaultPrompt:
             'Lehne Ausgaben ab, die für Glücksspiele, Kinobesuche oder andere offensichtlich nicht geschäftliche Zwecke sind.\n\nErinnere den:die Nutzer:in daran, immer ein Belegfoto beizufügen, auf dem das Trinkgeld klar erkennbar ist.\n\nGenehmige den Bericht, wenn er früheren Berichten derselben Person sehr ähnlich ist.\n\nLehne Berichte mit mehr als 500 $ an Reisekosten ab.',
-        copilotNote: 'Dieser Agent wird als Copilot mit vollem Zugriff auf dein Konto hinzugefügt, sodass er in deinem Namen handeln kann.',
+        copilotNote: 'Dieser Agent wird als vollwertige Assistenz für Ihr Konto hinzugefügt, sodass er in Ihrem Namen handeln kann.',
     },
     editAgentPage: {
         title: 'Agent bearbeiten',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 01b62f1f765..19654251e3f 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -1753,7 +1753,6 @@ const translations: TranslationDeepObject<typeof en> = {
                 }
             },
             [CONST.NEXT_STEP.MESSAGE_KEY.WAITING_TO_MARK_AS_DONE]: (actor, actorType, _eta, _etaType) => {
-                // eslint-disable-next-line default-case
                 switch (actorType) {
                     case CONST.NEXT_STEP.ACTOR_TYPE.CURRENT_USER:
                         return `Esperando a que <strong>tú</strong> lo marques como listo.`;
@@ -2718,7 +2717,7 @@ ${amount} para ${merchant} - ${date}`,
         defaultAgentName: (displayName: string) => `Agente de ${displayName}`,
         defaultPrompt:
             'Rechazar gastos por juegos de azar, películas u otras razones claramente no comerciales.\n\nRecordar al usuario que siempre incluya una imagen del recibo que muestre claramente la propina.\n\nAprobar el informe si es muy similar a informes anteriores del mismo usuario.\n\nRechazar informes con más de $500 en gastos de viaje.',
-        copilotNote: 'Este agente se añadirá como copiloto con acceso completo a tu cuenta, para que pueda actuar en tu nombre.',
+        copilotNote: 'Este agente se añadirá como copiloto completo de tu cuenta, para que pueda actuar en tu nombre.',
     },
     editAgentPage: {
         title: 'Editar agente',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index d7d30af598a..69af235edc5 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -1,6 +1,7 @@
 /**
  *   _____                      __         __
  *  / ___/__ ___  ___ _______ _/ /____ ___/ /
+ * / (_ / -_) _ \/ -_) __/ _ \`/ __/ -_) _  /
  * \___/\__/_//_/\__/_/  \_,_/\__/\__/\_,_/
  *
  * This file was automatically generated. Please consider these alternatives before manually editing it:
@@ -862,7 +863,7 @@ const translations: TranslationDeepObject<typeof en> = {
         beginningOfChatHistory: (users: string) => `Cette discussion est avec ${users}.`,
         beginningOfChatHistoryPolicyExpenseChat: (workspaceName: string, submitterDisplayName: string) =>
             `C’est ici que <strong>${submitterDisplayName}</strong> soumettra des dépenses à <strong>${workspaceName}</strong>. Utilisez simplement le bouton +.`,
-        beginningOfChatHistoryPolicyExpenseChatTrack: 'C\u2019est ici que vous suivrez vos dépenses',
+        beginningOfChatHistoryPolicyExpenseChatTrack: 'C’est ici que vous suivrez vos dépenses',
         beginningOfChatHistorySelfDM: 'Ceci est votre espace personnel. Utilisez-le pour vos notes, tâches, brouillons et rappels.',
         beginningOfChatHistorySystemDM: 'Bienvenue ! Procédons à la configuration.',
         chatWithAccountManager: 'Discutez avec votre gestionnaire de compte ici',
@@ -2852,7 +2853,7 @@ ${amount} pour ${merchant} - ${date}`,
         defaultAgentName: (displayName: string) => `Agent de ${displayName}`,
         defaultPrompt:
             'Rejeter les dépenses liées aux jeux d’argent, aux films ou à d’autres motifs manifestement non professionnels.\n\nRappeler à l’utilisateur d’inclure systématiquement une image du reçu où le pourboire est clairement visible.\n\nApprouver le rapport s’il est très similaire aux rapports précédents du même utilisateur.\n\nRejeter les rapports contenant plus de 500 $ de frais de déplacement.',
-        copilotNote: 'Cet agent sera ajouté comme copilote avec un accès complet à votre compte, afin de pouvoir agir en votre nom.',
+        copilotNote: 'Cet agent sera ajouté comme copilote à part entière de votre compte, afin de pouvoir agir en votre nom.',
     },
     editAgentPage: {
         title: 'Modifier l’agent',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index d0fa1d2ade9..77d91665cc5 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -2841,7 +2841,7 @@ ${amount} per ${merchant} - ${date}`,
         defaultAgentName: (displayName: string) => `Agente di ${displayName}`,
         defaultPrompt:
             "Rifiuta le spese relative a gioco d'azzardo, cinema o altri motivi chiaramente non legati all'attività.\n\nRicorda all'utente di includere sempre un'immagine della ricevuta in cui la mancia sia ben visibile.\n\nApprova il report se è molto simile ai report precedenti dello stesso utente.\n\nRifiuta i report con più di 500 $ di spese di viaggio.",
-        copilotNote: 'Questo agente verrà aggiunto come Copilot con accesso completo al tuo account, così potrà agire per tuo conto.',
+        copilotNote: 'Questo agente verrà aggiunto come copilota completo del tuo account, così potrà agire per tuo conto.',
     },
     editAgentPage: {
         title: 'Modifica agente',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index c7b4be0ad9f..e75c804099a 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -2817,7 +2817,7 @@ ${date} の ${merchant} への ${amount}`,
         defaultAgentName: (displayName: string) => `${displayName} さんの代理人`,
         defaultPrompt:
             'ギャンブル、映画、またはその他明らかにビジネス目的ではない理由による経費は却下します。\n\nチップの金額が明確にわかるレシート画像を必ず添付するよう、ユーザーにリマインドします。\n\n同じユーザーの過去のレポートと非常によく似ている場合は、そのレポートを承認します。\n\n出張費が500ドルを超えるレポートは却下します。',
-        copilotNote: 'このエージェントは、アカウントへのフルアクセス権を持つCopilotとして追加され、あなたの代わりに操作できるようになります。',
+        copilotNote: 'このエージェントはお客様のアカウントの正式なコパイロットとして追加され、お客様に代わって操作できるようになります。',
     },
     editAgentPage: {
         title: 'エージェントを編集',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 0856c0a62b9..2f4e17498c3 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -2839,7 +2839,7 @@ ${amount} voor ${merchant} - ${date}`,
         defaultAgentName: (displayName: string) => `Agent van ${displayName}`,
         defaultPrompt:
             'Wijs declaraties af die zijn voor gokken, films of andere duidelijk niet-zakelijke redenen.\n\nHerinner de gebruiker eraan altijd een bonafbeelding toe te voegen waarop de fooi duidelijk is.\n\nKeur het verslag goed als het sterk lijkt op eerdere verslagen van dezelfde gebruiker.\n\nWijs verslagen af met meer dan $500 aan reiskosten.',
-        copilotNote: 'Deze agent wordt toegevoegd als Copilot met volledige toegang tot je account, zodat hij namens jou kan handelen.',
+        copilotNote: 'Deze agent wordt als volledige copiloot aan je account toegevoegd, zodat hij namens jou kan handelen.',
     },
     editAgentPage: {
         title: 'Agent bewerken',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 43fa09d6d3a..b8ab6f80669 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -2833,7 +2833,7 @@ ${amount} dla ${merchant} - ${date}`,
         defaultAgentName: (displayName: string) => `Agent ${displayName}`,
         defaultPrompt:
             'Odrzucaj wydatki związane z hazardem, filmami lub innymi oczywistymi celami niezwiązanymi z działalnością biznesową.\n\nPrzypominaj użytkownikowi, aby zawsze dołączał zdjęcie paragonu, na którym wysokość napiwku jest wyraźnie widoczna.\n\nZatwierdź raport, jeśli jest bardzo podobny do wcześniejszych raportów tego samego użytkownika.\n\nOdrzucaj raporty zawierające więcej niż 500 USD wydatków na podróże.',
-        copilotNote: 'Ten agent zostanie dodany jako Copilot z pełnym dostępem do Twojego konta, aby mógł działać w Twoim imieniu.',
+        copilotNote: 'Ten agent zostanie dodany jako pełny kopilot twojego konta, dzięki czemu będzie mógł działać w twoim imieniu.',
     },
     editAgentPage: {
         title: 'Edytuj agenta',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index ed3669b0ed5..96f2ec6b47e 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -2833,7 +2833,7 @@ ${amount} para ${merchant} - ${date}`,
         defaultAgentName: (displayName: string) => `Agente de ${displayName}`,
         defaultPrompt:
             'Rejeite despesas relacionadas a jogos de azar, cinema ou outros motivos claramente não relacionados ao negócio.\n\nLembre o usuário de sempre incluir uma imagem do recibo em que a gorjeta fique clara.\n\nAprove o relatório se ele for muito semelhante a relatórios anteriores do mesmo usuário.\n\nRejeite relatórios com mais de US$ 500 em despesas de viagem.',
-        copilotNote: 'Este agente será adicionado como Copilot com acesso total à sua conta, para que possa agir em seu nome.',
+        copilotNote: 'Esse agente será adicionado como copiloto completo da sua conta, para que possa agir em seu nome.',
     },
     editAgentPage: {
         title: 'Editar agente',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 74743614a1f..2527714e40e 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2761,7 +2761,7 @@ ${amount},商户:${merchant} - 日期:${date}`,
         defaultAgentName: (displayName: string) => `${displayName} 的代理人`,
         defaultPrompt:
             '拒绝与赌博、电影或其他明显非商务原因相关的报销。\n\n提醒用户务必附上一张能清楚显示小费金额的收据图片。\n\n如果报销报告与同一用户之前的报告非常相似,则批准该报告。\n\n拒绝包含超过 500 美元差旅费用的报销报告。',
-        copilotNote: '该代理将作为对你账户拥有完全访问权限的 Copilot 添加,以便代表你执行操作。',
+        copilotNote: '此代理将被添加为你账户的完整副驾驶,因此它可以代表你采取行动。',
     },
     editAgentPage: {
         title: '编辑代理',

Note

You can apply these changes to your branch by copying the patch to your clipboard, then running pbpaste | git apply 😉

View workflow run

@yuwenmemon

Copy link
Copy Markdown
Contributor Author

@MelvinBot apply these translations

@yuwenmemon yuwenmemon marked this pull request as ready for review June 25, 2026 22:37
@yuwenmemon yuwenmemon requested review from a team as code owners June 25, 2026 22:37
@melvin-bot melvin-bot Bot requested review from cretadn22 and trjExpensify and removed request for a team June 25, 2026 22:37
@melvin-bot

melvin-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

@cretadn22 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot melvin-bot Bot removed the request for review from a team June 25, 2026 22:37
@yuwenmemon yuwenmemon changed the title Make a new agent a full co-pilot of its creator [HOLD WEB#54015] Make a new agent a full co-pilot of its creator Jun 25, 2026
@yuwenmemon yuwenmemon requested a review from puneetlath June 25, 2026 22:38
@MelvinBot

Copy link
Copy Markdown
Contributor

I can apply the Polyglot Parrot translation patch (the copilotNote updates across de, es, fr, it, ja, nl, pl, pt-BR, zh-hans, plus the minor fr/es cleanups), but I can't push to this branch right now.

⚠️ I can't push changes to this PR because I didn't open it and I'm not listed as an assignee. To have me make this fix, add me to the PR assignees and then retry your request.

In the meantime, you can apply the patch yourself by copying the diff from the Polyglot Parrot comment and running pbpaste | git apply.

puneetlath
puneetlath previously approved these changes Jun 26, 2026

@puneetlath puneetlath left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuwenmemon I don't feel strongly, but I feel like maybe it makes more sense to handle this on the back-end? In the future, we're going to have company-owned and personal-owned agents. Company-owned will not get added as copilots by default and personal-owned will. And I kind of feel like it makes sense for the back-end to be the one to make that choice, especially since there is nothing in the UI that is controlling which it is.

I think we are doing it this way for now because of RuleBot, which we don't want to make a copilot for anyone. But maybe we can just pass isRuleBot to the API instead and let it decide? That makes more logical sense to me.

I don't feel super strongly about it, so I'm going to approve anyways since this should work. But if you agree then please update.

@cretadn22

Copy link
Copy Markdown
Contributor

@puneetlath @yuwenmemon Does this PR need a C+ review and checklist?

@puneetlath

Copy link
Copy Markdown
Contributor

@cretadn22 yes, I think that would be idea. But the BE hasn't been merged yet. What do you think about my comment?

Comment thread src/libs/actions/Agent.ts Outdated
WRITE_COMMANDS.CREATE_AGENT,
{firstName, prompt, customExpensifyAvatarID, file, policyID, optimisticAccountID: String(optimisticAccountID)},
{firstName, prompt, customExpensifyAvatarID, file, policyID, optimisticAccountID: String(optimisticAccountID), shouldAddAsCopilot: true},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a planned use case for passing shouldAddAsCopilot: false to this command? If it's always intended to be true, we should consider removing this new parameter to keep the API clean

@cretadn22

cretadn22 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Reviewer Checklist

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified that the composer does not automatically focus or open the keyboard on mobile unless explicitly intended. This includes checking that returning the app from the background does not unexpectedly open the keyboard.
  • I verified tests pass on all platforms & I tested again on:
    • Android: HybridApp
    • Android: mWeb Chrome
    • iOS: HybridApp
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • For any bug fix or new feature in this PR, I verified that sufficient unit tests are included to prevent regressions in this flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Android: HybridApp
Screen.Recording.2026-07-03.at.12.27.34.mov
Android: mWeb Chrome
Screen.Recording.2026-07-03.at.12.20.01.mov
iOS: HybridApp
Screen.Recording.2026-07-03.at.12.21.55.mov
iOS: mWeb Safari
Screen.Recording.2026-07-03.at.12.06.29.mov
MacOS: Chrome / Safari
Screen.Recording.2026-07-03.at.12.04.54.mov

@cretadn22

Copy link
Copy Markdown
Contributor

The frontend changes look good, we're just waiting on the backend update

Screenshot 2026-06-30 at 21 15 55

@NicolasBonet NicolasBonet changed the title [HOLD WEB#54015] Make a new agent a full co-pilot of its creator [HOLD WEB#54103] Make a new agent a full co-pilot of its creator Jun 30, 2026
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ Changes either increased or maintained existing code coverage, great job!

Files with missing lines Coverage Δ
src/libs/actions/Agent.ts 80.30% <ø> (ø)
src/pages/settings/Agents/AddAgentPage.tsx 86.44% <100.00%> (+0.23%) ⬆️
... and 210 files with indirect coverage changes

@yuwenmemon yuwenmemon changed the title [HOLD WEB#54103] Make a new agent a full co-pilot of its creator Make a new agent a full co-pilot of its creator Jul 2, 2026
@yuwenmemon

Copy link
Copy Markdown
Contributor Author

Web is on staging, removing HOLD

@yuwenmemon

Copy link
Copy Markdown
Contributor Author

@cretadn22 bump on this one please!

Comment thread src/libs/actions/Agent.ts
// Flag this as the user's personal agent; the backend makes personal agents a full co-pilot of the creator.
WRITE_COMMANDS.CREATE_AGENT,
{firstName, prompt, customExpensifyAvatarID, file, policyID, optimisticAccountID: String(optimisticAccountID)},
{firstName, prompt, customExpensifyAvatarID, file, policyID, optimisticAccountID: String(optimisticAccountID), isPersonalAgent: true},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a planned use case for passing isPersonalAgent: false to this command? If it's always intended to be true, we should consider removing this new parameter to keep the API clean

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, workspace agents are a planned future use-case

@cretadn22 cretadn22 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one callout: #94602 (comment)

@melvin-bot melvin-bot Bot requested a review from madmax330 July 3, 2026 05:29
@melvin-bot

melvin-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

@madmax330 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@melvin-bot melvin-bot Bot changed the title Make a new agent a full co-pilot of its creator [Payment due @cretadn22] Make a new agent a full co-pilot of its creator Jul 3, 2026
@melvin-bot

melvin-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

🎯 @cretadn22, thanks for reviewing and testing this PR! 🎉

A payment issue will be created for your review once this PR is deployed to production.
E/E issue linked to the PR - https://www.github.com/Expensify/Expensify/issues/651811.

If payment is not needed (e.g., regression PR review fix etc), react with 👎 to this comment to prevent the payment issue from being created.

@trjExpensify trjExpensify left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Core PR for a WN project. 👍

@puneetlath puneetlath merged commit d8ac0fd into main Jul 6, 2026
44 of 46 checks passed
@puneetlath puneetlath deleted the yuwen-651811-agent-copilot branch July 6, 2026 21:34
@OSBotify

OSBotify commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🚧 puneetlath has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify

OSBotify commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/puneetlath in version: 9.4.29-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@MelvinBot

Copy link
Copy Markdown
Contributor

🤖 Help site review — changes required

This PR changes agent creation so a new agent is automatically added as a full Copilot of its creator's account (so it can act on your behalf, without you adding it as a Copilot by hand). That directly affects the Create and Use Agents help article.

The article on main already documented adding an agent as a Copilot on your own account, but framed it as an optional/manual step. I've updated it to reflect the new automatic behavior and the note now shown above the Create agent button.

Draft help site PR: #95531

What changed in the article (docs/articles/new-expensify/ai-agents/Create-and-Use-Custom-Agents.md):

  • Intro: agent is now automatically added as a full Copilot on your account (was "You can also add…").
  • How to create an Agent: added a step to review the note above the button explaining the agent will be added as a full Copilot of your account.
  • What happens after you create an agent: the optional bullet now states the agent is automatically added as a full Copilot, with a pointer to Account > Security > Copilot: Delegated access to review it.
  • FAQ: reworked to reflect that the Copilot relationship is created automatically.

@yuwenmemon, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR Ready for review

@OSBotify

OSBotify commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/puneetlath in version: 9.4.31-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@MelvinBot

Copy link
Copy Markdown
Contributor

Help site review — changes required ✅

This PR makes a newly created agent automatically a full-access Copilot of its creator's account so it can act on their behalf, and adds an on-screen note explaining this before creation.

The existing help article Create and Use Agents already covered this capability, but described it as an optional / manual step ("You can also add an agent as a Copilot on your own account"). With this PR it now happens automatically on creation, so the docs were out of date.

Draft help site PR: #95675

What the docs PR updates
  • Intro: Now states creating an agent automatically adds it as a full-access Copilot on your account, and points to Copilot: Delegated Access under Account > Security.
  • How to create an Agent: Adds a step for the on-screen note above the Create agent button.
  • What happens after you create an agent: Changes the "You can optionally add…" bullet to reflect the automatic behavior.
  • FAQ: Reworks the "add an agent as a Copilot on my own account" entry to explain it's automatic on creation.
  • Metadata: Updates the description.

UI labels were verified against the existing Copilot help articles and this PR's copy for exact capitalization.

@yuwenmemon, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR Ready for review

@OSBotify

OSBotify commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/grgia in version: 9.4.31-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

@melvin-bot

melvin-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

🤖 Payment issue created: #95679

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.

7 participants