feat: add detail parameter to list/get mental models (#846)
* feat: add detail parameter to list/get mental models (#825) Add a `detail` query parameter (metadata|content|full) to both list and get mental model endpoints (HTTP + MCP) to control response size. This reduces payload for agent boot flows and MCP clients where context budget is limited. Closes #825 * fix: update Rust CLI for optional mental model fields The generated Rust client now has content/source_query as Option<String> after the detail parameter was added. Update CLI code to handle optionals.
This commit is contained in:
parent
7d6c570a3a
commit
8d1bfbbd2b
14 changed files with 594 additions and 154 deletions
|
|
@ -1534,13 +1534,14 @@ class MentalModelResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
bank_id: str
|
bank_id: str
|
||||||
name: str
|
name: str
|
||||||
source_query: str
|
source_query: str | None = None
|
||||||
content: str = Field(
|
content: str | None = Field(
|
||||||
description="The mental model content as well-formatted markdown (auto-generated from reflect endpoint)"
|
default=None,
|
||||||
|
description="The mental model content as well-formatted markdown (auto-generated from reflect endpoint)",
|
||||||
)
|
)
|
||||||
tags: list[str] = FieldWithDefault(list)
|
tags: list[str] = FieldWithDefault(list)
|
||||||
max_tokens: int = Field(default=2048)
|
max_tokens: int | None = Field(default=None)
|
||||||
trigger: MentalModelTrigger = FieldWithDefault(MentalModelTrigger)
|
trigger: MentalModelTrigger | None = Field(default=None)
|
||||||
last_refreshed_at: str | None = None
|
last_refreshed_at: str | None = None
|
||||||
created_at: str | None = None
|
created_at: str | None = None
|
||||||
reflect_response: dict | None = Field(
|
reflect_response: dict | None = Field(
|
||||||
|
|
@ -3041,6 +3042,10 @@ def _register_routes(app: FastAPI):
|
||||||
bank_id: str,
|
bank_id: str,
|
||||||
tags_filter: list[str] | None = Query(None, alias="tags", description="Filter by tags"),
|
tags_filter: list[str] | None = Query(None, alias="tags", description="Filter by tags"),
|
||||||
tags_match: Literal["any", "all", "exact"] = Query("any", description="How to match tags"),
|
tags_match: Literal["any", "all", "exact"] = Query("any", description="How to match tags"),
|
||||||
|
detail: Literal["metadata", "content", "full"] = Query(
|
||||||
|
"full",
|
||||||
|
description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)",
|
||||||
|
),
|
||||||
limit: int = Query(100, ge=1, le=1000),
|
limit: int = Query(100, ge=1, le=1000),
|
||||||
offset: int = Query(0, ge=0),
|
offset: int = Query(0, ge=0),
|
||||||
request_context: RequestContext = Depends(get_request_context),
|
request_context: RequestContext = Depends(get_request_context),
|
||||||
|
|
@ -3051,6 +3056,7 @@ def _register_routes(app: FastAPI):
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
tags=tags_filter,
|
tags=tags_filter,
|
||||||
tags_match=tags_match,
|
tags_match=tags_match,
|
||||||
|
detail=detail,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
request_context=request_context,
|
request_context=request_context,
|
||||||
|
|
@ -3078,6 +3084,10 @@ def _register_routes(app: FastAPI):
|
||||||
async def api_get_mental_model(
|
async def api_get_mental_model(
|
||||||
bank_id: str,
|
bank_id: str,
|
||||||
mental_model_id: str,
|
mental_model_id: str,
|
||||||
|
detail: Literal["metadata", "content", "full"] = Query(
|
||||||
|
"full",
|
||||||
|
description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)",
|
||||||
|
),
|
||||||
request_context: RequestContext = Depends(get_request_context),
|
request_context: RequestContext = Depends(get_request_context),
|
||||||
):
|
):
|
||||||
"""Get a mental model by ID."""
|
"""Get a mental model by ID."""
|
||||||
|
|
@ -3085,6 +3095,7 @@ def _register_routes(app: FastAPI):
|
||||||
mental_model = await app.state.memory.get_mental_model(
|
mental_model = await app.state.memory.get_mental_model(
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
mental_model_id=mental_model_id,
|
mental_model_id=mental_model_id,
|
||||||
|
detail=detail,
|
||||||
request_context=request_context,
|
request_context=request_context,
|
||||||
)
|
)
|
||||||
if mental_model is None:
|
if mental_model is None:
|
||||||
|
|
|
||||||
|
|
@ -6351,6 +6351,7 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
*,
|
*,
|
||||||
tags: list[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
tags_match: str = "any",
|
tags_match: str = "any",
|
||||||
|
detail: str = "full",
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
offset: int = 0,
|
offset: int = 0,
|
||||||
request_context: "RequestContext",
|
request_context: "RequestContext",
|
||||||
|
|
@ -6361,6 +6362,7 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
bank_id: Bank identifier
|
bank_id: Bank identifier
|
||||||
tags: Optional tags to filter by
|
tags: Optional tags to filter by
|
||||||
tags_match: How to match tags - 'any', 'all', or 'exact'
|
tags_match: How to match tags - 'any', 'all', or 'exact'
|
||||||
|
detail: Detail level - 'metadata', 'content', or 'full'
|
||||||
limit: Maximum number of results
|
limit: Maximum number of results
|
||||||
offset: Offset for pagination
|
offset: Offset for pagination
|
||||||
request_context: Request context for authentication
|
request_context: Request context for authentication
|
||||||
|
|
@ -6402,13 +6404,14 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
*params,
|
*params,
|
||||||
)
|
)
|
||||||
|
|
||||||
return [self._row_to_mental_model(row) for row in rows]
|
return [self._row_to_mental_model(row, detail=detail) for row in rows]
|
||||||
|
|
||||||
async def get_mental_model(
|
async def get_mental_model(
|
||||||
self,
|
self,
|
||||||
bank_id: str,
|
bank_id: str,
|
||||||
mental_model_id: str,
|
mental_model_id: str,
|
||||||
*,
|
*,
|
||||||
|
detail: str = "full",
|
||||||
request_context: "RequestContext",
|
request_context: "RequestContext",
|
||||||
) -> dict[str, Any] | None:
|
) -> dict[str, Any] | None:
|
||||||
"""Get a single pinned mental model by ID.
|
"""Get a single pinned mental model by ID.
|
||||||
|
|
@ -6416,6 +6419,7 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
Args:
|
Args:
|
||||||
bank_id: Bank identifier
|
bank_id: Bank identifier
|
||||||
mental_model_id: Pinned mental model UUID
|
mental_model_id: Pinned mental model UUID
|
||||||
|
detail: Detail level - 'metadata', 'content', or 'full'
|
||||||
request_context: Request context for authentication
|
request_context: Request context for authentication
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
@ -6449,7 +6453,7 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
mental_model_id,
|
mental_model_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = self._row_to_mental_model(row) if row else None
|
result = self._row_to_mental_model(row, detail=detail) if row else None
|
||||||
|
|
||||||
# Post-operation hook (usage recording)
|
# Post-operation hook (usage recording)
|
||||||
if result and self._operation_validator:
|
if result and self._operation_validator:
|
||||||
|
|
@ -6847,34 +6851,47 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
|
|
||||||
return result == "DELETE 1"
|
return result == "DELETE 1"
|
||||||
|
|
||||||
def _row_to_mental_model(self, row) -> dict[str, Any]:
|
_MENTAL_MODEL_METADATA_FIELDS = frozenset({"id", "bank_id", "name", "tags", "last_refreshed_at", "created_at"})
|
||||||
"""Convert a database row to a mental model dict."""
|
|
||||||
reflect_response = row.get("reflect_response")
|
def _row_to_mental_model(self, row, *, detail: str = "full") -> dict[str, Any]:
|
||||||
# Parse JSON string to dict if needed (asyncpg may return JSONB as string)
|
"""Convert a database row to a mental model dict.
|
||||||
if isinstance(reflect_response, str):
|
|
||||||
try:
|
Args:
|
||||||
reflect_response = json.loads(reflect_response)
|
row: Database row
|
||||||
except json.JSONDecodeError:
|
detail: Detail level - 'metadata', 'content', or 'full'
|
||||||
reflect_response = None
|
"""
|
||||||
|
result: dict[str, Any] = {
|
||||||
|
"id": str(row["id"]),
|
||||||
|
"bank_id": row["bank_id"],
|
||||||
|
"name": row["name"],
|
||||||
|
"tags": row["tags"] or [],
|
||||||
|
"last_refreshed_at": row["last_refreshed_at"].isoformat() if row["last_refreshed_at"] else None,
|
||||||
|
"created_at": row["created_at"].isoformat() if row["created_at"] else None,
|
||||||
|
}
|
||||||
|
if detail == "metadata":
|
||||||
|
return result
|
||||||
|
|
||||||
trigger = row.get("trigger")
|
trigger = row.get("trigger")
|
||||||
if isinstance(trigger, str):
|
if isinstance(trigger, str):
|
||||||
try:
|
try:
|
||||||
trigger = json.loads(trigger)
|
trigger = json.loads(trigger)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
trigger = None
|
trigger = None
|
||||||
return {
|
result["source_query"] = row["source_query"]
|
||||||
"id": str(row["id"]),
|
result["content"] = row["content"]
|
||||||
"bank_id": row["bank_id"],
|
result["max_tokens"] = row.get("max_tokens")
|
||||||
"name": row["name"],
|
result["trigger"] = trigger
|
||||||
"source_query": row["source_query"],
|
|
||||||
"content": row["content"],
|
if detail == "full":
|
||||||
"tags": row["tags"] or [],
|
reflect_response = row.get("reflect_response")
|
||||||
"max_tokens": row.get("max_tokens"),
|
if isinstance(reflect_response, str):
|
||||||
"trigger": trigger,
|
try:
|
||||||
"last_refreshed_at": row["last_refreshed_at"].isoformat() if row["last_refreshed_at"] else None,
|
reflect_response = json.loads(reflect_response)
|
||||||
"created_at": row["created_at"].isoformat() if row["created_at"] else None,
|
except json.JSONDecodeError:
|
||||||
"reflect_response": reflect_response,
|
reflect_response = None
|
||||||
}
|
result["reflect_response"] = reflect_response
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# Directives - Hard rules injected into prompts
|
# Directives - Hard rules injected into prompts
|
||||||
|
|
|
||||||
|
|
@ -1002,6 +1002,7 @@ def _register_list_mental_models(mcp: FastMCP, memory: MemoryEngine, config: MCP
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
async def list_mental_models(
|
async def list_mental_models(
|
||||||
tags: list[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
|
detail: str = "full",
|
||||||
bank_id: str | None = None,
|
bank_id: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
@ -1013,6 +1014,7 @@ def _register_list_mental_models(mcp: FastMCP, memory: MemoryEngine, config: MCP
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tags: Optional tags to filter by (returns models matching any tag)
|
tags: Optional tags to filter by (returns models matching any tag)
|
||||||
|
detail: Detail level - 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response). Default: 'full'
|
||||||
bank_id: Optional bank to list from (defaults to session bank). Use for cross-bank operations.
|
bank_id: Optional bank to list from (defaults to session bank). Use for cross-bank operations.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -1023,6 +1025,7 @@ def _register_list_mental_models(mcp: FastMCP, memory: MemoryEngine, config: MCP
|
||||||
models = await memory.list_mental_models(
|
models = await memory.list_mental_models(
|
||||||
bank_id=target_bank,
|
bank_id=target_bank,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
|
detail=detail,
|
||||||
request_context=_get_request_context(config),
|
request_context=_get_request_context(config),
|
||||||
)
|
)
|
||||||
return json.dumps({"items": models}, indent=2, default=str)
|
return json.dumps({"items": models}, indent=2, default=str)
|
||||||
|
|
@ -1038,6 +1041,7 @@ def _register_list_mental_models(mcp: FastMCP, memory: MemoryEngine, config: MCP
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
async def list_mental_models(
|
async def list_mental_models(
|
||||||
tags: list[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
|
detail: str = "full",
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
List mental models (pinned reflections) for this memory bank.
|
List mental models (pinned reflections) for this memory bank.
|
||||||
|
|
@ -1048,6 +1052,7 @@ def _register_list_mental_models(mcp: FastMCP, memory: MemoryEngine, config: MCP
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tags: Optional tags to filter by (returns models matching any tag)
|
tags: Optional tags to filter by (returns models matching any tag)
|
||||||
|
detail: Detail level - 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response). Default: 'full'
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
target_bank = config.bank_id_resolver()
|
target_bank = config.bank_id_resolver()
|
||||||
|
|
@ -1057,6 +1062,7 @@ def _register_list_mental_models(mcp: FastMCP, memory: MemoryEngine, config: MCP
|
||||||
models = await memory.list_mental_models(
|
models = await memory.list_mental_models(
|
||||||
bank_id=target_bank,
|
bank_id=target_bank,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
|
detail=detail,
|
||||||
request_context=_get_request_context(config),
|
request_context=_get_request_context(config),
|
||||||
)
|
)
|
||||||
return {"items": models}
|
return {"items": models}
|
||||||
|
|
@ -1076,16 +1082,18 @@ def _register_get_mental_model(mcp: FastMCP, memory: MemoryEngine, config: MCPTo
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
async def get_mental_model(
|
async def get_mental_model(
|
||||||
mental_model_id: str,
|
mental_model_id: str,
|
||||||
|
detail: str = "full",
|
||||||
bank_id: str | None = None,
|
bank_id: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Get a specific mental model by ID.
|
Get a specific mental model by ID.
|
||||||
|
|
||||||
Returns the full mental model including its generated content, source query,
|
Returns the mental model with the requested detail level. Use list_mental_models
|
||||||
and metadata. Use list_mental_models first to discover available model IDs.
|
first to discover available model IDs.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
mental_model_id: The ID of the mental model to retrieve
|
mental_model_id: The ID of the mental model to retrieve
|
||||||
|
detail: Detail level - 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response). Default: 'full'
|
||||||
bank_id: Optional bank (defaults to session bank). Use for cross-bank operations.
|
bank_id: Optional bank (defaults to session bank). Use for cross-bank operations.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -1096,6 +1104,7 @@ def _register_get_mental_model(mcp: FastMCP, memory: MemoryEngine, config: MCPTo
|
||||||
model = await memory.get_mental_model(
|
model = await memory.get_mental_model(
|
||||||
bank_id=target_bank,
|
bank_id=target_bank,
|
||||||
mental_model_id=mental_model_id,
|
mental_model_id=mental_model_id,
|
||||||
|
detail=detail,
|
||||||
request_context=_get_request_context(config),
|
request_context=_get_request_context(config),
|
||||||
)
|
)
|
||||||
if model is None:
|
if model is None:
|
||||||
|
|
@ -1113,15 +1122,17 @@ def _register_get_mental_model(mcp: FastMCP, memory: MemoryEngine, config: MCPTo
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
async def get_mental_model(
|
async def get_mental_model(
|
||||||
mental_model_id: str,
|
mental_model_id: str,
|
||||||
|
detail: str = "full",
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Get a specific mental model by ID.
|
Get a specific mental model by ID.
|
||||||
|
|
||||||
Returns the full mental model including its generated content, source query,
|
Returns the mental model with the requested detail level. Use list_mental_models
|
||||||
and metadata. Use list_mental_models first to discover available model IDs.
|
first to discover available model IDs.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
mental_model_id: The ID of the mental model to retrieve
|
mental_model_id: The ID of the mental model to retrieve
|
||||||
|
detail: Detail level - 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response). Default: 'full'
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
target_bank = config.bank_id_resolver()
|
target_bank = config.bank_id_resolver()
|
||||||
|
|
@ -1131,6 +1142,7 @@ def _register_get_mental_model(mcp: FastMCP, memory: MemoryEngine, config: MCPTo
|
||||||
model = await memory.get_mental_model(
|
model = await memory.get_mental_model(
|
||||||
bank_id=target_bank,
|
bank_id=target_bank,
|
||||||
mental_model_id=mental_model_id,
|
mental_model_id=mental_model_id,
|
||||||
|
detail=detail,
|
||||||
request_context=_get_request_context(config),
|
request_context=_get_request_context(config),
|
||||||
)
|
)
|
||||||
if model is None:
|
if model is None:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"""Tests for the shared MCP tools module."""
|
"""Tests for the shared MCP tools module."""
|
||||||
|
|
||||||
|
import json
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from unittest.mock import AsyncMock, MagicMock
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
||||||
|
|
@ -75,25 +76,63 @@ class TestBuildContentDict:
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
_MENTAL_MODEL_METADATA_FIELDS = frozenset({"id", "bank_id", "name", "tags", "last_refreshed_at", "created_at"})
|
||||||
|
|
||||||
|
_FULL_MENTAL_MODELS = [
|
||||||
|
{
|
||||||
|
"id": "mm-1",
|
||||||
|
"bank_id": "test-bank",
|
||||||
|
"name": "Coding Prefs",
|
||||||
|
"source_query": "coding preferences?",
|
||||||
|
"content": "Prefers Python",
|
||||||
|
"tags": ["coding"],
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": {"interval": "daily"},
|
||||||
|
"last_refreshed_at": "2026-01-01T00:00:00",
|
||||||
|
"created_at": "2026-01-01T00:00:00",
|
||||||
|
"reflect_response": {"text": "Prefers Python", "based_on": {"world_facts": [{"id": "f1", "text": "Python is popular"}]}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "mm-2",
|
||||||
|
"bank_id": "test-bank",
|
||||||
|
"name": "Goals",
|
||||||
|
"source_query": "current goals?",
|
||||||
|
"content": "Ship v2",
|
||||||
|
"tags": [],
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": None,
|
||||||
|
"last_refreshed_at": "2026-01-01T00:00:00",
|
||||||
|
"created_at": "2026-01-01T00:00:00",
|
||||||
|
"reflect_response": {"text": "Ship v2", "based_on": {}},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_detail(model: dict, detail: str) -> dict:
|
||||||
|
"""Simulate engine detail filtering for mocks."""
|
||||||
|
if detail == "metadata":
|
||||||
|
return {k: v for k, v in model.items() if k in _MENTAL_MODEL_METADATA_FIELDS}
|
||||||
|
if detail == "content":
|
||||||
|
return {k: v for k, v in model.items() if k != "reflect_response"}
|
||||||
|
return model
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_memory():
|
def mock_memory():
|
||||||
"""Create a mock MemoryEngine with all MCP tool methods."""
|
"""Create a mock MemoryEngine with all MCP tool methods."""
|
||||||
memory = MagicMock()
|
memory = MagicMock()
|
||||||
# Mental model methods
|
|
||||||
memory.list_mental_models = AsyncMock(
|
# Mental model methods — simulate engine detail filtering
|
||||||
return_value=[
|
async def _list_mental_models(**kwargs):
|
||||||
{"id": "mm-1", "name": "Coding Prefs", "source_query": "coding preferences?", "content": "Prefers Python"},
|
detail = kwargs.get("detail", "full")
|
||||||
{"id": "mm-2", "name": "Goals", "source_query": "current goals?", "content": "Ship v2"},
|
return [_apply_detail(m, detail) for m in _FULL_MENTAL_MODELS]
|
||||||
]
|
|
||||||
)
|
async def _get_mental_model(**kwargs):
|
||||||
memory.get_mental_model = AsyncMock(
|
detail = kwargs.get("detail", "full")
|
||||||
return_value={
|
return _apply_detail(_FULL_MENTAL_MODELS[0], detail)
|
||||||
"id": "mm-1",
|
|
||||||
"name": "Coding Prefs",
|
memory.list_mental_models = AsyncMock(side_effect=_list_mental_models)
|
||||||
"source_query": "coding preferences?",
|
memory.get_mental_model = AsyncMock(side_effect=_get_mental_model)
|
||||||
"content": "Prefers Python",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
memory.create_mental_model = AsyncMock(return_value={"id": "mm-new"})
|
memory.create_mental_model = AsyncMock(return_value={"id": "mm-new"})
|
||||||
memory.submit_async_refresh_mental_model = AsyncMock(return_value={"operation_id": "op-123"})
|
memory.submit_async_refresh_mental_model = AsyncMock(return_value={"operation_id": "op-123"})
|
||||||
memory.update_mental_model = AsyncMock(
|
memory.update_mental_model = AsyncMock(
|
||||||
|
|
@ -390,12 +429,12 @@ class TestGetMentalModel:
|
||||||
assert mock_memory.get_mental_model.call_args.kwargs["bank_id"] == "other-bank"
|
assert mock_memory.get_mental_model.call_args.kwargs["bank_id"] == "other-bank"
|
||||||
|
|
||||||
async def test_get_not_found_multi_bank(self, mcp_server_with_mental_models, mock_memory):
|
async def test_get_not_found_multi_bank(self, mcp_server_with_mental_models, mock_memory):
|
||||||
mock_memory.get_mental_model.return_value = None
|
mock_memory.get_mental_model.side_effect = AsyncMock(return_value=None)
|
||||||
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(mental_model_id="missing")
|
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(mental_model_id="missing")
|
||||||
assert "not found" in result
|
assert "not found" in result
|
||||||
|
|
||||||
async def test_get_not_found_single_bank(self, mcp_server_single_bank, mock_memory):
|
async def test_get_not_found_single_bank(self, mcp_server_single_bank, mock_memory):
|
||||||
mock_memory.get_mental_model.return_value = None
|
mock_memory.get_mental_model.side_effect = AsyncMock(return_value=None)
|
||||||
result = await _tools(mcp_server_single_bank)["get_mental_model"].fn(mental_model_id="missing")
|
result = await _tools(mcp_server_single_bank)["get_mental_model"].fn(mental_model_id="missing")
|
||||||
assert isinstance(result, dict)
|
assert isinstance(result, dict)
|
||||||
assert "not found" in result["error"]
|
assert "not found" in result["error"]
|
||||||
|
|
@ -415,6 +454,97 @@ class TestGetMentalModel:
|
||||||
assert "error" in result
|
assert "error" in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
class TestListMentalModelsDetail:
|
||||||
|
"""Test the detail parameter for list_mental_models."""
|
||||||
|
|
||||||
|
async def test_list_detail_full_includes_reflect_response(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["list_mental_models"].fn(detail="full")
|
||||||
|
parsed = json.loads(result)
|
||||||
|
item = parsed["items"][0]
|
||||||
|
assert "reflect_response" in item
|
||||||
|
assert "content" in item
|
||||||
|
assert "source_query" in item
|
||||||
|
|
||||||
|
async def test_list_detail_content_excludes_reflect_response(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["list_mental_models"].fn(detail="content")
|
||||||
|
parsed = json.loads(result)
|
||||||
|
item = parsed["items"][0]
|
||||||
|
assert "reflect_response" not in item
|
||||||
|
assert "content" in item
|
||||||
|
assert "source_query" in item
|
||||||
|
assert "trigger" in item
|
||||||
|
|
||||||
|
async def test_list_detail_metadata_only_has_core_fields(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["list_mental_models"].fn(detail="metadata")
|
||||||
|
parsed = json.loads(result)
|
||||||
|
item = parsed["items"][0]
|
||||||
|
assert item["id"] == "mm-1"
|
||||||
|
assert item["name"] == "Coding Prefs"
|
||||||
|
assert "tags" in item
|
||||||
|
assert "content" not in item
|
||||||
|
assert "source_query" not in item
|
||||||
|
assert "reflect_response" not in item
|
||||||
|
assert "trigger" not in item
|
||||||
|
|
||||||
|
async def test_list_detail_default_is_full(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["list_mental_models"].fn()
|
||||||
|
parsed = json.loads(result)
|
||||||
|
item = parsed["items"][0]
|
||||||
|
assert "reflect_response" in item
|
||||||
|
|
||||||
|
async def test_list_detail_single_bank_metadata(self, mcp_server_single_bank, mock_memory):
|
||||||
|
result = await _tools(mcp_server_single_bank)["list_mental_models"].fn(detail="metadata")
|
||||||
|
assert isinstance(result, dict)
|
||||||
|
item = result["items"][0]
|
||||||
|
assert "id" in item
|
||||||
|
assert "name" in item
|
||||||
|
assert "content" not in item
|
||||||
|
assert "reflect_response" not in item
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
class TestGetMentalModelDetail:
|
||||||
|
"""Test the detail parameter for get_mental_model."""
|
||||||
|
|
||||||
|
async def test_get_detail_full_includes_reflect_response(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(
|
||||||
|
mental_model_id="mm-1", detail="full"
|
||||||
|
)
|
||||||
|
parsed = json.loads(result)
|
||||||
|
assert "reflect_response" in parsed
|
||||||
|
assert "content" in parsed
|
||||||
|
|
||||||
|
async def test_get_detail_content_excludes_reflect_response(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(
|
||||||
|
mental_model_id="mm-1", detail="content"
|
||||||
|
)
|
||||||
|
parsed = json.loads(result)
|
||||||
|
assert "reflect_response" not in parsed
|
||||||
|
assert "content" in parsed
|
||||||
|
assert "source_query" in parsed
|
||||||
|
|
||||||
|
async def test_get_detail_metadata_only_has_core_fields(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(
|
||||||
|
mental_model_id="mm-1", detail="metadata"
|
||||||
|
)
|
||||||
|
parsed = json.loads(result)
|
||||||
|
assert parsed["id"] == "mm-1"
|
||||||
|
assert parsed["name"] == "Coding Prefs"
|
||||||
|
assert "tags" in parsed
|
||||||
|
assert "content" not in parsed
|
||||||
|
assert "reflect_response" not in parsed
|
||||||
|
assert "trigger" not in parsed
|
||||||
|
|
||||||
|
async def test_get_detail_single_bank_content(self, mcp_server_single_bank, mock_memory):
|
||||||
|
result = await _tools(mcp_server_single_bank)["get_mental_model"].fn(
|
||||||
|
mental_model_id="mm-1", detail="content"
|
||||||
|
)
|
||||||
|
assert isinstance(result, dict)
|
||||||
|
assert "content" in result
|
||||||
|
assert "reflect_response" not in result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
class TestCreateMentalModel:
|
class TestCreateMentalModel:
|
||||||
async def test_create_multi_bank(self, mcp_server_with_mental_models, mock_memory):
|
async def test_create_multi_bank(self, mcp_server_with_mental_models, mock_memory):
|
||||||
|
|
@ -702,12 +832,12 @@ class TestMentalModelInputValidation:
|
||||||
mock_memory.update_mental_model.assert_not_called()
|
mock_memory.update_mental_model.assert_not_called()
|
||||||
|
|
||||||
async def test_not_found_error_includes_bank_id_multi_bank(self, mcp_server_with_mental_models, mock_memory):
|
async def test_not_found_error_includes_bank_id_multi_bank(self, mcp_server_with_mental_models, mock_memory):
|
||||||
mock_memory.get_mental_model.return_value = None
|
mock_memory.get_mental_model.side_effect = AsyncMock(return_value=None)
|
||||||
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(mental_model_id="missing")
|
result = await _tools(mcp_server_with_mental_models)["get_mental_model"].fn(mental_model_id="missing")
|
||||||
assert "test-bank" in result
|
assert "test-bank" in result
|
||||||
|
|
||||||
async def test_not_found_error_includes_bank_id_single_bank(self, mcp_server_single_bank, mock_memory):
|
async def test_not_found_error_includes_bank_id_single_bank(self, mcp_server_single_bank, mock_memory):
|
||||||
mock_memory.get_mental_model.return_value = None
|
mock_memory.get_mental_model.side_effect = AsyncMock(return_value=None)
|
||||||
result = await _tools(mcp_server_single_bank)["get_mental_model"].fn(mental_model_id="missing")
|
result = await _tools(mcp_server_single_bank)["get_mental_model"].fn(mental_model_id="missing")
|
||||||
assert isinstance(result, dict)
|
assert isinstance(result, dict)
|
||||||
assert "fixed-bank" in result["error"]
|
assert "fixed-bank" in result["error"]
|
||||||
|
|
|
||||||
|
|
@ -550,14 +550,14 @@ impl ApiClient {
|
||||||
|
|
||||||
pub fn list_mental_models(&self, bank_id: &str, _verbose: bool) -> Result<types::MentalModelListResponse> {
|
pub fn list_mental_models(&self, bank_id: &str, _verbose: bool) -> Result<types::MentalModelListResponse> {
|
||||||
self.runtime.block_on(async {
|
self.runtime.block_on(async {
|
||||||
let response = self.client.list_mental_models(bank_id, None, None, None, None, None).await?;
|
let response = self.client.list_mental_models(bank_id, None, None, None, None, None, None).await?;
|
||||||
Ok(response.into_inner())
|
Ok(response.into_inner())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mental_model(&self, bank_id: &str, mental_model_id: &str, _verbose: bool) -> Result<types::MentalModelResponse> {
|
pub fn get_mental_model(&self, bank_id: &str, mental_model_id: &str, _verbose: bool) -> Result<types::MentalModelResponse> {
|
||||||
self.runtime.block_on(async {
|
self.runtime.block_on(async {
|
||||||
let response = self.client.get_mental_model(bank_id, mental_model_id, None).await?;
|
let response = self.client.get_mental_model(bank_id, mental_model_id, None, None).await?;
|
||||||
Ok(response.into_inner())
|
Ok(response.into_inner())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,11 @@ pub fn list(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Show content preview
|
// Show content preview
|
||||||
let preview: String = mental_model.content.chars().take(80).collect();
|
if let Some(ref content) = mental_model.content {
|
||||||
let ellipsis = if mental_model.content.len() > 80 { "..." } else { "" };
|
let preview: String = content.chars().take(80).collect();
|
||||||
println!(" {}{}", ui::dim(&preview), ellipsis);
|
let ellipsis = if content.len() > 80 { "..." } else { "" };
|
||||||
|
println!(" {}{}", ui::dim(&preview), ellipsis);
|
||||||
|
}
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
@ -326,11 +328,15 @@ fn print_mental_model_detail(mental_model: &types::MentalModelResponse) {
|
||||||
ui::print_section_header(&mental_model.name);
|
ui::print_section_header(&mental_model.name);
|
||||||
|
|
||||||
println!(" {} {}", ui::dim("ID:"), ui::gradient_start(&mental_model.id));
|
println!(" {} {}", ui::dim("ID:"), ui::gradient_start(&mental_model.id));
|
||||||
println!(" {} {}", ui::dim("Source Query:"), &mental_model.source_query);
|
if let Some(ref source_query) = mental_model.source_query {
|
||||||
|
println!(" {} {}", ui::dim("Source Query:"), source_query);
|
||||||
|
}
|
||||||
|
|
||||||
println!();
|
if let Some(ref content) = mental_model.content {
|
||||||
println!("{}", ui::gradient_text("─── Content ───"));
|
println!();
|
||||||
println!();
|
println!("{}", ui::gradient_text("─── Content ───"));
|
||||||
println!("{}", &mental_model.content);
|
println!();
|
||||||
println!();
|
println!("{}", content);
|
||||||
|
println!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -656,6 +656,23 @@ paths:
|
||||||
title: Tags Match
|
title: Tags Match
|
||||||
type: string
|
type: string
|
||||||
style: form
|
style: form
|
||||||
|
- description: "Detail level: 'metadata' (names/tags only), 'content' (adds\
|
||||||
|
\ content/config), 'full' (includes reflect_response)"
|
||||||
|
explode: true
|
||||||
|
in: query
|
||||||
|
name: detail
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: full
|
||||||
|
description: "Detail level: 'metadata' (names/tags only), 'content' (adds\
|
||||||
|
\ content/config), 'full' (includes reflect_response)"
|
||||||
|
enum:
|
||||||
|
- metadata
|
||||||
|
- content
|
||||||
|
- full
|
||||||
|
title: Detail
|
||||||
|
type: string
|
||||||
|
style: form
|
||||||
- explode: true
|
- explode: true
|
||||||
in: query
|
in: query
|
||||||
name: limit
|
name: limit
|
||||||
|
|
@ -810,6 +827,23 @@ paths:
|
||||||
title: Mental Model Id
|
title: Mental Model Id
|
||||||
type: string
|
type: string
|
||||||
style: simple
|
style: simple
|
||||||
|
- description: "Detail level: 'metadata' (names/tags only), 'content' (adds\
|
||||||
|
\ content/config), 'full' (includes reflect_response)"
|
||||||
|
explode: true
|
||||||
|
in: query
|
||||||
|
name: detail
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: full
|
||||||
|
description: "Detail level: 'metadata' (names/tags only), 'content' (adds\
|
||||||
|
\ content/config), 'full' (includes reflect_response)"
|
||||||
|
enum:
|
||||||
|
- metadata
|
||||||
|
- content
|
||||||
|
- full
|
||||||
|
title: Detail
|
||||||
|
type: string
|
||||||
|
style: form
|
||||||
- explode: false
|
- explode: false
|
||||||
in: header
|
in: header
|
||||||
name: authorization
|
name: authorization
|
||||||
|
|
@ -4534,12 +4568,10 @@ components:
|
||||||
title: Name
|
title: Name
|
||||||
type: string
|
type: string
|
||||||
source_query:
|
source_query:
|
||||||
title: Source Query
|
nullable: true
|
||||||
type: string
|
type: string
|
||||||
content:
|
content:
|
||||||
description: The mental model content as well-formatted markdown (auto-generated
|
nullable: true
|
||||||
from reflect endpoint)
|
|
||||||
title: Content
|
|
||||||
type: string
|
type: string
|
||||||
tags:
|
tags:
|
||||||
default: []
|
default: []
|
||||||
|
|
@ -4547,8 +4579,7 @@ components:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
max_tokens:
|
max_tokens:
|
||||||
default: 2048
|
nullable: true
|
||||||
title: Max Tokens
|
|
||||||
type: integer
|
type: integer
|
||||||
trigger:
|
trigger:
|
||||||
$ref: '#/components/schemas/MentalModelTrigger-Output'
|
$ref: '#/components/schemas/MentalModelTrigger-Output'
|
||||||
|
|
@ -4563,10 +4594,8 @@ components:
|
||||||
nullable: true
|
nullable: true
|
||||||
required:
|
required:
|
||||||
- bank_id
|
- bank_id
|
||||||
- content
|
|
||||||
- id
|
- id
|
||||||
- name
|
- name
|
||||||
- source_query
|
|
||||||
title: MentalModelResponse
|
title: MentalModelResponse
|
||||||
MentalModelTrigger-Input:
|
MentalModelTrigger-Input:
|
||||||
description: Trigger settings for a mental model.
|
description: Trigger settings for a mental model.
|
||||||
|
|
|
||||||
|
|
@ -288,9 +288,16 @@ type ApiGetMentalModelRequest struct {
|
||||||
ApiService *MentalModelsAPIService
|
ApiService *MentalModelsAPIService
|
||||||
bankId string
|
bankId string
|
||||||
mentalModelId string
|
mentalModelId string
|
||||||
|
detail *string
|
||||||
authorization *string
|
authorization *string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
func (r ApiGetMentalModelRequest) Detail(detail string) ApiGetMentalModelRequest {
|
||||||
|
r.detail = &detail
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func (r ApiGetMentalModelRequest) Authorization(authorization string) ApiGetMentalModelRequest {
|
func (r ApiGetMentalModelRequest) Authorization(authorization string) ApiGetMentalModelRequest {
|
||||||
r.authorization = &authorization
|
r.authorization = &authorization
|
||||||
return r
|
return r
|
||||||
|
|
@ -342,6 +349,12 @@ func (a *MentalModelsAPIService) GetMentalModelExecute(r ApiGetMentalModelReques
|
||||||
localVarQueryParams := url.Values{}
|
localVarQueryParams := url.Values{}
|
||||||
localVarFormParams := url.Values{}
|
localVarFormParams := url.Values{}
|
||||||
|
|
||||||
|
if r.detail != nil {
|
||||||
|
parameterAddToHeaderOrQuery(localVarQueryParams, "detail", r.detail, "form", "")
|
||||||
|
} else {
|
||||||
|
var defaultValue string = "full"
|
||||||
|
r.detail = &defaultValue
|
||||||
|
}
|
||||||
// to determine the Content-Type header
|
// to determine the Content-Type header
|
||||||
localVarHTTPContentTypes := []string{}
|
localVarHTTPContentTypes := []string{}
|
||||||
|
|
||||||
|
|
@ -541,6 +554,7 @@ type ApiListMentalModelsRequest struct {
|
||||||
bankId string
|
bankId string
|
||||||
tags *[]string
|
tags *[]string
|
||||||
tagsMatch *string
|
tagsMatch *string
|
||||||
|
detail *string
|
||||||
limit *int32
|
limit *int32
|
||||||
offset *int32
|
offset *int32
|
||||||
authorization *string
|
authorization *string
|
||||||
|
|
@ -558,6 +572,12 @@ func (r ApiListMentalModelsRequest) TagsMatch(tagsMatch string) ApiListMentalMod
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
func (r ApiListMentalModelsRequest) Detail(detail string) ApiListMentalModelsRequest {
|
||||||
|
r.detail = &detail
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func (r ApiListMentalModelsRequest) Limit(limit int32) ApiListMentalModelsRequest {
|
func (r ApiListMentalModelsRequest) Limit(limit int32) ApiListMentalModelsRequest {
|
||||||
r.limit = &limit
|
r.limit = &limit
|
||||||
return r
|
return r
|
||||||
|
|
@ -633,6 +653,12 @@ func (a *MentalModelsAPIService) ListMentalModelsExecute(r ApiListMentalModelsRe
|
||||||
var defaultValue string = "any"
|
var defaultValue string = "any"
|
||||||
r.tagsMatch = &defaultValue
|
r.tagsMatch = &defaultValue
|
||||||
}
|
}
|
||||||
|
if r.detail != nil {
|
||||||
|
parameterAddToHeaderOrQuery(localVarQueryParams, "detail", r.detail, "form", "")
|
||||||
|
} else {
|
||||||
|
var defaultValue string = "full"
|
||||||
|
r.detail = &defaultValue
|
||||||
|
}
|
||||||
if r.limit != nil {
|
if r.limit != nil {
|
||||||
parameterAddToHeaderOrQuery(localVarQueryParams, "limit", r.limit, "form", "")
|
parameterAddToHeaderOrQuery(localVarQueryParams, "limit", r.limit, "form", "")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,11 @@ type MentalModelResponse struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
BankId string `json:"bank_id"`
|
BankId string `json:"bank_id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
SourceQuery string `json:"source_query"`
|
SourceQuery NullableString `json:"source_query,omitempty"`
|
||||||
// The mental model content as well-formatted markdown (auto-generated from reflect endpoint)
|
Content NullableString `json:"content,omitempty"`
|
||||||
Content string `json:"content"`
|
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
MaxTokens *int32 `json:"max_tokens,omitempty"`
|
MaxTokens NullableInt32 `json:"max_tokens,omitempty"`
|
||||||
Trigger *MentalModelTriggerOutput `json:"trigger,omitempty"`
|
Trigger NullableMentalModelTriggerOutput `json:"trigger,omitempty"`
|
||||||
LastRefreshedAt NullableString `json:"last_refreshed_at,omitempty"`
|
LastRefreshedAt NullableString `json:"last_refreshed_at,omitempty"`
|
||||||
CreatedAt NullableString `json:"created_at,omitempty"`
|
CreatedAt NullableString `json:"created_at,omitempty"`
|
||||||
ReflectResponse map[string]interface{} `json:"reflect_response,omitempty"`
|
ReflectResponse map[string]interface{} `json:"reflect_response,omitempty"`
|
||||||
|
|
@ -41,15 +40,11 @@ type _MentalModelResponse MentalModelResponse
|
||||||
// This constructor will assign default values to properties that have it defined,
|
// This constructor will assign default values to properties that have it defined,
|
||||||
// and makes sure properties required by API are set, but the set of arguments
|
// and makes sure properties required by API are set, but the set of arguments
|
||||||
// will change when the set of required properties is changed
|
// will change when the set of required properties is changed
|
||||||
func NewMentalModelResponse(id string, bankId string, name string, sourceQuery string, content string) *MentalModelResponse {
|
func NewMentalModelResponse(id string, bankId string, name string) *MentalModelResponse {
|
||||||
this := MentalModelResponse{}
|
this := MentalModelResponse{}
|
||||||
this.Id = id
|
this.Id = id
|
||||||
this.BankId = bankId
|
this.BankId = bankId
|
||||||
this.Name = name
|
this.Name = name
|
||||||
this.SourceQuery = sourceQuery
|
|
||||||
this.Content = content
|
|
||||||
var maxTokens int32 = 2048
|
|
||||||
this.MaxTokens = &maxTokens
|
|
||||||
return &this
|
return &this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,8 +53,6 @@ func NewMentalModelResponse(id string, bankId string, name string, sourceQuery s
|
||||||
// but it doesn't guarantee that properties required by API are set
|
// but it doesn't guarantee that properties required by API are set
|
||||||
func NewMentalModelResponseWithDefaults() *MentalModelResponse {
|
func NewMentalModelResponseWithDefaults() *MentalModelResponse {
|
||||||
this := MentalModelResponse{}
|
this := MentalModelResponse{}
|
||||||
var maxTokens int32 = 2048
|
|
||||||
this.MaxTokens = &maxTokens
|
|
||||||
return &this
|
return &this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,52 +128,88 @@ func (o *MentalModelResponse) SetName(v string) {
|
||||||
o.Name = v
|
o.Name = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSourceQuery returns the SourceQuery field value
|
// GetSourceQuery returns the SourceQuery field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
func (o *MentalModelResponse) GetSourceQuery() string {
|
func (o *MentalModelResponse) GetSourceQuery() string {
|
||||||
if o == nil {
|
if o == nil || IsNil(o.SourceQuery.Get()) {
|
||||||
var ret string
|
var ret string
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
return *o.SourceQuery.Get()
|
||||||
return o.SourceQuery
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSourceQueryOk returns a tuple with the SourceQuery field value
|
// GetSourceQueryOk returns a tuple with the SourceQuery field value if set, nil otherwise
|
||||||
// and a boolean to check if the value has been set.
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
func (o *MentalModelResponse) GetSourceQueryOk() (*string, bool) {
|
func (o *MentalModelResponse) GetSourceQueryOk() (*string, bool) {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return &o.SourceQuery, true
|
return o.SourceQuery.Get(), o.SourceQuery.IsSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSourceQuery sets field value
|
// HasSourceQuery returns a boolean if a field has been set.
|
||||||
|
func (o *MentalModelResponse) HasSourceQuery() bool {
|
||||||
|
if o != nil && o.SourceQuery.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSourceQuery gets a reference to the given NullableString and assigns it to the SourceQuery field.
|
||||||
func (o *MentalModelResponse) SetSourceQuery(v string) {
|
func (o *MentalModelResponse) SetSourceQuery(v string) {
|
||||||
o.SourceQuery = v
|
o.SourceQuery.Set(&v)
|
||||||
|
}
|
||||||
|
// SetSourceQueryNil sets the value for SourceQuery to be an explicit nil
|
||||||
|
func (o *MentalModelResponse) SetSourceQueryNil() {
|
||||||
|
o.SourceQuery.Set(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContent returns the Content field value
|
// UnsetSourceQuery ensures that no value is present for SourceQuery, not even an explicit nil
|
||||||
|
func (o *MentalModelResponse) UnsetSourceQuery() {
|
||||||
|
o.SourceQuery.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContent returns the Content field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
func (o *MentalModelResponse) GetContent() string {
|
func (o *MentalModelResponse) GetContent() string {
|
||||||
if o == nil {
|
if o == nil || IsNil(o.Content.Get()) {
|
||||||
var ret string
|
var ret string
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
return *o.Content.Get()
|
||||||
return o.Content
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContentOk returns a tuple with the Content field value
|
// GetContentOk returns a tuple with the Content field value if set, nil otherwise
|
||||||
// and a boolean to check if the value has been set.
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
func (o *MentalModelResponse) GetContentOk() (*string, bool) {
|
func (o *MentalModelResponse) GetContentOk() (*string, bool) {
|
||||||
if o == nil {
|
if o == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return &o.Content, true
|
return o.Content.Get(), o.Content.IsSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContent sets field value
|
// HasContent returns a boolean if a field has been set.
|
||||||
|
func (o *MentalModelResponse) HasContent() bool {
|
||||||
|
if o != nil && o.Content.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContent gets a reference to the given NullableString and assigns it to the Content field.
|
||||||
func (o *MentalModelResponse) SetContent(v string) {
|
func (o *MentalModelResponse) SetContent(v string) {
|
||||||
o.Content = v
|
o.Content.Set(&v)
|
||||||
|
}
|
||||||
|
// SetContentNil sets the value for Content to be an explicit nil
|
||||||
|
func (o *MentalModelResponse) SetContentNil() {
|
||||||
|
o.Content.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetContent ensures that no value is present for Content, not even an explicit nil
|
||||||
|
func (o *MentalModelResponse) UnsetContent() {
|
||||||
|
o.Content.Unset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTags returns the Tags field value if set, zero value otherwise.
|
// GetTags returns the Tags field value if set, zero value otherwise.
|
||||||
|
|
@ -215,68 +244,88 @@ func (o *MentalModelResponse) SetTags(v []string) {
|
||||||
o.Tags = v
|
o.Tags = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMaxTokens returns the MaxTokens field value if set, zero value otherwise.
|
// GetMaxTokens returns the MaxTokens field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
func (o *MentalModelResponse) GetMaxTokens() int32 {
|
func (o *MentalModelResponse) GetMaxTokens() int32 {
|
||||||
if o == nil || IsNil(o.MaxTokens) {
|
if o == nil || IsNil(o.MaxTokens.Get()) {
|
||||||
var ret int32
|
var ret int32
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
return *o.MaxTokens
|
return *o.MaxTokens.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMaxTokensOk returns a tuple with the MaxTokens field value if set, nil otherwise
|
// GetMaxTokensOk returns a tuple with the MaxTokens field value if set, nil otherwise
|
||||||
// and a boolean to check if the value has been set.
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
func (o *MentalModelResponse) GetMaxTokensOk() (*int32, bool) {
|
func (o *MentalModelResponse) GetMaxTokensOk() (*int32, bool) {
|
||||||
if o == nil || IsNil(o.MaxTokens) {
|
if o == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return o.MaxTokens, true
|
return o.MaxTokens.Get(), o.MaxTokens.IsSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasMaxTokens returns a boolean if a field has been set.
|
// HasMaxTokens returns a boolean if a field has been set.
|
||||||
func (o *MentalModelResponse) HasMaxTokens() bool {
|
func (o *MentalModelResponse) HasMaxTokens() bool {
|
||||||
if o != nil && !IsNil(o.MaxTokens) {
|
if o != nil && o.MaxTokens.IsSet() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMaxTokens gets a reference to the given int32 and assigns it to the MaxTokens field.
|
// SetMaxTokens gets a reference to the given NullableInt32 and assigns it to the MaxTokens field.
|
||||||
func (o *MentalModelResponse) SetMaxTokens(v int32) {
|
func (o *MentalModelResponse) SetMaxTokens(v int32) {
|
||||||
o.MaxTokens = &v
|
o.MaxTokens.Set(&v)
|
||||||
|
}
|
||||||
|
// SetMaxTokensNil sets the value for MaxTokens to be an explicit nil
|
||||||
|
func (o *MentalModelResponse) SetMaxTokensNil() {
|
||||||
|
o.MaxTokens.Set(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTrigger returns the Trigger field value if set, zero value otherwise.
|
// UnsetMaxTokens ensures that no value is present for MaxTokens, not even an explicit nil
|
||||||
|
func (o *MentalModelResponse) UnsetMaxTokens() {
|
||||||
|
o.MaxTokens.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrigger returns the Trigger field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
func (o *MentalModelResponse) GetTrigger() MentalModelTriggerOutput {
|
func (o *MentalModelResponse) GetTrigger() MentalModelTriggerOutput {
|
||||||
if o == nil || IsNil(o.Trigger) {
|
if o == nil || IsNil(o.Trigger.Get()) {
|
||||||
var ret MentalModelTriggerOutput
|
var ret MentalModelTriggerOutput
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
return *o.Trigger
|
return *o.Trigger.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTriggerOk returns a tuple with the Trigger field value if set, nil otherwise
|
// GetTriggerOk returns a tuple with the Trigger field value if set, nil otherwise
|
||||||
// and a boolean to check if the value has been set.
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
func (o *MentalModelResponse) GetTriggerOk() (*MentalModelTriggerOutput, bool) {
|
func (o *MentalModelResponse) GetTriggerOk() (*MentalModelTriggerOutput, bool) {
|
||||||
if o == nil || IsNil(o.Trigger) {
|
if o == nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return o.Trigger, true
|
return o.Trigger.Get(), o.Trigger.IsSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasTrigger returns a boolean if a field has been set.
|
// HasTrigger returns a boolean if a field has been set.
|
||||||
func (o *MentalModelResponse) HasTrigger() bool {
|
func (o *MentalModelResponse) HasTrigger() bool {
|
||||||
if o != nil && !IsNil(o.Trigger) {
|
if o != nil && o.Trigger.IsSet() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTrigger gets a reference to the given MentalModelTriggerOutput and assigns it to the Trigger field.
|
// SetTrigger gets a reference to the given NullableMentalModelTriggerOutput and assigns it to the Trigger field.
|
||||||
func (o *MentalModelResponse) SetTrigger(v MentalModelTriggerOutput) {
|
func (o *MentalModelResponse) SetTrigger(v MentalModelTriggerOutput) {
|
||||||
o.Trigger = &v
|
o.Trigger.Set(&v)
|
||||||
|
}
|
||||||
|
// SetTriggerNil sets the value for Trigger to be an explicit nil
|
||||||
|
func (o *MentalModelResponse) SetTriggerNil() {
|
||||||
|
o.Trigger.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetTrigger ensures that no value is present for Trigger, not even an explicit nil
|
||||||
|
func (o *MentalModelResponse) UnsetTrigger() {
|
||||||
|
o.Trigger.Unset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLastRefreshedAt returns the LastRefreshedAt field value if set, zero value otherwise (both if not set or set to explicit null).
|
// GetLastRefreshedAt returns the LastRefreshedAt field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
|
@ -409,16 +458,20 @@ func (o MentalModelResponse) ToMap() (map[string]interface{}, error) {
|
||||||
toSerialize["id"] = o.Id
|
toSerialize["id"] = o.Id
|
||||||
toSerialize["bank_id"] = o.BankId
|
toSerialize["bank_id"] = o.BankId
|
||||||
toSerialize["name"] = o.Name
|
toSerialize["name"] = o.Name
|
||||||
toSerialize["source_query"] = o.SourceQuery
|
if o.SourceQuery.IsSet() {
|
||||||
toSerialize["content"] = o.Content
|
toSerialize["source_query"] = o.SourceQuery.Get()
|
||||||
|
}
|
||||||
|
if o.Content.IsSet() {
|
||||||
|
toSerialize["content"] = o.Content.Get()
|
||||||
|
}
|
||||||
if !IsNil(o.Tags) {
|
if !IsNil(o.Tags) {
|
||||||
toSerialize["tags"] = o.Tags
|
toSerialize["tags"] = o.Tags
|
||||||
}
|
}
|
||||||
if !IsNil(o.MaxTokens) {
|
if o.MaxTokens.IsSet() {
|
||||||
toSerialize["max_tokens"] = o.MaxTokens
|
toSerialize["max_tokens"] = o.MaxTokens.Get()
|
||||||
}
|
}
|
||||||
if !IsNil(o.Trigger) {
|
if o.Trigger.IsSet() {
|
||||||
toSerialize["trigger"] = o.Trigger
|
toSerialize["trigger"] = o.Trigger.Get()
|
||||||
}
|
}
|
||||||
if o.LastRefreshedAt.IsSet() {
|
if o.LastRefreshedAt.IsSet() {
|
||||||
toSerialize["last_refreshed_at"] = o.LastRefreshedAt.Get()
|
toSerialize["last_refreshed_at"] = o.LastRefreshedAt.Get()
|
||||||
|
|
@ -440,8 +493,6 @@ func (o *MentalModelResponse) UnmarshalJSON(data []byte) (err error) {
|
||||||
"id",
|
"id",
|
||||||
"bank_id",
|
"bank_id",
|
||||||
"name",
|
"name",
|
||||||
"source_query",
|
|
||||||
"content",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allProperties := make(map[string]interface{})
|
allProperties := make(map[string]interface{})
|
||||||
|
|
|
||||||
|
|
@ -648,6 +648,7 @@ class MentalModelsApi:
|
||||||
self,
|
self,
|
||||||
bank_id: StrictStr,
|
bank_id: StrictStr,
|
||||||
mental_model_id: StrictStr,
|
mental_model_id: StrictStr,
|
||||||
|
detail: Annotated[Optional[StrictStr], Field(description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)")] = None,
|
||||||
authorization: Optional[StrictStr] = None,
|
authorization: Optional[StrictStr] = None,
|
||||||
_request_timeout: Union[
|
_request_timeout: Union[
|
||||||
None,
|
None,
|
||||||
|
|
@ -670,6 +671,8 @@ class MentalModelsApi:
|
||||||
:type bank_id: str
|
:type bank_id: str
|
||||||
:param mental_model_id: (required)
|
:param mental_model_id: (required)
|
||||||
:type mental_model_id: str
|
:type mental_model_id: str
|
||||||
|
:param detail: Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
:type detail: str
|
||||||
:param authorization:
|
:param authorization:
|
||||||
:type authorization: str
|
:type authorization: str
|
||||||
:param _request_timeout: timeout setting for this request. If one
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
|
@ -697,6 +700,7 @@ class MentalModelsApi:
|
||||||
_param = self._get_mental_model_serialize(
|
_param = self._get_mental_model_serialize(
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
mental_model_id=mental_model_id,
|
mental_model_id=mental_model_id,
|
||||||
|
detail=detail,
|
||||||
authorization=authorization,
|
authorization=authorization,
|
||||||
_request_auth=_request_auth,
|
_request_auth=_request_auth,
|
||||||
_content_type=_content_type,
|
_content_type=_content_type,
|
||||||
|
|
@ -724,6 +728,7 @@ class MentalModelsApi:
|
||||||
self,
|
self,
|
||||||
bank_id: StrictStr,
|
bank_id: StrictStr,
|
||||||
mental_model_id: StrictStr,
|
mental_model_id: StrictStr,
|
||||||
|
detail: Annotated[Optional[StrictStr], Field(description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)")] = None,
|
||||||
authorization: Optional[StrictStr] = None,
|
authorization: Optional[StrictStr] = None,
|
||||||
_request_timeout: Union[
|
_request_timeout: Union[
|
||||||
None,
|
None,
|
||||||
|
|
@ -746,6 +751,8 @@ class MentalModelsApi:
|
||||||
:type bank_id: str
|
:type bank_id: str
|
||||||
:param mental_model_id: (required)
|
:param mental_model_id: (required)
|
||||||
:type mental_model_id: str
|
:type mental_model_id: str
|
||||||
|
:param detail: Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
:type detail: str
|
||||||
:param authorization:
|
:param authorization:
|
||||||
:type authorization: str
|
:type authorization: str
|
||||||
:param _request_timeout: timeout setting for this request. If one
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
|
@ -773,6 +780,7 @@ class MentalModelsApi:
|
||||||
_param = self._get_mental_model_serialize(
|
_param = self._get_mental_model_serialize(
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
mental_model_id=mental_model_id,
|
mental_model_id=mental_model_id,
|
||||||
|
detail=detail,
|
||||||
authorization=authorization,
|
authorization=authorization,
|
||||||
_request_auth=_request_auth,
|
_request_auth=_request_auth,
|
||||||
_content_type=_content_type,
|
_content_type=_content_type,
|
||||||
|
|
@ -800,6 +808,7 @@ class MentalModelsApi:
|
||||||
self,
|
self,
|
||||||
bank_id: StrictStr,
|
bank_id: StrictStr,
|
||||||
mental_model_id: StrictStr,
|
mental_model_id: StrictStr,
|
||||||
|
detail: Annotated[Optional[StrictStr], Field(description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)")] = None,
|
||||||
authorization: Optional[StrictStr] = None,
|
authorization: Optional[StrictStr] = None,
|
||||||
_request_timeout: Union[
|
_request_timeout: Union[
|
||||||
None,
|
None,
|
||||||
|
|
@ -822,6 +831,8 @@ class MentalModelsApi:
|
||||||
:type bank_id: str
|
:type bank_id: str
|
||||||
:param mental_model_id: (required)
|
:param mental_model_id: (required)
|
||||||
:type mental_model_id: str
|
:type mental_model_id: str
|
||||||
|
:param detail: Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
:type detail: str
|
||||||
:param authorization:
|
:param authorization:
|
||||||
:type authorization: str
|
:type authorization: str
|
||||||
:param _request_timeout: timeout setting for this request. If one
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
|
@ -849,6 +860,7 @@ class MentalModelsApi:
|
||||||
_param = self._get_mental_model_serialize(
|
_param = self._get_mental_model_serialize(
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
mental_model_id=mental_model_id,
|
mental_model_id=mental_model_id,
|
||||||
|
detail=detail,
|
||||||
authorization=authorization,
|
authorization=authorization,
|
||||||
_request_auth=_request_auth,
|
_request_auth=_request_auth,
|
||||||
_content_type=_content_type,
|
_content_type=_content_type,
|
||||||
|
|
@ -871,6 +883,7 @@ class MentalModelsApi:
|
||||||
self,
|
self,
|
||||||
bank_id,
|
bank_id,
|
||||||
mental_model_id,
|
mental_model_id,
|
||||||
|
detail,
|
||||||
authorization,
|
authorization,
|
||||||
_request_auth,
|
_request_auth,
|
||||||
_content_type,
|
_content_type,
|
||||||
|
|
@ -898,6 +911,10 @@ class MentalModelsApi:
|
||||||
if mental_model_id is not None:
|
if mental_model_id is not None:
|
||||||
_path_params['mental_model_id'] = mental_model_id
|
_path_params['mental_model_id'] = mental_model_id
|
||||||
# process the query parameters
|
# process the query parameters
|
||||||
|
if detail is not None:
|
||||||
|
|
||||||
|
_query_params.append(('detail', detail))
|
||||||
|
|
||||||
# process the header parameters
|
# process the header parameters
|
||||||
if authorization is not None:
|
if authorization is not None:
|
||||||
_header_params['authorization'] = authorization
|
_header_params['authorization'] = authorization
|
||||||
|
|
@ -1235,6 +1252,7 @@ class MentalModelsApi:
|
||||||
bank_id: StrictStr,
|
bank_id: StrictStr,
|
||||||
tags: Annotated[Optional[List[StrictStr]], Field(description="Filter by tags")] = None,
|
tags: Annotated[Optional[List[StrictStr]], Field(description="Filter by tags")] = None,
|
||||||
tags_match: Annotated[Optional[StrictStr], Field(description="How to match tags")] = None,
|
tags_match: Annotated[Optional[StrictStr], Field(description="How to match tags")] = None,
|
||||||
|
detail: Annotated[Optional[StrictStr], Field(description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)")] = None,
|
||||||
limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None,
|
limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None,
|
||||||
offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
|
offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
|
||||||
authorization: Optional[StrictStr] = None,
|
authorization: Optional[StrictStr] = None,
|
||||||
|
|
@ -1261,6 +1279,8 @@ class MentalModelsApi:
|
||||||
:type tags: List[str]
|
:type tags: List[str]
|
||||||
:param tags_match: How to match tags
|
:param tags_match: How to match tags
|
||||||
:type tags_match: str
|
:type tags_match: str
|
||||||
|
:param detail: Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
:type detail: str
|
||||||
:param limit:
|
:param limit:
|
||||||
:type limit: int
|
:type limit: int
|
||||||
:param offset:
|
:param offset:
|
||||||
|
|
@ -1293,6 +1313,7 @@ class MentalModelsApi:
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
tags_match=tags_match,
|
tags_match=tags_match,
|
||||||
|
detail=detail,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
authorization=authorization,
|
authorization=authorization,
|
||||||
|
|
@ -1323,6 +1344,7 @@ class MentalModelsApi:
|
||||||
bank_id: StrictStr,
|
bank_id: StrictStr,
|
||||||
tags: Annotated[Optional[List[StrictStr]], Field(description="Filter by tags")] = None,
|
tags: Annotated[Optional[List[StrictStr]], Field(description="Filter by tags")] = None,
|
||||||
tags_match: Annotated[Optional[StrictStr], Field(description="How to match tags")] = None,
|
tags_match: Annotated[Optional[StrictStr], Field(description="How to match tags")] = None,
|
||||||
|
detail: Annotated[Optional[StrictStr], Field(description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)")] = None,
|
||||||
limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None,
|
limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None,
|
||||||
offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
|
offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
|
||||||
authorization: Optional[StrictStr] = None,
|
authorization: Optional[StrictStr] = None,
|
||||||
|
|
@ -1349,6 +1371,8 @@ class MentalModelsApi:
|
||||||
:type tags: List[str]
|
:type tags: List[str]
|
||||||
:param tags_match: How to match tags
|
:param tags_match: How to match tags
|
||||||
:type tags_match: str
|
:type tags_match: str
|
||||||
|
:param detail: Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
:type detail: str
|
||||||
:param limit:
|
:param limit:
|
||||||
:type limit: int
|
:type limit: int
|
||||||
:param offset:
|
:param offset:
|
||||||
|
|
@ -1381,6 +1405,7 @@ class MentalModelsApi:
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
tags_match=tags_match,
|
tags_match=tags_match,
|
||||||
|
detail=detail,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
authorization=authorization,
|
authorization=authorization,
|
||||||
|
|
@ -1411,6 +1436,7 @@ class MentalModelsApi:
|
||||||
bank_id: StrictStr,
|
bank_id: StrictStr,
|
||||||
tags: Annotated[Optional[List[StrictStr]], Field(description="Filter by tags")] = None,
|
tags: Annotated[Optional[List[StrictStr]], Field(description="Filter by tags")] = None,
|
||||||
tags_match: Annotated[Optional[StrictStr], Field(description="How to match tags")] = None,
|
tags_match: Annotated[Optional[StrictStr], Field(description="How to match tags")] = None,
|
||||||
|
detail: Annotated[Optional[StrictStr], Field(description="Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)")] = None,
|
||||||
limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None,
|
limit: Optional[Annotated[int, Field(le=1000, strict=True, ge=1)]] = None,
|
||||||
offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
|
offset: Optional[Annotated[int, Field(strict=True, ge=0)]] = None,
|
||||||
authorization: Optional[StrictStr] = None,
|
authorization: Optional[StrictStr] = None,
|
||||||
|
|
@ -1437,6 +1463,8 @@ class MentalModelsApi:
|
||||||
:type tags: List[str]
|
:type tags: List[str]
|
||||||
:param tags_match: How to match tags
|
:param tags_match: How to match tags
|
||||||
:type tags_match: str
|
:type tags_match: str
|
||||||
|
:param detail: Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
:type detail: str
|
||||||
:param limit:
|
:param limit:
|
||||||
:type limit: int
|
:type limit: int
|
||||||
:param offset:
|
:param offset:
|
||||||
|
|
@ -1469,6 +1497,7 @@ class MentalModelsApi:
|
||||||
bank_id=bank_id,
|
bank_id=bank_id,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
tags_match=tags_match,
|
tags_match=tags_match,
|
||||||
|
detail=detail,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
authorization=authorization,
|
authorization=authorization,
|
||||||
|
|
@ -1494,6 +1523,7 @@ class MentalModelsApi:
|
||||||
bank_id,
|
bank_id,
|
||||||
tags,
|
tags,
|
||||||
tags_match,
|
tags_match,
|
||||||
|
detail,
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
authorization,
|
authorization,
|
||||||
|
|
@ -1530,6 +1560,10 @@ class MentalModelsApi:
|
||||||
|
|
||||||
_query_params.append(('tags_match', tags_match))
|
_query_params.append(('tags_match', tags_match))
|
||||||
|
|
||||||
|
if detail is not None:
|
||||||
|
|
||||||
|
_query_params.append(('detail', detail))
|
||||||
|
|
||||||
if limit is not None:
|
if limit is not None:
|
||||||
|
|
||||||
_query_params.append(('limit', limit))
|
_query_params.append(('limit', limit))
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import pprint
|
||||||
import re # noqa: F401
|
import re # noqa: F401
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
|
from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr
|
||||||
from typing import Any, ClassVar, Dict, List, Optional
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
from hindsight_client_api.models.mental_model_trigger_output import MentalModelTriggerOutput
|
from hindsight_client_api.models.mental_model_trigger_output import MentalModelTriggerOutput
|
||||||
from typing import Optional, Set
|
from typing import Optional, Set
|
||||||
|
|
@ -30,10 +30,10 @@ class MentalModelResponse(BaseModel):
|
||||||
id: StrictStr
|
id: StrictStr
|
||||||
bank_id: StrictStr
|
bank_id: StrictStr
|
||||||
name: StrictStr
|
name: StrictStr
|
||||||
source_query: StrictStr
|
source_query: Optional[StrictStr] = None
|
||||||
content: StrictStr = Field(description="The mental model content as well-formatted markdown (auto-generated from reflect endpoint)")
|
content: Optional[StrictStr] = None
|
||||||
tags: Optional[List[StrictStr]] = None
|
tags: Optional[List[StrictStr]] = None
|
||||||
max_tokens: Optional[StrictInt] = 2048
|
max_tokens: Optional[StrictInt] = None
|
||||||
trigger: Optional[MentalModelTriggerOutput] = None
|
trigger: Optional[MentalModelTriggerOutput] = None
|
||||||
last_refreshed_at: Optional[StrictStr] = None
|
last_refreshed_at: Optional[StrictStr] = None
|
||||||
created_at: Optional[StrictStr] = None
|
created_at: Optional[StrictStr] = None
|
||||||
|
|
@ -82,6 +82,26 @@ class MentalModelResponse(BaseModel):
|
||||||
# override the default output from pydantic by calling `to_dict()` of trigger
|
# override the default output from pydantic by calling `to_dict()` of trigger
|
||||||
if self.trigger:
|
if self.trigger:
|
||||||
_dict['trigger'] = self.trigger.to_dict()
|
_dict['trigger'] = self.trigger.to_dict()
|
||||||
|
# set to None if source_query (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.source_query is None and "source_query" in self.model_fields_set:
|
||||||
|
_dict['source_query'] = None
|
||||||
|
|
||||||
|
# set to None if content (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.content is None and "content" in self.model_fields_set:
|
||||||
|
_dict['content'] = None
|
||||||
|
|
||||||
|
# set to None if max_tokens (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.max_tokens is None and "max_tokens" in self.model_fields_set:
|
||||||
|
_dict['max_tokens'] = None
|
||||||
|
|
||||||
|
# set to None if trigger (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.trigger is None and "trigger" in self.model_fields_set:
|
||||||
|
_dict['trigger'] = None
|
||||||
|
|
||||||
# set to None if last_refreshed_at (nullable) is None
|
# set to None if last_refreshed_at (nullable) is None
|
||||||
# and model_fields_set contains the field
|
# and model_fields_set contains the field
|
||||||
if self.last_refreshed_at is None and "last_refreshed_at" in self.model_fields_set:
|
if self.last_refreshed_at is None and "last_refreshed_at" in self.model_fields_set:
|
||||||
|
|
@ -115,7 +135,7 @@ class MentalModelResponse(BaseModel):
|
||||||
"source_query": obj.get("source_query"),
|
"source_query": obj.get("source_query"),
|
||||||
"content": obj.get("content"),
|
"content": obj.get("content"),
|
||||||
"tags": obj.get("tags"),
|
"tags": obj.get("tags"),
|
||||||
"max_tokens": obj.get("max_tokens") if obj.get("max_tokens") is not None else 2048,
|
"max_tokens": obj.get("max_tokens"),
|
||||||
"trigger": MentalModelTriggerOutput.from_dict(obj["trigger"]) if obj.get("trigger") is not None else None,
|
"trigger": MentalModelTriggerOutput.from_dict(obj["trigger"]) if obj.get("trigger") is not None else None,
|
||||||
"last_refreshed_at": obj.get("last_refreshed_at"),
|
"last_refreshed_at": obj.get("last_refreshed_at"),
|
||||||
"created_at": obj.get("created_at"),
|
"created_at": obj.get("created_at"),
|
||||||
|
|
|
||||||
|
|
@ -1435,13 +1435,13 @@ export type MentalModelResponse = {
|
||||||
/**
|
/**
|
||||||
* Source Query
|
* Source Query
|
||||||
*/
|
*/
|
||||||
source_query: string;
|
source_query?: string | null;
|
||||||
/**
|
/**
|
||||||
* Content
|
* Content
|
||||||
*
|
*
|
||||||
* The mental model content as well-formatted markdown (auto-generated from reflect endpoint)
|
* The mental model content as well-formatted markdown (auto-generated from reflect endpoint)
|
||||||
*/
|
*/
|
||||||
content: string;
|
content?: string | null;
|
||||||
/**
|
/**
|
||||||
* Tags
|
* Tags
|
||||||
*/
|
*/
|
||||||
|
|
@ -1449,8 +1449,8 @@ export type MentalModelResponse = {
|
||||||
/**
|
/**
|
||||||
* Max Tokens
|
* Max Tokens
|
||||||
*/
|
*/
|
||||||
max_tokens?: number;
|
max_tokens?: number | null;
|
||||||
trigger?: MentalModelTriggerOutput;
|
trigger?: MentalModelTriggerOutput | null;
|
||||||
/**
|
/**
|
||||||
* Last Refreshed At
|
* Last Refreshed At
|
||||||
*/
|
*/
|
||||||
|
|
@ -3331,6 +3331,12 @@ export type ListMentalModelsData = {
|
||||||
* How to match tags
|
* How to match tags
|
||||||
*/
|
*/
|
||||||
tags_match?: "any" | "all" | "exact";
|
tags_match?: "any" | "all" | "exact";
|
||||||
|
/**
|
||||||
|
* Detail
|
||||||
|
*
|
||||||
|
* Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
*/
|
||||||
|
detail?: "metadata" | "content" | "full";
|
||||||
/**
|
/**
|
||||||
* Limit
|
* Limit
|
||||||
*/
|
*/
|
||||||
|
|
@ -3458,7 +3464,14 @@ export type GetMentalModelData = {
|
||||||
*/
|
*/
|
||||||
mental_model_id: string;
|
mental_model_id: string;
|
||||||
};
|
};
|
||||||
query?: never;
|
query?: {
|
||||||
|
/**
|
||||||
|
* Detail
|
||||||
|
*
|
||||||
|
* Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)
|
||||||
|
*/
|
||||||
|
detail?: "metadata" | "content" | "full";
|
||||||
|
};
|
||||||
url: "/v1/default/banks/{bank_id}/mental-models/{mental_model_id}";
|
url: "/v1/default/banks/{bank_id}/mental-models/{mental_model_id}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,19 +186,52 @@ Enable automatic refresh for mental models that need to stay current. Disable it
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### Detail Levels
|
||||||
|
|
||||||
|
Both **List** and **Get** endpoints accept an optional `detail` query parameter that controls how much data is returned. This is useful for reducing response size, especially in agent boot flows or MCP clients where context budget is limited.
|
||||||
|
|
||||||
|
| Level | Fields Returned | Use Case |
|
||||||
|
|-------|----------------|----------|
|
||||||
|
| `metadata` | `id`, `bank_id`, `name`, `tags`, `last_refreshed_at`, `created_at` | Inventory — "what models exist?" |
|
||||||
|
| `content` | All metadata fields + `source_query`, `content`, `max_tokens`, `trigger` | Agent boot — "what do the models say?" |
|
||||||
|
| `full` (default) | All fields including `reflect_response` | Deep inspection — "what evidence backs this model?" |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List only names and tags (smallest response)
|
||||||
|
curl "$BASE_URL/v1/default/banks/$BANK_ID/mental-models?detail=metadata"
|
||||||
|
|
||||||
|
# List with content but without provenance chains
|
||||||
|
curl "$BASE_URL/v1/default/banks/$BANK_ID/mental-models?detail=content"
|
||||||
|
|
||||||
|
# Get full detail (default behavior)
|
||||||
|
curl "$BASE_URL/v1/default/banks/$BANK_ID/mental-models/$MODEL_ID?detail=full"
|
||||||
|
```
|
||||||
|
|
||||||
|
The `detail` parameter is also available in the MCP tools:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"bank_id": "my-bank", "detail": "metadata"}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
Use `detail=content` for agent orientation flows. It includes everything the agent needs to understand the models without the heavyweight `reflect_response` provenance chains, which can exceed 200KB for banks with many models.
|
||||||
|
:::
|
||||||
|
|
||||||
### Response Fields
|
### Response Fields
|
||||||
|
|
||||||
| Field | Type | Description |
|
| Field | Type | Detail Level | Description |
|
||||||
|-------|------|-------------|
|
|-------|------|-------------|-------------|
|
||||||
| `id` | string | Unique mental model ID |
|
| `id` | string | metadata | Unique mental model ID |
|
||||||
| `bank_id` | string | Memory bank ID |
|
| `bank_id` | string | metadata | Memory bank ID |
|
||||||
| `name` | string | Human-readable name |
|
| `name` | string | metadata | Human-readable name |
|
||||||
| `source_query` | string | The query used to generate content |
|
| `tags` | list | metadata | Tags for filtering |
|
||||||
| `content` | string | The generated mental model text |
|
| `last_refreshed_at` | string | metadata | When the mental model was last updated |
|
||||||
| `tags` | list | Tags for filtering |
|
| `created_at` | string | metadata | When the mental model was created |
|
||||||
| `last_refreshed_at` | string | When the mental model was last updated |
|
| `source_query` | string | content | The query used to generate content |
|
||||||
| `created_at` | string | When the mental model was created |
|
| `content` | string | content | The generated mental model text |
|
||||||
| `reflect_response` | object | Full reflect response including `based_on` facts |
|
| `max_tokens` | int | content | Maximum tokens for the mental model content |
|
||||||
|
| `trigger` | object | content | Trigger settings (see [Automatic Refresh](#automatic-refresh)) |
|
||||||
|
| `reflect_response` | object | full | Full reflect response including `based_on` provenance facts |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -971,6 +971,23 @@
|
||||||
},
|
},
|
||||||
"description": "How to match tags"
|
"description": "How to match tags"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "detail",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"enum": [
|
||||||
|
"metadata",
|
||||||
|
"content",
|
||||||
|
"full"
|
||||||
|
],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)",
|
||||||
|
"default": "full",
|
||||||
|
"title": "Detail"
|
||||||
|
},
|
||||||
|
"description": "Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "limit",
|
"name": "limit",
|
||||||
"in": "query",
|
"in": "query",
|
||||||
|
|
@ -1129,6 +1146,23 @@
|
||||||
"title": "Mental Model Id"
|
"title": "Mental Model Id"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "detail",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"enum": [
|
||||||
|
"metadata",
|
||||||
|
"content",
|
||||||
|
"full"
|
||||||
|
],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)",
|
||||||
|
"default": "full",
|
||||||
|
"title": "Detail"
|
||||||
|
},
|
||||||
|
"description": "Detail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "authorization",
|
"name": "authorization",
|
||||||
"in": "header",
|
"in": "header",
|
||||||
|
|
@ -6706,11 +6740,25 @@
|
||||||
"title": "Name"
|
"title": "Name"
|
||||||
},
|
},
|
||||||
"source_query": {
|
"source_query": {
|
||||||
"type": "string",
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
"title": "Source Query"
|
"title": "Source Query"
|
||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"type": "string",
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
"title": "Content",
|
"title": "Content",
|
||||||
"description": "The mental model content as well-formatted markdown (auto-generated from reflect endpoint)"
|
"description": "The mental model content as well-formatted markdown (auto-generated from reflect endpoint)"
|
||||||
},
|
},
|
||||||
|
|
@ -6723,13 +6771,25 @@
|
||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
"max_tokens": {
|
"max_tokens": {
|
||||||
"type": "integer",
|
"anyOf": [
|
||||||
"title": "Max Tokens",
|
{
|
||||||
"default": 2048
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Max Tokens"
|
||||||
},
|
},
|
||||||
"trigger": {
|
"trigger": {
|
||||||
"$ref": "#/components/schemas/MentalModelTrigger-Output",
|
"anyOf": [
|
||||||
"default": {}
|
{
|
||||||
|
"$ref": "#/components/schemas/MentalModelTrigger-Output"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"last_refreshed_at": {
|
"last_refreshed_at": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|
@ -6771,9 +6831,7 @@
|
||||||
"required": [
|
"required": [
|
||||||
"id",
|
"id",
|
||||||
"bank_id",
|
"bank_id",
|
||||||
"name",
|
"name"
|
||||||
"source_query",
|
|
||||||
"content"
|
|
||||||
],
|
],
|
||||||
"title": "MentalModelResponse",
|
"title": "MentalModelResponse",
|
||||||
"description": "Response model for a mental model (stored reflect response)."
|
"description": "Response model for a mental model (stored reflect response)."
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue