mirror of
https://github.com/vectorize-io/hindsight.git
synced 2026-09-14 19:31:49 +08:00
41d71a9818
* feat(mcp): let create_mental_model configure tags_match (#2808) A tagged mental model with no explicit tags_match in its trigger JSON refreshes under all_strict (a memory must carry every one of the model's tags), while the staleness check and every recall/reflect path default to any. Broadly-tagged models reading narrowly-tagged memories therefore get marked stale and then refresh to empty content. The HTTP API, generated SDK clients, and Control Plane UI already let users set trigger.tags_match; the MCP create_mental_model tool did not. Add a tags_match argument (validated against TagsMatch) to both MCP variants. It is only written into the trigger when explicitly passed, so the resolved all_strict default is preserved for existing callers. Document the all_strict footgun and the tags_match override in the MCP and mental-models API docs (regen skills/hindsight-docs mirror). * fix(ts-client): expose tags_match/tag_groups on createMentalModel The ergonomic TypeScript wrapper's createMentalModel accepted only { refreshAfterConsolidation } in its trigger option and dropped every other trigger field, so a wrapper user could not set tags_match — the exact knob needed to avoid the empty-refresh footgun in #2808. The low-level generated sdk already accepts the full MentalModelTriggerInput; thread tagsMatch and tagGroups through, mirroring how recall/reflect already expose them. The Python client needs no change: its wrapper takes a pass-through trigger dict and the generated MentalModelTriggerInput already validates tags_match. * test(ts-client): cover createMentalModel trigger mapping Mock the generated sdk layer (no server needed) and assert the ergonomic camelCase trigger options map onto the snake_case body: tagsMatch -> tags_match, tagGroups -> tag_groups, refreshAfterConsolidation still maps, and omitting trigger sends none (preserving the all_strict default). Locks in the #2808 wrapper fix. * docs(mental-models): add tags_match code snippet Replace the static JSON block in the tags_match override section with a live CodeSnippet pulled from the Python example, showing how to create a model with trigger.tags_match="any" so a broadly-tagged model reads narrowly-tagged memories on refresh (#2808). * feat(cli): add --tags-match to mental-model create + all-language docs The Rust CLI's `mental-model create` was the last creation surface with no way to set tags_match, so a tagged model created via the CLI hit the same empty-refresh footgun (#2808). Add a `--tags-match` flag (any/all/any_strict/ all_strict/exact) that is only sent when passed, preserving the server's all_strict default; invalid values are rejected before the request. Expand the mental-models docs "tags_match override" example from a single Python snippet to a full Tabs block (Python / Node.js / CLI / Go), each pulled from the runnable example files, and regen the skills mirror.
111 lines
4.1 KiB
Bash
111 lines
4.1 KiB
Bash
#!/bin/bash
|
|
# Mental Models API examples for Hindsight CLI
|
|
# Run: bash examples/api/mental-models.sh
|
|
|
|
set -e
|
|
|
|
HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
|
|
BANK_ID="mental-models-demo-bank"
|
|
|
|
# =============================================================================
|
|
# Setup (not shown in docs)
|
|
# =============================================================================
|
|
hindsight bank create "$BANK_ID" --name "Mental Models Demo"
|
|
hindsight memory retain "$BANK_ID" "The team prefers async communication via Slack"
|
|
hindsight memory retain "$BANK_ID" "For urgent issues, use the #incidents channel"
|
|
hindsight memory retain "$BANK_ID" "Weekly syncs happen every Monday at 10am"
|
|
sleep 2
|
|
|
|
# =============================================================================
|
|
# Doc Examples
|
|
# =============================================================================
|
|
|
|
# [docs:create-mental-model]
|
|
# Create a mental model (runs reflect in background)
|
|
hindsight mental-model create "$BANK_ID" \
|
|
"Team Communication Preferences" \
|
|
"How does the team prefer to communicate?"
|
|
# [/docs:create-mental-model]
|
|
|
|
# [docs:create-mental-model-with-id]
|
|
# Create a mental model with a specific custom ID
|
|
hindsight mental-model create "$BANK_ID" \
|
|
"Communication Policy" \
|
|
"What are the team's communication guidelines?" \
|
|
--id communication-policy
|
|
# [/docs:create-mental-model-with-id]
|
|
|
|
sleep 5
|
|
|
|
# [docs:create-mental-model-with-trigger]
|
|
# Create a mental model and get its ID for subsequent operations
|
|
hindsight mental-model create "$BANK_ID" \
|
|
"Project Status" \
|
|
"What is the current project status?"
|
|
# [/docs:create-mental-model-with-trigger]
|
|
|
|
# [docs:create-mental-model-tags-match]
|
|
# Override how the model's tags filter source memories on refresh.
|
|
# A tagged model defaults to all_strict (a memory must carry EVERY tag);
|
|
# pass --tags-match any when your memories are tagged narrowly (one topic
|
|
# each), so the refresh reads any memory carrying at least one of the tags.
|
|
hindsight mental-model create "$BANK_ID" \
|
|
"Current Projects" \
|
|
"Which projects is the user currently working on?" \
|
|
--tags projects,mental-model \
|
|
--tags-match any
|
|
# [/docs:create-mental-model-tags-match]
|
|
|
|
sleep 5
|
|
|
|
# [docs:list-mental-models]
|
|
# List all mental models in a bank
|
|
hindsight mental-model list "$BANK_ID"
|
|
# [/docs:list-mental-models]
|
|
|
|
# Get the first mental model ID for subsequent examples
|
|
MENTAL_MODEL_ID=$(hindsight mental-model list "$BANK_ID" -o json | python3 -c "import sys,json; items=json.load(sys.stdin).get('items',[]); print(items[0]['id'] if items else '')" 2>/dev/null || echo "")
|
|
|
|
if [ -n "$MENTAL_MODEL_ID" ]; then
|
|
# [docs:get-mental-model]
|
|
# Get a specific mental model
|
|
hindsight mental-model get "$BANK_ID" "$MENTAL_MODEL_ID"
|
|
# [/docs:get-mental-model]
|
|
|
|
# [docs:refresh-mental-model]
|
|
# Refresh a mental model to update with current knowledge
|
|
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" \
|
|
--name "Updated Team Communication Preferences"
|
|
# [/docs:update-mental-model]
|
|
|
|
# [docs:get-mental-model-history]
|
|
# Get the change history of a mental model
|
|
hindsight mental-model history "$BANK_ID" "$MENTAL_MODEL_ID"
|
|
# [/docs:get-mental-model-history]
|
|
|
|
# [docs:delete-mental-model]
|
|
# Delete a mental model
|
|
hindsight mental-model delete "$BANK_ID" "$MENTAL_MODEL_ID" -y
|
|
# [/docs:delete-mental-model]
|
|
fi
|
|
|
|
# =============================================================================
|
|
# Cleanup (not shown in docs)
|
|
# =============================================================================
|
|
curl -s -X DELETE "${HINDSIGHT_URL}/v1/default/banks/${BANK_ID}" > /dev/null
|
|
|
|
echo "mental-models.sh: All examples passed"
|