diff --git a/answer_rocket/client.py b/answer_rocket/client.py index 5fcb59a..944c59f 100644 --- a/answer_rocket/client.py +++ b/answer_rocket/client.py @@ -8,6 +8,7 @@ from answer_rocket.output import OutputBuilder from answer_rocket.skill import Skill from answer_rocket.llm import Llm +from answer_rocket.layouts import DynamicLayouts class AnswerRocketClient: @@ -38,6 +39,7 @@ def __init__(self, url: Optional[str] = None, token: Optional[str] = None, tenan self.output = OutputBuilder(self._client_config, self._gql_client) self.skill = Skill(self._client_config, self._gql_client) self.llm = Llm(self._client_config, self._gql_client) + self.dynamic_layouts = DynamicLayouts(self._client_config, self._gql_client) def can_connect(self) -> bool: """ diff --git a/answer_rocket/graphql/operations/layouts.gql b/answer_rocket/graphql/operations/layouts.gql new file mode 100644 index 0000000..61d1306 --- /dev/null +++ b/answer_rocket/graphql/operations/layouts.gql @@ -0,0 +1,10 @@ +query getDynamicLayout($id: UUID!) { + getDynamicLayout(id: $id) { + id + name + layoutJson + inputVariables { + name + } + } +} \ No newline at end of file diff --git a/answer_rocket/graphql/schema.py b/answer_rocket/graphql/schema.py index 33e1cad..397c2f0 100644 --- a/answer_rocket/graphql/schema.py +++ b/answer_rocket/graphql/schema.py @@ -964,6 +964,30 @@ class MaxDomainAttributeStatisticInfo(sgqlc.types.Type): distinct_count = sgqlc.types.Field(Int, graphql_name='distinctCount') +class MaxDynamicLayout(sgqlc.types.Type): + __schema__ = schema + __field_names__ = ('id', 'name', 'layout_json', 'input_variables', 'available_elements', 'available_fields', 'owner_user_id') + id = sgqlc.types.Field(sgqlc.types.non_null(UUID), graphql_name='id') + name = sgqlc.types.Field(String, graphql_name='name') + layout_json = sgqlc.types.Field(String, graphql_name='layoutJson') + input_variables = sgqlc.types.Field(sgqlc.types.list_of(sgqlc.types.non_null('MaxDynamicLayoutInputVariable')), graphql_name='inputVariables') + available_elements = sgqlc.types.Field(sgqlc.types.list_of(sgqlc.types.non_null(String)), graphql_name='availableElements') + available_fields = sgqlc.types.Field(sgqlc.types.list_of(sgqlc.types.non_null(String)), graphql_name='availableFields', args=sgqlc.types.ArgDict(( + ('element_name', sgqlc.types.Arg(String, graphql_name='elementName', default=None)), +)) + ) + owner_user_id = sgqlc.types.Field(UUID, graphql_name='ownerUserId') + + +class MaxDynamicLayoutInputVariable(sgqlc.types.Type): + __schema__ = schema + __field_names__ = ('name', 'is_required', 'default_value', 'targets') + name = sgqlc.types.Field(sgqlc.types.non_null(String), graphql_name='name') + is_required = sgqlc.types.Field(Boolean, graphql_name='isRequired') + default_value = sgqlc.types.Field(JSON, graphql_name='defaultValue') + targets = sgqlc.types.Field(sgqlc.types.list_of(sgqlc.types.non_null('MaxLayoutFieldPointer')), graphql_name='targets') + + class MaxLLmPrompt(sgqlc.types.Type): __schema__ = schema __field_names__ = ('llm_prompt_id', 'name', 'prompt_response') @@ -972,6 +996,13 @@ class MaxLLmPrompt(sgqlc.types.Type): prompt_response = sgqlc.types.Field(JSON, graphql_name='promptResponse') +class MaxLayoutFieldPointer(sgqlc.types.Type): + __schema__ = schema + __field_names__ = ('element_name', 'field_name') + element_name = sgqlc.types.Field(String, graphql_name='elementName') + field_name = sgqlc.types.Field(String, graphql_name='fieldName') + + class MaxMetricHierarchyNode(sgqlc.types.Type): __schema__ = schema __field_names__ = ('metric_hierarchy_node_id', 'metric_id', 'description', 'children') @@ -1504,7 +1535,7 @@ class ParameterDefinition(sgqlc.types.Type): class Query(sgqlc.types.Type): __schema__ = schema - __field_names__ = ('ping', 'current_user', 'get_copilot_skill_artifact_by_path', 'get_copilots', 'get_copilot_info', 'get_copilot_skill', 'run_copilot_skill', 'get_skill_components', 'get_copilot_hydrated_reports', 'get_async_skill_run_status', 'get_max_agent_workflow', 'execute_sql_query', 'execute_rql_query', 'get_databases', 'get_database', 'get_database_tables', 'get_dataset_id', 'get_dataset', 'get_dataset2', 'get_datasets', 'get_domain_object', 'get_domain_object_by_name', 'get_grounded_value', 'get_database_kshots', 'get_database_kshot_by_id', 'get_dataset_kshots', 'get_dataset_kshot_by_id', 'run_max_sql_gen', 'run_sql_ai', 'generate_visualization', 'llmapi_config_for_sdk', 'generate_embeddings', 'get_max_llm_prompt', 'user_chat_threads', 'user_chat_entries', 'chat_thread', 'chat_entry', 'user', 'all_chat_entries', 'skill_memory', 'chat_completion', 'narrative_completion', 'narrative_completion_with_prompt', 'sql_completion', 'research_completion', 'chat_completion_with_prompt', 'research_completion_with_prompt', 'get_chat_artifact', 'get_chat_artifacts') + __field_names__ = ('ping', 'current_user', 'get_copilot_skill_artifact_by_path', 'get_copilots', 'get_copilot_info', 'get_copilot_skill', 'run_copilot_skill', 'get_skill_components', 'get_copilot_hydrated_reports', 'get_async_skill_run_status', 'get_max_agent_workflow', 'execute_sql_query', 'execute_rql_query', 'get_databases', 'get_database', 'get_database_tables', 'get_dataset_id', 'get_dataset', 'get_dataset2', 'get_datasets', 'get_domain_object', 'get_domain_object_by_name', 'get_grounded_value', 'get_database_kshots', 'get_database_kshot_by_id', 'get_dataset_kshots', 'get_dataset_kshot_by_id', 'run_max_sql_gen', 'run_sql_ai', 'generate_visualization', 'llmapi_config_for_sdk', 'generate_embeddings', 'get_max_llm_prompt', 'user_chat_threads', 'user_chat_entries', 'chat_thread', 'chat_entry', 'user', 'all_chat_entries', 'skill_memory', 'chat_completion', 'narrative_completion', 'narrative_completion_with_prompt', 'sql_completion', 'research_completion', 'chat_completion_with_prompt', 'research_completion_with_prompt', 'get_chat_artifact', 'get_chat_artifacts', 'get_dynamic_layout') ping = sgqlc.types.Field(String, graphql_name='ping') current_user = sgqlc.types.Field(MaxUser, graphql_name='currentUser') get_copilot_skill_artifact_by_path = sgqlc.types.Field(CopilotSkillArtifact, graphql_name='getCopilotSkillArtifactByPath', args=sgqlc.types.ArgDict(( @@ -1764,6 +1795,10 @@ class Query(sgqlc.types.Type): ('paging', sgqlc.types.Arg(sgqlc.types.non_null(PagingInput), graphql_name='paging', default=None)), )) ) + get_dynamic_layout = sgqlc.types.Field(MaxDynamicLayout, graphql_name='getDynamicLayout', args=sgqlc.types.ArgDict(( + ('id', sgqlc.types.Arg(sgqlc.types.non_null(UUID), graphql_name='id', default=None)), +)) + ) class RunMaxSqlGenResponse(sgqlc.types.Type): diff --git a/answer_rocket/graphql/sdk_operations.py b/answer_rocket/graphql/sdk_operations.py index 8f7a9af..09177d0 100644 --- a/answer_rocket/graphql/sdk_operations.py +++ b/answer_rocket/graphql/sdk_operations.py @@ -1007,6 +1007,17 @@ def query_get_dataset_kshot_by_id(): return _op +def query_get_dynamic_layout(): + _op = sgqlc.operation.Operation(_schema_root.query_type, name='getDynamicLayout', variables=dict(id=sgqlc.types.Arg(sgqlc.types.non_null(_schema.UUID)))) + _op_get_dynamic_layout = _op.get_dynamic_layout(id=sgqlc.types.Variable('id')) + _op_get_dynamic_layout.id() + _op_get_dynamic_layout.name() + _op_get_dynamic_layout.layout_json() + _op_get_dynamic_layout_input_variables = _op_get_dynamic_layout.input_variables() + _op_get_dynamic_layout_input_variables.name() + return _op + + def query_generate_embeddings(): _op = sgqlc.operation.Operation(_schema_root.query_type, name='GenerateEmbeddings', variables=dict(texts=sgqlc.types.Arg(sgqlc.types.non_null(sgqlc.types.list_of(sgqlc.types.non_null(_schema.String)))), modelOverride=sgqlc.types.Arg(_schema.String))) _op_generate_embeddings = _op.generate_embeddings(texts=sgqlc.types.Variable('texts'), model_override=sgqlc.types.Variable('modelOverride')) @@ -1107,6 +1118,7 @@ class Query: get_dataset_kshot_by_id = query_get_dataset_kshot_by_id() get_dataset_kshots = query_get_dataset_kshots() get_datasets = query_get_datasets() + get_dynamic_layout = query_get_dynamic_layout() get_grounded_value = query_get_grounded_value() get_max_agent_workflow = query_get_max_agent_workflow() get_max_llm_prompt = query_get_max_llm_prompt() diff --git a/answer_rocket/layouts.py b/answer_rocket/layouts.py new file mode 100644 index 0000000..8558909 --- /dev/null +++ b/answer_rocket/layouts.py @@ -0,0 +1,32 @@ +from typing import Optional +from sgqlc.types import Variable, Arg, non_null, String +from answer_rocket.client_config import ClientConfig +from answer_rocket.graphql.client import GraphQlClient +from answer_rocket.graphql.schema import UUID as GQL_UUID + + +class DynamicLayouts: + """ + Helper for accessing config, whether local or fetched from the configured server. + """ + + def __init__(self, config: ClientConfig, gql_client: GraphQlClient) -> None: + self._gql_client = gql_client + self._config = config + self.copilot_id = self._config.copilot_id + self.copilot_skill_id = self._config.copilot_skill_id + + def get_dynamic_layout(self, id: str): + """ + Get a dynamic layout by id. + + id : str + The UUID of the dynamic layout to retrieve. + + """ + op = Operations.query.get_dynamic_layout + self._gql_client.submit(op, { + 'id': id, + }) + + return result.get_dynamic_layout