88import os
99import sys
1010import re
11+ from functools import lru_cache
1112from time import perf_counter
1213from pathlib import Path
1314from typing import Any , Callable , Mapping
4950CODE_SEARCH_SCHEMA_VERSION = "agenticflow.code.search.v1"
5051CODE_EXECUTE_SCHEMA_VERSION = "agenticflow.code.execute.v1"
5152CLI_CONFIG_DIR_ENV_VAR = "AGENTICFLOW_CLI_DIR"
53+ CURATED_MANIFEST_PATH = Path (__file__ ).resolve ().parent / "public_ops_manifest.json"
54+ SUPPORT_SCOPE_EXECUTED = "supported-executed"
55+ SUPPORT_SCOPE_BLOCKED = "supported-blocked-policy"
5256
5357
5458def _add_common_call_flags (parser : argparse .ArgumentParser ) -> None :
@@ -643,18 +647,81 @@ def _catalog_operation_item(operation: Any) -> dict[str, Any]:
643647 }
644648
645649
650+ @lru_cache (maxsize = 1 )
651+ def _manifest_scope_by_operation_id () -> dict [str , str ]:
652+ try :
653+ raw = json .loads (CURATED_MANIFEST_PATH .read_text (encoding = "utf-8" ))
654+ except Exception :
655+ return {}
656+ if not isinstance (raw , list ):
657+ return {}
658+
659+ scopes : dict [str , str ] = {}
660+ for item in raw :
661+ if not isinstance (item , Mapping ):
662+ continue
663+ operation_id = item .get ("operation_id" )
664+ support_scope = item .get ("support_scope" )
665+ if isinstance (operation_id , str ) and operation_id and isinstance (support_scope , str ):
666+ scopes [operation_id ] = support_scope
667+ return scopes
668+
669+
670+ def _should_use_curated_manifest (spec_file : Path , public_only : bool ) -> bool :
671+ if not public_only :
672+ return False
673+ try :
674+ return spec_file .resolve () == default_spec_path ().resolve ()
675+ except Exception :
676+ return False
677+
678+
679+ def _apply_curated_manifest_filter (
680+ operations : list [Any ],
681+ * ,
682+ public_only : bool ,
683+ spec_file : Path ,
684+ ) -> list [Any ]:
685+ if not _should_use_curated_manifest (spec_file , public_only ):
686+ return operations
687+
688+ manifest_scope = _manifest_scope_by_operation_id ()
689+ if not manifest_scope :
690+ return operations
691+ allowed_operation_ids = set (manifest_scope )
692+ return [
693+ operation
694+ for operation in operations
695+ if getattr (operation , "operation_id" , None ) in allowed_operation_ids
696+ ]
697+
698+
646699def _catalog_records (
647- registry : OperationRegistry , public_only : bool
700+ registry : OperationRegistry ,
701+ public_only : bool ,
702+ spec_file : Path ,
648703) -> list [dict [str , Any ]]:
649704 operations = _list_operations (registry , public_only = public_only , tag = None )
705+ operations = _apply_curated_manifest_filter (
706+ operations ,
707+ public_only = public_only ,
708+ spec_file = spec_file ,
709+ )
650710 records = [_catalog_operation_item (operation ) for operation in operations ]
651711 return sorted (records , key = lambda item : (item ["path" ], item ["method" ], item ["operation_id" ]))
652712
653713
654714def _catalog_operations (
655- registry : OperationRegistry , public_only : bool
715+ registry : OperationRegistry ,
716+ public_only : bool ,
717+ spec_file : Path ,
656718) -> list [Any ]:
657719 operations = _list_operations (registry , public_only = public_only , tag = None )
720+ operations = _apply_curated_manifest_filter (
721+ operations ,
722+ public_only = public_only ,
723+ spec_file = spec_file ,
724+ )
658725 return sorted (
659726 operations ,
660727 key = lambda item : (item .path , item .method , item .operation_id ),
@@ -711,6 +778,7 @@ def _rank_catalog_operations(
711778 task : str ,
712779 max_cost : float | None = None ,
713780 max_latency_ms : float | None = None ,
781+ manifest_scope_by_operation_id : Mapping [str , str ] | None = None ,
714782) -> list [dict [str , Any ]]:
715783 task_terms = _tokenize_catalog_text (task )
716784 if not task_terms :
@@ -736,13 +804,64 @@ def _rank_catalog_operations(
736804 if max_latency_ms is not None and latency > max_latency_ms :
737805 continue
738806
739- score = round ((relevance * 10 ) - cost - (latency / 200 ), 3 )
807+ support_scope = None
808+ if manifest_scope_by_operation_id is not None :
809+ support_scope = manifest_scope_by_operation_id .get (
810+ operation_record ["operation_id" ]
811+ )
812+ scope_bonus = 0.0
813+ if support_scope == SUPPORT_SCOPE_EXECUTED :
814+ scope_bonus = 4.0
815+ elif support_scope == SUPPORT_SCOPE_BLOCKED :
816+ scope_bonus = 2.0
817+
818+ dependency_bonus = 0.0
819+ builder_terms = {
820+ "build" ,
821+ "builder" ,
822+ "create" ,
823+ "workflow" ,
824+ "workflows" ,
825+ "agent" ,
826+ "agents" ,
827+ "workforce" ,
828+ "dependencies" ,
829+ "dependency" ,
830+ }
831+ if task_terms .intersection (builder_terms ):
832+ dependency_tokens = {
833+ "node" ,
834+ "nodes" ,
835+ "connection" ,
836+ "connections" ,
837+ "provider" ,
838+ "providers" ,
839+ "template" ,
840+ "templates" ,
841+ "validate" ,
842+ "schema" ,
843+ }
844+ dependency_bonus = float (
845+ min (3 , len (operation_tokens .intersection (dependency_tokens )))
846+ )
847+
848+ score = round (
849+ (relevance * 10 )
850+ - cost
851+ - (latency / 200 )
852+ + scope_bonus
853+ + dependency_bonus ,
854+ 3 ,
855+ )
740856 ranked .append (
741857 {
742858 ** operation_record ,
743859 "relevance" : relevance ,
744860 "cost" : cost ,
745861 "estimated_latency_ms" : latency ,
862+ "support_scope" : support_scope ,
863+ "scope_bonus" : scope_bonus ,
864+ "dependency_bonus" : dependency_bonus ,
746865 "score" : score ,
747866 }
748867 )
@@ -1406,6 +1525,11 @@ def _invoke_sdk_operation(
14061525def _run_ops_command (args : argparse .Namespace , registry : OperationRegistry ) -> int :
14071526 if args .ops_command == "list" :
14081527 operations = _list_operations (registry , args .public_only , args .tag )
1528+ operations = _apply_curated_manifest_filter (
1529+ operations ,
1530+ public_only = args .public_only ,
1531+ spec_file = args .spec_file ,
1532+ )
14091533 for operation in operations :
14101534 operation_id = getattr (operation , "operation_id" , "" )
14111535 method = getattr (operation , "method" , "" )
@@ -1456,7 +1580,11 @@ def _run_catalog_command(
14561580 args : argparse .Namespace , registry : OperationRegistry
14571581) -> int :
14581582 if args .catalog_command == "export" :
1459- items = _catalog_records (registry , public_only = args .public_only )
1583+ items = _catalog_records (
1584+ registry ,
1585+ public_only = args .public_only ,
1586+ spec_file = args .spec_file ,
1587+ )
14601588 if args .json :
14611589 payload = {
14621590 "schema_version" : CATALOG_EXPORT_SCHEMA_VERSION ,
@@ -1474,12 +1602,22 @@ def _run_catalog_command(
14741602 return 0
14751603
14761604 if args .catalog_command == "rank" :
1477- operations = _catalog_operations (registry , public_only = args .public_only )
1605+ operations = _catalog_operations (
1606+ registry ,
1607+ public_only = args .public_only ,
1608+ spec_file = args .spec_file ,
1609+ )
1610+ manifest_scope = (
1611+ _manifest_scope_by_operation_id ()
1612+ if _should_use_curated_manifest (args .spec_file , args .public_only )
1613+ else None
1614+ )
14781615 ranked = _rank_catalog_operations (
14791616 operations ,
14801617 task = args .task ,
14811618 max_cost = args .max_cost ,
14821619 max_latency_ms = args .max_latency_ms ,
1620+ manifest_scope_by_operation_id = manifest_scope ,
14831621 )
14841622 if args .json :
14851623 payload = {
@@ -2191,11 +2329,21 @@ def _run_code_search_command(
21912329 registry : OperationRegistry ,
21922330 sdk_client : AgenticFlowSDK ,
21932331) -> int :
2332+ manifest_scope = (
2333+ _manifest_scope_by_operation_id ()
2334+ if _should_use_curated_manifest (args .spec_file , args .public_only )
2335+ else None
2336+ )
21942337 ranked = _rank_catalog_operations (
2195- _catalog_operations (registry , public_only = args .public_only ),
2338+ _catalog_operations (
2339+ registry ,
2340+ public_only = args .public_only ,
2341+ spec_file = args .spec_file ,
2342+ ),
21962343 task = args .task ,
21972344 max_cost = args .max_cost ,
21982345 max_latency_ms = args .max_latency_ms ,
2346+ manifest_scope_by_operation_id = manifest_scope ,
21992347 )
22002348
22012349 if args .limit is not None and args .limit > 0 :
0 commit comments