Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 1 addition & 26 deletions dashboard/amplify/data/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ type DataSourceIndexFields = "accountId" | "scorecardId" | "scoreId" | "name" |
type DataSourceVersionIndexFields = "dataSourceId" | "createdAt" | "updatedAt";
type DataSetIndexFields = "accountId" | "scorecardId" | "scoreId" | "scoreVersionId" | "dataSourceVersionId" | "createdAt" | "updatedAt";
type ProcedureIndexFields = "accountId" | "scorecardId" | "scoreId" | "scoreVersionId" | "parentProcedureId" | "updatedAt" | "createdAt" | "category" | "version" | "status" | "createdByUserId";
type ProcedureScoreVersionIndexFields = "procedureId" | "scoreVersionId" | "updatedAt";

// New index types for Feedback Alignment
// type FeedbackAlignmentIndexFields = "accountId" | "scorecardId" | "createdAt"; // REMOVED
Expand Down Expand Up @@ -225,8 +224,7 @@ const schema = a.schema({
childVersions: a.hasMany('ScoreVersion', 'parentVersionId'),
evaluations: a.hasMany('Evaluation', 'scoreVersionId'),
dataSets: a.hasMany('DataSet', 'scoreVersionId'),
procedures: a.hasMany('Procedure', 'scoreVersionId'),
procedureLinks: a.hasMany('ProcedureScoreVersion', 'scoreVersionId')
procedures: a.hasMany('Procedure', 'scoreVersionId')
})
.authorization((allow) => [
allow.publicApiKey(),
Expand Down Expand Up @@ -906,7 +904,6 @@ const schema = a.schema({
score: a.belongsTo('Score', 'scoreId'),
scoreVersionId: a.string(),
scoreVersion: a.belongsTo('ScoreVersion', 'scoreVersionId'),
scoreVersionLinks: a.hasMany('ProcedureScoreVersion', 'procedureId'),
chatSessions: a.hasMany('ChatSession', 'procedureId'),
chatMessages: a.hasMany('ChatMessage', 'procedureId'),
createdByUserId: a.string(),
Expand All @@ -927,28 +924,6 @@ const schema = a.schema({
idx("createdByUserId")
]),

ProcedureScoreVersion: a
.model({
procedureId: a.string().required(),
procedure: a.belongsTo('Procedure', 'procedureId'),
scoreVersionId: a.string().required(),
scoreVersion: a.belongsTo('ScoreVersion', 'scoreVersionId'),
accountId: a.string().required(),
scorecardId: a.string(),
scoreId: a.string(),
relationshipTypes: a.string().array(),
createdAt: a.datetime().required(),
updatedAt: a.datetime().required(),
})
.authorization((allow) => [
allow.publicApiKey(),
allow.authenticated()
])
.secondaryIndexes((idx: (field: ProcedureScoreVersionIndexFields) => any) => [
idx("procedureId").sortKeys(["updatedAt"]),
idx("scoreVersionId").sortKeys(["updatedAt"])
]),

ChatSession: a
.model({
accountId: a.string().required(),
Expand Down
143 changes: 0 additions & 143 deletions plexus/cli/shared/optimizer_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,39 +136,6 @@ def _sort_by_updated_at_desc(items: Iterable[Dict[str, Any]]) -> List[Dict[str,
)


def _optimizer_manifest_score_version_links(manifest: Dict[str, Any]) -> Dict[str, List[str]]:
links: Dict[str, List[str]] = {}

def add(version_id: Any, relationship_type: str) -> None:
if not isinstance(version_id, str) or not version_id:
return
relationship_types = links.setdefault(version_id, [])
if relationship_type not in relationship_types:
relationship_types.append(relationship_type)

baseline = manifest.get("baseline") or {}
if isinstance(baseline, dict):
add(baseline.get("version_id"), "baseline")

best = manifest.get("best") or {}
if isinstance(best, dict):
add(best.get("winning_version_id"), "winning")
add(best.get("last_accepted_version_id"), "accepted")

for cycle in manifest.get("cycles") or []:
if not isinstance(cycle, dict):
continue
add(cycle.get("version_id"), "cycle")
for candidate in cycle.get("candidates") or []:
if isinstance(candidate, dict):
add(candidate.get("version_id"), "candidate")
for candidate in cycle.get("no_version_candidates") or []:
if isinstance(candidate, dict):
add(candidate.get("version_id"), "no_version_candidate")

return links


def _evaluation_url(evaluation_id: Optional[str]) -> Optional[str]:
return f"{LAB_EVALUATION_BASE_URL}/{evaluation_id}" if evaluation_id else None

Expand Down Expand Up @@ -647,115 +614,6 @@ def _artifact_keys_for_task(self, task_id: str) -> Dict[str, str]:
"runtime_log": f"tasks/{task_id}/{OPTIMIZER_RUNTIME_LOG_SUFFIX}",
}

def _list_score_version_links_for_procedure(self, procedure_id: str) -> List[Dict[str, Any]]:
query = """
query ListProcedureScoreVersionByProcedureIdAndUpdatedAtForOptimizer(
$procedureId: String!
$limit: Int
$nextToken: String
) {
listProcedureScoreVersionByProcedureIdAndUpdatedAt(
procedureId: $procedureId
sortDirection: DESC
limit: $limit
nextToken: $nextToken
) {
items {
id
procedureId
scoreVersionId
}
nextToken
}
}
"""
links: List[Dict[str, Any]] = []
next_token: Optional[str] = None
while True:
variables: Dict[str, Any] = {"procedureId": procedure_id, "limit": 100}
if next_token:
variables["nextToken"] = next_token
result = self.client.execute(query, variables)
payload = result.get("listProcedureScoreVersionByProcedureIdAndUpdatedAt", {})
links.extend(item for item in payload.get("items") or [] if isinstance(item, dict))
next_token = payload.get("nextToken")
if not next_token:
break
return links

def _sync_optimizer_score_version_links(
self,
*,
procedure: Dict[str, Any],
manifest: Dict[str, Any],
) -> None:
procedure_id = str(procedure.get("id") or "")
account_id = str(procedure.get("accountId") or "")
if not procedure_id or not account_id:
return

now = _utc_now_iso()
desired = _optimizer_manifest_score_version_links(manifest)
existing = self._list_score_version_links_for_procedure(procedure_id)
existing_by_version = {
item.get("scoreVersionId"): item
for item in existing
if isinstance(item.get("scoreVersionId"), str)
}

create_mutation = """
mutation CreateProcedureScoreVersionForOptimizer($input: CreateProcedureScoreVersionInput!) {
createProcedureScoreVersion(input: $input) {
id
}
}
"""
update_mutation = """
mutation UpdateProcedureScoreVersionForOptimizer($input: UpdateProcedureScoreVersionInput!) {
updateProcedureScoreVersion(input: $input) {
id
}
}
"""
delete_mutation = """
mutation DeleteProcedureScoreVersionForOptimizer($input: DeleteProcedureScoreVersionInput!) {
deleteProcedureScoreVersion(input: $input) {
id
}
}
"""

for version_id, relationship_types in desired.items():
existing_item = existing_by_version.get(version_id)
input_data = {
"procedureId": procedure_id,
"scoreVersionId": version_id,
"accountId": account_id,
"scorecardId": procedure.get("scorecardId"),
"scoreId": procedure.get("scoreId"),
"relationshipTypes": relationship_types,
"updatedAt": now,
}
if existing_item:
self.client.execute(
update_mutation,
{"input": {"id": existing_item["id"], **input_data}},
)
else:
link_id = f"{procedure_id}:{version_id}"
self.client.execute(
create_mutation,
{"input": {"id": link_id, "createdAt": now, **input_data}},
)

desired_versions = set(desired.keys())
for existing_item in existing:
version_id = existing_item.get("scoreVersionId")
link_id = existing_item.get("id")
if version_id in desired_versions or not link_id:
continue
self.client.execute(delete_mutation, {"input": {"id": link_id}})

def index_optimizer_run(
self,
procedure_id: str,
Expand Down Expand Up @@ -786,7 +644,6 @@ def index_optimizer_run(
raise RuntimeError("aws.storage.task_attachments_bucket is required for optimizer artifacts.")

manifest = self.build_manifest(procedure=procedure, task=task, state=state)
self._sync_optimizer_score_version_links(procedure=procedure, manifest=manifest)
artifact_keys = self._artifact_keys_for_task(task.id)
upload_task_attachment_bytes(
bucket_name=bucket_name,
Expand Down
22 changes: 0 additions & 22 deletions plexus/cli/shared/optimizer_results_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,8 @@
class _FakeClient:
def __init__(self):
self.update_calls = []
self.link_creates = []
self.link_updates = []
self.link_deletes = []

def execute(self, query, variables):
if "listProcedureScoreVersionByProcedureIdAndUpdatedAt" in query:
return {"listProcedureScoreVersionByProcedureIdAndUpdatedAt": {"items": [], "nextToken": None}}
if "createProcedureScoreVersion" in query:
self.link_creates.append({"query": query, "variables": variables})
return {"createProcedureScoreVersion": {"id": variables["input"]["id"]}}
if "updateProcedureScoreVersion" in query:
self.link_updates.append({"query": query, "variables": variables})
return {"updateProcedureScoreVersion": {"id": variables["input"]["id"]}}
if "deleteProcedureScoreVersion" in query:
self.link_deletes.append({"query": query, "variables": variables})
return {"deleteProcedureScoreVersion": {"id": variables["input"]["id"]}}
if "updateProcedure(input:" in query:
self.update_calls.append({"query": query, "variables": variables})
return {"updateProcedure": {"id": variables["input"]["id"], "metadata": variables["input"]["metadata"]}}
Expand Down Expand Up @@ -172,14 +158,6 @@ def test_index_optimizer_run_persists_manifest_and_pointer(monkeypatch):
pointer = saved_metadata[OPTIMIZER_ARTIFACTS_METADATA_KEY]
assert pointer["task_id"] == "task-123"
assert pointer["manifest"] == "tasks/task-123/optimizer/manifest.json"
linked_versions = {
call["variables"]["input"]["scoreVersionId"]: call["variables"]["input"]["relationshipTypes"]
for call in client.link_creates
}
assert linked_versions["version-baseline"] == ["baseline"]
assert linked_versions["version-accepted"] == ["winning", "accepted", "cycle"]
assert linked_versions["version-1"] == ["cycle"]
assert linked_versions["version-candidate"] == ["candidate"]


def test_list_optimizer_candidates_for_score_aggregates_best_visible_metrics(monkeypatch):
Expand Down
Loading