Skip to content

fix: make agent chat input full width#604

Closed
chenjiayi8 wants to merge 183 commits into
dataelement:mainfrom
chenjiayi8:fix/chat-input-full-width
Closed

fix: make agent chat input full width#604
chenjiayi8 wants to merge 183 commits into
dataelement:mainfrom
chenjiayi8:fix/chat-input-full-width

Conversation

@chenjiayi8
Copy link
Copy Markdown

Summary

  • add a base .chat-input CSS rule so the textarea expands to the available composer width
  • keep the fix minimal and scoped to the existing chat input class
  • add a regression test that fails unless the full-width rule exists

Root cause

The /agents/:id/chat composer used className="chat-input", but index.css only defined placeholder/focus/disabled states for that class. There was no base .chat-input layout rule, so the textarea kept its intrinsic width instead of stretching to fill the available space.

Verification

  • node --test frontend/tests/chatInputWidthRegression.test.mjs
  • npm test
  • npm run build
  • gitnexus detect_changes on the worktree branch (scope: staged and scope: compare, risk: low, affected processes: 0)

- entrypoint.sh: add clawith user to docker socket group for container mgmt
- agent_seeder.py: support SKIP_DEFAULT_AGENTS env var
- nginx.conf: fix proxy_pass to use consultant_backend hostname
SQLAlchemy 2.0 models for tracking workspace deployments (static + container)
and user/health-check bug reports with auto-fix circuit breaker fields.
Also adds WORKSPACE_STATIC_DIR, WORKSPACE_CONF_DIR, WORKSPACE_GATEWAY_CONTAINER
config settings.
…ecks

- workspace_tools.py: slug validation, deploy_static, request_container_deploy,
  approve/reject pipeline, undeploy, bug report tools, gateway reload
- workspace_index.py: auto-generated HTML index page at /workspace/
- workspace_health.py: periodic health checks with parallel execution and
  circuit breaker (max 3 auto-fixes per 24h window)
- POST /api/workspace/projects/{slug}/report-bug (public, rate-limited, honeypot)
- POST /api/workspace/projects/{slug}/approve (builds Docker image, starts container)
- POST /api/workspace/projects/{slug}/reject
- GET /api/workspace/projects (list all projects)
Add tool definitions (AGENT_TOOLS), dispatch wiring (execute_tool),
and DB seeding (BUILTIN_TOOLS) for: request_build, list_build_requests,
deploy_static, request_container_deploy, list_workspace_projects,
undeploy_project, get_bug_reports, resolve_bug, report_workspace_bug.
Register workspace models for auto-creation, workspace API routers,
and health check background task in the FastAPI lifespan.
* feat: add mobile responsive layout shell

Add hamburger menu, slide-over sidebar, and full-width main content
for viewports <=768px. Desktop layout unchanged.

* fix: remove unused isMobile state, close sidebar on account settings click

Address code review: simplify closeMobileMenu, add closeMobileMenu
to account settings handler so sidebar dismisses on mobile.

* feat: make Dashboard responsive for mobile

Stats grid goes 2x2, agent table becomes card list,
activity column hidden on narrow viewports.

* feat: make Chat page responsive for mobile

Wider bubbles, smaller avatars, compact input area,
dvh-based height for mobile viewport.

* feat: make Plaza responsive for mobile

Two-column layout stacks vertically, remove avatar indent
on narrow viewports, sidebar moves below feed.

* fix: address final code review issues

- Move display:grid from agent-row-header inline to CSS class so
  media query display:none works on mobile
- Move plaza-sidebar width/position from inline to CSS class,
  remove !important from media query overrides
- Make agent detail tabs horizontally scrollable on mobile
- Stack chat session sidebar above chat area on mobile
  instead of side-by-side columns
Gateway tools (category=mcp-gateway) are platform-level and should be
visible on all agent tool pages like builtin tools. Previously, all MCP
tools were hidden unless the agent already had an explicit AgentTool
assignment, creating a chicken-and-egg problem where tools couldn't be
assigned from the UI.
CAPTCHA solving via 2Captcha can take up to 180s. The previous timeouts
(30s streamable HTTP, 60s SSE) caused "Both transports failed" errors
when the gateway was still waiting for 2Captcha to respond.
Supports the skill autocomplete & role system feature. The is_hidden flag
allows persisting injected role context messages that are sent to the LLM
but not displayed to the user.
- Add _resolve_skill_content() and _inject_skill_if_matched() helpers
  for parsing /skill:sub prefixes and injecting hidden context messages
- Add _persist_and_inject_skill() to save hidden messages to DB
- Add type-based dispatch: "edit" messages rebuild conversation from DB
  and re-invoke LLM; normal messages follow existing path
- Add /role:clear handling to remove all hidden skill messages
- Track hidden message indices via websocket._hidden_indices for
  filtering on clear
…ebsocket

The config module exports get_settings(), not a settings instance.
chenjiayi8 and others added 28 commits May 18, 2026 23:15
Constraint: Reuse tenant-scoped skill access rules while preserving registry semantics for presets
Rejected: Storing uploaded folders only on disk for enterprise skills | Would bypass the existing registry model and preset import flow
Confidence: medium
Scope-risk: moderate
Directive: Keep registry updates transactional and preserve explicit confirmation for destructive syncs
Tested: pytest backend/tests/test_skills_api.py -q
Not-tested: frontend integration and real DB transaction edge cases
Constraint: Keep the follow-up fix inside the assigned test scope while validating the spec's replacement semantics
Rejected: Leaving the update test at mode-only assertions | Would not prove stale registry rows are removed and rewritten exactly
Confidence: high
Scope-risk: narrow
Directive: Keep Task 3 coverage focused on observable registry sync effects, not just happy-path status fields
Tested: cd backend && python -m pytest tests/test_skills_api.py -q
Not-tested: frontend integration and real DB transaction edge cases
Constraint: Keep the repo dependency set unchanged while still producing ZIP uploads from local folders
Rejected: Adding JSZip or fflate immediately | Repo guidance prefers no new dependencies unless explicitly requested
Confidence: medium
Scope-risk: moderate
Directive: Keep the ZIP utility narrowly scoped to skill-folder uploads rather than general archive creation
Tested: cd frontend && npm run build
Not-tested: Browser folder selection and drag-drop behavior
Constraint: The active route still renders frontend/src/pages/AgentDetail.tsx, so new UI behavior must land there first
Rejected: Implementing only frontend/src/pages/agent-detail/tabs/SkillsTab.tsx | That path is not the active route today
Confidence: high
Scope-risk: moderate
Directive: Keep the shared modal generic so enterprise can reuse it without duplicating diff-confirmation logic
Tested: cd frontend && npm run build
Not-tested: Browser drag-drop flow and API round-trip behavior
Constraint: Task 6 needs to reuse the same modal without agent-specific copy coupling or unsafe async state reuse
Rejected: Relying on the latest resolved preview promise | Late responses can restore stale preview payloads after folder, target, or modal state changes
Confidence: high
Scope-risk: narrow
Directive: Keep invalidation-driven async guards aligned with any future modal reuse so preview and apply always operate on the same snapshot
Tested: cd frontend && npm run build
Not-tested: Browser folder-picker interaction timing and live API race behavior
Constraint: Keep agent and enterprise upload semantics aligned while preserving separate storage backends
Rejected: A second enterprise-only modal implementation | Would duplicate diff preview and drift from the agent flow
Confidence: medium
Scope-risk: moderate
Directive: Reuse the shared modal and keep warning copy aligned between agent and enterprise flows
Tested: pytest backend/tests/test_skill_archive_import.py -q; pytest backend/tests/test_files_api.py -q; pytest backend/tests/test_skills_api.py -q; cd frontend && npm run build
Not-tested: End-to-end browser interaction against a running app
Constraint: The implementation plan's final verification names pytest commands from the repo root, so backend tests must import `app` without requiring a manual `cd backend` workaround.
Rejected: Relying on implicit operator knowledge to `cd backend` first | Leaves the documented verification steps inaccurate on this branch
Confidence: high
Scope-risk: narrow
Directive: Keep backend test imports runnable from the repository root while preserving the existing backend package layout
Tested: pytest backend/tests/test_skill_archive_import.py -q; pytest backend/tests/test_files_api.py -q; pytest backend/tests/test_skills_api.py -q
Not-tested: Full backend test suite from repo root
Constraint: The PR promises preview/apply drift protection and metadata-preserving exact-sync across agent and enterprise uploads
Rejected: Leaving enterprise drift tokens optional and lossy archive decoding in place | Would allow preview bypasses and silent file corruption
Confidence: high
Scope-risk: narrow
Directive: Keep folder-upload archives UTF-8 text-only until the skill storage model can preserve binary assets end-to-end
Tested: python -m pytest backend/tests/test_skill_archive_import.py backend/tests/test_files_api.py backend/tests/test_skills_api.py -q; cd frontend && npm run build
Not-tested: Browser-driven end-to-end upload interaction against a running app
Constraint: Review surfaced folder-name persistence bugs and UTF-8 ZIP filename corruption that would break valid skill uploads
Rejected: Leaving folder names unchecked or trusting legacy ZIP default encoding | Produces unreachable registry rows and mangled non-ASCII paths
Confidence: high
Scope-risk: narrow
Directive: Reuse the strict folder-name contract across agent and enterprise uploads, and preserve UTF-8 filename flags in any future ZIP writer changes
Tested: python -m pytest backend/tests/test_skill_archive_import.py backend/tests/test_files_api.py backend/tests/test_skills_api.py backend/tests/test_skill_folder_zip_compat.py -q; cd frontend && npm run build
Not-tested: Browser-driven end-to-end upload interaction against a running app
…s or size limits

Constraint: Global unique indexes and the registry's 500KB storage budget must still hold for the new folder-upload path
Rejected: Relying on scoped preview lookups or late commit failures | Leaves hidden conflicts, name collisions, and oversize uploads to explode after preview
Confidence: high
Scope-risk: narrow
Directive: Keep registry upload previews aligned with the real database uniqueness boundary, and preserve deterministic 409/413 errors before destructive apply work
Tested: python -m pytest backend/tests/test_skill_archive_import.py backend/tests/test_files_api.py backend/tests/test_skills_api.py backend/tests/test_skill_folder_zip_compat.py -q; cd frontend && npm run build
Not-tested: Browser-driven end-to-end upload interaction against a running app
Constraint: Task 1 required pure helpers and failing-first bundled tests without touching page wiring
Rejected: wiring pages now | out of assigned scope for this task
Confidence: high
Scope-risk: narrow
Directive: Keep these helpers pure until the UI surfaces are migrated in follow-up tasks
Tested: node --test frontend/tests/skillsActionItems.test.mjs; node --test frontend/tests/skillUploadSurfaceAdapters.test.mjs
Not-tested: page-level integration wiring in EnterpriseSettings, SkillsTab, and AgentDetail
Constraint: Spec requires exact exported helper names for follow-up task integration
Rejected: keeping surface-adapter suffixes | diverges from approved Task 1 contract
Confidence: high
Scope-risk: narrow
Directive: Keep test and helper export names aligned with the task contract before wiring consumers
Tested: node --test frontend/tests/skillsActionItems.test.mjs; node --test frontend/tests/skillUploadSurfaceAdapters.test.mjs
Not-tested: page-level integration wiring remains intentionally untouched
Constraint: Task 1 bundled node tests import esbuild directly and must not rely on transitive deps
Rejected: relying on Vite transitive esbuild | brittle and outside the test contract
Confidence: high
Scope-risk: narrow
Directive: Keep direct test-runtime dependencies explicit in frontend/package.json
Tested: node --test frontend/tests/skillsActionItems.test.mjs; node --test frontend/tests/skillUploadSurfaceAdapters.test.mjs; cd frontend && npm run build
Not-tested: unrelated audit vulnerability remediation
Constraint: Task 1 tests must run in standard frontend and CI verification without changing helper logic
Rejected: custom one-off CI commands only | would leave local npm test incomplete
Confidence: high
Scope-risk: narrow
Directive: Keep frontend Node-based regression tests reachable via npm test and CI before build
Tested: cd frontend && npm test; cd frontend && npm run build
Not-tested: GitHub Actions execution itself beyond equivalent local commands
Constraint: Preserve existing enterprise settings, URL import, ClawHub, and folder upload behavior while introducing the shared seam
Rejected: Keep the inline SkillsTab action cluster | would continue duplicating action order and upload wiring
Confidence: high
Scope-risk: narrow
Directive: Keep enterprise action ordering sourced from shared skillsActionItems and upload behavior sourced from the shared adapter
Tested: cd frontend && npm test; cd frontend && npm run build
Not-tested: Manual browser verification of the enterprise settings tab UI
Constraint: Keep the shared action bar presentational while proving the enterprise tab stays wired to the shared action and upload seams
Rejected: Leave the action config as Record<string, ...> | too loose to protect the shared seam
Confidence: high
Scope-risk: narrow
Directive: Keep enterprise seam coverage in the existing skillsActionItems test file so shared ordering and source wiring stay locked together
Tested: cd frontend && npm test; cd frontend && npm run build
Not-tested: Manual browser verification of the enterprise skills tab layout
Constraint: Task 3 ownership limited changes to AgentDetail and targeted tests while preserving agent-only modal flows
Rejected: Keeping the bespoke action cluster and URL import UI | would diverge from the canonical shared agent action set
Confidence: high
Scope-risk: narrow
Directive: Keep agent skill action ordering sourced from getAgentSkillActionIds() and reuse the shared upload adapter for future surface changes
Tested: cd frontend && npm test; cd frontend && npm run build
Not-tested: Manual browser interaction of the Agent Detail skills tab
Constraint: Task 4 required removing the stale inline enterprise SkillsTab while preserving existing route usage.
Rejected: Keeping the inline duplicate and only asserting route usage | would preserve dead divergent code and fail the consolidation goal
Confidence: high
Scope-risk: narrow
Directive: Keep EnterpriseSettings importing the canonical tab file instead of reintroducing local SkillsTab logic.
Tested: cd frontend && npm test; cd frontend && npm run build
Not-tested: Manual browser verification of the /enterprise skills tab UI
Constraint: Chromium only opens a true folder picker when the directory attributes are present on the rendered file input itself
Rejected: set webkitdirectory in useEffect | still falls back to file-only selection in the live modal
Confidence: high
Scope-risk: narrow
Directive: Keep directory-selection attributes rendered on the hidden file input and retain enterprise upload-folder wiring coverage
Tested: cd frontend && node --test tests/skillsUploadFolderRegression.test.mjs; cd frontend && npm test; cd frontend && npm run build
Not-tested: authenticated live-browser interaction against ai-company.growatt-support.com/enterprise
Skip iterating skill.files when creating a new registry skill during folder upload.
Add a regression test covering the enterprise create path so async lazy-loading does not regress.
Use SQLAlchemy NULL predicates for tenant-scoped tool queries and orphan MCP cleanup, and add regression coverage for both code paths.
Constraint: Global admin MCP tools remain unassigned until linked to an agent
Rejected: NULL-only orphan cleanup | Deletes admin-seeded MCP records and resets their state
Confidence: high
Scope-risk: narrow
Directive: Keep orphan cleanup limited to agent-installed MCP records unless tool ownership semantics change
Tested: python -m pytest tests/test_tool_tenant_scope.py -q
Not-tested: startup cleanup against a live database with seeded admin MCP tools
Constraint: Production still serves the legacy EnterpriseSettings Org tab while the backend now returns {items,total_member}
Rejected: Revert backend response shape | would break the newer org tab and lose the total-member metadata
Confidence: high
Scope-risk: narrow
Directive: Keep the legacy EnterpriseSettings Org tab tolerant of both array and object department payloads until the old page is fully retired
Tested: node --test tests/enterpriseOrgDataShapeRegression.test.mjs; npm test; npm run build
Not-tested: Live browser verification against production after redeploy
Create the missing tenant_settings table used by tenant-scoped tool config and add a regression test so legacy installs keep a forward migration for it.
Constraint: PR review found legacy installs could lose pre-existing tenant_settings data on rollback
Rejected: Destructive downgrade guard | still risks dropping legacy-owned data
Confidence: high
Scope-risk: narrow
Directive: Treat backfill migrations that may adopt pre-existing schema as non-destructive on downgrade unless creation ownership is provable
Tested: python -m pytest -q backend/tests/test_tenant_settings_migration_regression.py; python -m ruff check backend/alembic/versions/add_tenant_settings.py backend/tests/test_tenant_settings_migration_regression.py
Not-tested: Full Alembic upgrade/downgrade against a live database or CI matrix
Constraint: The OKR page already links users to /enterprise#okr, so the fix had to preserve that contract with a narrow frontend-only change.
Rejected: Deleting the CTA or changing it to a plain message | That would hide the regression instead of restoring the intended settings flow.
Confidence: high
Scope-risk: narrow
Directive: Keep the Enterprise Settings tab list, hash routing, and translation keys aligned whenever tab wiring is refactored.
Tested: node --test frontend/tests/enterpriseOkrTabWiring.test.mjs; cd frontend && npm test; cd frontend && npm run build
Not-tested: Live production browser verification after deploy
Co-authored-by: OmX <omx@oh-my-codex.dev>
Constraint: The existing /enterprise#okr deep-link contract needed bidirectional hash sync without broadening the frontend change beyond Enterprise Settings.

Rejected: Leaving tab clicks state-only | That let the visible tab and shared URL drift apart after navigation.

Confidence: high

Scope-risk: narrow

Directive: When Enterprise Settings tabs change, keep URL hash state and regression coverage aligned with the active tab.

Tested: node --test frontend/tests/enterpriseOkrTabWiring.test.mjs; cd frontend && npm test -- --runInBand; cd frontend && npm run build

Not-tested: Live production browser verification after deploy
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 562946f2c4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread frontend/src/index.css
Comment on lines +3983 to +3987
.chat-input {
display: block;
width: 100%;
min-width: 0;
box-sizing: border-box;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve core .chat-input styles in base rule

The new .chat-input block now sets only layout width properties, but /agents/:id/chat renders className="chat-input" in frontend/src/pages/AgentDetail.tsx without a .chat-input-area wrapper, so this change removes the previous min-height, padding, border/background, and resize: none behavior for the live composer. In practice the textarea falls back to browser defaults and can be manually resized, which regresses the primary chat input UX on the main agent chat route.

Useful? React with 👍 / 👎.

@chenjiayi8 chenjiayi8 closed this May 26, 2026
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.

1 participant