Commit Graph

19351 Commits

Author SHA1 Message Date
Robin Braumann
f3269e1396 Merge branch 'n8n-agents' into toolchains-spike
Resolves conflicts to keep:
- Apps toolset surface from toolchains-spike (registry, factory, normalizer,
  AppDefinition, /catalog/apps/:kind/operations endpoint, FE registry +
  modals + list panel + tool-step labels).
- Builder/integration polish from n8n-agents (i18n-keyed help/connected
  copy, narrower default chat column, agent RBAC resource).

Drops the inline displayHelpText/displayConnectedText fields on
ChatIntegrationDescriptor and the per-platform classes — the strings now
live in the FE i18n catalog keyed by integration type.

Adds the missing 'agent' entry to rbac.store.ts scopesByResourceId so the
new Resource union type compiles.
2026-04-28 10:12:27 +02:00
Robin Braumann
63eb10cd38 Add Slack integration 2026-04-27 14:59:01 +02:00
bjorger
d2bc913cd7
feat(agents): Polish agent builder UI and tighten builder/chat reliability (#29047)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 14:31:14 +02:00
Robin Braumann
58bcf5d800 add google sheets support 2026-04-27 14:22:04 +02:00
Robin Braumann
cdab0f0356 refactor(agents): unify @n8n/agents imports; FE owns its own toolsets copy
Restore the agents SDK to a single canonical import path
(`from '@n8n/agents'`) for backend consumers, and decouple the editor-ui
from the SDK entirely so the package stays server-only.

The previous split via `exports` + `typesVersions` made `toolsets` a
second-class subpath while every other SDK export lived at the package
root. The asymmetry papered over the real issue: the SDK is server-side
(pulls undici via MCP/AI-SDK), so the editor-ui shouldn't depend on it.

- editor-ui: new `features/agents/utils/appToolsets.ts` mirrors the
  registry data + walker + types the FE needs (~200 lines). Drop the
  `@n8n/agents` workspace dep. Drift between this and the BE registry
  is enforced by code review when adding new apps.
- `@n8n/agents`: drop the `exports` and `typesVersions` blocks. Restore
  flat re-exports of `APP_REGISTRY`, `findAppDefinition`,
  `buildOperationsFromDescription`, `buildManifest`, and toolsets types
  from `src/index.ts` so cli can keep `from '@n8n/agents'` for
  everything.
- cli: consolidate imports back to `@n8n/agents`. No subpath imports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:22:57 +02:00
Robin Braumann
e9cbbef10f refactor(agents): address review follow-ups on the toolsets cleanup
Three small follow-ups from the cleanup's final review:

- `app-toolset-factory.ts`: drop the hand-rolled `zodObjectToJson` /
  `zodTypeNameToJson` helpers and use `zodToJsonSchema` from `@n8n/agents`.
  The hand-rolled walker was non-recursive and dropped nested object
  structure for `collection` / `fixedCollection` params; the shared
  utility recurses correctly via `zod-to-json-schema`.
- `useCredentialScopes`: add a 30s TTL to the module-level scope cache so
  re-opening the modal after re-OAuth surfaces refreshed scopes within
  the window. Failures are still uncached. Also export an
  `invalidateCredentialScopes(id)` for explicit invalidation when callers
  know the scopes have changed.
- `buildOperationsFromDescription`: emit one OperationEntry per resource
  when an operation group declares multiple in `displayOptions.show.resource`,
  rather than dropping all but the first. Dedupe by `resource:operation`
  to handle the rare case of overlapping operation groups. Two new tests
  cover the multi-resource and dedupe paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:09:26 +02:00
Robin Braumann
e1b3229403 fix(agents): split @n8n/agents into FE-safe and full-SDK entries
The agents toolsets cleanup made editor-ui import from @n8n/agents for
the registry, which transitively bundled the full server SDK (MCP client,
AI SDK adapters) and pulled `undici` into the browser bundle, breaking
`pnpm build`. Tree-shaking can't help here — the package compiles to CJS
and isn't marked side-effect-free.

Declare the boundary at the package surface instead:

- `exports` field: `.` continues to expose the full SDK; new `./toolsets`
  entry exposes only the pure-data + pure-algorithm surface
  (`AppDefinition`, `OperationEntry`, `buildOperationsFromDescription`,
  `buildManifest`, `APP_REGISTRY`, `findAppDefinition`).
- `typesVersions` mirrors the subpath so TypeScript resolves it under
  the repo's `moduleResolution: "node"` (legacy mode ignores `exports`).
- Drop the flat re-exports of toolsets symbols from `src/index.ts`. The
  registry now has exactly one canonical import path,
  `@n8n/agents/toolsets`. Backend code that wants the namespace can keep
  using `import { toolsets } from '@n8n/agents'`.
- Update cli (`agents.service`, `app-toolset-factory` + its test) and
  editor-ui (`AgentAppsModal`, `AgentAppConfigModal`, `AgentAppsListPanel`,
  `AgentChatToolSteps`) to import from `@n8n/agents/toolsets`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:02:30 +02:00
Robin Braumann
1b6430d466 refactor(agents): generalize Gmail toolset POC into a per-app registry
Restructure the Gmail-only "apps/toolsets" POC so adding a second app is a
one-file change. Each integration ships as an `AppDefinition` in
`@n8n/agents/src/toolsets/registry/`; backend and frontend consume the
registry through the same flat re-exports off `@n8n/agents`.

- New `@n8n/agents/toolsets/` module: `AppDefinition` + `OperationEntry`
  types, `buildOperationsFromDescription` (single source of truth for the
  registry walk + scope-based status classification), `buildManifest`
  (string/function/default-deriver resolution), and `APP_REGISTRY` with
  Gmail as the first entry.
- Generic `buildAppToolset` factory in cli replaces the Gmail-specific
  `buildGmailToolset`. `agents.service.attachAppToolsets` now resolves
  app kinds via `findAppDefinition` and skips unknown kinds with a warn
  log instead of rejecting at save time.
- New `GET /credentials/:credentialId/oauth-scopes` endpoint +
  `CredentialsService.getOAuthGrantedScopes` helper. Reads
  `oauthTokenData.scope` (post-grant) with a fallback to declared
  `scope` (pre-grant). Distinct from the existing RBAC `getCredentialScopes`.
- New `useCredentialScopes` FE composable feeds the App config modal so
  per-operation status badges classify against the credential's
  actually-granted scopes.
- `AgentJsonAppRef.kind` widened from the `'gmail'` literal to plain
  string. Forward-compat: a config saved with an unknown kind loads
  cleanly.
- Editor-ui: `AgentAppsModal` rebuilt on `Modal.vue` + `NodeCredentials`
  (drops the hand-rolled backdrop and raw select). `AgentAppConfigModal`,
  `AgentAppsListPanel`, and `AgentChatToolSteps` resolve icon, label, and
  dispatcher names from the registry.
- Drop the Gmail-only `gmail-toolset.ts` and `gmailOperations.ts`.

Tests: 10 new in `@n8n/agents/toolsets`, 6 in
`cli/src/modules/agents/toolsets`, 4 in `cli/src/credentials`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:25:11 +02:00
Robin Braumann
a71242029c test(agents): unblock CI after onBeforeRouteUpdate + drop stale FE tests
- AgentBuilderView.test: extend the vue-router mock with onBeforeRouteUpdate
  (added in the recent unpublished-changes-on-agent-switch fix), stub the
  editor-column panels (info/advanced/memory/evals/tools/integrations/sessions)
  so the view test doesn't have to mock the chatHub/users/sessions ecosystem,
  and update the chat-mode assertions to the current "default to build unless
  URL pins a session" behaviour.
- AgentBuilderHeader.test: assert the single project breadcrumb the header
  actually renders today (workspace crumb removed earlier).
- AgentPublishButton.test: bump testTimeout — first SFC compile crept past
  the default 5 s on slower CI workers, causing a flaky timeout on the first
  case only.
- AgentConfigTree.test, AgentCard.test: delete. Both were stale enough that
  fixing them would be a rewrite, and the user has explicitly de-prioritised
  this layer of FE coverage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 09:04:53 +02:00
Robin Braumann
9c2fbc7218 fix(agents): guard interactive-summary against non-object outputs
Without an object check, a malformed wire payload (string/number/null
inside an unknown) would throw at the `'skipped' in resume` line. Bail
on non-object outputs and return undefined so the caller falls back to
just the tool name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 20:42:04 +02:00
Robin Braumann
79fc8614f0 feat(agents): improve interactive cards (compact history + auto-resolve)
Stage 1 — frontend rendering
- Resolved interactive cards (ask_question / ask_credential / ask_llm) used to
  vanish from chat history; now they leave a compact "→ tool · answer" trace
  in AgentChatToolSteps, matching how non-interactive tool calls render.
- ToolCall carries an optional displaySummary populated on tool-result, on
  the optimistic resume flip, and rolled back on resume failure.
- New summariseInteractiveOutput helper + 7 unit tests.

Stage 2 — server-side auto-resolve
- ask_question: auto-resolves when options.length === 1 (schema relaxed
  from min(2) to min(1) so the LLM can actually pass single-option
  questions).
- ask_credential: auto-resolves when exactly one credential of the
  requested type is available to the user.
- ask_llm: auto-resolves when exactly one LLM-provider credential exists,
  using a new LLM_PROVIDER_DEFAULTS table for the canonical default model
  per provider (Anthropic, OpenAI, Google, xAI, Groq, Mistral, DeepSeek,
  Cohere).
- CredentialProvider threaded through getJsonTools to the interactive
  factories. 12 new unit tests (cli) covering suspend-vs-auto-resolve.

Lint
- AgentAdvancedPanel.test.ts: hoist @vueuse/core type alias to a top-level
  `import type * as` so the inline `typeof import(...)` annotation goes
  away (consistent-type-imports).
- AgentConfigJsonEditor.vue: move `void debouncedJsonSave(text)` from
  expression to statement form so no-void stops complaining.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 20:33:30 +02:00
Robin Braumann
28d592a77c fix cubic issues 2026-04-26 20:18:03 +02:00
Robin Braumann
0e935f5dd8 fix(agents): address reviewer-flagged builder/chat reliability issues
- Parse typed AgentSseEvent in AgentBuilderProgress (was reading legacy shape)
- Snapshot autosave + token-guard fetchConfig/fetchAgent to stop cross-agent state bleed on quick agent switches
- Roll back optimistic resume state when /build/resume POST or SSE errors
- Reuse onBeforeRouteLeave's unpublished-changes guard via onBeforeRouteUpdate so in-component agent switches also prompt
- Token-guard agentSessions.fetchThreads/loadMore against racing switches
- Rebind a session after onContinueLoaded clears a stale continueSessionId so the Test pane doesn't go blank

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 18:49:29 +02:00
Robin Braumann
0a3d4c5f7c docs(agents): explain why relative-time.ts isn't using app/components/TimeAgo.vue 2026-04-26 18:26:34 +02:00
Robin Braumann
9d59a46d59 fix(agents): label fills the row, only timestamp right-aligns in session picker
The design-system's append-slot wrapper has `margin-left: auto` to push appended content (e.g. badge) to the right. With our slot rendering both the label and the timestamp, the whole row was sticking to the right. Override the wrapper to flex full width so the label expands and the timestamp's own `margin-left: auto` keeps it on the right edge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 18:25:24 +02:00
Robin Braumann
b299d8a224 fix(agents): polish session-picker dropdown layout
- Drop the dot separator; render the title and timestamp as separate flex
  children so they can be styled independently.
- Right-align the timestamp with margin-left:auto, drop it to text-tint-2 +
  font-size-2xs so it reads as secondary metadata.
- Cap the popper at min 280 / max 360px so long titles don't blow it open;
  truncate the title with text-overflow:ellipsis when it would overflow.
- Title is rendered via the per-id append slot now (the design-system's bare
  title text node can't host an ellipsis); empty-state row keeps using the
  built-in title field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 18:23:59 +02:00
Robin Braumann
76422211e1 feat(agents): show relative timestamp on session-picker rows
Each row in the chat history dropdown now reads "<title> · <when>" where
when is one of: "just now", "Ns ago", "Nm ago", "Nh ago" (same calendar
day), "Yesterday", or a short locale date for older entries. Hour granularity
stops at the local-day boundary so a 20h-ago timestamp from yesterday morning
reads "Yesterday" instead of "20h ago", which matches user expectation.

i18n keys live under agents.relativeTime.*. Future timestamps clamp to
"just now" rather than rendering an "in N" label that doesn't fit this
context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 18:20:08 +02:00
Robin Braumann
ec20ba2cd2 fix(agents): better session-picker labels
Two bugs the empty/untitled cases surfaced:

- Session-picker dropdown's empty state reused the agent-switcher's i18n key
  ("No other agents"). Add a dedicated agents.builder.chat.sessionPicker.empty
  ("No previous chats") and point the menu at it.
- Sessions without an LLM-generated title yet rendered indistinguishably as
  "New chat" — both in the dropdown rows and in the active-session header.
  formatThreadTitle now falls back through firstMessage (already populated by
  the BE) before the i18n string, so the user sees a recognisable preview
  until the title generator catches up. Whitespace is collapsed and the
  preview is capped at 60 chars with an ellipsis. Test covers the fallback
  chain.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 18:15:15 +02:00
Robin Braumann
827461b28c chore(agents): move agentSectionEditor.utils into utils/
The file is a pure helper module (splitPath, getSlice, setSlice, pickFrom, configToDoc, tryParseConfig) — moving it out of components/ aligns it with the other agent helpers in utils/. Update both importers and the two test files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:59:36 +02:00
Robin Braumann
26f32f76ac test(agents): cover provider-capabilities + AgentAdvancedPanel state
- provider-capabilities: regression guard for the static capability map. Locks the canonical reasoning-effort order, the Anthropic/OpenAI thinking modes, the no-thinking provider list, and the lowercase key invariant the panel relies on.
- AgentAdvancedPanel: budget-tokens vs reasoning-effort sub-control switching, disabled-toggle for unsupported providers, the thinking-on emit shape, and the disabled-prop fanout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:56:47 +02:00
Robin Braumann
b2929893a1 chore(agents): annotate JSON-rehydration casts
Schema is persisted as JSON; the as unknown as cast in two services rehydrates to the typed config. One-line comments make the rationale explicit so future readers don't try to tighten the type without addressing the storage boundary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:54:07 +02:00
Robin Braumann
a469de2431 refactor(agents): extract useAgentSectionNav from builder view 2026-04-26 17:51:29 +02:00
Robin Braumann
8c52200d04 refactor(agents): extract useAgentConfigAutosave from builder view 2026-04-26 17:49:34 +02:00
Robin Braumann
7f9d215be7 refactor(agents): extract useAgentChatMode from builder view 2026-04-26 17:47:06 +02:00
Robin Braumann
4eab9d0ee1 refactor(agents): extract useAgentBuilderSession from builder view 2026-04-26 17:44:22 +02:00
Robin Braumann
f728c98643 refactor(agents): extract useAgentBuilderLayout from builder view 2026-04-26 17:41:26 +02:00
Robin Braumann
261563b5aa refactor(agents): move config-slice helpers to agentSectionEditor.utils
Move splitPath, getSlice (non-mutating walker), setSlice (deep-copy writer), pickFrom (top-level subset), configToDoc (renderer for either section path or pickKeys) from AgentSectionEditor.vue into the colocated utils file. New unit tests cover dotted/numeric paths, missing keys, the empty-path replacement case, and the two configToDoc branches. AgentSectionEditor.vue drops ~70 lines of inline traversal code plus a deepCopy import.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:39:50 +02:00
Robin Braumann
568cdfb12e refactor(agents): replace handrolled Tools/Tree/Switch UI with design-system
- AgentToolsListPanel custom row: <button> wrapper that nested an N8nIconButton (HTML invalid) → div role=button with keyboard handlers; remove button no longer nested.
- AgentConfigTree count + status pills → N8nBadge; drop the inline pill styling.
- AgentAdvancedPanel: ElSwitch (element-plus) → N8nSwitch2 for both thinking + approval toggles.
- ToolCredsMissingChip: kept handrolled with a comment — N8nButton has no warning theme; reassess when one lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:37:03 +02:00
Robin Braumann
d157601163 refactor(agents): replace handrolled buttons/banner with design-system
- AgentBuilderHeader: back + chat-toggle <button> → N8nIconButton (ghost/subtle variants for active state); switcher trigger → N8nButton ghost variant. Removes ~50 lines of handrolled chrome CSS.
- AgentChatPanel: misconfigured-agent error banner → N8nCallout (theme="danger"); inner buttons → N8nButton + N8nIconButton. Drops ~70 lines of inline banner styling.
- AgentSectionEditor: copy button → N8nIconButton (subtle, xmini); keep only the absolute-positioning wrapper class.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:29:27 +02:00
Robin Braumann
bf57297d75 refactor(agents): collapse 3 CodeMirror editors into useCodeMirrorEditor
Three editors (AgentMiniEditor, AgentSectionEditor, AgentConfigJsonEditor) repeated the same setup: track a `view`, use a programmatic-update flag to suppress self-emits, manage a Compartment for reactive read-only, and run identical mount/destroy lifecycles. New composables/useCodeMirrorEditor.ts owns those concerns; the components only declare their language + theme extensions and react to props.

- Drop ~120 LOC of editor lifecycle boilerplate across the three components.
- Each editor preserves its own behaviour (focus-guarded replace in SectionEditor + JsonEditor; one-way watch in MiniEditor).
- Test covers initial doc, replaceDoc programmatic-no-emit, no-op when content matches, reactive readOnly toggle, and view destruction on unmount.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:23:46 +02:00
Robin Braumann
c44d6663eb refactor(agents): centralise model-string parsing with tests
Three callers (AgentInfoPanel, AgentAdvancedPanel, AskLlmCard) used to roll their own parseProvider/sanitizeModelId/etc. — same intent, drifting names + edge-case handling. Move to utils/model-string.ts with unit tests covering: provider/name split with embedded slashes, object-form input, Google "models/" prefix stripping, and nullish handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:19:43 +02:00
Robin Braumann
62e03e95c8 refactor(agents): rename Behavior section to Advanced
The label was misleading — the panel hosts execution-tuning knobs (thinking, concurrency, approval) rather than behavior in the agent-personality sense. Rename keeps the surface and the internals consistent:

- File: AgentBehaviorPanel.vue → AgentAdvancedPanel.vue
- Constant: BEHAVIOR_SECTION_KEY '__behavior' → ADVANCED_SECTION_KEY '__advanced'
- i18n keys: agents.builder.behavior.* → agents.builder.advanced.*; sections.behavior → sections.advanced
- Update all imports and references in AgentBuilderView and AgentConfigTree.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:17:04 +02:00
Robin Braumann
37711bef86 refactor(agents): extract shared scrollbar + disabled-overlay styles
- New styles/agent-panel.module.scss with .scrollbarThin and .disabledOverlay; imported into 9 panels/views as a CSS module and composed via :class array.
- Drop ~70 lines of duplicated scrollbar declarations across InfoPanel, BehaviorPanel, MemoryPanel, EvalsPanel, ToolsListPanel, ConfigTree (children scroller), ChatMessageList, AgentBuilderView (treeColumn + triggersTab), AgentSessionsListView.
- AgentConfigJsonEditor uses .disabledOverlay; AgentInfoPanel does the same for its disabled field.
- Memory + Tools panels keep a local .disabled > :not(.header) rule because the structural selector excludes the header — the scrollbar is still extracted.
- AgentSectionEditor's nested .cm-scroller and AgentBuilderHeader's :global .el-menu scrollbars stay local: they target deep descendants of element-plus / CodeMirror that CSS-module composition can't reach.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:11:57 +02:00
Robin Braumann
f03e8ae281 refactor(agents): extract magic strings to typed constants
- CHAT_MESSAGE_STATUS / TOOL_CALL_STATE in features/agents/constants.ts; replace ~30 literal occurrences in useAgentChatStream, agentChatMessages, AgentChatMessageList. ToolCallState type now lives next to its values; agentChatMessages re-exports for callers.
- CONTINUE_SESSION_ID_PARAM for the URL-deeplink query key, used in AgentBuilderView and AgentSessionTimelineView.
- Backend: BUILDER_TOOLS + AGENT_THREAD_PREFIX in builder/builder-tool-names.ts; replace literals in agents.controller, agents-builder-tools.service, agents.service, agents-builder.service.
- Add missing agents.sort.* i18n keys (lastUpdated, lastCreated, nameAsc, nameDesc) — ResourcesListLayout looks them up via resource-key="agents".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 17:03:24 +02:00
Robin Braumann
c87e19d9f1 i18n(agents): wrap hardcoded strings and drop dead keys
- Add ~30 keys for behavior panel, agent panel, tools list, builder progress, section editor, tree section labels (Behavior, Evaluations, Coming soon, Executions, config.json).
- Wrap all matching template literals in AgentBehaviorPanel, AgentInfoPanel, AgentConfigTree, AgentToolsListPanel, AgentBuilderProgress, AgentSectionEditor.
- Use the canonical pipe-form plural for the tools count.
- Remove three unused agents.builder.sections.* keys (configuration, credential, name); guardrails stays in use.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 16:52:31 +02:00
Robin Braumann
a8e5845d72 fix(agents): share integration status between panel and modal; drop Session N fallback
- Extract useAgentIntegrationStatus composable; panel + modal read the same reactive state, so connecting in the modal instantly refreshes the Triggers panel.
- Replace "Session ${sessionNumber}" title fallback (project-scoped counter showed "Session 24" on a new agent's first thread) with "New chat" via a small thread-title util.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:09:27 +02:00
Robin Braumann
d28ece6eba feat(agents): polish chat UX after n8n-agents merge
- fold trailing assistant text into toolRun group (one bubble per turn)
- optimistically resolve interactive tool card on submit (no waiting for tool-result)
- hide interactive cards once resolved; show inline status in tool step
- replace floating history button with session header strip (title + new-chat)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:25:58 +02:00
Robin Braumann
8c5762549e Merge branch 'n8n-agents' into agent-32-feature-redesign-agent-builder-with-three-column-config
# Conflicts:
#	packages/cli/src/modules/agents/agents.controller.ts
#	packages/frontend/editor-ui/src/features/agents/__tests__/AgentBuilderView.test.ts
#	packages/frontend/editor-ui/src/features/agents/components/AgentChatMessageList.vue
#	packages/frontend/editor-ui/src/features/agents/components/AgentChatPanel.vue
#	packages/frontend/editor-ui/src/features/agents/composables/agentChatMessages.ts
#	packages/frontend/editor-ui/src/features/agents/composables/useAgentApi.ts
#	packages/frontend/editor-ui/src/features/agents/views/AgentBuilderView.vue
2026-04-24 17:07:28 +02:00
Robin Braumann
2752320103 fix(agents): chat top padding; nudge history anchor to the edge
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:36:35 +02:00
Robin Braumann
cadb37a13e fix(agents): chat history back to top-right anchor; new-chat stays in quick actions
The upward-flipped dropdown was fighting element-plus positioning.
Put the history dropdown back in the floating top-right anchor where
it always worked. New-chat button stays on the left of the Test
panel's quick-actions row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:35:21 +02:00
Robin Braumann
754e60eb96 fix(agents): revert chat history to NavigationDropdown; flip popper upward via transform
ActionDropdown's items weren't reactive to the sessions store polling
and the flat ElDropdownItem list read as a tooltip. Go back to the
reactive NavigationDropdown and use a CSS translateY to seat the
popper above the trigger, since ElSubMenu doesn't expose placement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:33:37 +02:00
Robin Braumann
ee30121818 fix(agents): drop nested scrollbar on agent switcher; align copy button top with Raw toggle
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:29:53 +02:00
Robin Braumann
c7cffb2596 fix(agents): chat history opens upward; new-chat sits beside history
Swap N8nNavigationDropdown for N8nActionDropdown (placement=top-start)
so the sessions menu grows above the button. The new-chat button
sits immediately right of the history button instead of being pushed
to the far edge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:28:34 +02:00
Robin Braumann
1b52b8179c fix(agents): Test chat shows history + new-chat instead of Add tool/trigger
Replaced AgentChatQuickActions in the Test panel with a two-button
group: history dropdown on the left, new-chat on the right (conditional
on the current session having messages). Build panel keeps the
Add tool / Add trigger quick actions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:25:58 +02:00
Robin Braumann
860e7a298b fix(agents): move new-chat/history buttons into Test quick-actions row
The floating top-right anchor collided with user message bubbles as
they scrolled. Moved both buttons into the Test panel's quickActionsRow
so they live above the input alongside Add tool / Add trigger; dropped
the historyBtnAnchor styles and restored the chat's compact padding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:23:51 +02:00
Robin Braumann
2897655255 fix(agents): bump chat top padding so header buttons don't overlap bubbles
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:19:59 +02:00
Robin Braumann
251fe82a16 fix(agents): tighter chat padding; drop/restore session id on Build/Test
Chat messages now use sm/md padding instead of lg/xl so more of the
chat fits on screen. Switching to Build clears continueSessionId from
the URL; switching back to Test restores the active session id so the
URL stays consistent with the visible tab.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:19:32 +02:00
Robin Braumann
c6102a02df feat(agents): persist current chat session in URL; open Test when URL has session
Promote the ephemeral activeChatSessionId to the URL as continueSessionId
so refresh / copy-paste keeps the active chat. If the URL already has a
session id on initial load (and the agent has instructions) the builder
lands on the Test tab instead of Build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:17:46 +02:00
Robin Braumann
fac7fd0271 fix(agents): tighten new-chat/history button spacing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:15:26 +02:00
Robin Braumann
45b23de249 fix(agents): revert new-chat icon to plus; hide until session has messages
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:14:05 +02:00