Skip to content

[TMP] [TESTING] merge(preview): consolidated preview of all 14 active PRs - #12773

Closed
majdyz wants to merge 208 commits into
devfrom
preview/all-active-prs
Closed

[TMP] [TESTING] merge(preview): consolidated preview of all 14 active PRs#12773
majdyz wants to merge 208 commits into
devfrom
preview/all-active-prs

Conversation

@majdyz

@majdyz majdyz commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Why

This PR consolidates all 14 active PRs targeting dev into a single branch for combined testing, preview deployment, and screenshot verification before individual PRs are merged.

PRs included:

What

  • All 14 PRs fully reviewed (0 unresolved threads each), CI green
  • Merged into preview/all-active-prs from latest dev base
  • Merge conflicts resolved (platform_cost_test.py, routes_test.py, baseline/service.py, config.py, openapi.json, UserTable.tsx)
  • Deployed to dev-builder.agpt.co for E2E testing

How

  1. /pr-review + /pr-address run for each of the 14 PRs
  2. All review comments addressed, CI green across all PRs
  3. Branches merged sequentially from fresh dev base with conflict resolution
  4. Deployed via cloud infra GHA workflow to dev-agpt namespace
  5. /pr-test run for each PR scenario against dev-builder.agpt.co

Checklist

  • All 14 PRs: CI green + 0 unresolved review threads
  • Consolidated branch deployed to dev-builder.agpt.co
  • E2E test screenshots attached (pending deployment)
  • No passwords in screenshots

majdyz added 30 commits April 8, 2026 07:43
- Validate node existence before connect_nodes in handleApplyAction
- Add cleanup guard to session creation effect to prevent state updates
  after unmount
- Extract extractTextFromParts helper to deduplicate text extraction
- Remove dead code in ActionItem (applied state was always true)
- Remove redundant setTimeout scroll in handleSend (useEffect handles it)
- Update test to match simplified ActionItem
…ecurity & UX fixes

Merge resolution keeps:
- buildSeedPrompt helper (prompt injection mitigation with XML tags)
- extractTextFromParts naming (aligned with remote)
- cancelled flag pattern for session creation cleanup
- streamError display and empty/welcome state (new in this branch)
- Static Applied badge (span, no dead toggle logic)
- ARIA roles: role=dialog, role=log
- react-markdown for assistant messages
- Placeholder hint for Enter/Shift+Enter
- All new tests: keyboard, multi-action, customized_name, truncation,
  primitive validation, stream error, ARIA assertions
…aRef

- Extract `getActionKey(action)` to helpers.ts, removing duplicated key
  computation from BuilderChatPanel.tsx and useBuilderChatPanel.ts
- Wire `textareaRef` through PanelInputProps so focus-on-open works
- Add `getActionKey` tests covering both action types
…ction and session error

- Add useBuilderChatPanel.test.ts with direct tests for handleApplyAction:
  update_node_input (merges hardcodedValues, no-ops for unknown node),
  connect_nodes (calls addEdge with correct args, no-ops if either node missing)
- Add panel open/close state tests for useBuilderChatPanel
- Add session error UI test to BuilderChatPanel.test.tsx
…n handleApplyAction

Rejects update_node_input keys not present in inputSchema.properties and
connect_nodes handles not present in outputSchema/inputSchema.properties,
preventing AI from writing arbitrary fields that blocks do not support.
Validation is permissive when schema is undefined (backwards-compatible).
…ng turn

handleApplyAction was defined and exported but never called, so the
"AI applied these changes" panel was displaying actions that had no
effect. Wire up a handleApplyActionRef so the status-change effect
can safely apply each parsed action to the local Zustand stores once
per completed AI turn, before the canvas refetch resolves.
The initialization prompt ("I'm building an agent in the AutoGPT flow
builder...") was sent as a visible user message, exposing raw prompt
engineering instructions to end users. Track its ID via seedMessageId
and exclude it from the rendered message list.
… prompt injection

- Replace auto-apply with per-action Apply buttons; users must explicitly
  confirm each AI suggestion before the graph is mutated
- Accumulate parsedActions across all assistant messages so multi-turn
  suggestions remain visible rather than disappearing after the next turn
- Escape < and > in node names/descriptions before embedding in XML prompt
  context to prevent AI prompt injection via crafted node labels
- Add MAX_EDGES cap (200) in serializeGraphForChat to mirror the MAX_NODES
  limit and prevent token overruns on dense graphs
- Add Escape key handler in the hook to close the chat panel
- Add helpers.test.ts with unit tests for buildSeedPrompt,
  extractTextFromParts, and XML sanitization
…ests, session ref guard

- Filter seed message by content prefix (SEED_PROMPT_PREFIX) instead of position
- Add exhaustiveness guard for unhandled GraphAction types
- Guard handleApplyAction against unknown keys/handles via inputSchema/outputSchema
- Add renderHook-based tests: session lifecycle, flowID reset, handleApplyAction, edge cases
- Fix session-creation effect to use isCreatingSessionRef so state-driven re-renders
  don't prematurely cancel the in-flight request via the cancelled flag
- Add empty-input rejection test for BuilderChatPanel send button
…dedup fix, component tests

- Move inputValue, handleSend, handleKeyDown, isStreaming, canSend into
  useBuilderChatPanel (0ubbe: keep render logic out of component)
- Add undo support: snapshot node state before apply, expose undoStack +
  handleUndoLastAction, show undo button in PanelHeader
- Add toast feedback on handleApplyAction validation failures so users
  know why Apply did nothing
- Fix getActionKey for update_node_input to include value so AI corrections
  in later turns are not silently dropped by the dedup Set
- Add getNodeDisplayName shared helper in helpers.ts; use in both
  serializeGraphForChat and ActionItem (removes duplication)
- Use Map<id, node> in serializeGraphForChat for O(1) edge lookups
- Add Retry button to session error state in MessageList
- Add graph context sent banner after seed message so AI response
  does not appear unprompted (addresses confusing auto-response UX)
- Add aria-label to Apply buttons for screen-reader accessibility
- Remove hook-only test file (0ubbe: test component, not hook)
- Expand component tests: undo, retry, seed banner, action label format,
  getNodeDisplayName, getActionKey value-inclusion, edge truncation
- All 1026 tests pass; lint and types clean
…ak on navigation

- Restore useBuilderChatPanel.test.ts with 28 tests covering session lifecycle
  (create success, failure, non-200), seed message dispatch + only-once guard,
  flowID reset (sessionId, sessionError, appliedActionKeys), cache invalidation
  assertion after handleApplyAction, and undo stack behaviour
- Fix sentry-flagged bug: reset isCreatingSessionRef.current in the flowID
  change effect so navigating mid-session-creation doesn't permanently block
  future session creation on the new graph
…es, add hook tests

- sanitizeForXml now escapes &, ", ' in addition to < and >
- connect_nodes actions now push an undo snapshot (removeEdge) so they can be reverted like update_node_input
- useBuilderChatPanel.test.ts adds removeEdge mock and test for undo of connect_nodes
- Replace fragile setTimeout double-toggle retry with dedicated retrySession()
  callback that resets sessionError and lets the session-creation effect re-run
- Remove invalidateQueries after apply actions — caused server refetch to
  overwrite local Zustand state changes (sentry HIGH severity bug)
- Deep-clone prevHardcoded before undo capture so sequential applies to the
  same node each have an independent snapshot
- Remove unsolicited "What does this agent do?" question from seed prompt;
  invite user to initiate instead
- Remove useCallback from handleUndoLastAction per project convention
- Remove unused sendMessage and status from hook return
- Remove JSDoc comment from BuilderChatPanel per project convention
- Hoist nodeMap construction from ActionItem to parent parsedActions.map
  to avoid N identical Maps per render cycle
- Make useChat mock configurable (mockChatMessages/mockChatStatus) and add
  tests for parsedActions integration, Escape key handler, retrySession,
  and handleSend input-clearing behavior
…tore

Use setNodes/setEdges directly in undo restore closures instead of
updateNodeData/removeEdge which push to the history store. This prevents
the global Ctrl+Z from re-applying changes that the user already undid via
the chat panel's own undo button.

Also removes unused removeEdge selector from the hook.
…undo

Apply chat panel changes via setNodes/setEdges (bypassing history store)
so Ctrl+Z cannot revert them and leave the "Applied" badge stale.
Also hoist jsonBlockRegex to module scope, cap node description length
at 500 chars, and remove useShallow from single-value selectors.
…, undo anti-pattern, stack cap, a11y, and test coverage

- Guard against duplicate connect_nodes edges: check prevEdges before applying,
  mark as already-applied without duplicating if edge exists
- Cap undo stack at MAX_UNDO=20 to prevent unbounded memory growth for large graphs
- Fix React anti-pattern: call restore() before setUndoStack updater instead of
  inside it (state updaters must be pure — no side effects)
- Add aria-modal="true" to dialog panel and aria-expanded to toggle button
- Extract IIFE nodeMap into ActionList sub-component (cleaner render path)
- Add 18 new tests: handleSend when canSend=false, Shift+Enter no-send,
  schema-absent permissive paths (update + connect_nodes), sequential multi-undo
  LIFO order, duplicate edge guard, undo stack size cap, empty stack no-op
…ads render correctly

Chat panel used setEdges directly without the markerEnd property that edgeStore.addEdge
sets automatically. Added MarkerType.ArrowClosed with strokeWidth=2, color="#555" to
match the standard edge appearance.
Adds a useEffect in useBuilderChatPanel that calls setMessages([]) whenever
the flowID query param changes, preventing old technical seed prompts from
the prior session briefly appearing when switching between agents.
…arts

The AI SDK can return messages with undefined parts in certain error
scenarios. Accept null/undefined in extractTextFromParts and fall back
to an empty array to prevent a TypeError and component crash.
…logs with explicit start

Closes branch gaps in platform_cost.py (lines 29-31 and 312→314) that
were introduced via the dev merge but not exercised by existing tests.
This also forces the backend CI to run so Codecov uploads fresh coverage
instead of carrying forward stale data from before the cost-tracking
feature landed on dev.
- Overlapping placeholders: add !seedMessage guard to empty-state block so the
  "Ask me to explain…" and "Graph context sent" banners are mutually exclusive
- aria-modal without focus trap: replace role="dialog"/aria-modal="true" with
  role="complementary" since this is a side panel, not a blocking modal
- Stale closure in handleApplyAction: use useNodeStore/useEdgeStore.getState()
  for both validation and mutation so rapid applies see live data
- Gate nodes/edges Zustand subscriptions behind isOpen to prevent chat-panel
  hook re-running on every node drag/resize when panel is closed
- inputValue not cleared on flowID change: add setInputValue("") to flowID reset
- ReactMarkdown links: add custom <a> component with target="_blank" and rel="noopener noreferrer"
- XML sanitization: apply sanitizeForXml() to n.id and edge handle names
- Regex statefulness: move JSON_BLOCK_REGEX inside parseGraphActions() to avoid
  shared lastIndex state (eliminates fragile lastIndex=0 reset)
- Type guard soundness: add typeof p.text === "string" to extractTextFromParts filter
- Session ID validation: validate format before interpolating into streaming URL
- Shallow-copy undo snapshots: spread prevNodes/prevEdges so closures hold
  independent arrays
- Set spread optimisation: use new Set(prev).add(key) instead of new Set([...prev, key])
- Tests: remove dead getGetV1GetSpecificGraphQueryKey mock, add markerEnd assertion
  to connect_nodes tests, add transport prepareSendMessagesRequest coverage,
  add Enter-with-empty-input and inputValue-reset-on-flowID-change tests
…t panel

Shows three bouncing dots in an assistant-style bubble while waiting
for the first response token (status submitted, no assistant text yet).
Disappears once streaming begins and text appears.
…n, function length, textarea maxLength, and test coverage

- Fix prototype pollution bypass: use Object.prototype.hasOwnProperty.call instead of `in` operator for schema key validation, preventing __proto__/constructor injection through schema-validated nodes
- Extract applyUpdateNodeInput and applyConnectNodes as module-level helpers to reduce handleApplyAction from 165 lines to a 20-line dispatcher
- Add JSDoc to useBuilderChatPanel documenting session lifecycle, transport, seed message, action parsing, undo, and input responsibilities
- Add maxLength=4000 to PanelInput textarea to cap token usage
- Add prototype pollution tests (__proto__ and constructor keys rejected when inputSchema is present)
- Strengthen Send-button-disabled assertion in component test
…ool detection

- Remove auto-send seed message on chat open (user initiates context manually)
- Cache chat session per graph ID (module-level Map) so reopening the panel for
  the same graph reuses the existing session and preserves conversation history
- Detect edit_agent tool completion → trigger graph refetch via onGraphEdited callback
- Detect run_agent tool completion → update flowExecutionID in URL to auto-follow run
- retrySession now evicts the stale cache entry so a fresh session is created
- Flow.tsx passes refetchGraph as onGraphEdited to BuilderChatPanel
… session cache in tests

- Restore isGraphLoaded prop and hasSentSeedMessageRef seed-message effect that
  were removed in a prior external modification; all seed-message tests now pass
- Apply Object.prototype.hasOwnProperty.call() guard in inline handleApplyAction
  for input-schema and handle validation (three sites), matching the extracted
  helper functions; prototype-pollution tests now pass
- Export clearGraphSessionCacheForTesting() and call it in beforeEach to prevent
  stale module-level graphSessionCache from leaking across tests (fixes flowID
  reset test)
- Update BuilderChatPanel test to expect isGraphLoaded in useBuilderChatPanel call
- Remove unused Dispatch, SetStateAction, CustomEdge, CustomNode imports
…endering

Replace the simplified ReactMarkdown block in BuilderChatPanel's MessageList
with MessagePartRenderer from the copilot panel, enabling proper rendering of
tool invocations, error markers, and system markers in addition to text parts.
…ent check

- Wire isInitialLoadComplete as isGraphLoaded prop in Flow.tsx so the seed
  message effect in useBuilderChatPanel actually fires once the graph is ready
- Add panelRef to BuilderChatPanel and pass it to the hook so the Escape key
  listener only closes the panel when focus is inside it, preventing conflicts
  with other dialogs or canvas keyboard handlers
- Update BuilderChatPanel test to use objectContaining for the hook call
  assertion, accommodating the new panelRef argument
…; fix EMPTY_NODES ref

- Add tests for edit_agent tool call detection: verifies onGraphEdited fires on
  output-available state, is suppressed during streaming, and is not called twice
  for the same toolCallId (processedToolCallsRef deduplication)
- Add tests for session ID validation: verifies that path-traversal IDs
  (../../admin) and IDs with spaces set sessionError and leave sessionId null
- Extract EMPTY_NODES module-level constant to give useShallow a stable
  reference when the panel is closed, preventing spurious re-renders
majdyz and others added 3 commits April 14, 2026 21:50
…show pending message in chat

- Bug 1: ChatInput now shows a Tray (enqueue) button instead of Stop when
  streaming and the user has typed text; Stop only shows when input is empty
- Bug 2: postV2QueuePendingMessage was missing from the generated API file;
  ran pnpm generate:api so orval correctly generated the function from openapi.json
- Bug 3: useCopilotPage tracks queuedMessage state after successful enqueue,
  clears it when stream ends; ChatMessagesContainer renders a pending message
  bubble with opacity-60, dashed border, and a Clock "Queued" label
…disabled

When ENABLE_PLATFORM_PAYMENT is off for paid tier requests, return 422
instead of setting the tier directly. Admin tier changes must go through
the /api/admin/ routes, not the self-service endpoint.

Updates the corresponding subscription route test to assert the 422
response and removes the now-invalid set_subscription_tier mock.
@majdyz
majdyz force-pushed the preview/all-active-prs branch from d7bced0 to 147294d Compare April 14, 2026 15:21
@github-actions github-actions Bot removed the conflicts Automatically applied to PRs with merge conflicts label Apr 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly.

majdyz and others added 2 commits April 14, 2026 22:41
…ment handling

- Use user_id="system" for global LD flag lookups (price IDs don't need user context)
- Skip Supabase lookup silently for non-UUID keys in _fetch_user_context_data
- Block paid tier changes when ENABLE_PLATFORM_PAYMENT is disabled
- Add invoice.payment_failed handler: deduct from balance or downgrade to FREE
- Hide upgrade/downgrade buttons in UI when payment flag is disabled
…across refresh, clear when buffer is empty

- Remove redundant "Message queued" toast (the queued bubble in chat is sufficient visual feedback)
- Add GET /sessions/{session_id}/messages/pending endpoint (peek without draining) so the frontend can check buffer state
- On session load, restore the queued message indicator from the backend buffer so it survives a page refresh
- On turn end, peek the buffer before clearing the indicator — if messages remain (SDK path drains at next turn start), keep showing the queued bubble

Co-authored-by: Zamil Majdy <zamil.majdy@gmail.com>
@majdyz
majdyz force-pushed the preview/all-active-prs branch from 147294d to 44cedce Compare April 14, 2026 15:45
Comment on lines +1681 to +1691
# already downgraded and the sub must go.
try:
await _cancel_customer_subscriptions(customer_id)
except stripe.StripeError:
logger.warning(
"handle_subscription_payment_failure: failed to cancel Stripe sub %s"
" for user %s (customer %s); Stripe may continue retrying",
sub_id,
user.id,
customer_id,
)

This comment was marked as outdated.

majdyz added 6 commits April 14, 2026 22:58
The manually edited openapi.json had field ordering that differed from
what export-api-schema generates. Regenerated using:
  poetry run export-api-schema --output ../frontend/src/app/api/openapi.json
  pnpm prettier --write src/app/api/openapi.json
  pnpm generate:api
@majdyz
majdyz force-pushed the preview/all-active-prs branch from 44cedce to afcd985 Compare April 14, 2026 16:15
@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label Apr 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

@majdyz

majdyz commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

Closing in favor of preview/zamil-many-active-prs

@majdyz majdyz closed this Apr 15, 2026
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to ✅ Done in AutoGPT development kanban Apr 15, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflicts Automatically applied to PRs with merge conflicts platform/backend AutoGPT Platform - Back end platform/blocks platform/frontend AutoGPT Platform - Front end size/xl

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant