Task 010 implement research manifest flow
This commit is contained in:
@@ -20,6 +20,8 @@ from src.domain.contracts import (
|
||||
PlanSummary,
|
||||
PublishingRules,
|
||||
PublishingStatus,
|
||||
ResearchArtifactManifestSummary,
|
||||
ResearchArtifactSummary,
|
||||
ArticleWorkflowStatus,
|
||||
WorkflowEventSummary,
|
||||
Role,
|
||||
@@ -46,6 +48,7 @@ class BackendRepository:
|
||||
self.articles = ArticlesRepository(self)
|
||||
self.boundary_questions = BoundaryQuestionsRepository(self)
|
||||
self.article_plans = ArticlePlansRepository(self)
|
||||
self.research_manifests = ResearchManifestsRepository(self)
|
||||
self.agent_jobs = AgentJobsRepository(self)
|
||||
self.script_config_versions = ScriptConfigVersionsRepository(self)
|
||||
self.script_config_version_events = ScriptConfigVersionAuditEventsRepository(self)
|
||||
@@ -1005,6 +1008,121 @@ class ArticlePlansRepository:
|
||||
"""
|
||||
|
||||
|
||||
class ResearchManifestsRepository:
|
||||
def __init__(self, repository: BackendRepository) -> None:
|
||||
self._repository = repository
|
||||
|
||||
def create(
|
||||
self,
|
||||
*,
|
||||
article_id: UUID,
|
||||
agent_job_id: UUID,
|
||||
s3_prefix: str,
|
||||
artifacts: list[JsonObject],
|
||||
created_at: datetime,
|
||||
) -> ResearchArtifactManifestSummary:
|
||||
manifest_id = uuid4()
|
||||
placeholder = self._repository.placeholder()
|
||||
json_cast = self._repository.json_cast()
|
||||
source_urls = [artifact["source_url"] for artifact in artifacts]
|
||||
object_keys = [artifact["object_key"] for artifact in artifacts]
|
||||
content_hashes = [artifact["content_hash"] for artifact in artifacts]
|
||||
artifact_types = [artifact["artifact_type"] for artifact in artifacts]
|
||||
metadata_references = [
|
||||
artifact.get("metadata", {}).get("metadata_object_key")
|
||||
for artifact in artifacts
|
||||
]
|
||||
with self._repository.connection() as connection:
|
||||
connection.execute(
|
||||
f"""
|
||||
INSERT INTO research_run_manifests (
|
||||
id,
|
||||
article_id,
|
||||
agent_job_id,
|
||||
s3_prefix,
|
||||
source_urls,
|
||||
object_keys,
|
||||
content_hashes,
|
||||
artifact_types,
|
||||
metadata_references,
|
||||
artifacts,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder},
|
||||
{placeholder}{json_cast},
|
||||
{placeholder}{json_cast},
|
||||
{placeholder}{json_cast},
|
||||
{placeholder}{json_cast},
|
||||
{placeholder}{json_cast},
|
||||
{placeholder}{json_cast},
|
||||
{placeholder}
|
||||
)
|
||||
""",
|
||||
(
|
||||
str(manifest_id),
|
||||
str(article_id),
|
||||
str(agent_job_id),
|
||||
s3_prefix,
|
||||
_json_value(source_urls),
|
||||
_json_value(object_keys),
|
||||
_json_value(content_hashes),
|
||||
_json_value(artifact_types),
|
||||
_json_value(metadata_references),
|
||||
_json_value(artifacts),
|
||||
_datetime_value(created_at),
|
||||
),
|
||||
)
|
||||
|
||||
return self.get(manifest_id)
|
||||
|
||||
def list_for_article(self, article_id: UUID) -> list[ResearchArtifactManifestSummary]:
|
||||
placeholder = self._repository.placeholder()
|
||||
with self._repository.connection() as connection:
|
||||
rows = connection.execute(
|
||||
f"""
|
||||
SELECT
|
||||
id,
|
||||
article_id,
|
||||
agent_job_id,
|
||||
s3_prefix,
|
||||
artifacts,
|
||||
created_at
|
||||
FROM research_run_manifests
|
||||
WHERE article_id = {placeholder}
|
||||
ORDER BY created_at
|
||||
""",
|
||||
(str(article_id),),
|
||||
).fetchall()
|
||||
|
||||
return [_research_manifest_from_row(row) for row in rows]
|
||||
|
||||
def get(self, manifest_id: UUID) -> ResearchArtifactManifestSummary:
|
||||
placeholder = self._repository.placeholder()
|
||||
with self._repository.connection() as connection:
|
||||
row = connection.execute(
|
||||
f"""
|
||||
SELECT
|
||||
id,
|
||||
article_id,
|
||||
agent_job_id,
|
||||
s3_prefix,
|
||||
artifacts,
|
||||
created_at
|
||||
FROM research_run_manifests
|
||||
WHERE id = {placeholder}
|
||||
""",
|
||||
(str(manifest_id),),
|
||||
).fetchone()
|
||||
|
||||
if row is None:
|
||||
raise LookupError(f"Research manifest not found: {manifest_id}")
|
||||
return _research_manifest_from_row(row)
|
||||
|
||||
|
||||
class AgentJobsRepository:
|
||||
def __init__(self, repository: BackendRepository) -> None:
|
||||
self._repository = repository
|
||||
@@ -1715,6 +1833,20 @@ def _plan_summary_from_row(
|
||||
)
|
||||
|
||||
|
||||
def _research_manifest_from_row(row: Any) -> ResearchArtifactManifestSummary:
|
||||
return ResearchArtifactManifestSummary(
|
||||
id=_row_value(row, "id"),
|
||||
article_id=_row_value(row, "article_id"),
|
||||
agent_job_id=_row_value(row, "agent_job_id"),
|
||||
s3_prefix=_row_value(row, "s3_prefix"),
|
||||
artifacts=[
|
||||
ResearchArtifactSummary(**artifact)
|
||||
for artifact in _json_from_row(row, "artifacts")
|
||||
],
|
||||
created_at=_row_value(row, "created_at"),
|
||||
)
|
||||
|
||||
|
||||
def _agent_job_summary_from_row(row: Any) -> AgentJobSummary:
|
||||
return AgentJobSummary(
|
||||
id=_row_value(row, "id"),
|
||||
|
||||
Reference in New Issue
Block a user