All skills
vectorize-io avatar

/hindsight-docs

@5bfef3c
by vectorize-iovectorize-io/hindsight44k stars
5,845

Complete Hindsight documentation for AI agents. Use this to learn about Hindsight architecture, APIs, configuration, and best practices.

Use this Skill: https://skilld.dev/gh/vectorize-io/hindsight/hindsight-docs

This session only. Nothing lands on disk.

referencesdeveloperapibank-templates.md

≈3.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Bank Templates

Declarative JSON manifests for creating pre-configured memory banks with a single API call.

{/* Import raw source files */}

Overview

A bank template is a JSON manifest that describes a bank's full setup: configuration overrides, mental models, directives, and more. Instead of making multiple API calls to configure a bank, you submit one manifest and the API provisions everything.

Templates are useful for:

  • Replication — stamp out identically-configured banks for multiple users or agents
  • Onboarding — new users start with a known-good configuration instead of configuring from scratch
  • Sharing — distribute recommended setups as portable JSON files
  • Framework integrations — ship a recommended template alongside your integration

Browse the Bank Templates Hub for ready-to-use templates.

Manifest Schema

{
  "version": "1",
  "bank": {
    "reflect_mission": "...",
    "retain_mission": "...",
    "retain_extraction_mode": "concise | verbose | custom | verbatim | chunks",
    "retain_custom_instructions": "...",
    "retain_chunk_size": 2048,
    "retain_structured_chunk_size": 8192,
    "disposition_skepticism": 3,
    "disposition_literalism": 3,
    "disposition_empathy": 3,
    "enable_observations": true,
    "observations_mission": "...",
    "entity_labels": [{ "key": "sentiment", "type": "value", "values": [{ "value": "positive" }, { "value": "negative" }] }],
    "entities_allow_free_form": true
  },
  "mental_models": [
    {
      "id": "unique-lowercase-id",
      "name": "Human-Readable Name",
      "source_query": "The query that generates this mental model's content",
      "tags": ["optional", "tags"],
      "max_tokens": 2048,
      "trigger": {
        "refresh_after_consolidation": false,
        "fact_types": ["world", "experience", "observation"],
        "exclude_mental_models": false,
        "exclude_mental_model_ids": []
      }
    }
  ],
  "directives": [
    {
      "name": "directive-name",
      "content": "The directive instruction text",
      "priority": 0,
      "is_active": true,
      "tags": ["optional", "tags"]
    }
  ]
}

Fields

Field Required Description
version Yes Schema version. Currently "1".
bank No Bank configuration overrides. Omit to leave config unchanged.
mental_models No Mental models to create or update. Omit to leave unchanged.
directives No Directives to create or update. Omit to leave unchanged.

All of bank, mental_models, and directives are optional. Omit any section to leave that part of the bank unchanged.

Bank Config Fields

Every per-bank configuration setting can be carried in a template, so an exported bank reproduces its full configuration when imported elsewhere. All fields in bank are optional — only the fields you include are set as per-bank overrides, and everything else inherits from the server/tenant defaults.

The complete, always-current list is the template JSON Schema; each field means the same thing it does in Configuration. The most commonly used ones:

Field Type Description
reflect_mission string Mission/context for reflect operations
retain_mission string Steers what gets extracted during retain
retain_extraction_mode string concise, verbose, custom, verbatim, or chunks
retain_custom_instructions string Custom extraction prompt (requires mode=custom)
retain_chunk_size integer Target max characters per content chunk
retain_structured_chunk_size integer Max characters for a single JSONL line or conversation turn to keep whole; defaults to retain_chunk_size when unset
disposition_skepticism integer (1-5) How skeptical the disposition is
disposition_literalism integer (1-5) How literal the disposition is
disposition_empathy integer (1-5) How empathetic the disposition is
enable_observations boolean Toggle observation consolidation
observations_mission string Controls what gets synthesised into observations
entity_labels object[] Controlled vocabulary as label groups — see Memory Banks → entity_labels
entities_allow_free_form boolean Allow entities outside the label vocabulary

Mental Model Fields

Field Required Description
id Yes Unique ID (lowercase alphanumeric with hyphens). Used to match on re-import.
name Yes Human-readable name
source_query Yes The query that generates this model's content via reflect
tags No Tags for scoped visibility. Default: []
max_tokens No Max tokens for generated content (256-8192). Default: 2048
trigger No Trigger settings for auto-refresh

Directive Fields

Field Required Description
name Yes Directive name. Used as the match key on re-import.
content Yes The directive instruction text.
priority No Priority value (higher = more important). Default: 0
is_active No Whether the directive is active. Default: true
tags No Tags for categorization. Default: []

Import

Import a manifest into a bank. If the bank doesn't exist, it's created automatically.

Python

template = {
    "version": "1",
    "bank": {
        "retain_mission": "Extract customer issues, resolutions, and sentiment.",
        "enable_observations": True,
        "observations_mission": "Track recurring customer pain points.",
    },
    "mental_models": [
        {
            "id": "sentiment-overview",
            "name": "Customer Sentiment Overview",
            "source_query": "What is the overall sentiment trend?",
            "trigger": {"refresh_after_consolidation": True},
        }
    ],
    "directives": [
        {
            "name": "Acknowledge frustration",
            "content": "Always acknowledge frustration before offering solutions.",
            "priority": 10,
        }
    ],
}

response = requests.post(
    f"{HINDSIGHT_URL}/v1/default/banks/my-bank/import",
    json=template,
)
result = response.json()
print(f"Config applied: {result['config_applied']}")
print(f"Mental models created: {result['mental_models_created']}")
print(f"Directives created: {result['directives_created']}")

Node.js

const template = {
  version: '1',
  bank: {
    retain_mission: 'Extract customer issues, resolutions, and sentiment.',
    enable_observations: true,
    observations_mission: 'Track recurring customer pain points.',
  },
  mental_models: [
    {
      id: 'sentiment-overview',
      name: 'Customer Sentiment Overview',
      source_query: 'What is the overall sentiment trend?',
      trigger: { refresh_after_consolidation: true },
    },
  ],
  directives: [
    {
      name: 'Acknowledge frustration',
      content: 'Always acknowledge frustration before offering solutions.',
      priority: 10,
    },
  ],
};

const importResponse = await fetch(
  `${HINDSIGHT_URL}/v1/default/banks/my-bank/import`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(template),
  },
);
const result = await importResponse.json();
console.log('Config applied:', result.config_applied);
console.log('Mental models created:', result.mental_models_created);
console.log('Directives created:', result.directives_created);

CLI

curl -X POST "$HINDSIGHT_URL/v1/default/banks/my-bank/import" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "1",
    "bank": {
      "retain_mission": "Extract customer issues, resolutions, and sentiment.",
      "enable_observations": true,
      "observations_mission": "Track recurring customer pain points."
    },
    "mental_models": [
      {
        "id": "sentiment-overview",
        "name": "Customer Sentiment Overview",
        "source_query": "What is the overall sentiment trend?",
        "trigger": { "refresh_after_consolidation": true }
      }
    ],
    "directives": [
      {
        "name": "Acknowledge frustration",
        "content": "Always acknowledge frustration before offering solutions.",
        "priority": 10
      }
    ]
  }'

Go

template := map[string]interface{}{
	"version": "1",
	"bank": map[string]interface{}{
		"retain_mission":      "Extract customer issues, resolutions, and sentiment.",
		"enable_observations": true,
		"observations_mission": "Track recurring customer pain points.",
	},
	"mental_models": []map[string]interface{}{
		{
			"id":           "sentiment-overview",
			"name":         "Customer Sentiment Overview",
			"source_query": "What is the overall sentiment trend?",
			"trigger":      map[string]interface{}{"refresh_after_consolidation": true},
		},
	},
	"directives": []map[string]interface{}{
		{
			"name":     "Acknowledge frustration",
			"content":  "Always acknowledge frustration before offering solutions.",
			"priority": 10,
		},
	},
}

body, _ := json.Marshal(template)
resp, _ := http.Post(
	apiURL+"/v1/default/banks/my-bank/import",
	"application/json",
	bytes.NewReader(body),
)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
fmt.Println(string(respBody))

Behavior

  • Config: all bank fields are applied as per-bank config overrides
  • Mental models: matched by id — existing models are updated, new ones are created
  • Directives: matched by name — existing directives are updated, new ones are created
  • Async: mental model content is generated asynchronously. The response includes operation_ids to track progress.

Dry Run

Validate a manifest without applying changes:

Python

response = requests.post(
    f"{HINDSIGHT_URL}/v1/default/banks/my-bank/import",
    params={"dry_run": "true"},
    json=template,
)
result = response.json()
print(f"Dry run: {result['dry_run']}")
print(f"Would apply config: {result['config_applied']}")

Node.js

const dryRunResponse = await fetch(
  `${HINDSIGHT_URL}/v1/default/banks/my-bank/import?dry_run=true`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(template),
  },
);
const dryRunResult = await dryRunResponse.json();
console.log('Dry run:', dryRunResult.dry_run);
console.log('Would apply config:', dryRunResult.config_applied);

CLI

curl -X POST "$HINDSIGHT_URL/v1/default/banks/my-bank/import?dry_run=true" \
  -H "Content-Type: application/json" \
  -d '{"version": "1", "bank": {"retain_mission": "Dry run test."}}'

Go

resp, _ = http.Post(
	apiURL+"/v1/default/banks/my-bank/import?dry_run=true",
	"application/json",
	bytes.NewReader(body),
)
defer resp.Body.Close()
dryRunBody, _ := io.ReadAll(resp.Body)
fmt.Println(string(dryRunBody))

Returns what would happen (which config would be applied, which mental models would be created) without making any changes. Returns HTTP 400 with a detailed error message if the manifest is invalid.

Export

Export a bank's current config overrides, mental models, and directives as a manifest:

Python

response = requests.get(
    f"{HINDSIGHT_URL}/v1/default/banks/my-bank/export"
)
exported = response.json()
print(json.dumps(exported, indent=2))

Node.js

const exportResponse = await fetch(
  `${HINDSIGHT_URL}/v1/default/banks/my-bank/export`,
);
const exported = await exportResponse.json();
console.log(JSON.stringify(exported, null, 2));

CLI

curl "$HINDSIGHT_URL/v1/default/banks/my-bank/export"

Go

resp, _ = http.Get(apiURL + "/v1/default/banks/my-bank/export")
defer resp.Body.Close()
exported, _ := io.ReadAll(resp.Body)
fmt.Println(string(exported))

The exported manifest only includes config fields that were explicitly set as per-bank overrides — not the fully resolved config (which includes server/tenant defaults). This means the exported manifest is portable: importing it into a new bank only overrides the fields that were intentionally customized.

Round-trip

Export from one bank and import into another to replicate the setup:

Python

# Export from source bank
response = requests.get(
    f"{HINDSIGHT_URL}/v1/default/banks/source-bank/export"
)
exported = response.json()

# Import into a new bank
response = requests.post(
    f"{HINDSIGHT_URL}/v1/default/banks/new-bank/import",
    json=exported,
)

Node.js

// Export from source bank
const srcResponse = await fetch(
  `${HINDSIGHT_URL}/v1/default/banks/source-bank/export`,
);
const srcExported = await srcResponse.json();

// Import into a new bank
await fetch(`${HINDSIGHT_URL}/v1/default/banks/new-bank/import`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(srcExported),
});

CLI

# Export from source bank
curl "$HINDSIGHT_URL/v1/default/banks/source-bank/export" > template.json

# Import into a new bank
curl -X POST "$HINDSIGHT_URL/v1/default/banks/new-bank/import" \
  -H "Content-Type: application/json" \
  -d @template.json

Go

// Export from source bank
resp, _ = http.Get(apiURL + "/v1/default/banks/source-bank/export")
defer resp.Body.Close()
srcExported, _ := io.ReadAll(resp.Body)

// Import into a new bank
resp, _ = http.Post(
	apiURL+"/v1/default/banks/new-bank/import",
	"application/json",
	bytes.NewReader(srcExported),
)
defer resp.Body.Close()

JSON Schema

The manifest format is defined by a JSON Schema. Fetch the live schema from your server:

Python

response = requests.get(
    f"{HINDSIGHT_URL}/v1/bank-template-schema"
)
schema = response.json()
print(json.dumps(schema, indent=2))

Node.js

const schemaResponse = await fetch(
  `${HINDSIGHT_URL}/v1/bank-template-schema`,
);
const schema = await schemaResponse.json();
console.log(JSON.stringify(schema, null, 2));

CLI

curl "$HINDSIGHT_URL/v1/bank-template-schema"

Go

resp, _ = http.Get(apiURL + "/v1/bank-template-schema")
defer resp.Body.Close()
schema, _ := io.ReadAll(resp.Body)
fmt.Println(string(schema))

The static schema is also available at bank-template-schema.json.

Control Plane

The control plane bank creation dialog includes an optional "Import from template" toggle. Enable it to paste a manifest JSON and pre-configure the bank on creation.

You can also export any bank's template from the bank Settings page via Actions → Export Template, which copies the manifest JSON to your clipboard.

Versioning

The version field enables forward-compatible schema evolution. The current version is "1".

When future versions are released:

  • Older manifests are automatically upgraded to the current schema on import
  • Export always produces the latest version
  • The API rejects manifests with a version newer than what the server supports (with a clear error message suggesting an upgrade)

This means old templates keep working indefinitely — no need to manually update them.

Source: SKILL.md on GitHub

1 alerttoday5 checks · Risk SAFE
  • Gen Agent Trust Hubtoday

    The skill is a comprehensive documentation set for the Hindsight memory system, providing architecture overviews, API references, and integration guides for multiple AI agent frameworks. No security risks were identified in the documentation or provided examples.

  • Sockettoday

    No alerts

  • Snyktoday

    Risk: LOW · No issues

  • Runlayer6mo

    30/42 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 5bfef3c. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 14 hours ago.

Activeupdated 2 months ago

README badge

README badge for vectorize-io/hindsight/hindsight-docs