admin/skills: fail loud on DB error + read skills dir from env
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m8s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m8s
- Raise HTTPException(503) when Paperclip DB is unreachable instead of silently falling through to disk-only mode and returning []. - Honor PAPERCLIP_SKILLS_DIR env var (falls back to ~/.paperclip/...). In the Coolify container the host's skills dir is bind-mounted at /paperclip-skills; without this, Path.home() resolved to /root/ and the disk inventory was always empty. Both bugs together silently turned a Paperclip DB outage into "no skills installed" on the /skills page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
22
web/app.py
22
web/app.py
@@ -2656,9 +2656,15 @@ async def api_reset_methodology(category: str, key: str):
|
|||||||
PAPERCLIP_DB_URL = os.environ.get(
|
PAPERCLIP_DB_URL = os.environ.get(
|
||||||
"PAPERCLIP_DB_URL", "postgresql://paperclip:paperclip@127.0.0.1:54329/paperclip"
|
"PAPERCLIP_DB_URL", "postgresql://paperclip:paperclip@127.0.0.1:54329/paperclip"
|
||||||
)
|
)
|
||||||
# Paperclip runs locally via pm2; skills are in ~/.paperclip
|
# Paperclip skills directory. In the Coolify container this is bind-mounted from
|
||||||
_local_skills = Path.home() / ".paperclip" / "instances" / "default" / "skills"
|
# the host's ~/.paperclip/instances/default/skills (see PAPERCLIP_SKILLS_DIR env).
|
||||||
PAPERCLIP_SKILLS_DIR = _local_skills
|
# Fallback to the host path for local/dev use.
|
||||||
|
PAPERCLIP_SKILLS_DIR = Path(
|
||||||
|
os.environ.get(
|
||||||
|
"PAPERCLIP_SKILLS_DIR",
|
||||||
|
str(Path.home() / ".paperclip" / "instances" / "default" / "skills"),
|
||||||
|
)
|
||||||
|
)
|
||||||
# Default company ID for skills
|
# Default company ID for skills
|
||||||
SKILLS_COMPANY_ID = os.environ.get("PAPERCLIP_COMPANY_ID", "42a7acd0-30c5-4cbd-ac97-7424f65df294")
|
SKILLS_COMPANY_ID = os.environ.get("PAPERCLIP_COMPANY_ID", "42a7acd0-30c5-4cbd-ac97-7424f65df294")
|
||||||
|
|
||||||
@@ -2666,7 +2672,6 @@ SKILLS_COMPANY_ID = os.environ.get("PAPERCLIP_COMPANY_ID", "42a7acd0-30c5-4cbd-a
|
|||||||
@app.get("/api/admin/skills")
|
@app.get("/api/admin/skills")
|
||||||
async def api_list_skills():
|
async def api_list_skills():
|
||||||
"""List installed Paperclip skills with DB sync status."""
|
"""List installed Paperclip skills with DB sync status."""
|
||||||
rows = []
|
|
||||||
try:
|
try:
|
||||||
conn = await asyncpg.connect(PAPERCLIP_DB_URL, timeout=5)
|
conn = await asyncpg.connect(PAPERCLIP_DB_URL, timeout=5)
|
||||||
try:
|
try:
|
||||||
@@ -2677,9 +2682,12 @@ async def api_list_skills():
|
|||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
await conn.close()
|
await conn.close()
|
||||||
except (OSError, asyncpg.PostgresError, asyncpg.InterfaceError, TimeoutError):
|
except (OSError, asyncpg.PostgresError, asyncpg.InterfaceError, TimeoutError) as e:
|
||||||
# Paperclip DB unreachable — continue with disk-only skills
|
logger.exception("Paperclip DB unreachable while listing skills")
|
||||||
pass
|
raise HTTPException(
|
||||||
|
status_code=503,
|
||||||
|
detail=f"Paperclip database unreachable: {type(e).__name__}: {e}",
|
||||||
|
) from e
|
||||||
|
|
||||||
skills = []
|
skills = []
|
||||||
for r in rows:
|
for r in rows:
|
||||||
|
|||||||
Reference in New Issue
Block a user