Skip to content

Merge onboarding and deployment updates#573

Open
yaojin3616 wants to merge 18 commits into
mainfrom
feature-ha
Open

Merge onboarding and deployment updates#573
yaojin3616 wants to merge 18 commits into
mainfrom
feature-ha

Conversation

@yaojin3616
Copy link
Copy Markdown
Collaborator

Summary

  • merge the latest onboarding, auth, and UI updates on feature-ha
  • include deployment and compose changes for multi-instance setup
  • resolve merge conflicts in backend file and startup logic

Testing

  • not run

yaojin and others added 15 commits May 6, 2026 16:12
- read focus/agenda files via storage keys in agent context
- write A2A focus updates through storage backend instead of local paths
- add S3 local fallback read-through migration wrapper
- document S3/fallback environment settings
- add boto3 dependency and regression coverage
…cking

- Replace sync boto3 writes with aioboto3 async client to eliminate stale
  connection stalls (30s → <2s on concurrent skill uploads)
- Add tcp_keepalive, connect_timeout, and read_timeout to boto3 config
- Add aioboto3>=13.0.0 dependency
- Simplify skill upload in create_agent: single gather, no semaphore, no
  nested helper function
- Add workspace locking service for HA-safe concurrent agent operations
- Extend storage runtime base with versioned write (write_bytes_if_match),
  get_version, and StorageVersion/WriteCondition/ConditionalWriteResult types
- Propagate storage backend through files API, agent tools, and seeder
- Add fallback storage backend for local→S3 migration path
- Add nginx multi-instance config for HA deployment
- Add tests: storage S3, files API storage, agent tools workspace, org sync
…service

Conflict resolution decisions:
- files.py: keep storage backend, discard main's local filesystem calls
  (focus checks already present via HEAD's is_focus_file_path)
- agent_context.py: use main's focus_service.render_focus_context
  (cleaner than file-based focus reading)
- agent_tools.py: keep HEAD's _execute_workspace_mutation abstraction,
  merge main's focus tools (list/upsert/complete_focus_item),
  use main's _append_focus_item via ensure_focus_item service
- relationships.py: merge both imports (storage + permissions + Identity)
- main.py: keep HEAD's _role_enabled guard, add main's app.models.focus
- skill_seeder.py: keep HEAD's storage backend approach
- trigger_daemon.py: keep HEAD's runtime extraction, preserve main's
  _should_skip_non_workday and _handle_okr_report_trigger
- heartbeat.py: keep HEAD's storage backend imports
- MarkdownRenderer.tsx: keep HEAD's CLAWITHMDTOKEN naming
Lost during merge conflict resolution. Re-adds main's filtering logic
to the storage-backend list_files implementation:
- Skip .gitkeep files
- Hide focus.md / agenda.md at workspace root (managed via Focus API)
- Filter enterprise_info at root (already injected as virtual entry)
Merge conflict resolution dropped several defensive checks from main:

files.py:
- Add is_focus_file_path check to read_file endpoint (410 GONE)
- Add .gitkeep filtering to list_enterprise_kb_files

agent_tools.py (_execute_workspace_mutation):
- Add is_focus_file_path guard to write_file, move_file, delete_file,
  edit_file (returns user-friendly error directing to Focus API)

Enterprise endpoints' path safety is already guaranteed by
normalize_storage_key which strips ../ traversal, so the explicit
startswith checks from main are not required here.
- Add deploy directory with docker-compose.yml and nginx configs
- Add deploy-all-in-one.sh deployment script
- Update network to clawith_yaojin_network to avoid conflicts
- Resolve agent_tools.py merge conflict with generate_image_custom support
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


P0 Badge Remove unexpected top-level indentation

This indented statement sits at module scope, which makes trigger_daemon.py fail to import with IndentationError. Because backend/app/main.py imports start_trigger_daemon during lifespan startup, this syntax error prevents the backend from starting in all roles, not just worker mode.

ℹ️ 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 on lines +55 to +56
pipe.expire(self._connection_key(connection_id), PRESENCE_TTL_SECONDS)
pipe.expire(self._agent_index_key(agent_id), PRESENCE_TTL_SECONDS)
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 Keep websocket presence keys alive while connected

Presence keys are given a 180-second TTL only at registration time, but there is no refresh path in this router. Any WebSocket that stays open longer than 3 minutes will age out of Redis even though it is still connected, causing cross-instance message routing and active-session/viewer checks to silently stop working for long-lived sessions.

Useful? React with 👍 / 👎.

Backend:
- Add identity_provider_lookup service for unified provider resolution
- Enhance Google Workspace OAuth integration
- Improve SSO service and auth provider registry
- Resolve merge conflict in relationships.py

Frontend:
- Add Atlas design system (18 components: plates, buttons, inputs, etc.)
- Add CosmicBackground and StarField visual effects
- Update Login, Onboarding, CompanySetup pages with Atlas theme
- Update agent detail and enterprise settings tabs
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


P0 Badge Restore valid indentation in trigger daemon module

This file contains a top-level indented block starting at line 81 without any enclosing statement, which raises SyntaxError: unexpected indent as soon as app.services.trigger_daemon is imported. Because backend/app/main.py imports start_trigger_daemon during application lifespan startup, this parse error prevents the backend from starting in any environment where startup runs.

ℹ️ 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".

Use ThreadPoolExecutor for password hashing/verification, update
agents API, chat sessions, and agent detail page.
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: 4056d65753

ℹ️ 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 backend/app/api/files.py
Comment on lines 857 to 858
if normalized_path not in {"workspace", "skills"} and not normalized_path.startswith(("workspace/", "skills/")):
raise HTTPException(status_code=400, detail="右侧根目录视图是 agent 根目录;上传文件时请放到 workspace/ 或 skills/ 目录下")
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 Normalize upload path before prefix validation

The upload endpoint validates path with startswith("workspace/")/"skills/" before it is normalized, but _agent_storage_key() later removes .. segments; this allows inputs like workspace/../../soul.md to pass validation and be written outside the intended upload roots. In upload_file_to_workspace, a user with normal agent access can therefore overwrite arbitrary files under the agent root instead of being confined to workspace/ or skills/ as the API contract implies.

Useful? React with 👍 / 👎.

Comment on lines +579 to +583
if entry.is_dir:
keys.extend(await _collect_storage_tree_versions(storage, entry.key))
else:
version = await storage.get_version(entry.key)
keys.append((entry.key, version.token))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve empty directories when moving folder trees

Directory moves now copy only file entries collected by _collect_storage_tree_versions, which recursively skips directory nodes and returns no record for empty folders. When moving a directory that contains empty subdirectories, those empty subdirectories are dropped (the source tree is removed later), which is a regression from the previous shutil.move behavior and causes silent data-structure loss in workspace trees.

Useful? React with 👍 / 👎.

Comment on lines +278 to +279
tmp = NamedTemporaryFile(delete=False, suffix=suffix)
tmp.close()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid leaking temp files in S3 local materialization

S3StorageBackend.local_path_for() creates a NamedTemporaryFile(delete=False) and returns its path without any lifecycle cleanup, so every preview/extraction/download path that materializes S3 objects leaves orphan files on disk. Under repeated document previews/uploads this accumulates indefinitely and can eventually exhaust container disk space.

Useful? React with 👍 / 👎.

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