Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
744f74a39a | ||
|
|
07c8870b7b | ||
|
|
ef6fb55b00 | ||
|
|
8e9fa2ac60 |
@@ -3971,6 +3971,48 @@ def _register_routes(app: FastAPI):
|
||||
)
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.post(
|
||||
"/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear",
|
||||
response_model=MentalModelResponse,
|
||||
summary="Clear mental model content",
|
||||
description=(
|
||||
"Clear a mental model's content so the next refresh performs a full re-synthesis. "
|
||||
"This is useful for delta-mode models that have accumulated drift over many "
|
||||
"incremental refreshes. After clearing, call the /refresh endpoint to trigger "
|
||||
"a clean full rebuild."
|
||||
),
|
||||
operation_id="clear_mental_model",
|
||||
tags=["Mental Models"],
|
||||
)
|
||||
@audited("clear_mental_model", request_param=None)
|
||||
async def api_clear_mental_model(
|
||||
bank_id: str,
|
||||
mental_model_id: str,
|
||||
request_context: RequestContext = Depends(get_request_context),
|
||||
):
|
||||
"""Clear a mental model's content."""
|
||||
try:
|
||||
mental_model = await app.state.memory.clear_mental_model(
|
||||
bank_id=bank_id,
|
||||
mental_model_id=mental_model_id,
|
||||
request_context=request_context,
|
||||
)
|
||||
if mental_model is None:
|
||||
raise HTTPException(status_code=404, detail=f"Mental model '{mental_model_id}' not found")
|
||||
return MentalModelResponse(**mental_model)
|
||||
except OperationValidationError as e:
|
||||
raise HTTPException(status_code=e.status_code, detail=e.reason)
|
||||
except (AuthenticationError, HTTPException):
|
||||
raise
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
error_detail = f"{str(e)}\n\nTraceback:\n{traceback.format_exc()}"
|
||||
logger.error(
|
||||
f"Error in POST /v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear: {error_detail}"
|
||||
)
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.patch(
|
||||
"/v1/default/banks/{bank_id}/mental-models/{mental_model_id}",
|
||||
response_model=MentalModelResponse,
|
||||
|
||||
@@ -107,6 +107,7 @@ def create_mcp_server(memory: MemoryEngine, multi_bank: bool = True) -> FastMCP:
|
||||
"update_mental_model",
|
||||
"delete_mental_model",
|
||||
"refresh_mental_model",
|
||||
"clear_mental_model",
|
||||
"list_directives",
|
||||
"create_directive",
|
||||
"delete_directive",
|
||||
|
||||
@@ -8121,6 +8121,54 @@ class MemoryEngine(MemoryEngineInterface):
|
||||
|
||||
return self._row_to_mental_model(row) if row else None
|
||||
|
||||
async def clear_mental_model(
|
||||
self,
|
||||
bank_id: str,
|
||||
mental_model_id: str,
|
||||
*,
|
||||
request_context: "RequestContext",
|
||||
) -> dict[str, Any] | None:
|
||||
"""Clear a mental model's content so the next refresh performs a full re-synthesis.
|
||||
|
||||
Resets content to an empty string and clears structured_content and
|
||||
last_refreshed_source_query. This is useful for delta-mode models that
|
||||
have accumulated drift — after clearing, a normal /refresh will fall
|
||||
back to full mode because there is no delta baseline.
|
||||
|
||||
Args:
|
||||
bank_id: Bank identifier
|
||||
mental_model_id: Mental model UUID
|
||||
request_context: Request context for authentication
|
||||
|
||||
Returns:
|
||||
Updated mental model dict or None if not found
|
||||
"""
|
||||
await self._authenticate_tenant(request_context)
|
||||
if self._operation_validator:
|
||||
from hindsight_api.extensions import BankWriteContext
|
||||
|
||||
ctx = BankWriteContext(bank_id=bank_id, operation="clear_mental_model", request_context=request_context)
|
||||
await self._validate_operation(self._operation_validator.validate_bank_write(ctx))
|
||||
backend = await self._get_backend()
|
||||
|
||||
async with acquire_with_retry(backend) as conn:
|
||||
row = await conn.fetchrow(
|
||||
f"""
|
||||
UPDATE {fq_table("mental_models")}
|
||||
SET content = '',
|
||||
structured_content = NULL,
|
||||
last_refreshed_source_query = NULL
|
||||
WHERE bank_id = $1 AND id = $2
|
||||
RETURNING id, bank_id, name, source_query, content, tags,
|
||||
last_refreshed_at, created_at, reflect_response,
|
||||
max_tokens, trigger, structured_content
|
||||
""",
|
||||
bank_id,
|
||||
mental_model_id,
|
||||
)
|
||||
|
||||
return self._row_to_mental_model(row) if row else None
|
||||
|
||||
async def delete_mental_model(
|
||||
self,
|
||||
bank_id: str,
|
||||
|
||||
@@ -44,6 +44,7 @@ _ALL_TOOLS: frozenset[str] = frozenset(
|
||||
"update_mental_model",
|
||||
"delete_mental_model",
|
||||
"refresh_mental_model",
|
||||
"clear_mental_model",
|
||||
"list_directives",
|
||||
"create_directive",
|
||||
"delete_directive",
|
||||
@@ -221,6 +222,7 @@ def register_mcp_tools(
|
||||
"update_mental_model",
|
||||
"delete_mental_model",
|
||||
"refresh_mental_model",
|
||||
"clear_mental_model",
|
||||
"list_directives",
|
||||
"create_directive",
|
||||
"delete_directive",
|
||||
@@ -277,6 +279,9 @@ def register_mcp_tools(
|
||||
if "refresh_mental_model" in tools_to_register:
|
||||
_register_refresh_mental_model(mcp, memory, config)
|
||||
|
||||
if "clear_mental_model" in tools_to_register:
|
||||
_register_clear_mental_model(mcp, memory, config)
|
||||
|
||||
# Directive tools
|
||||
if "list_directives" in tools_to_register:
|
||||
_register_list_directives(mcp, memory, config)
|
||||
@@ -438,6 +443,7 @@ _AUDITABLE_MCP_TOOLS: frozenset[str] = frozenset(
|
||||
"update_mental_model",
|
||||
"delete_mental_model",
|
||||
"refresh_mental_model",
|
||||
"clear_mental_model",
|
||||
"create_directive",
|
||||
"delete_directive",
|
||||
"delete_document",
|
||||
@@ -1773,6 +1779,98 @@ def _register_refresh_mental_model(mcp: FastMCP, memory: MemoryEngine, config: M
|
||||
return {"error": str(e)}
|
||||
|
||||
|
||||
def _register_clear_mental_model(mcp: FastMCP, memory: MemoryEngine, config: MCPToolsConfig) -> None:
|
||||
"""Register the clear_mental_model tool."""
|
||||
|
||||
if config.include_bank_id_param:
|
||||
|
||||
@mcp.tool()
|
||||
async def clear_mental_model(
|
||||
mental_model_id: str,
|
||||
bank_id: str | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis.
|
||||
|
||||
This is useful for delta-mode models that have accumulated drift over many
|
||||
incremental refreshes. After clearing, call refresh_mental_model to trigger
|
||||
a clean full rebuild.
|
||||
|
||||
Args:
|
||||
mental_model_id: The ID of the mental model to clear
|
||||
bank_id: Optional bank (defaults to session bank). Use for cross-bank operations.
|
||||
"""
|
||||
try:
|
||||
target_bank = bank_id or config.bank_id_resolver()
|
||||
if target_bank is None:
|
||||
return '{"error": "No bank_id configured"}'
|
||||
|
||||
result = await memory.clear_mental_model(
|
||||
bank_id=target_bank,
|
||||
mental_model_id=mental_model_id,
|
||||
request_context=_get_request_context(config),
|
||||
)
|
||||
if result is None:
|
||||
return json.dumps({"error": f"Mental model '{mental_model_id}' not found"})
|
||||
return json.dumps(
|
||||
{
|
||||
"mental_model_id": result["id"],
|
||||
"status": "cleared",
|
||||
"message": f"Mental model '{mental_model_id}' content cleared. Call refresh_mental_model to rebuild.",
|
||||
}
|
||||
)
|
||||
except OperationValidationError as e:
|
||||
logger.warning(f"Operation rejected: {e}")
|
||||
return json.dumps({"error": str(e)})
|
||||
except ValueError as e:
|
||||
return json.dumps({"error": str(e)})
|
||||
except Exception as e:
|
||||
logger.error(f"Error clearing mental model: {e}", exc_info=True)
|
||||
return f'{{"error": "{e}"}}'
|
||||
|
||||
else:
|
||||
|
||||
@mcp.tool()
|
||||
async def clear_mental_model(
|
||||
mental_model_id: str,
|
||||
) -> dict:
|
||||
"""
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis.
|
||||
|
||||
This is useful for delta-mode models that have accumulated drift over many
|
||||
incremental refreshes. After clearing, call refresh_mental_model to trigger
|
||||
a clean full rebuild.
|
||||
|
||||
Args:
|
||||
mental_model_id: The ID of the mental model to clear
|
||||
"""
|
||||
try:
|
||||
target_bank = config.bank_id_resolver()
|
||||
if target_bank is None:
|
||||
return {"error": "No bank_id configured"}
|
||||
|
||||
result = await memory.clear_mental_model(
|
||||
bank_id=target_bank,
|
||||
mental_model_id=mental_model_id,
|
||||
request_context=_get_request_context(config),
|
||||
)
|
||||
if result is None:
|
||||
return {"error": f"Mental model '{mental_model_id}' not found"}
|
||||
return {
|
||||
"mental_model_id": result["id"],
|
||||
"status": "cleared",
|
||||
"message": f"Mental model '{mental_model_id}' content cleared. Call refresh_mental_model to rebuild.",
|
||||
}
|
||||
except OperationValidationError as e:
|
||||
logger.warning(f"Operation rejected: {e}")
|
||||
return {"error": str(e)}
|
||||
except ValueError as e:
|
||||
return {"error": str(e)}
|
||||
except Exception as e:
|
||||
logger.error(f"Error clearing mental model: {e}", exc_info=True)
|
||||
return {"error": str(e)}
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# DIRECTIVE TOOLS
|
||||
# =========================================================================
|
||||
|
||||
@@ -360,7 +360,8 @@ class TestMentalModelToolRegistration:
|
||||
assert "delete_bank" in tools
|
||||
assert "clear_memories" in tools
|
||||
assert "sync_retain" in tools
|
||||
assert len(tools) == 29
|
||||
assert "clear_mental_model" in tools
|
||||
assert len(tools) == 30
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -1838,3 +1838,51 @@ class TestMentalModelTriggerSchema:
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
MentalModelTrigger(tag_groups=[{"invalid_key": "bad"}])
|
||||
|
||||
|
||||
class TestClearMentalModel:
|
||||
"""Test clear_mental_model resets content so next refresh is full."""
|
||||
|
||||
async def test_clear_resets_content(self, memory: MemoryEngine, request_context):
|
||||
"""Clear sets content to empty string and nulls structured/tracking fields."""
|
||||
bank_id = f"test-mm-clear-{uuid.uuid4().hex[:8]}"
|
||||
await memory.get_bank_profile(bank_id, request_context=request_context)
|
||||
|
||||
mm = await memory.create_mental_model(
|
||||
bank_id=bank_id,
|
||||
name="Test Model",
|
||||
source_query="What do we know?",
|
||||
content="Some existing content",
|
||||
request_context=request_context,
|
||||
)
|
||||
assert mm["content"] == "Some existing content"
|
||||
|
||||
cleared = await memory.clear_mental_model(
|
||||
bank_id=bank_id,
|
||||
mental_model_id=mm["id"],
|
||||
request_context=request_context,
|
||||
)
|
||||
assert cleared is not None
|
||||
assert cleared["content"] == ""
|
||||
assert cleared["id"] == mm["id"]
|
||||
assert cleared["name"] == "Test Model"
|
||||
|
||||
# Re-fetch to confirm persistence
|
||||
fetched = await memory.get_mental_model(bank_id, mm["id"], request_context=request_context)
|
||||
assert fetched["content"] == ""
|
||||
|
||||
await memory.delete_bank(bank_id, request_context=request_context)
|
||||
|
||||
async def test_clear_nonexistent_returns_none(self, memory: MemoryEngine, request_context):
|
||||
"""Clearing a non-existent mental model returns None."""
|
||||
bank_id = f"test-mm-clear-none-{uuid.uuid4().hex[:8]}"
|
||||
await memory.get_bank_profile(bank_id, request_context=request_context)
|
||||
|
||||
result = await memory.clear_mental_model(
|
||||
bank_id=bank_id,
|
||||
mental_model_id="nonexistent-id",
|
||||
request_context=request_context,
|
||||
)
|
||||
assert result is None
|
||||
|
||||
await memory.delete_bank(bank_id, request_context=request_context)
|
||||
|
||||
@@ -35,6 +35,9 @@ list_document_chunks = "UI-only endpoint for the control plane document detail d
|
||||
# Reprocess triggers an async retain re-run; exposed in the control plane UI only.
|
||||
reprocess_document = "UI-only endpoint for the control plane document detail dialog"
|
||||
|
||||
# Clear mental model content is a new endpoint; CLI subcommand not yet implemented.
|
||||
clear_mental_model = "Not yet exposed in the CLI; use the HTTP API or SDK"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Per-operation parameter skips
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1157,6 +1157,54 @@ paths:
|
||||
summary: Refresh mental model
|
||||
tags:
|
||||
- Mental Models
|
||||
/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear:
|
||||
post:
|
||||
description: "Clear a mental model's content so the next refresh performs a\
|
||||
\ full re-synthesis. This is useful for delta-mode models that have accumulated\
|
||||
\ drift over many incremental refreshes. After clearing, call the /refresh\
|
||||
\ endpoint to trigger a clean full rebuild."
|
||||
operationId: clear_mental_model
|
||||
parameters:
|
||||
- explode: false
|
||||
in: path
|
||||
name: bank_id
|
||||
required: true
|
||||
schema:
|
||||
title: Bank Id
|
||||
type: string
|
||||
style: simple
|
||||
- explode: false
|
||||
in: path
|
||||
name: mental_model_id
|
||||
required: true
|
||||
schema:
|
||||
title: Mental Model Id
|
||||
type: string
|
||||
style: simple
|
||||
- explode: false
|
||||
in: header
|
||||
name: authorization
|
||||
required: false
|
||||
schema:
|
||||
nullable: true
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MentalModelResponse'
|
||||
description: Successful Response
|
||||
"422":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/HTTPValidationError'
|
||||
description: Validation Error
|
||||
summary: Clear mental model content
|
||||
tags:
|
||||
- Mental Models
|
||||
/v1/default/banks/{bank_id}/directives:
|
||||
get:
|
||||
description: List hard rules that are injected into prompts.
|
||||
|
||||
@@ -24,6 +24,132 @@ import (
|
||||
// MentalModelsAPIService MentalModelsAPI service
|
||||
type MentalModelsAPIService service
|
||||
|
||||
type ApiClearMentalModelRequest struct {
|
||||
ctx context.Context
|
||||
ApiService *MentalModelsAPIService
|
||||
bankId string
|
||||
mentalModelId string
|
||||
authorization *string
|
||||
}
|
||||
|
||||
func (r ApiClearMentalModelRequest) Authorization(authorization string) ApiClearMentalModelRequest {
|
||||
r.authorization = &authorization
|
||||
return r
|
||||
}
|
||||
|
||||
func (r ApiClearMentalModelRequest) Execute() (*MentalModelResponse, *http.Response, error) {
|
||||
return r.ApiService.ClearMentalModelExecute(r)
|
||||
}
|
||||
|
||||
/*
|
||||
ClearMentalModel Clear mental model content
|
||||
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.
|
||||
|
||||
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||
@param bankId
|
||||
@param mentalModelId
|
||||
@return ApiClearMentalModelRequest
|
||||
*/
|
||||
func (a *MentalModelsAPIService) ClearMentalModel(ctx context.Context, bankId string, mentalModelId string) ApiClearMentalModelRequest {
|
||||
return ApiClearMentalModelRequest{
|
||||
ApiService: a,
|
||||
ctx: ctx,
|
||||
bankId: bankId,
|
||||
mentalModelId: mentalModelId,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the request
|
||||
// @return MentalModelResponse
|
||||
func (a *MentalModelsAPIService) ClearMentalModelExecute(r ApiClearMentalModelRequest) (*MentalModelResponse, *http.Response, error) {
|
||||
var (
|
||||
localVarHTTPMethod = http.MethodPost
|
||||
localVarPostBody interface{}
|
||||
formFiles []formFile
|
||||
localVarReturnValue *MentalModelResponse
|
||||
)
|
||||
|
||||
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MentalModelsAPIService.ClearMentalModel")
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||
}
|
||||
|
||||
localVarPath := localBasePath + "/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear"
|
||||
localVarPath = strings.Replace(localVarPath, "{"+"bank_id"+"}", url.PathEscape(parameterValueToString(r.bankId, "bankId")), -1)
|
||||
localVarPath = strings.Replace(localVarPath, "{"+"mental_model_id"+"}", url.PathEscape(parameterValueToString(r.mentalModelId, "mentalModelId")), -1)
|
||||
|
||||
localVarHeaderParams := make(map[string]string)
|
||||
localVarQueryParams := url.Values{}
|
||||
localVarFormParams := url.Values{}
|
||||
|
||||
// to determine the Content-Type header
|
||||
localVarHTTPContentTypes := []string{}
|
||||
|
||||
// set Content-Type header
|
||||
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||
if localVarHTTPContentType != "" {
|
||||
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||
|
||||
// set Accept header
|
||||
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||
if localVarHTTPHeaderAccept != "" {
|
||||
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||
}
|
||||
if r.authorization != nil {
|
||||
parameterAddToHeaderOrQuery(localVarHeaderParams, "authorization", r.authorization, "simple", "")
|
||||
}
|
||||
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||
if err != nil {
|
||||
return localVarReturnValue, nil, err
|
||||
}
|
||||
|
||||
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||
if err != nil || localVarHTTPResponse == nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||
localVarHTTPResponse.Body.Close()
|
||||
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||
if err != nil {
|
||||
return localVarReturnValue, localVarHTTPResponse, err
|
||||
}
|
||||
|
||||
if localVarHTTPResponse.StatusCode >= 300 {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: localVarHTTPResponse.Status,
|
||||
}
|
||||
if localVarHTTPResponse.StatusCode == 422 {
|
||||
var v HTTPValidationError
|
||||
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr.error = err.Error()
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
|
||||
newErr.model = v
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
newErr := &GenericOpenAPIError{
|
||||
body: localVarBody,
|
||||
error: err.Error(),
|
||||
}
|
||||
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||
}
|
||||
|
||||
return localVarReturnValue, localVarHTTPResponse, nil
|
||||
}
|
||||
|
||||
type ApiCreateMentalModelRequest struct {
|
||||
ctx context.Context
|
||||
ApiService *MentalModelsAPIService
|
||||
|
||||
@@ -1048,6 +1048,19 @@ class Hindsight:
|
||||
"""
|
||||
return _run_async(self._mental_models_api.refresh_mental_model(bank_id, mental_model_id, _request_timeout=self._timeout))
|
||||
|
||||
def clear_mental_model(self, bank_id: str, mental_model_id: str):
|
||||
"""
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis.
|
||||
|
||||
Args:
|
||||
bank_id: The memory bank ID
|
||||
mental_model_id: The mental model ID
|
||||
|
||||
Returns:
|
||||
MentalModelResponse with cleared content
|
||||
"""
|
||||
return _run_async(self._mental_models_api.clear_mental_model(bank_id, mental_model_id, _request_timeout=self._timeout))
|
||||
|
||||
def update_mental_model(
|
||||
self,
|
||||
bank_id: str,
|
||||
|
||||
@@ -44,6 +44,299 @@ class MentalModelsApi:
|
||||
self.api_client = api_client
|
||||
|
||||
|
||||
@validate_call
|
||||
async def clear_mental_model(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
mental_model_id: StrictStr,
|
||||
authorization: Optional[StrictStr] = None,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
Tuple[
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
Annotated[StrictFloat, Field(gt=0)]
|
||||
]
|
||||
] = None,
|
||||
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||
_content_type: Optional[StrictStr] = None,
|
||||
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||
) -> MentalModelResponse:
|
||||
"""Clear mental model content
|
||||
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param mental_model_id: (required)
|
||||
:type mental_model_id: str
|
||||
:param authorization:
|
||||
:type authorization: str
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:type _request_timeout: int, tuple(int, int), optional
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the
|
||||
authentication in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:param _content_type: force content-type for the request.
|
||||
:type _content_type: str, Optional
|
||||
:param _headers: set to override the headers for a single
|
||||
request; this effectively ignores the headers
|
||||
in the spec for a single request.
|
||||
:type _headers: dict, optional
|
||||
:param _host_index: set to override the host_index for a single
|
||||
request; this effectively ignores the host_index
|
||||
in the spec for a single request.
|
||||
:type _host_index: int, optional
|
||||
:return: Returns the result object.
|
||||
""" # noqa: E501
|
||||
|
||||
_param = self._clear_mental_model_serialize(
|
||||
bank_id=bank_id,
|
||||
mental_model_id=mental_model_id,
|
||||
authorization=authorization,
|
||||
_request_auth=_request_auth,
|
||||
_content_type=_content_type,
|
||||
_headers=_headers,
|
||||
_host_index=_host_index
|
||||
)
|
||||
|
||||
_response_types_map: Dict[str, Optional[str]] = {
|
||||
'200': "MentalModelResponse",
|
||||
'422': "HTTPValidationError",
|
||||
}
|
||||
response_data = await self.api_client.call_api(
|
||||
*_param,
|
||||
_request_timeout=_request_timeout
|
||||
)
|
||||
await response_data.read()
|
||||
return self.api_client.response_deserialize(
|
||||
response_data=response_data,
|
||||
response_types_map=_response_types_map,
|
||||
).data
|
||||
|
||||
|
||||
@validate_call
|
||||
async def clear_mental_model_with_http_info(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
mental_model_id: StrictStr,
|
||||
authorization: Optional[StrictStr] = None,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
Tuple[
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
Annotated[StrictFloat, Field(gt=0)]
|
||||
]
|
||||
] = None,
|
||||
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||
_content_type: Optional[StrictStr] = None,
|
||||
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||
) -> ApiResponse[MentalModelResponse]:
|
||||
"""Clear mental model content
|
||||
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param mental_model_id: (required)
|
||||
:type mental_model_id: str
|
||||
:param authorization:
|
||||
:type authorization: str
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:type _request_timeout: int, tuple(int, int), optional
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the
|
||||
authentication in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:param _content_type: force content-type for the request.
|
||||
:type _content_type: str, Optional
|
||||
:param _headers: set to override the headers for a single
|
||||
request; this effectively ignores the headers
|
||||
in the spec for a single request.
|
||||
:type _headers: dict, optional
|
||||
:param _host_index: set to override the host_index for a single
|
||||
request; this effectively ignores the host_index
|
||||
in the spec for a single request.
|
||||
:type _host_index: int, optional
|
||||
:return: Returns the result object.
|
||||
""" # noqa: E501
|
||||
|
||||
_param = self._clear_mental_model_serialize(
|
||||
bank_id=bank_id,
|
||||
mental_model_id=mental_model_id,
|
||||
authorization=authorization,
|
||||
_request_auth=_request_auth,
|
||||
_content_type=_content_type,
|
||||
_headers=_headers,
|
||||
_host_index=_host_index
|
||||
)
|
||||
|
||||
_response_types_map: Dict[str, Optional[str]] = {
|
||||
'200': "MentalModelResponse",
|
||||
'422': "HTTPValidationError",
|
||||
}
|
||||
response_data = await self.api_client.call_api(
|
||||
*_param,
|
||||
_request_timeout=_request_timeout
|
||||
)
|
||||
await response_data.read()
|
||||
return self.api_client.response_deserialize(
|
||||
response_data=response_data,
|
||||
response_types_map=_response_types_map,
|
||||
)
|
||||
|
||||
|
||||
@validate_call
|
||||
async def clear_mental_model_without_preload_content(
|
||||
self,
|
||||
bank_id: StrictStr,
|
||||
mental_model_id: StrictStr,
|
||||
authorization: Optional[StrictStr] = None,
|
||||
_request_timeout: Union[
|
||||
None,
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
Tuple[
|
||||
Annotated[StrictFloat, Field(gt=0)],
|
||||
Annotated[StrictFloat, Field(gt=0)]
|
||||
]
|
||||
] = None,
|
||||
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||
_content_type: Optional[StrictStr] = None,
|
||||
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||
) -> RESTResponseType:
|
||||
"""Clear mental model content
|
||||
|
||||
Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.
|
||||
|
||||
:param bank_id: (required)
|
||||
:type bank_id: str
|
||||
:param mental_model_id: (required)
|
||||
:type mental_model_id: str
|
||||
:param authorization:
|
||||
:type authorization: str
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:type _request_timeout: int, tuple(int, int), optional
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the
|
||||
authentication in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:param _content_type: force content-type for the request.
|
||||
:type _content_type: str, Optional
|
||||
:param _headers: set to override the headers for a single
|
||||
request; this effectively ignores the headers
|
||||
in the spec for a single request.
|
||||
:type _headers: dict, optional
|
||||
:param _host_index: set to override the host_index for a single
|
||||
request; this effectively ignores the host_index
|
||||
in the spec for a single request.
|
||||
:type _host_index: int, optional
|
||||
:return: Returns the result object.
|
||||
""" # noqa: E501
|
||||
|
||||
_param = self._clear_mental_model_serialize(
|
||||
bank_id=bank_id,
|
||||
mental_model_id=mental_model_id,
|
||||
authorization=authorization,
|
||||
_request_auth=_request_auth,
|
||||
_content_type=_content_type,
|
||||
_headers=_headers,
|
||||
_host_index=_host_index
|
||||
)
|
||||
|
||||
_response_types_map: Dict[str, Optional[str]] = {
|
||||
'200': "MentalModelResponse",
|
||||
'422': "HTTPValidationError",
|
||||
}
|
||||
response_data = await self.api_client.call_api(
|
||||
*_param,
|
||||
_request_timeout=_request_timeout
|
||||
)
|
||||
return response_data.response
|
||||
|
||||
|
||||
def _clear_mental_model_serialize(
|
||||
self,
|
||||
bank_id,
|
||||
mental_model_id,
|
||||
authorization,
|
||||
_request_auth,
|
||||
_content_type,
|
||||
_headers,
|
||||
_host_index,
|
||||
) -> RequestSerialized:
|
||||
|
||||
_host = None
|
||||
|
||||
_collection_formats: Dict[str, str] = {
|
||||
}
|
||||
|
||||
_path_params: Dict[str, str] = {}
|
||||
_query_params: List[Tuple[str, str]] = []
|
||||
_header_params: Dict[str, Optional[str]] = _headers or {}
|
||||
_form_params: List[Tuple[str, str]] = []
|
||||
_files: Dict[
|
||||
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
|
||||
] = {}
|
||||
_body_params: Optional[bytes] = None
|
||||
|
||||
# process the path parameters
|
||||
if bank_id is not None:
|
||||
_path_params['bank_id'] = bank_id
|
||||
if mental_model_id is not None:
|
||||
_path_params['mental_model_id'] = mental_model_id
|
||||
# process the query parameters
|
||||
# process the header parameters
|
||||
if authorization is not None:
|
||||
_header_params['authorization'] = authorization
|
||||
# process the form parameters
|
||||
# process the body parameter
|
||||
|
||||
|
||||
# set the HTTP header `Accept`
|
||||
if 'Accept' not in _header_params:
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
[
|
||||
'application/json'
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# authentication setting
|
||||
_auth_settings: List[str] = [
|
||||
]
|
||||
|
||||
return self.api_client.param_serialize(
|
||||
method='POST',
|
||||
resource_path='/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear',
|
||||
path_params=_path_params,
|
||||
query_params=_query_params,
|
||||
header_params=_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
auth_settings=_auth_settings,
|
||||
collection_formats=_collection_formats,
|
||||
_host=_host,
|
||||
_request_auth=_request_auth
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@validate_call
|
||||
async def create_mental_model(
|
||||
self,
|
||||
|
||||
@@ -23,6 +23,9 @@ import type {
|
||||
ClearMemoryObservationsData,
|
||||
ClearMemoryObservationsErrors,
|
||||
ClearMemoryObservationsResponses,
|
||||
ClearMentalModelData,
|
||||
ClearMentalModelErrors,
|
||||
ClearMentalModelResponses,
|
||||
ClearObservationsData,
|
||||
ClearObservationsErrors,
|
||||
ClearObservationsResponses,
|
||||
@@ -563,6 +566,19 @@ export const refreshMentalModel = <ThrowOnError extends boolean = false>(
|
||||
ThrowOnError
|
||||
>({ url: "/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/refresh", ...options });
|
||||
|
||||
/**
|
||||
* Clear mental model content
|
||||
*
|
||||
* Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.
|
||||
*/
|
||||
export const clearMentalModel = <ThrowOnError extends boolean = false>(
|
||||
options: Options<ClearMentalModelData, ThrowOnError>
|
||||
) =>
|
||||
(options.client ?? client).post<ClearMentalModelResponses, ClearMentalModelErrors, ThrowOnError>({
|
||||
url: "/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear",
|
||||
...options,
|
||||
});
|
||||
|
||||
/**
|
||||
* List directives
|
||||
*
|
||||
|
||||
@@ -4335,6 +4335,46 @@ export type RefreshMentalModelResponses = {
|
||||
export type RefreshMentalModelResponse =
|
||||
RefreshMentalModelResponses[keyof RefreshMentalModelResponses];
|
||||
|
||||
export type ClearMentalModelData = {
|
||||
body?: never;
|
||||
headers?: {
|
||||
/**
|
||||
* Authorization
|
||||
*/
|
||||
authorization?: string | null;
|
||||
};
|
||||
path: {
|
||||
/**
|
||||
* Bank Id
|
||||
*/
|
||||
bank_id: string;
|
||||
/**
|
||||
* Mental Model Id
|
||||
*/
|
||||
mental_model_id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: "/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear";
|
||||
};
|
||||
|
||||
export type ClearMentalModelErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type ClearMentalModelError = ClearMentalModelErrors[keyof ClearMentalModelErrors];
|
||||
|
||||
export type ClearMentalModelResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: MentalModelResponse;
|
||||
};
|
||||
|
||||
export type ClearMentalModelResponse = ClearMentalModelResponses[keyof ClearMentalModelResponses];
|
||||
|
||||
export type ListDirectivesData = {
|
||||
body?: never;
|
||||
headers?: {
|
||||
|
||||
@@ -834,6 +834,23 @@ export class HindsightClient {
|
||||
return this.validateResponse(response, "refreshMentalModel");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a mental model's content so the next refresh performs a full re-synthesis.
|
||||
*/
|
||||
async clearMentalModel(
|
||||
bankId: string,
|
||||
mentalModelId: string,
|
||||
options?: { signal?: AbortSignal }
|
||||
): Promise<MentalModelResponse> {
|
||||
const response = await sdk.clearMentalModel({
|
||||
client: this.client,
|
||||
path: { bank_id: bankId, mental_model_id: mentalModelId },
|
||||
signal: options?.signal,
|
||||
});
|
||||
|
||||
return this.validateResponse(response, "clearMentalModel");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a mental model's metadata.
|
||||
*/
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { dataplaneBankUrl, getDataplaneHeaders } from "@/lib/hindsight-client";
|
||||
|
||||
export async function POST(
|
||||
request: Request,
|
||||
{ params }: { params: Promise<{ bankId: string; mentalModelId: string }> }
|
||||
) {
|
||||
try {
|
||||
const { bankId, mentalModelId } = await params;
|
||||
|
||||
if (!bankId || !mentalModelId) {
|
||||
return NextResponse.json(
|
||||
{ error: "bank_id and mental_model_id are required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
dataplaneBankUrl(bankId, `/mental-models/${encodeURIComponent(mentalModelId)}/clear`),
|
||||
{ method: "POST", headers: getDataplaneHeaders() }
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error("API error clearing mental model:", errorText);
|
||||
return NextResponse.json(
|
||||
{ error: errorText || "Failed to clear mental model" },
|
||||
{ status: response.status }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return NextResponse.json(data, { status: 200 });
|
||||
} catch (error) {
|
||||
console.error("Error clearing mental model:", error);
|
||||
return NextResponse.json({ error: "Failed to clear mental model" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -283,6 +283,35 @@ Refreshing is useful when:
|
||||
|
||||
---
|
||||
|
||||
## Clear a Mental Model
|
||||
|
||||
Clear a mental model's content so the next refresh performs a **full re-synthesis** from scratch, regardless of the model's trigger mode.
|
||||
|
||||
This is useful for delta-mode models that have accumulated drift over many incremental refreshes. Over time, small inaccuracies can compound as each delta refresh only sees new facts since the last. Clearing and then refreshing produces a clean baseline from all facts.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python">
|
||||
<CodeSnippet code={mentalModelsPy} section="clear-mental-model" language="python" />
|
||||
</TabItem>
|
||||
<TabItem value="node" label="Node.js">
|
||||
<CodeSnippet code={mentalModelsMjs} section="clear-mental-model" language="javascript" />
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="CLI">
|
||||
<CodeSnippet code={mentalModelsSh} section="clear-mental-model" language="bash" />
|
||||
</TabItem>
|
||||
<TabItem value="go" label="Go">
|
||||
<CodeSnippet code={mentalModelsGo} section="clear-mental-model" language="go" />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The clear operation is synchronous and resets the content to an empty string. The model's configuration (name, source query, trigger settings) is preserved. Since the content is now empty, the next `/refresh` call will always perform a full regeneration — even if the model's trigger mode is set to `delta`.
|
||||
|
||||
:::tip
|
||||
For long-lived delta-mode mental models, consider scheduling a periodic clear + refresh (e.g. every 48 hours) to keep the content accurate while still benefiting from incremental delta updates in between.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Update a Mental Model
|
||||
|
||||
Update the mental model's name:
|
||||
|
||||
@@ -125,6 +125,16 @@ func main() {
|
||||
fmt.Printf("Refresh operation ID: %s\n", refreshResult.GetOperationId())
|
||||
// [/docs:refresh-mental-model]
|
||||
|
||||
// [docs:clear-mental-model]
|
||||
// Clear a mental model's content, then refresh for a full re-synthesis
|
||||
client.MentalModelsAPI.ClearMentalModel(ctx, mmBankID, mentalModelID).Execute()
|
||||
|
||||
// Trigger a fresh full rebuild
|
||||
fullRefreshResult, _, _ := client.MentalModelsAPI.RefreshMentalModel(ctx, mmBankID, mentalModelID).Execute()
|
||||
|
||||
fmt.Printf("Full refresh operation ID: %s\n", fullRefreshResult.GetOperationId())
|
||||
// [/docs:clear-mental-model]
|
||||
|
||||
// [docs:update-mental-model]
|
||||
// Update a mental model's metadata
|
||||
newName := "Updated Team Communication Preferences"
|
||||
|
||||
@@ -96,6 +96,16 @@ const refreshResult = await client.refreshMentalModel(BANK_ID, mentalModelId);
|
||||
console.log(`Refresh operation ID: ${refreshResult.operation_id}`);
|
||||
// [/docs:refresh-mental-model]
|
||||
|
||||
// [docs:clear-mental-model]
|
||||
// Clear a mental model's content, then refresh for a full re-synthesis
|
||||
await client.clearMentalModel(BANK_ID, mentalModelId);
|
||||
|
||||
// Trigger a fresh full rebuild
|
||||
const fullRefreshResult = await client.refreshMentalModel(BANK_ID, mentalModelId);
|
||||
|
||||
console.log(`Full refresh operation ID: ${fullRefreshResult.operation_id}`);
|
||||
// [/docs:clear-mental-model]
|
||||
|
||||
// [docs:update-mental-model]
|
||||
// Update a mental model's metadata
|
||||
const updated = await client.updateMentalModel(BANK_ID, mentalModelId, {
|
||||
|
||||
@@ -109,6 +109,23 @@ if mental_model_id:
|
||||
# [/docs:refresh-mental-model]
|
||||
|
||||
|
||||
# [docs:clear-mental-model]
|
||||
# Clear a mental model's content, then refresh for a full re-synthesis
|
||||
client.clear_mental_model(
|
||||
bank_id=BANK_ID,
|
||||
mental_model_id=mental_model_id
|
||||
)
|
||||
|
||||
# Trigger a fresh full rebuild
|
||||
result = client.refresh_mental_model(
|
||||
bank_id=BANK_ID,
|
||||
mental_model_id=mental_model_id
|
||||
)
|
||||
|
||||
print(f"Full refresh operation ID: {result.operation_id}")
|
||||
# [/docs:clear-mental-model]
|
||||
|
||||
|
||||
# [docs:update-mental-model]
|
||||
# Update a mental model's metadata
|
||||
updated = client.update_mental_model(
|
||||
|
||||
@@ -65,6 +65,14 @@ if [ -n "$MENTAL_MODEL_ID" ]; then
|
||||
hindsight mental-model refresh "$BANK_ID" "$MENTAL_MODEL_ID"
|
||||
# [/docs:refresh-mental-model]
|
||||
|
||||
# [docs:clear-mental-model]
|
||||
# Clear a mental model's content, then refresh for a full re-synthesis
|
||||
curl -s -X POST "${HINDSIGHT_URL}/v1/default/banks/${BANK_ID}/mental-models/${MENTAL_MODEL_ID}/clear"
|
||||
|
||||
# Trigger a fresh full rebuild
|
||||
hindsight mental-model refresh "$BANK_ID" "$MENTAL_MODEL_ID"
|
||||
# [/docs:clear-mental-model]
|
||||
|
||||
# [docs:update-mental-model]
|
||||
# Update a mental model's metadata
|
||||
hindsight mental-model update "$BANK_ID" "$MENTAL_MODEL_ID" \
|
||||
|
||||
@@ -1690,6 +1690,74 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Mental Models"
|
||||
],
|
||||
"summary": "Clear mental model content",
|
||||
"description": "Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.",
|
||||
"operationId": "clear_mental_model",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "bank_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Bank Id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mental_model_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Mental Model Id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"in": "header",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Authorization"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/MentalModelResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/default/banks/{bank_id}/directives": {
|
||||
"get": {
|
||||
"tags": [
|
||||
|
||||
@@ -400,6 +400,48 @@ Refreshing is useful when:
|
||||
|
||||
---
|
||||
|
||||
## Clear a Mental Model
|
||||
|
||||
Clear a mental model's content so the next refresh performs a **full re-synthesis** from scratch, regardless of the model's trigger mode.
|
||||
|
||||
This is useful for delta-mode models that have accumulated drift over many incremental refreshes. Over time, small inaccuracies can compound as each delta refresh only sees new facts since the last. Clearing and then refreshing produces a clean baseline from all facts.
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
# Section 'clear-mental-model' not found in api/mental-models.py
|
||||
```
|
||||
|
||||
### Node.js
|
||||
|
||||
```javascript
|
||||
// Clear a mental model's content, then refresh for a full re-synthesis
|
||||
await client.clearMentalModel(BANK_ID, mentalModelId);
|
||||
|
||||
// Trigger a fresh full rebuild
|
||||
const fullRefreshResult = await client.refreshMentalModel(BANK_ID, mentalModelId);
|
||||
|
||||
console.log(`Full refresh operation ID: ${fullRefreshResult.operation_id}`);
|
||||
```
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
# Section 'clear-mental-model' not found in api/mental-models.sh
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```go
|
||||
# Section 'clear-mental-model' not found in api/mental-models.go
|
||||
```
|
||||
|
||||
The clear operation is synchronous and resets the content to an empty string. The model's configuration (name, source query, trigger settings) is preserved. Since the content is now empty, the next `/refresh` call will always perform a full regeneration — even if the model's trigger mode is set to `delta`.
|
||||
|
||||
:::tip
|
||||
For long-lived delta-mode mental models, consider scheduling a periodic clear + refresh (e.g. every 48 hours) to keep the content accurate while still benefiting from incremental delta updates in between.
|
||||
---
|
||||
|
||||
## Update a Mental Model
|
||||
|
||||
Update the mental model's name:
|
||||
|
||||
@@ -1690,6 +1690,74 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/clear": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Mental Models"
|
||||
],
|
||||
"summary": "Clear mental model content",
|
||||
"description": "Clear a mental model's content so the next refresh performs a full re-synthesis. This is useful for delta-mode models that have accumulated drift over many incremental refreshes. After clearing, call the /refresh endpoint to trigger a clean full rebuild.",
|
||||
"operationId": "clear_mental_model",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "bank_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Bank Id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mental_model_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"title": "Mental Model Id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"in": "header",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"title": "Authorization"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/MentalModelResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/default/banks/{bank_id}/directives": {
|
||||
"get": {
|
||||
"tags": [
|
||||
|
||||
Reference in New Issue
Block a user