From 5e5578c0d888571fbcc95cd0d5efc6aa9f3f85c8 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Fri, 17 Apr 2026 16:46:31 -0700 Subject: [PATCH 01/12] test(agents): branch on expected_type in agent tool tests Tests were branching on isinstance(loaded_tool, ...), which is the object under test. A loader regression returning the wrong subtype could silently skip entire assertion blocks and still pass. Branching on the parametrized expected_type keeps the isinstance check as a real assertion. --- .../test_data_classes/test_agents/test_agent_tools.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py index d0215314b6..5c36ee515b 100644 --- a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py +++ b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py @@ -114,6 +114,7 @@ def test_agent_tool_dump_returns_correct_type(self, tool_data: dict, expected_ty dumped_tool = loaded_tool.dump(camel_case=True) if expected_type is UnknownAgentTool: + assert isinstance(loaded_tool, UnknownAgentTool) assert dumped_tool["type"] == unknown_example["type"] else: assert dumped_tool["type"] == expected_type._type @@ -160,6 +161,7 @@ def test_agent_tool_upsert_returns_correct_type(self, tool_data: dict, expected_ dumped_tool = loaded_tool.as_write().dump(camel_case=True) if expected_type is UnknownAgentTool: + assert isinstance(loaded_tool, UnknownAgentTool) assert dumped_tool["type"] == unknown_example["type"] else: assert dumped_tool["type"] == expected_type._type From 2b07993e7a289db26d8506699e07a578664c3992 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Fri, 17 Apr 2026 17:29:43 -0700 Subject: [PATCH 02/12] test(agents): assert loaded_tool type up front in dump and upsert tests Mirrors the pattern already used by test_agent_tool_load_returns_correct_subtype, so a loader regression returning a wrong subtype fails loudly here instead of relying on _type string equality alone. --- .../test_data_classes/test_agents/test_agent_tools.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py index 5c36ee515b..d0215314b6 100644 --- a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py +++ b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py @@ -114,7 +114,6 @@ def test_agent_tool_dump_returns_correct_type(self, tool_data: dict, expected_ty dumped_tool = loaded_tool.dump(camel_case=True) if expected_type is UnknownAgentTool: - assert isinstance(loaded_tool, UnknownAgentTool) assert dumped_tool["type"] == unknown_example["type"] else: assert dumped_tool["type"] == expected_type._type @@ -161,7 +160,6 @@ def test_agent_tool_upsert_returns_correct_type(self, tool_data: dict, expected_ dumped_tool = loaded_tool.as_write().dump(camel_case=True) if expected_type is UnknownAgentTool: - assert isinstance(loaded_tool, UnknownAgentTool) assert dumped_tool["type"] == unknown_example["type"] else: assert dumped_tool["type"] == expected_type._type From a506e4c26ec9afd784ff7cd35c099a23d331e019 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Wed, 15 Apr 2026 22:19:51 -0700 Subject: [PATCH 03/12] feat: add QueryAgentTool for the "query" tool type The cog-ai backend and Fusion frontend already support the "query" tool type, but the Python SDK deserialized it as UnknownAgentTool. This adds first-class support with QueryAgentTool, QueryAgentToolUpsert, and QueryAgentToolConfiguration classes. --- cognite/client/_api/agents/agents.py | 31 ++++++ cognite/client/_sync_api/agents/agents.py | 33 +++++- .../client/data_classes/agents/__init__.py | 6 ++ .../client/data_classes/agents/agent_tools.py | 100 ++++++++++++++++++ .../test_agents/test_agent_tools.py | 76 ++++++++++++- 5 files changed, 244 insertions(+), 2 deletions(-) diff --git a/cognite/client/_api/agents/agents.py b/cognite/client/_api/agents/agents.py index 03869378aa..a0214d9183 100644 --- a/cognite/client/_api/agents/agents.py +++ b/cognite/client/_api/agents/agents.py @@ -79,6 +79,37 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... ) >>> client.agents.upsert(agents=[agent]) + Create an agent with the query tool (Preview): + + >>> from cognite.client.data_classes.agents import ( + ... AgentUpsert, + ... QueryAgentToolUpsert, + ... QueryAgentToolConfiguration, + ... DataModelInfo, + ... InstanceSpaces, + ... ) + >>> query_tool = QueryAgentToolUpsert( + ... name="explore data", + ... description="Run flexible queries against your data model", + ... configuration=QueryAgentToolConfiguration( + ... data_models=[ + ... DataModelInfo( + ... space="cdf_idm", + ... external_id="CogniteProcessIndustries", + ... version="v1", + ... ) + ... ], + ... instance_spaces=InstanceSpaces(type="all"), + ... ), + ... ) + >>> agent = AgentUpsert( + ... external_id="my_agent", + ... name="My Agent", + ... labels=["published"], + ... tools=[query_tool], + ... ) + >>> client.agents.upsert(agents=[agent]) + Create an agent with multiple different tools: >>> from cognite.client.data_classes.agents import ( diff --git a/cognite/client/_sync_api/agents/agents.py b/cognite/client/_sync_api/agents/agents.py index 01824b8959..48fd6c9a99 100644 --- a/cognite/client/_sync_api/agents/agents.py +++ b/cognite/client/_sync_api/agents/agents.py @@ -1,6 +1,6 @@ """ =============================================================================== -063c42ab744021733ccbdc455b150b2c +d88277929dfc151715f521eb7176622b This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ @@ -77,6 +77,37 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... ) >>> client.agents.upsert(agents=[agent]) + Create an agent with the query tool (Preview): + + >>> from cognite.client.data_classes.agents import ( + ... AgentUpsert, + ... QueryAgentToolUpsert, + ... QueryAgentToolConfiguration, + ... DataModelInfo, + ... InstanceSpaces, + ... ) + >>> query_tool = QueryAgentToolUpsert( + ... name="explore data", + ... description="Run flexible queries against your data model", + ... configuration=QueryAgentToolConfiguration( + ... data_models=[ + ... DataModelInfo( + ... space="cdf_idm", + ... external_id="CogniteProcessIndustries", + ... version="v1", + ... ) + ... ], + ... instance_spaces=InstanceSpaces(type="all"), + ... ), + ... ) + >>> agent = AgentUpsert( + ... external_id="my_agent", + ... name="My Agent", + ... labels=["published"], + ... tools=[query_tool], + ... ) + >>> client.agents.upsert(agents=[agent]) + Create an agent with multiple different tools: >>> from cognite.client.data_classes.agents import ( diff --git a/cognite/client/data_classes/agents/__init__.py b/cognite/client/data_classes/agents/__init__.py index f0d39aebc9..9531002d5e 100644 --- a/cognite/client/data_classes/agents/__init__.py +++ b/cognite/client/data_classes/agents/__init__.py @@ -9,6 +9,9 @@ AskDocumentAgentToolUpsert, DataModelInfo, InstanceSpaces, + QueryAgentTool, + QueryAgentToolConfiguration, + QueryAgentToolUpsert, QueryKnowledgeGraphAgentTool, QueryKnowledgeGraphAgentToolConfiguration, QueryKnowledgeGraphAgentToolUpsert, @@ -70,6 +73,9 @@ "Message", "MessageContent", "MessageList", + "QueryAgentTool", + "QueryAgentToolConfiguration", + "QueryAgentToolUpsert", "QueryKnowledgeGraphAgentTool", "QueryKnowledgeGraphAgentToolConfiguration", "QueryKnowledgeGraphAgentToolUpsert", diff --git a/cognite/client/data_classes/agents/agent_tools.py b/cognite/client/data_classes/agents/agent_tools.py index 8957b208cf..a9287563ca 100644 --- a/cognite/client/data_classes/agents/agent_tools.py +++ b/cognite/client/data_classes/agents/agent_tools.py @@ -194,6 +194,43 @@ def as_write(self) -> QueryKnowledgeGraphAgentToolConfiguration: return self +@dataclass +class QueryAgentToolConfiguration(WriteableCogniteResource): + """Configuration for query agent tools. + + Args: + data_models (Sequence[DataModelInfo]): The data models to query. + instance_spaces (InstanceSpaces | None): The instance spaces to query. + """ + + data_models: Sequence[DataModelInfo] + instance_spaces: InstanceSpaces | None = None + + @classmethod + def _load(cls, resource: dict[str, Any]) -> QueryAgentToolConfiguration: + dm_config = resource.get("dataModels", {}) + data_models = [DataModelInfo._load(dm) for dm in dm_config.get("dataModels", [])] + return cls( + data_models=data_models, + instance_spaces=InstanceSpaces._load_if(resource.get("instanceSpaces")), + ) + + def dump(self, camel_case: bool = True) -> dict[str, Any]: + result: dict[str, Any] = {} + key = "dataModels" if camel_case else "data_models" + result[key] = { + "type": "manual", + key: [dm.dump(camel_case=camel_case) for dm in self.data_models], + } + if self.instance_spaces: + key = "instanceSpaces" if camel_case else "instance_spaces" + result[key] = self.instance_spaces.dump(camel_case=camel_case) + return result + + def as_write(self) -> QueryAgentToolConfiguration: + return self + + @dataclass class SummarizeDocumentAgentTool(AgentTool): """Agent tool for summarizing documents. @@ -389,6 +426,69 @@ def _load(cls, resource: dict[str, Any]) -> QueryTimeSeriesDatapointsAgentToolUp ) +@dataclass +class QueryAgentTool(AgentTool): + """Agent tool for running flexible queries against data models. + + Args: + name (str): The name of the agent tool. Used by the agent to decide when to use this tool. + description (str): The description of the agent tool. Used by the agent to decide when to use this tool. + configuration (QueryAgentToolConfiguration | None): The configuration of the query agent tool. + """ + + _type: ClassVar[str] = "query" + configuration: QueryAgentToolConfiguration | None = None + + @classmethod + def _load_tool(cls, resource: dict[str, Any]) -> QueryAgentTool: + return cls( + name=resource["name"], + description=resource["description"], + configuration=QueryAgentToolConfiguration._load_if(resource.get("configuration")), + ) + + def as_write(self) -> QueryAgentToolUpsert: + return QueryAgentToolUpsert( + name=self.name, + description=self.description, + configuration=self.configuration, + ) + + def dump(self, camel_case: bool = True) -> dict[str, Any]: + result = super().dump(camel_case=camel_case) + if self.configuration: + result["configuration"] = self.configuration.dump(camel_case=camel_case) + return result + + +@dataclass +class QueryAgentToolUpsert(AgentToolUpsert): + """Upsert version of query agent tool. + + Args: + name (str): The name of the agent tool. Used by the agent to decide when to use this tool. + description (str): The description of the agent tool. Used by the agent to decide when to use this tool. + configuration (QueryAgentToolConfiguration | None): The configuration of the query agent tool. + """ + + _type: ClassVar[str] = "query" + configuration: QueryAgentToolConfiguration | None = None + + def dump(self, camel_case: bool = True) -> dict[str, Any]: + result = super().dump(camel_case=camel_case) + if self.configuration: + result["configuration"] = self.configuration.dump(camel_case=camel_case) + return result + + @classmethod + def _load(cls, resource: dict[str, Any]) -> QueryAgentToolUpsert: + return cls( + name=resource["name"], + description=resource["description"], + configuration=QueryAgentToolConfiguration._load_if(resource.get("configuration")), + ) + + @dataclass class UnknownAgentTool(AgentTool): """Agent tool for unknown/unrecognized tool types. diff --git a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py index d0215314b6..8dd0f6a200 100644 --- a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py +++ b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py @@ -5,6 +5,8 @@ from cognite.client.data_classes.agents.agent_tools import ( AgentTool, AskDocumentAgentTool, + QueryAgentTool, + QueryAgentToolConfiguration, QueryKnowledgeGraphAgentTool, QueryKnowledgeGraphAgentToolConfiguration, QueryTimeSeriesDatapointsAgentTool, @@ -42,6 +44,32 @@ "description": "Query the time series datapoints", } +query_example = { + "name": "queryExample", + "type": "query", + "description": "Run flexible queries against your data model", + "configuration": { + "dataModels": { + "type": "manual", + "dataModels": [ + { + "space": "cdf_idm", + "externalId": "CogniteProcessIndustries", + "version": "v1", + "viewExternalIds": ["CogniteAsset"], + } + ], + }, + "instanceSpaces": {"type": "manual", "spaces": ["my_space"]}, + }, +} + +query_no_config_example = { + "name": "queryNoConfigExample", + "type": "query", + "description": "Run flexible queries against your data model", +} + unknown_example = { "name": "unknownExample", "type": "yolo", # This is not a known tool type @@ -58,9 +86,19 @@ class TestAgentToolLoad: (ask_document_example, AskDocumentAgentTool), (summarize_document_example, SummarizeDocumentAgentTool), (query_time_series_datapoints_example, QueryTimeSeriesDatapointsAgentTool), + (query_example, QueryAgentTool), + (query_no_config_example, QueryAgentTool), (unknown_example, UnknownAgentTool), ], - ids=["queryKnowledgeGraph", "askDocument", "summarizeDocument", "queryTimeSeriesDatapoints", "somethingElse"], + ids=[ + "queryKnowledgeGraph", + "askDocument", + "summarizeDocument", + "queryTimeSeriesDatapoints", + "query", + "queryNoConfig", + "somethingElse", + ], ) def test_agent_tool_load_returns_correct_subtype(self, tool_data: dict, expected_type: type[AgentTool]) -> None: """Test that AgentTool._load() returns the correct subtype based on the tool type.""" @@ -81,6 +119,10 @@ def test_agent_tool_load_returns_correct_subtype(self, tool_data: dict, expected assert isinstance(loaded_tool, QueryKnowledgeGraphAgentTool) assert isinstance(loaded_tool.configuration, QueryKnowledgeGraphAgentToolConfiguration) assert loaded_tool.configuration.dump(camel_case=True) == tool_data["configuration"] + elif expected_type is QueryAgentTool: + assert isinstance(loaded_tool, QueryAgentTool) + assert isinstance(loaded_tool.configuration, QueryAgentToolConfiguration) + assert loaded_tool.configuration.dump(camel_case=True) == tool_data["configuration"] elif expected_type is UnknownAgentTool: assert isinstance(loaded_tool, UnknownAgentTool) assert loaded_tool.configuration == tool_data["configuration"] @@ -104,6 +146,7 @@ class TestAgentToolDump: (ask_document_example, AskDocumentAgentTool), (summarize_document_example, SummarizeDocumentAgentTool), (query_time_series_datapoints_example, QueryTimeSeriesDatapointsAgentTool), + (query_example, QueryAgentTool), (unknown_example, UnknownAgentTool), ], ) @@ -150,6 +193,7 @@ class TestAgentToolUpsert: (ask_document_example, AskDocumentAgentTool), (summarize_document_example, SummarizeDocumentAgentTool), (query_time_series_datapoints_example, QueryTimeSeriesDatapointsAgentTool), + (query_example, QueryAgentTool), (unknown_example, UnknownAgentTool), ], ) @@ -166,3 +210,33 @@ def test_agent_tool_upsert_returns_correct_type(self, tool_data: dict, expected_ assert dumped_tool["name"] == tool_data["name"] assert dumped_tool["description"] == tool_data["description"] + + +class TestQueryAgentTool: + def test_load_with_configuration(self) -> None: + loaded = AgentTool._load(query_example) + assert isinstance(loaded, QueryAgentTool) + assert loaded.configuration is not None + assert isinstance(loaded.configuration, QueryAgentToolConfiguration) + assert len(loaded.configuration.data_models) == 1 + assert loaded.configuration.data_models[0].space == "cdf_idm" + assert loaded.configuration.data_models[0].external_id == "CogniteProcessIndustries" + assert loaded.configuration.instance_spaces is not None + assert loaded.configuration.instance_spaces.type == "manual" + assert loaded.configuration.instance_spaces.spaces == ["my_space"] + + def test_load_without_configuration(self) -> None: + loaded = AgentTool._load(query_no_config_example) + assert isinstance(loaded, QueryAgentTool) + assert loaded.configuration is None + + def test_round_trip(self) -> None: + loaded = AgentTool._load(query_example) + dumped = loaded.dump(camel_case=True) + assert dumped == query_example + + def test_as_write_round_trip(self) -> None: + loaded = AgentTool._load(query_example) + write = loaded.as_write() + dumped = write.dump(camel_case=True) + assert dumped == query_example From 838c777813e2eb7334e6e7a032ab31f8fbcce317 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Wed, 15 Apr 2026 23:17:06 -0700 Subject: [PATCH 04/12] fix: defensive null handling in QueryAgentToolConfiguration._load --- cognite/client/data_classes/agents/agent_tools.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cognite/client/data_classes/agents/agent_tools.py b/cognite/client/data_classes/agents/agent_tools.py index a9287563ca..40071e3384 100644 --- a/cognite/client/data_classes/agents/agent_tools.py +++ b/cognite/client/data_classes/agents/agent_tools.py @@ -208,8 +208,9 @@ class QueryAgentToolConfiguration(WriteableCogniteResource): @classmethod def _load(cls, resource: dict[str, Any]) -> QueryAgentToolConfiguration: - dm_config = resource.get("dataModels", {}) - data_models = [DataModelInfo._load(dm) for dm in dm_config.get("dataModels", [])] + # API always returns dataModels, but guard against null defensively: + dm_config = resource.get("dataModels") or {} + data_models = [DataModelInfo._load(dm) for dm in (dm_config.get("dataModels") or [])] return cls( data_models=data_models, instance_spaces=InstanceSpaces._load_if(resource.get("instanceSpaces")), From d6c57a9233ba9be6c165874a9a0a5a8d983cded4 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Thu, 16 Apr 2026 00:10:22 -0700 Subject: [PATCH 05/12] fix: address PR feedback on query agent tool Remove maturity label from docstring examples and surface missing dataModels key instead of silently defaulting to empty dict. --- cognite/client/_api/agents/agents.py | 2 +- cognite/client/_sync_api/agents/agents.py | 4 ++-- cognite/client/data_classes/agents/agent_tools.py | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cognite/client/_api/agents/agents.py b/cognite/client/_api/agents/agents.py index a0214d9183..a842fe8341 100644 --- a/cognite/client/_api/agents/agents.py +++ b/cognite/client/_api/agents/agents.py @@ -79,7 +79,7 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... ) >>> client.agents.upsert(agents=[agent]) - Create an agent with the query tool (Preview): + Create an agent with the query tool: >>> from cognite.client.data_classes.agents import ( ... AgentUpsert, diff --git a/cognite/client/_sync_api/agents/agents.py b/cognite/client/_sync_api/agents/agents.py index 48fd6c9a99..f7bfc2a130 100644 --- a/cognite/client/_sync_api/agents/agents.py +++ b/cognite/client/_sync_api/agents/agents.py @@ -1,6 +1,6 @@ """ =============================================================================== -d88277929dfc151715f521eb7176622b +990185c07f95962938122269ec34ae29 This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ @@ -77,7 +77,7 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... ) >>> client.agents.upsert(agents=[agent]) - Create an agent with the query tool (Preview): + Create an agent with the query tool: >>> from cognite.client.data_classes.agents import ( ... AgentUpsert, diff --git a/cognite/client/data_classes/agents/agent_tools.py b/cognite/client/data_classes/agents/agent_tools.py index 40071e3384..e8722b258b 100644 --- a/cognite/client/data_classes/agents/agent_tools.py +++ b/cognite/client/data_classes/agents/agent_tools.py @@ -208,9 +208,8 @@ class QueryAgentToolConfiguration(WriteableCogniteResource): @classmethod def _load(cls, resource: dict[str, Any]) -> QueryAgentToolConfiguration: - # API always returns dataModels, but guard against null defensively: - dm_config = resource.get("dataModels") or {} - data_models = [DataModelInfo._load(dm) for dm in (dm_config.get("dataModels") or [])] + dm_config = resource["dataModels"] + data_models = [DataModelInfo._load(dm) for dm in dm_config.get("dataModels", [])] return cls( data_models=data_models, instance_spaces=InstanceSpaces._load_if(resource.get("instanceSpaces")), From 96d70a79937fd448c872172811fda14093ce1fde Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Thu, 16 Apr 2026 00:13:36 -0700 Subject: [PATCH 06/12] fix(tests): remove redundant round-trip tests for QueryAgentTool Covered automatically by tests/tests_unit/test_base.py. --- .../test_data_classes/test_agents/test_agent_tools.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py index 8dd0f6a200..b8237b49d4 100644 --- a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py +++ b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py @@ -229,14 +229,3 @@ def test_load_without_configuration(self) -> None: loaded = AgentTool._load(query_no_config_example) assert isinstance(loaded, QueryAgentTool) assert loaded.configuration is None - - def test_round_trip(self) -> None: - loaded = AgentTool._load(query_example) - dumped = loaded.dump(camel_case=True) - assert dumped == query_example - - def test_as_write_round_trip(self) -> None: - loaded = AgentTool._load(query_example) - write = loaded.as_write() - dumped = write.dump(camel_case=True) - assert dumped == query_example From 349550bb9775f3979baf8d6623d38864787b3f15 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Thu, 16 Apr 2026 00:26:41 -0700 Subject: [PATCH 07/12] fix(tests): remove redundant test_load_with_configuration Covered by automatic load/dump tests in test_base.py. Keep only test_load_without_configuration for the None config edge case. --- .../test_agents/test_agent_tools.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py index b8237b49d4..358fd4cc5b 100644 --- a/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py +++ b/tests/tests_unit/test_data_classes/test_agents/test_agent_tools.py @@ -213,18 +213,6 @@ def test_agent_tool_upsert_returns_correct_type(self, tool_data: dict, expected_ class TestQueryAgentTool: - def test_load_with_configuration(self) -> None: - loaded = AgentTool._load(query_example) - assert isinstance(loaded, QueryAgentTool) - assert loaded.configuration is not None - assert isinstance(loaded.configuration, QueryAgentToolConfiguration) - assert len(loaded.configuration.data_models) == 1 - assert loaded.configuration.data_models[0].space == "cdf_idm" - assert loaded.configuration.data_models[0].external_id == "CogniteProcessIndustries" - assert loaded.configuration.instance_spaces is not None - assert loaded.configuration.instance_spaces.type == "manual" - assert loaded.configuration.instance_spaces.spaces == ["my_space"] - def test_load_without_configuration(self) -> None: loaded = AgentTool._load(query_no_config_example) assert isinstance(loaded, QueryAgentTool) From 0780663a6e2d993156429e4f8ed4b06596108b5b Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Fri, 17 Apr 2026 17:46:27 -0700 Subject: [PATCH 08/12] chore(codegen): refresh sync_api hash after rebase Local codegen run during the rebase produced a stale hash; regenerated to match CI. --- cognite/client/_sync_api/agents/agents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cognite/client/_sync_api/agents/agents.py b/cognite/client/_sync_api/agents/agents.py index f7bfc2a130..4675e12ec9 100644 --- a/cognite/client/_sync_api/agents/agents.py +++ b/cognite/client/_sync_api/agents/agents.py @@ -1,6 +1,6 @@ """ =============================================================================== -990185c07f95962938122269ec34ae29 +83ebe251b32d1a7ce1ba064499beebf5 This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ From 375a55f74220bab308b322df6a1521d9876557b3 Mon Sep 17 00:00:00 2001 From: Kelvin Sundli Date: Mon, 20 Apr 2026 23:00:20 -0700 Subject: [PATCH 09/12] docs(agents): pin runtime_version in QueryAgentTool example The current default runtime does not support the Query tool, so the example would fail as written. Pin to 1.1.3-preview until the Query tool lands in the default runtime. --- cognite/client/_api/agents/agents.py | 1 + cognite/client/_sync_api/agents/agents.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cognite/client/_api/agents/agents.py b/cognite/client/_api/agents/agents.py index a842fe8341..d90564522c 100644 --- a/cognite/client/_api/agents/agents.py +++ b/cognite/client/_api/agents/agents.py @@ -106,6 +106,7 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... external_id="my_agent", ... name="My Agent", ... labels=["published"], + ... runtime_version="1.1.3-preview", ... tools=[query_tool], ... ) >>> client.agents.upsert(agents=[agent]) diff --git a/cognite/client/_sync_api/agents/agents.py b/cognite/client/_sync_api/agents/agents.py index 4675e12ec9..d133cde3be 100644 --- a/cognite/client/_sync_api/agents/agents.py +++ b/cognite/client/_sync_api/agents/agents.py @@ -1,6 +1,6 @@ """ =============================================================================== -83ebe251b32d1a7ce1ba064499beebf5 +57cfb4e7d78e02413a52b09b2c269427 This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ @@ -104,6 +104,7 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... external_id="my_agent", ... name="My Agent", ... labels=["published"], + ... runtime_version="1.1.3-preview", ... tools=[query_tool], ... ) >>> client.agents.upsert(agents=[agent]) From fb96946791f372a6c4aa5a7550fc36a197cb5f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20V=2E=20Treider?= Date: Tue, 21 Apr 2026 22:34:55 +0200 Subject: [PATCH 10/12] fix wrong runtime_version in example --- cognite/client/_api/agents/agents.py | 2 +- cognite/client/_sync_api/agents/agents.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cognite/client/_api/agents/agents.py b/cognite/client/_api/agents/agents.py index d90564522c..88fd732858 100644 --- a/cognite/client/_api/agents/agents.py +++ b/cognite/client/_api/agents/agents.py @@ -106,7 +106,7 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... external_id="my_agent", ... name="My Agent", ... labels=["published"], - ... runtime_version="1.1.3-preview", + ... runtime_version="1.1.2-preview", ... tools=[query_tool], ... ) >>> client.agents.upsert(agents=[agent]) diff --git a/cognite/client/_sync_api/agents/agents.py b/cognite/client/_sync_api/agents/agents.py index d133cde3be..3cf62db3c7 100644 --- a/cognite/client/_sync_api/agents/agents.py +++ b/cognite/client/_sync_api/agents/agents.py @@ -1,6 +1,6 @@ """ =============================================================================== -57cfb4e7d78e02413a52b09b2c269427 +37b63c7d3241f9eda9fbe5a76220e6c9 This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ @@ -104,7 +104,7 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... external_id="my_agent", ... name="My Agent", ... labels=["published"], - ... runtime_version="1.1.3-preview", + ... runtime_version="1.1.2-preview", ... tools=[query_tool], ... ) >>> client.agents.upsert(agents=[agent]) From ce493abd84751a4fae597490026e0ecbb034d9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20V=2E=20Treider?= Date: Tue, 21 Apr 2026 22:37:22 +0200 Subject: [PATCH 11/12] simplify code example for agents.upsert --- cognite/client/_api/agents/agents.py | 6 +++--- cognite/client/_sync_api/agents/agents.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cognite/client/_api/agents/agents.py b/cognite/client/_api/agents/agents.py index 88fd732858..5884cd8974 100644 --- a/cognite/client/_api/agents/agents.py +++ b/cognite/client/_api/agents/agents.py @@ -77,7 +77,7 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... labels=["published"], ... tools=[find_assets_tool], ... ) - >>> client.agents.upsert(agents=[agent]) + >>> client.agents.upsert(agent) Create an agent with the query tool: @@ -109,7 +109,7 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... runtime_version="1.1.2-preview", ... tools=[query_tool], ... ) - >>> client.agents.upsert(agents=[agent]) + >>> client.agents.upsert(agent) Create an agent with multiple different tools: @@ -191,7 +191,7 @@ async def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | A ... ts_tool, ... ], ... ) - >>> client.agents.upsert(agents=[agent]) + >>> client.agents.upsert(agent) """ diff --git a/cognite/client/_sync_api/agents/agents.py b/cognite/client/_sync_api/agents/agents.py index 3cf62db3c7..b68bc08754 100644 --- a/cognite/client/_sync_api/agents/agents.py +++ b/cognite/client/_sync_api/agents/agents.py @@ -1,6 +1,6 @@ """ =============================================================================== -37b63c7d3241f9eda9fbe5a76220e6c9 +178ce7222985b04d03174af7b7e0f525 This file is auto-generated from the Async API modules, - do not edit manually! =============================================================================== """ @@ -75,7 +75,7 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... labels=["published"], ... tools=[find_assets_tool], ... ) - >>> client.agents.upsert(agents=[agent]) + >>> client.agents.upsert(agent) Create an agent with the query tool: @@ -107,7 +107,7 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... runtime_version="1.1.2-preview", ... tools=[query_tool], ... ) - >>> client.agents.upsert(agents=[agent]) + >>> client.agents.upsert(agent) Create an agent with multiple different tools: @@ -189,7 +189,7 @@ def upsert(self, agents: AgentUpsert | Sequence[AgentUpsert]) -> Agent | AgentLi ... ts_tool, ... ], ... ) - >>> client.agents.upsert(agents=[agent]) + >>> client.agents.upsert(agent) """ return run_sync(self.__async_client.agents.upsert(agents=agents)) From 11cb8b0297ba482a037cacde66dd9f44dd7b0b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20V=2E=20Treider?= Date: Tue, 21 Apr 2026 22:54:28 +0200 Subject: [PATCH 12/12] add a todo --- cognite/client/data_classes/agents/agent_tools.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cognite/client/data_classes/agents/agent_tools.py b/cognite/client/data_classes/agents/agent_tools.py index e8722b258b..8d01531034 100644 --- a/cognite/client/data_classes/agents/agent_tools.py +++ b/cognite/client/data_classes/agents/agent_tools.py @@ -219,6 +219,8 @@ def dump(self, camel_case: bool = True) -> dict[str, Any]: result: dict[str, Any] = {} key = "dataModels" if camel_case else "data_models" result[key] = { + # TODO(ks93): Clarify whether "type" can take other values (cf. InstanceSpaces.type); + # if so, make it a real field "type": "manual", key: [dm.dump(camel_case=camel_case) for dm in self.data_models], }