Skip to content

[AGE-4141] feat(frontend): Persist an agent's icon on its workflow artifact - #6922

Merged
ashrafchowdury merged 3 commits into
release/v0.118.5from
feat/persist-agent-icon-on-artifact
Sep 17, 2026
Merged

ashrafchowdury merged 3 commits into
release/v0.118.5from
feat/persist-agent-icon-on-artifact

Conversation

@ashrafchowdury

Copy link
Copy Markdown
Contributor

Context

The agent icon picker (#6062) kept its choice in the browser's localStorage. Pick a robot and a colour on your laptop, and your phone, a second browser, and every teammate still saw the default glyph. The choice needs to live with the agent.

Closes #6082.

Changes

The icon now lives on the workflow artifact, under tags["@ag"].icon. Only the name and the colour travel; the glyph is looked up by name in the generated catalog, so no SVG markup is stored or rendered from data.

Stored on the artifact:

{"tags": {"@ag": {"icon": {"name": "robot", "color": "#113955"}}}}

Nothing changes for the surfaces. Every chip, row and avatar still reads agentIconAtomFamily(workflowId), and the picker still writes it. Only the atom behind that seam changed:

  • Read: the icon comes from the apps list (already loaded wherever agents show), with a by-id fetch only for an agent the list does not carry, and the old localStorage value as a last fallback so a pick made before this change does not vanish on that device.
  • Write: the pick shows at once, the artifact's latest tags are fetched and @ag.icon merged into them (the edit endpoint replaces the whole map, so every other tag comes back with it), then the PUT goes out. On failure the chip snaps back and a toast says so.
  • Two quick picks (icon, then colour) used to race. They now save in order, and the second pick builds on the first because the pending value is read ahead of the query cache. The query observer notifies a tick late, and a colour picked in that tick built on the old icon.
  • Clearing the icon sends {} rather than null. The API drops a null field and would have kept the old tags.

Three type fixes came out of this: UpdateWorkflowPayload.tags (and its create and evaluator siblings) said string[] against a nested-map schema; the evaluator drawer was sending Object.keys(tags), which the API rejects, and now passes the map through; and updateWorkflow skipped the PUT when tags was falsy.

No backend or SDK change. Tags already accepts nested maps, PUT /workflows/{id} writes them, and every workflow read returns them.

Tests

  • 15 unit tests in agent-icon.test.ts: tag read and merge, optimistic write, rollback on a failed save, the null clear, and two picks in flight saving in order.
  • Type-checks clean in @agenta/entities, @agenta/entity-ui, web/mobile and web/oss.
  • Verified on /m against the EE dev stack: the PUT body carries {name, color} and no SVG, the row in workflow_artifacts holds the same, and Reset leaves {}.
  • A follow-up, not in this PR: updateWorkflow still fetches a revision after every metadata PUT.

What to QA

  • On /m, open an agent, click its chip, pick an icon and a colour. Reload with localStorage cleared: the icon is still there. Open the same agent in another browser or as another member: same icon.
  • Pick an icon and a colour with no pause between the clicks. Both land; the icon does not revert to the robot.
  • Reset in the picker. The chip goes back to the default, and stays so after a reload.
  • An agent with a pre-existing localStorage icon and none on the backend still shows it until the next pick.
  • Regression: rename an agent or edit its description from the overview. The write still lands.
  • Regression: edit a human evaluator that has tags in the annotate drawer. The save no longer fails.

@linear-code

linear-code Bot commented Sep 17, 2026

Copy link
Copy Markdown

AGE-4141

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Advanced

Run ID: 9090bde3-1a4e-45ed-bf8f-02ae1a043ecc

📥 Commits

Reviewing files that changed from the base of the PR and between 4ebb4db and eac62be.

📒 Files selected for processing (12)
  • web/oss/src/components/SharedDrawers/AnnotateDrawer/assets/CreateEvaluator/index.tsx
  • web/packages/agenta-entities/src/workflow/api/api.ts
  • web/packages/agenta-entities/src/workflow/index.ts
  • web/packages/agenta-entities/src/workflow/state/agentIcon.ts
  • web/packages/agenta-entities/src/workflow/state/evaluatorUtils.ts
  • web/packages/agenta-entities/src/workflow/state/index.ts
  • web/packages/agenta-entities/src/workflow/state/store.ts
  • web/packages/agenta-entities/tests/__mocks__/agenta-ui-agent-icon.ts
  • web/packages/agenta-entities/tests/__mocks__/agenta-ui-app-message.ts
  • web/packages/agenta-entities/tests/unit/agent-icon-record.test.ts
  • web/packages/agenta-entities/tests/unit/agent-icon.test.ts
  • web/packages/agenta-entities/vitest.config.ts
📝 Summary

Summary by CodeRabbit

  • New Features

    • Agent icons are now stored with workflow metadata, preserving each agent’s selected icon and color across sessions.
    • Icon changes appear immediately and stay synchronized with the latest workflow data.
    • Clearing or changing workflow tags now updates metadata correctly.
  • Bug Fixes

    • Fixed tag updates when clearing tags.
    • Improved reliability for rapid icon changes and save failures.
  • Tests

    • Added coverage for icon tagging, persistence, optimistic updates, error handling, and tag management.

Walkthrough

Workflow agent icons are now stored in workflow artifact tags. The implementation validates icon settings, resolves SVG paths from the catalog, preserves unrelated tags, updates caches, supports optimistic saves, and retains legacy browser values as fallback.

Changes

Agent icon persistence

Layer / File(s) Summary
Workflow tag contracts and cache data
web/packages/agenta-entities/src/workflow/api/api.ts, web/packages/agenta-entities/src/workflow/state/evaluatorUtils.ts, web/packages/agenta-entities/src/workflow/state/store.ts, web/oss/src/components/SharedDrawers/AnnotateDrawer/assets/CreateEvaluator/index.tsx
Workflow and evaluator payloads use the workflow tag shape. null tags trigger metadata updates. Workflow references retain tags, and artifact caches can receive metadata patches. Evaluator updates pass tags through unchanged.
Artifact-backed icon state
web/packages/agenta-entities/src/workflow/state/agentIcon.ts
Icon settings are read from @ag.icon, validated, resolved through the icon catalog, and saved with serialized optimistic updates. Saves merge with current tags, patch caches, roll back on failure, and remove migrated browser values after success.
Public exports and validation
web/packages/agenta-entities/src/workflow/index.ts, web/packages/agenta-entities/src/workflow/state/index.ts, web/packages/agenta-entities/tests/*, web/packages/agenta-entities/vitest.config.ts
The new helpers and type are exported. Tests cover parsing, merging, reads, saves, rollback, clearing, serialization, failures, and missing identifiers. Dedicated UI mocks support the tests. The previous record-validation test suite was removed.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant IconPicker
  participant agentIconAtomFamily
  participant queryWorkflows
  participant updateWorkflow
  participant WorkflowCaches
  IconPicker->>agentIconAtomFamily: select icon and color
  agentIconAtomFamily->>queryWorkflows: fetch latest workflow tags
  agentIconAtomFamily->>updateWorkflow: save merged `@ag.icon` tag
  updateWorkflow-->>agentIconAtomFamily: return success or failure
  agentIconAtomFamily->>WorkflowCaches: patch artifact caches
Loading

Merge Risk: 🟡 Moderate · up to 4ebb4

Icon updates can remove unrelated workflow metadata, while cleared or temporarily unavailable icons may render incorrectly. These issues should be fixed before merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: persisting an agent's icon on its workflow artifact.
Description check ✅ Passed The description directly explains the artifact-based icon persistence, tag handling, fallback behavior, tests, and related workflow fixes.
Linked Issues check ✅ Passed The pull request satisfies the coding requirements in [#6082]. It stores only the icon name and validated color in tags["@ag"].icon, and it resolves SVG paths from the generated catalog. `withAgentI…
Out of Scope Changes check ✅ Passed The changes stay within [#6082]. Tag typing, evaluator tag propagation, metadata handling, cache patching, catalog mocks, retryable catalog loading, and focused tests support persisted agent icon tags…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 60.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 11 files.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-pr-6922.up.railway.app/w
Project agenta-oss-clone-spike
Image tag pr-6922-ecccee2
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-09-17T13:56:20.776Z

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Advanced

Run ID: 000812a1-541f-4b18-a7c5-da0e8a2643aa

📥 Commits

Reviewing files that changed from the base of the PR and between c22ad69 and d51130e.

📒 Files selected for processing (12)
  • web/oss/src/components/SharedDrawers/AnnotateDrawer/assets/CreateEvaluator/index.tsx
  • web/packages/agenta-entities/src/workflow/api/api.ts
  • web/packages/agenta-entities/src/workflow/index.ts
  • web/packages/agenta-entities/src/workflow/state/agentIcon.ts
  • web/packages/agenta-entities/src/workflow/state/evaluatorUtils.ts
  • web/packages/agenta-entities/src/workflow/state/index.ts
  • web/packages/agenta-entities/src/workflow/state/store.ts
  • web/packages/agenta-entities/tests/__mocks__/agenta-ui-agent-icon.ts
  • web/packages/agenta-entities/tests/__mocks__/agenta-ui-app-message.ts
  • web/packages/agenta-entities/tests/unit/agent-icon-record.test.ts
  • web/packages/agenta-entities/tests/unit/agent-icon.test.ts
  • web/packages/agenta-entities/vitest.config.ts
💤 Files with no reviewable changes (1)
  • web/packages/agenta-entities/tests/unit/agent-icon-record.test.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread web/packages/agenta-entities/src/workflow/state/agentIcon.ts Outdated
} else {
tags = get(workflowArtifactQueryAtomFamily(workflowId)).data?.tags
}
return readAgentIconTag(tags) ?? readLegacySetting(get(legacyIconMapAtom)?.[workflowId])

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.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

sed -n '40,220p' web/packages/agenta-entities/src/workflow/state/agentIcon.ts
sed -n '150,210p' web/packages/agenta-entities/tests/unit/agent-icon.test.ts

Repository: Agenta-AI/agenta

Length of output: 10204


🏁 Script executed:

sed -n '1,170p' web/packages/agenta-entities/tests/unit/agent-icon.test.ts
printf '\n--- legacy references ---\n'
rg -n -C 5 'legacy|localStorage|agent-icon:1|clear.*icon|icon.*clear' web/packages/agenta-entities/tests web/packages/agenta-entities/src/workflow/state/agentIcon.ts

Repository: Agenta-AI/agenta

Length of output: 50372


Persist an explicit clear or migration marker.

When a successful null write removes @ag.icon, agentIconSettingAtomFamily falls back to readLegacySetting. The write removes the legacy entry only from the current browser. Another browser with the old localStorage value can render the stale icon because the artifact has no marker that distinguishes an explicit clear from an unmigrated workflow.

Use the legacy value only when the artifact has no migration marker. Persist that marker when the icon is cleared.

Comment thread web/packages/agenta-entities/src/workflow/state/agentIcon.ts
@ashrafchowdury
ashrafchowdury changed the base branch from release/v0.118.3 to main September 17, 2026 05:54

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Advanced

Run ID: 1937a62b-c240-41ea-8ecb-a8f30ccf356b

📥 Commits

Reviewing files that changed from the base of the PR and between d51130e and 4ebb4db.

📒 Files selected for processing (2)
  • web/packages/agenta-entities/src/workflow/state/agentIcon.ts
  • web/packages/agenta-entities/tests/unit/agent-icon.test.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread web/packages/agenta-entities/src/workflow/state/agentIcon.ts Outdated
Comment thread web/packages/agenta-entities/src/workflow/state/agentIcon.ts
… tags.@ag.icon

The picker's choice was in localStorage, so no other device or teammate saw it (#6082).
It now goes to the artifact as {name, color} — the glyph is resolved by name from the
catalog, so no SVG is stored or rendered from data. The seam is unchanged: every surface
still reads agentIconAtomFamily, and the picker still writes it.

The write is optimistic behind a synchronous overlay (the query observer notifies a tick
late, and a colour picked in that tick built on the old icon), saves are serialised per
agent, and the merged map is fetched fresh before the PUT because the edit replaces tags.
An emptied map is sent as {} — the API drops a null field and would keep the old tags.

Also: the payload types said tags were string[] against a nested-map schema; the
evaluator drawer was sending Object.keys(tags), which the API rejects; and updateWorkflow
skipped the PUT for tags: null.
…e fallback glyph

unwrap only substitutes NO_GLYPHS while the catalog promise is pending; a rejection threw
out of agentIconAtomFamily and into the nearest error boundary, taking the whole surface
with it. Swallow the failure into an empty map instead. The loader already drops a
rejected promise, so the picker's own retry is unaffected.
…ls a glyph map a failed load left empty

Two review findings. If the by-id query comes back without the workflow (a validation
failure, say), merging into nothing would write an icon-only map and wipe every other tag;
now the save throws into the rollback path instead. And a catalog load that failed once
left the glyph map empty for the session, so configured icons stayed on the fallback even
after the picker had loaded the catalog fine; the map is refreshable now and a successful
pick refills it.
@ashrafchowdury
ashrafchowdury force-pushed the feat/persist-agent-icon-on-artifact branch from 4ebb4db to eac62be Compare September 17, 2026 13:43
@ashrafchowdury
ashrafchowdury changed the base branch from main to release/v0.118.5 September 17, 2026 13:49
@ashrafchowdury
ashrafchowdury merged commit 4a3b207 into release/v0.118.5 Sep 17, 2026
46 of 47 checks passed
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.

(feat) persist custom agent icons across devices

1 participant