mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 23:13:15 +00:00
* fix(dashboard): managed-cloud OAuth hardening + admin user-mapping endpoint Prepare the dashboard backend for the managed LangGraph Cloud + Vercel runtime, where the API is HTTPS and cross-site from the UI. - OAuth redirect_uri (#2): coerce a schemeless DASHBOARD_API_BASE_URL to https:// in _api_base_url() so GitHub stops rejecting login with "redirect_uri not associated with this application". _cookie_security() now treats a schemeless (managed) value as Secure; SameSite=None too, consistent with the coerced scheme. - OAuth state cookie (#3): document that osw_oauth_state is host-only by design (a Domain cookie is unsafe across *.vercel.app, a public suffix), so login must always start on the stable alias to avoid "oauth state mismatch". Operational contract; no behavioral change. - Admin user mappings (#4): add POST /admin/user-mappings so an admin can set the github_login -> work_email link from the dashboard instead of a raw Store write. New "admin" MappingSource provenance value. * fix(webapp): refresh user-mapping cache on GitHub webhook paths On managed LangGraph Cloud the backend runs multiple replicas, so the per-process GitHub<->work-email mapping cache can be stale on the replica handling a webhook (a mapping created on another replica is invisible until refresh). process_github_pr_comment and process_github_issue now refresh the cache from the durable Store before resolving the author's email, matching the existing Slack mention path (process_slack_mention). * perf(webapp): defer deepagents import to speed custom-app cold start The custom FastAPI app (agent.webapp:app, the langgraph.json http.app) pulled deepagents -> langchain_anthropic -> anthropic into its import graph via dashboard.routes, only to build skill/chat seed files. Defer those create_file_data imports into the functions that use them. Removes deepagents/langchain_anthropic/anthropic from app import entirely and roughly halves module-import wall time (~0.6-0.8s -> ~0.35s warm; larger cold-start saving since native anthropic init is skipped). Behavior identical. (reviewer_diff already imports deepagents under TYPE_CHECKING.) * feat(ui): set work_email user mappings from the admin dashboard Add an "Add / update" form to the admin User mappings section and the adminUpsertUserMapping API client method, wiring the new POST /admin/user-mappings endpoint. Admins can now create or update a github_login -> work_email mapping directly instead of waiting for the user to self-connect Slack. * docs: document managed LangGraph Cloud + Vercel deployment - INSTALLATION §10: add the managed production env triad (LANGGRAPH_URL, DASHBOARD_BASE_URL + DASHBOARD_API_BASE_URL with https://, empty VITE_DASHBOARD_API_BASE_URL for same-origin), the stable-alias login and vercel.json stable-deployment-URL requirements, multi-replica cache note, plus redirect_uri-scheme and oauth-state-mismatch troubleshooting. Refresh the langgraph.json snippet to all six graphs. - README: reframe deployment around the managed migration; link the plan. - deploy/MIGRATION.md: import the self-hosted -> managed migration plan.
54 lines
2.2 KiB
Python
54 lines
2.2 KiB
Python
"""Repo-bundled analyzer skills, served to the agent as virtual files.
|
|
|
|
The two analyzer playbooks live as ``SKILL.md`` files under ``agent/skills/``.
|
|
They are surfaced to the deepagents ``SkillsMiddleware`` via a ``StateBackend``
|
|
mounted at ``/skills/`` in a ``CompositeBackend`` — so the agent reads them with
|
|
``read_file`` without anything ever being written to the execution sandbox.
|
|
|
|
The ``files`` channel is seeded at invoke time (see the launchers). Because
|
|
``CompositeBackend`` strips the ``/skills/`` route prefix before delegating to the
|
|
``StateBackend``, the seeded keys are the *stripped* paths (e.g.
|
|
``/bootstrap-repo-analysis/SKILL.md``), while the agent and ``SkillsMiddleware``
|
|
address them under ``/skills/...``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
SKILLS_DIR = Path(__file__).resolve().parent.parent / "skills"
|
|
SKILLS_ROUTE = "/skills/"
|
|
|
|
BOOTSTRAP_SKILL = "bootstrap-repo-analysis"
|
|
CONTINUAL_SKILL = "continual-learning"
|
|
|
|
ANALYZER_MODES = {"bootstrap": BOOTSTRAP_SKILL, "continual": CONTINUAL_SKILL}
|
|
|
|
|
|
def skill_path_for_mode(mode: str) -> str:
|
|
"""Return the agent-facing ``/skills/<name>/SKILL.md`` path for a run mode."""
|
|
skill = ANALYZER_MODES.get(mode, BOOTSTRAP_SKILL)
|
|
return f"{SKILLS_ROUTE}{skill}/SKILL.md"
|
|
|
|
|
|
def build_skill_files() -> dict[str, Any]:
|
|
"""Return ``{stripped_path: FileData}`` for every bundled analyzer skill.
|
|
|
|
Seed this into the run input's ``files`` so the ``/skills/`` StateBackend route
|
|
can serve them. Keys omit the ``/skills`` prefix (stripped by the composite
|
|
route); values are ``FileData`` v2 entries.
|
|
"""
|
|
# Deferred import: deepagents (and its langchain_anthropic / anthropic
|
|
# transitive deps) is heavy (~0.7s) and is otherwise pulled into the custom
|
|
# FastAPI app's import chain via dashboard.routes, slowing cold start. It's
|
|
# only needed when a skill bundle is actually built (analyzer launch), so
|
|
# import it lazily here.
|
|
from deepagents.backends.utils import create_file_data
|
|
|
|
files: dict[str, Any] = {}
|
|
for skill in ANALYZER_MODES.values():
|
|
skill_md = SKILLS_DIR / skill / "SKILL.md"
|
|
text = skill_md.read_text(encoding="utf-8")
|
|
files[f"/{skill}/SKILL.md"] = create_file_data(text)
|
|
return files
|