feat(web): Agent Platform Port — Paperclip מאחורי seam-import יחיד (R2, G12, #111) #175
96
web/agent_platform_port.py
Normal file
96
web/agent_platform_port.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Agent Platform Port (INV-G12 / docs/spec/X15) — the single seam to the platform.
|
||||
|
||||
Paperclip is the *agent platform*: a replaceable shell, not the core. This module
|
||||
is the ONLY place in the web layer that may import the Paperclip client
|
||||
(``web.paperclip_client`` / ``web.paperclip_api``). ``web/app.py`` — and any future
|
||||
web code — imports the platform operations from HERE, never from the Paperclip
|
||||
modules directly. So the dependency points inward (Ports & Adapters / the
|
||||
Dependency Rule, Cockburn / Martin): swapping the platform means re-implementing
|
||||
this one module, not touching app.py.
|
||||
|
||||
Enforced by the leak-guard (X15 §4 / R4): no file outside this Port imports
|
||||
``paperclip_client`` / ``paperclip_api``.
|
||||
|
||||
Two tiers:
|
||||
• **Lifecycle side-effects** — archive / restore / create a case's project, and
|
||||
the case-status notification — are also exposed under domain names
|
||||
(``archive_case_project`` …). These are the genuine domain events the app
|
||||
emits over a case's lifecycle; prefer them in new code.
|
||||
• **Issue / interaction / comment / agent operations** are re-exported under
|
||||
their existing ``pc_*`` names: they are request/response API calls, not
|
||||
events, so a faithful facade re-export — rather than an artificial "event" —
|
||||
is the honest treatment. Migrating these to domain verbs is a follow-up that
|
||||
can happen as call sites are touched; the import seam (the enforceable part
|
||||
of G12) holds regardless.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
# ── the Paperclip shell — imported ONLY here (the Port is the single seam) ──
|
||||
from web.paperclip_api import (
|
||||
emit_case_status_webhook,
|
||||
pc_request,
|
||||
require_paperclip_db_url,
|
||||
)
|
||||
from web.paperclip_client import (
|
||||
COMPANIES as PAPERCLIP_COMPANIES,
|
||||
accept_interaction as pc_accept_interaction,
|
||||
archive_project as pc_archive_project,
|
||||
create_project as pc_create_project,
|
||||
create_workflow_issue as pc_create_workflow_issue,
|
||||
get_agents_for_case as pc_get_agents_for_case,
|
||||
get_agents_for_company as pc_get_agents,
|
||||
get_case_issues as pc_get_case_issues,
|
||||
get_issue_comments as pc_get_issue_comments,
|
||||
get_issue_interactions as pc_get_issue_interactions,
|
||||
get_project_url,
|
||||
post_comment as pc_post_comment,
|
||||
reject_interaction as pc_reject_interaction,
|
||||
respond_to_interaction as pc_respond_to_interaction,
|
||||
restore_project as pc_restore_project,
|
||||
wake_analyst_for_appraiser_facts as pc_wake_analyst_for_appraiser_facts,
|
||||
wake_ceo_agent as pc_wake_ceo,
|
||||
wake_ceo_for_feedback_fold as pc_wake_ceo_for_feedback_fold,
|
||||
wake_curator_for_final as pc_wake_curator_for_final,
|
||||
wake_for_precedent_extraction as pc_wake_for_precedent_extraction,
|
||||
)
|
||||
|
||||
# ── domain-named lifecycle aliases (preferred for new call sites) ───────────
|
||||
archive_case_project = pc_archive_project
|
||||
restore_case_project = pc_restore_project
|
||||
create_case_project = pc_create_project
|
||||
notify_case_status = emit_case_status_webhook
|
||||
|
||||
__all__ = [
|
||||
# platform infrastructure
|
||||
"PAPERCLIP_COMPANIES",
|
||||
"pc_request",
|
||||
"require_paperclip_db_url",
|
||||
"get_project_url",
|
||||
# lifecycle — domain names (preferred) + legacy aliases
|
||||
"archive_case_project",
|
||||
"restore_case_project",
|
||||
"create_case_project",
|
||||
"notify_case_status",
|
||||
"emit_case_status_webhook",
|
||||
"pc_archive_project",
|
||||
"pc_restore_project",
|
||||
"pc_create_project",
|
||||
# issues / workflow
|
||||
"pc_create_workflow_issue",
|
||||
"pc_get_case_issues",
|
||||
# agents / wakeups
|
||||
"pc_get_agents_for_case",
|
||||
"pc_get_agents",
|
||||
"pc_wake_ceo",
|
||||
"pc_wake_ceo_for_feedback_fold",
|
||||
"pc_wake_curator_for_final",
|
||||
"pc_wake_for_precedent_extraction",
|
||||
"pc_wake_analyst_for_appraiser_facts",
|
||||
# comments / interactions
|
||||
"pc_post_comment",
|
||||
"pc_get_issue_comments",
|
||||
"pc_get_issue_interactions",
|
||||
"pc_accept_interaction",
|
||||
"pc_reject_interaction",
|
||||
"pc_respond_to_interaction",
|
||||
]
|
||||
46
web/app.py
46
web/app.py
@@ -47,28 +47,32 @@ from web.mcp_env_catalog import (
|
||||
normalize_for_compare,
|
||||
)
|
||||
from web.progress_store import ProgressStore
|
||||
from web.paperclip_api import emit_case_status_webhook, pc_request, require_paperclip_db_url
|
||||
from web.paperclip_client import (
|
||||
COMPANIES as PAPERCLIP_COMPANIES,
|
||||
accept_interaction as pc_accept_interaction,
|
||||
archive_project as pc_archive_project,
|
||||
create_project as pc_create_project,
|
||||
create_workflow_issue as pc_create_workflow_issue,
|
||||
get_agents_for_case as pc_get_agents_for_case,
|
||||
get_agents_for_company as pc_get_agents,
|
||||
get_case_issues as pc_get_case_issues,
|
||||
get_issue_comments as pc_get_issue_comments,
|
||||
get_issue_interactions as pc_get_issue_interactions,
|
||||
# Agent platform access goes through the Platform Port ONLY (INV-G12 / X15) —
|
||||
# app.py never imports web.paperclip_client / web.paperclip_api directly.
|
||||
from web.agent_platform_port import (
|
||||
PAPERCLIP_COMPANIES,
|
||||
emit_case_status_webhook,
|
||||
get_project_url,
|
||||
post_comment as pc_post_comment,
|
||||
reject_interaction as pc_reject_interaction,
|
||||
respond_to_interaction as pc_respond_to_interaction,
|
||||
restore_project as pc_restore_project,
|
||||
wake_analyst_for_appraiser_facts as pc_wake_analyst_for_appraiser_facts,
|
||||
wake_ceo_agent as pc_wake_ceo,
|
||||
wake_ceo_for_feedback_fold as pc_wake_ceo_for_feedback_fold,
|
||||
wake_curator_for_final as pc_wake_curator_for_final,
|
||||
wake_for_precedent_extraction as pc_wake_for_precedent_extraction,
|
||||
pc_accept_interaction,
|
||||
pc_archive_project,
|
||||
pc_create_project,
|
||||
pc_create_workflow_issue,
|
||||
pc_get_agents,
|
||||
pc_get_agents_for_case,
|
||||
pc_get_case_issues,
|
||||
pc_get_issue_comments,
|
||||
pc_get_issue_interactions,
|
||||
pc_post_comment,
|
||||
pc_reject_interaction,
|
||||
pc_request,
|
||||
pc_respond_to_interaction,
|
||||
pc_restore_project,
|
||||
pc_wake_analyst_for_appraiser_facts,
|
||||
pc_wake_ceo,
|
||||
pc_wake_ceo_for_feedback_fold,
|
||||
pc_wake_curator_for_final,
|
||||
pc_wake_for_precedent_extraction,
|
||||
require_paperclip_db_url,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user