Commit Graph

182 Commits

Author SHA1 Message Date
Ben 41ad2b55a0 feat(flowise): add Flowise integration with Hindsight memory tools (#1436)
* feat(flowise): add Flowise integration with Hindsight memory tools

Adds three Flowise Tool nodes — Hindsight Retain, Hindsight Recall,
Hindsight Reflect — that drop into any chatflow or agent flow alongside
the standard LangChain tools. Each node returns a DynamicStructuredTool
from init(), so it slots into Flowise's tool sockets and any LangChain
agent.

- One shared hindsightApi credential (apiUrl + optional apiKey) for all
  three nodes
- Source files use upstream-relative imports (`../../../src/Interface`
  and `../src/Interface`) and copy 1:1 into Flowise's
  packages/components/ tree at submission time. A local src/Interface.ts
  shim mirrors the upstream API so the files compile and unit-test
  outside the Flowise monorepo.
- 17 vitest unit tests covering INode metadata, credential shape, and
  init() returning a Tool that forwards to the Hindsight client with the
  expected arguments
- test-flowise-integration CI job (Node 22, npm install + tsc + vitest),
  flowise added to release-integration.sh, docs page at
  /sdks/integrations/flowise, integrations.json listing, real Flowise
  logo
2026-06-01 10:00:06 -04:00
Ben bf6b90263b feat(roo-code): add Roo Code integration with MCP + rules (#920)
* feat(roo-code): add Roo Code integration with MCP + rules

Adds hindsight-integrations/roo-code — persistent long-term memory for
Roo Code via Hindsight MCP. One-command installer sets up .roo/mcp.json
and injects a rules file that auto-recalls before tasks and auto-retains
after.
2026-05-28 16:23:09 -04:00
Ben dde133da00 feat(vapi): add Vapi voice AI webhook memory integration (#923)
* feat(vapi): add Vapi voice AI webhook memory integration
2026-05-28 15:53:32 -04:00
Ben 7cdacc4bf9 feat(gemini-spark): add Hindsight integration for Gemini Spark via MCP (#1779)
* feat(gemini-spark): add Hindsight integration for Gemini Spark via MCP

Config-only integration with example Antigravity 2.0 manifest and MCP
config, prioritizing Hindsight Cloud. Includes 14 pytest tests validating
config structure, CI job, and release script entry.
2026-05-28 11:26:47 -04:00
Nicolò Boschi a401b97eb7 docs: add 0.7.0 changelog and release blog post (#1781)
* docs: add 0.7.0 changelog and release blog post

Documents the 0.7.0 release: ParadeDB pg_search BM25 backend
(Citus-compatible), PGroonga + configurable BM25 language for
multilingual/CJK search, async link recompute that fixes outgoing-link
staleness after deletes, Control Plane i18n in 8 locales, targeted
consolidation by observation scope, an observation-consolidation prompt
rewrite, a clear-mental-model endpoint, ZeroEntropy + Codex OAuth
embeddings, and a long tail of bug fixes.

Also fixes release.sh to refresh the root package-lock.json after
workspace version bumps. Without this, npm ci in CI fails because the
lock pins the previous workspace versions and the publish + docs-deploy
jobs break (which is what happened to the initial v0.7.0 tag).

* docs(blog): tighten 0.7.0 release post

- Merge entity-edge-derivation (#1766), unused-index drops (#1762), and
  async link recompute into a single "Graph Storage & Maintenance"
  section that leads with the ~50% storage reduction.
- Merge "Targeted Consolidation by Scope" and "Consolidation Quality
  Rewrite" into one "Consolidation Improvements" section; drop prompt
  internals.
- Rewrite the multilingual section at a higher level (concepts, not env
  vars) and link out to /developer/multilingual.

* docs(blog): rewrite 0.7.0 release post in announcement tone

Rewrite each section in the same voice as prior major-release posts
(0.5.0, 0.6.0): lead with what the user gets and why it matters,
drop implementation internals (queue tables, FK cascades, JSON
predicates, AST walkers), keep concrete config knobs and code
examples where they help, and link out to docs for deep dives.

* docs(blog): move ParadeDB section to last; reorder intro to match

* docs(blog): demote Clear Mental Model from feature section to Other Notable Changes
2026-05-27 16:30:54 +02:00
Derek Bouius b20c0d8f67 fix(ci): set UV_FROZEN=1 on verify-generated-files job (#1629)
Set UV_FROZEN=1 as a job-level env var so all uv commands (sync, run,
lock) respect the committed lockfile without re-resolving. This is the
idiomatic uv approach for CI and prevents spurious uv.lock diffs that
blocked every Dependabot PR.

Reverts the lint.sh CI-specific --frozen logic from #1618 since the
env var covers it globally.
2026-05-14 10:24:47 -04:00
Derek Bouius 5c7aea4717 fix(ci): use frozen lockfile in lint.sh during CI (#1618)
lint.sh runs `uv sync` without --frozen at the repo root, which
re-resolves uv.lock. In CI's verify-generated-files job this causes
spurious 1-line diffs on every Dependabot PR, blocking them from
merging.

Use --frozen when $CI is set so the lockfile is never modified by
the lint step. Local development keeps the non-frozen sync to handle
version bumps gracefully.
2026-05-13 13:58:48 -04:00
Nicolò Boschi 2161c4e815 chore: stabilize CI — docs-skill pre-commit hook + retain dict-mutation fix (#1490)
* ci: add pre-commit hook to keep skills/hindsight-docs in sync

The CI verify-generated-files job has been failing on ~82% of recent
runs because PRs touch hindsight-docs/src/pages/changelog/ or
hindsight-docs/static/openapi.json without re-running
./scripts/generate-docs-skill.sh, leaving the committed
skills/hindsight-docs/references/ copy stale.

Catch the drift locally instead. The hook regenerates and, if the
working tree diverges from the index after regen, fails the commit
with a clear message pointing the author at `git add skills/hindsight-docs/`.

The pre-commit dispatcher (.githooks/pre-commit) already iterates every
*.sh in scripts/hooks/, so the new file is picked up automatically.

* fix(retain): stop mutating caller-provided content dicts

PR #1398 (memory pressure) added an in-place pop of the "content" key
on contents_dicts after building combined_content, to release per-item
strings the engine no longer needs. Because the engine forwarded the
caller's dict objects all the way through (memory_engine →
_retain_batch_async_internal → orchestrator.retain_batch), the pop
reached back through the same references and stripped the key from
the caller's input. Any code path that holds onto the contents list
after retain_batch_async returns then trips KeyError: 'content'.

This is what was making test_extensions.py::TestOperationHooksParameters::
test_retain_pre_hook_receives_all_parameters fail intermittently on
main (the streaming path triggers the pop; non-streaming paths skip it).

Fix:
- memory_engine.py: take an engine-owned shallow copy of contents
  after the validator hook so the orchestrator can mutate freely
  without leaking to the caller. Strings are shared by reference,
  so the copy adds only ~150 bytes of dict overhead per item —
  negligible vs the multi-MB strings.
- orchestrator.py (_streaming_retain_batch): clear combined_content
  immediately after handle_document_tracking / upsert_document_metadata
  in all three first-batch paths (no-facts skip, mini-batch DB work,
  post-loop fallback). Once tracking persists the document, nothing
  reads combined_content again, so releasing it shrinks the lifetime
  of the per-document text from "until function returns" to "until DB
  write completes" — recovering the bulk of #1398's memory savings
  without the caller-mutation side effect. nonlocal declarations on
  _process_db_batch and _run_mini_batch_db_work are required because
  Python infers combined_content as local once any branch assigns to it.

Memory profile vs PR #1398:
- #1398 benchmark shape (caller releases its reference at call time):
  identical sustained, brief 2x peak during the combined_content +
  per-item-strings overlap window before tracking completes. Other
  PR #1398 savings (chunks, batch lists, sanitized_content) untouched.
- HTTP / FastAPI callers (request body holds strings until the handler
  returns): no observable change — those strings were going to live
  through the request anyway.
2026-05-06 17:18:52 +02:00
Nicolò Boschi a86d5381d5 fix(packaging): hard-pin meta packages to matching hindsight-api-slim (#1486)
The meta packages (hindsight-api, hindsight-all, hindsight-all-slim,
hindsight-dev) are pure entry-point shims — all real code, including
__version__ shown on the startup banner, lives in hindsight-api-slim.
Their dependency on slim was a stale floor (>=0.4.17), so
`pip install -U hindsight-api==0.6.0` left an older slim in place and
the server reported the previous version.

Hard-pin each meta package to the matching slim/api version, and teach
scripts/release.sh to rewrite the pin alongside the existing
`version = "..."` bumps so future releases stay in sync.
2026-05-06 15:27:38 +02:00
Nicolò Boschi efe5ff8494 feat(perf): publish perf-test results to external dashboard (#1474)
* feat(perf): publish perf-test results to external dashboard repo

Adds `--benchmark-output-dir` to perf-test, which emits two JSON files
in github-action-benchmark format: latency.json (smaller-is-better:
durations + recall p50/p95/p99/mean) and throughput.json (bigger-is-
better: items/queries/memories per sec). The Performance Tests workflow
now publishes both to vectorize-io/hindsight-continuous-performance-
monitor's gh-pages branch on each scheduled run.

Iteration mode (TEMP — search "TEMP" to revert before merge):
push trigger on this branch, default scale=small, locomo skipped
unless manually dispatched.

Setup needed (one-time):
- PAT with Contents:write on the dashboard repo, stored as secret
  PERF_DASHBOARD_TOKEN.
- After the first run creates gh-pages there, enable Pages on that
  repo (Settings → Pages → gh-pages branch).

* fix(perf): wipe benchmark working dir between latency and throughput publishes

github-action-benchmark clones the dashboard repo into a fixed
./benchmark-data-repository directory and doesn't clean up, so the
second invocation in the same job fails with 'destination path already
exists'.

* feat(perf): replace github-action-benchmark with custom dashboard publisher

Drops the two benchmark-action steps (and the dead `--benchmark-output-dir`
flag + `_to_benchmark_entries` helper in system_perf.py) in favour of a
single `scripts/benchmarks/publish-perf-results.sh` step. The script:

1. Reads the perf-test JSON output.
2. Enriches it with commit metadata (subject, author, author_date,
   commit URL, PR URL via `gh api commits/<sha>/pulls`).
3. Clones the dashboard repo's gh-pages branch using PERF_DASHBOARD_TOKEN.
4. Writes data/<timestamp>-<short_sha>.json and prepends the run to
   data/index.json (newest first).
5. Commits and pushes (with one rebase-retry on push rejection).

The matching custom static site lives on gh-pages of
vectorize-io/hindsight-continuous-performance-monitor (separate commit
in that repo).

* perf(workflow): publish dashboard on workflow_dispatch too

* feat(perf): publish workflow run URL and LoComo results to dashboard

Perf script now embeds workflow_run.{id,url} in each enriched run JSON
and the manifest entry, sourced from default GitHub Actions env vars
(GITHUB_RUN_ID + GITHUB_REPOSITORY).

LoComo gets its own publish script (publish-locomo-results.sh) and a
new step in the locomo job. The script strips per-question
detailed_results (kept in the workflow artifact) before pushing — keeps
each run small enough for git. Output lands at:
  data/locomo/<timestamp>-<short_sha>.json
  data/locomo-index.json
The matching dashboard page (locomo.html) is in the dashboard repo.

* perf(workflow): revert iteration-mode TEMP markers

Restores the production defaults that were temporarily flipped while
iterating on the dashboard:
- drop the push trigger on feat/perf-dashboard
- default scale: small → large
- default locomo_skip: true → false
- locomo job condition: workflow_dispatch-only → inputs.locomo_skip != true

Scheduled cron now runs the full suite + LoComo daily and publishes
to the dashboard.
2026-05-06 15:12:11 +02:00
Nicolò Boschi c124b0f28b chore: remove self-driving-agents CLI — moved to vectorize-io/self-driving-agents (#1461)
The CLI source, tests, and CI have been moved to
https://github.com/vectorize-io/self-driving-agents and published
as @vectorize-io/self-driving-agents@0.0.7 from that repo.

Removed:
- hindsight-tools/self-driving-agents/ (source + tests)
- CI job test-self-driving-agents from test.yml
- Workspace entry from root package.json
- Tool entry from release-tool.sh
2026-05-06 09:12:30 +02:00
Ben bc23750b29 feat(dify): add Dify integration with Hindsight memory tools (#1434)
* feat(dify): add Dify integration with Hindsight memory tools

Adds a Dify Tool Plugin under hindsight-integrations/dify/ exposing three
tools — Retain, Recall, Reflect — that can drop into any Dify workflow,
chatflow, or agent app alongside other LLM and tool nodes.

- Provider with API URL + optional API key credentials, validated via
  Hindsight /health
- 15 unit tests (pytest + pytest-mock)
- test-dify-integration CI job, dify added to release-integration.sh
- Docs page at /sdks/integrations/dify, integrations.json listing,
  placeholder icon
- Live-tested end-to-end against local Hindsight: Retain → fact extraction
  → Recall → Reflect synthesis all pass via Dify workflow

Distributed via GitHub for now; Dify Marketplace submission to follow.

* chore(dify): use real Dify logo for integrations listing

Replaces the placeholder blue-D SVG with the actual Dify icon on the
integrations listing page.

* docs(dify): add author + contact info to plugin README

Required by the Dify Marketplace submission checklist.

* fix(dify): address review feedback — add tool tests, error handling, cleanup

- Add 14 tests for RetainTool, RecallTool, ReflectTool _invoke() methods
- Add try/except around client calls with user-friendly error messages
- Simplify urljoin to f-string in provider health check
- Remove deprecated Pydantic v1 dict() fallback in _memory_to_dict
- Remove emoji from build_package.sh output
- Add comment explaining reflect's lower default budget

---------

Co-authored-by: Nicolò Boschi <boschi1997@gmail.com>
2026-05-05 10:41:20 +02:00
Ben c1eaf7110d feat(n8n): add n8n community-node package for Hindsight memory (#1364)
* feat(n8n): add n8n community-node package for Hindsight memory

Adds @vectorize-io/n8n-nodes-hindsight — an n8n community node package
that exposes Hindsight retain / recall / reflect as workflow operations.
Drop the Hindsight node into any workflow alongside Slack, Sheets,
OpenAI, etc. and you have persistent memory across runs.

Package layout (n8n community-node convention):
- credentials/HindsightApi.credentials.ts: credential class
  (apiUrl + optional apiKey, /health test, Bearer auth)
- nodes/Hindsight/Hindsight.node.ts: single node with operation parameter
  exposing retain / recall / reflect (matches Slack-style multi-op nodes)
- nodes/Hindsight/hindsight.svg: node icon
- 14 unit tests (vitest) covering credential metadata, node properties,
  per-operation field gating, budget enums

Wiring:
- detect-changes filter + test-n8n-integration job in test.yml
  (cloned from test-opencode-integration shape)
- Added n8n to VALID_INTEGRATIONS in scripts/release-integration.sh
- New /sdks/integrations/n8n docs page
- Entry in integrations.json so n8n appears on the listing
- n8n.svg icon (placeholder; replace with brand-approved version)

Verified: tsc + vitest both clean (npm run build, npm test).

* feat(n8n): use Hindsight iris logo as node icon

Replaces the placeholder mark with the actual brand logo (PNG).
Updates copy-icons to ship any hindsight.* file with the build, and
ignores npm-pack tarballs.
2026-05-05 10:01:43 +02:00
Nicolò Boschi d39a2ca618 feat(oracle): unify migrations under Alembic with dialect dispatcher (#1330)
* feat(oracle): unify migrations under Alembic with dialect dispatcher

Oracle DDL was a 636-line idempotent file (`migrations_oracle.py`) outside
Alembic, which meant no version tracking, no per-tenant version table, and
schema drift every time a PG migration was added without a corresponding
Oracle change. This unifies both backends behind a single Alembic tree.

- New `alembic/_dialect.py::run_for_dialect(pg=, oracle=)` helper. Each
  migration declares `_pg_upgrade` / `_oracle_upgrade` and dispatches based
  on the live connection's dialect.
- `alembic/env.py` is dialect-aware: PG keeps the existing search_path /
  read-write session setup; Oracle uses `ALTER SESSION SET CURRENT_SCHEMA`
  and `DDL_LOCK_TIMEOUT`.
- `alembic/script.py.mako` scaffolds the new pattern by default.
- All 59 existing PG migrations refactored mechanically — bodies moved into
  `_pg_upgrade` / `_pg_downgrade`, top-level dispatchers added.
- New `o1a2b3c4d5e6_oracle_baseline` migration brings a fresh Oracle 23ai
  database to the current schema in one step (PG = no-op). Drops the legacy
  partition-conversion / dedup / `observation_sources` backfill since those
  only existed for pre-baseline Oracle installs we explicitly are not
  supporting.
- `OracleBackend.run_migrations()` now goes through the unified Alembic
  pipeline; `migrations.py` skips the PG-specific advisory lock + pgvector
  setup when the URL is Oracle.
- `migrations_oracle.py` deleted; tests updated to use `run_migrations()`.
- New `tests/test_migration_shape.py` lint fails CI if any migration omits
  `run_for_dialect` — keeps drift from re-emerging.
- CLAUDE.md updated with the new template and dialect-asymmetry guidance.

* ci: run client integration tests against Oracle on oracle-tests label

Adds test-python-client-oracle and test-typescript-client-oracle. These
mirror the existing test-python-client / test-typescript-client jobs but
spin up Oracle 23ai as a service container and point the API server at it
via HINDSIGHT_API_DATABASE_BACKEND=oracle + DATABASE_URL.

Why a new job instead of matrixing the existing one: Oracle Free's image
takes ~2min to start and is network-heavy, so we don't want to pay that
cost on every PR — only when oracle-tests is opted in via the PR label,
matching the existing test-api-oracle gate.

Why client tests, not unit tests: the unit suite already runs against
both backends via the abstraction layer. Only the client tests exercise
full HTTP round-trips with real serialized payloads, so they catch API
changes that work on PG but break on Oracle (or vice versa) in ways the
abstraction can't see.

* refactor(oracle): tighten feature requirements and dedup is_oracle_url

- Move is_oracle_url to db_url.py and import from there in env.py and
  migrations.py — was duplicated in both.
- Type-annotate _configure_pg_session / _configure_oracle_session params
  (Engine, Connection); ty checks pass.
- Update the Oracle baseline comment around vector + text index creation
  to make the hard requirement explicit: VECTOR + CTXSYS must be
  available, the migration fails hard if either is missing. The
  swallow-only-ORA-00955 behavior was already correct; the previous
  comment misleadingly called it "best-effort".

* chore(openclaw): apply pending prettier reformat to keep verify-generated-files green

Three formatting-only changes prettier wants to make. They've been stale
on main; CI's verify-generated-files runs lint with LINT_ALL=1 (vs the
"only changed integrations" local default), which surfaces them on every
unrelated PR. Folding them in here so this PR can land.

* fix(retain): plumb ops through handle_document_tracking

Line 312 of fact_storage.py references ``ops`` without ``handle_document_tracking``
declaring it as a parameter — straight NameError on every retain that walks
the upsert path. Bug landed on main in d8ec2d7f (#1325) when
``delete_stale_observations_for_memories`` started taking a backend-aware
``ops`` to choose between the PG array operator and the Oracle junction
table; the call site was added but the parameter wasn't threaded into the
enclosing function.

Fix: add ``ops=None`` to ``handle_document_tracking`` and pass ``pool.ops``
from each of the three call sites in orchestrator.py.

This is unrelated to the Alembic dialect-dispatcher refactor in this PR but
is what's blocking it — the NameError caused 17 retain tests to fail (and
left a pytest-xdist worker in a state that hung the whole job at 99%).

* test(observation): pass ops to handle_document_tracking in upsert test

The test calls fact_storage.handle_document_tracking directly, which
delegates to delete_stale_observations_for_memories(ops=ops). With ops=None
the helper falls back to the Oracle junction-table query and fails on PG
with "relation public.observation_sources does not exist". Real callers
(orchestrator, _delete_stale_observations_for_memories wrapper) all pass
self._backend.ops; the test just needs to do the same.

* ci: run client-against-oracle on every API change, drop label gate

Reserve the "oracle-tests" label for the heavy test-api-oracle (full unit
suite). The two client integration jobs against Oracle should run on every
API/client change just like their PG counterparts — the whole point is to
catch PG/Oracle drift before merge, which doesn't work if you have to
remember to label every PR. test-api-oracle keeps its label gate because
the full suite is too slow to run on every push.

* fix(oracle): rewrite path-style service to ?service_name= for SQLAlchemy

Oracle Free / Autonomous DB only register a service name with the listener,
but SQLAlchemy's oracle+oracledb dialect interprets the URL path as a SID.
That mismatch crashes alembic migrations on first connect:
  DPY-6003: SID "FREEPDB1" is not registered with the listener

Rewrite ``oracle://user:pass@host:port/SERVICE`` to
``oracle+oracledb://user:pass@host:port/?service_name=SERVICE`` so the
dialect uses the correct connect descriptor. ``?sid=`` and ``?service_name=``
already in the URL are passed through untouched.

Also adds scripts/dev/start-oracle.sh / stop-oracle.sh that spin up the same
Oracle 23ai Free image CI uses (``container-registry.oracle.com/database/free``)
and bootstrap the HINDSIGHT_TEST user, so we can repro this kind of issue
locally without round-tripping through GitHub Actions.

* fix(oracle): commit after migrations so alembic_version persists

On Oracle, alembic runs each migration with transactional_ddl=False
("Will assume non-transactional DDL"). Each CREATE TABLE auto-commits, but
the trailing ``UPDATE alembic_version SET version_num = ...`` is plain DML
that needs an explicit COMMIT. Without it the connection close rolls the
update back, leaving the schema fully created but the version row one
revision behind — so ``run_migrations`` reports success while the head row
sits at the previous revision.

Caught locally with the new scripts/dev/start-oracle.sh harness running the
same Oracle 23ai Free image CI uses; alembic_version was stuck at
``k6l7m8n9o0p1`` even though every table from the ``o1a2b3c4d5e6`` baseline
existed. After the fix it correctly advances to ``o1a2b3c4d5e6``, and a
second run is a no-op as expected.

PG already needs the same commit (Supabase RW-mode SET), so just drop the
``if not is_oracle`` guard.

* ci(oracle): run python client tests sequentially to avoid ORA-00060

The python client pyproject.toml defaults to -n auto (pytest-xdist).
Against Oracle that hits row-level deadlocks during retain cleanup —
ORA-00060 is logged repeatedly in the API server output and most tests
fail with "Internal Server Error" at fixture teardown. Same shape as the
existing test-api-oracle issue, which is already pinned to -n0.

Override to -n0 in the Oracle client job (only). The PG client job stays
parallel since pgvector + advisory locks handle concurrent retain fine.
TS client tests are unaffected — they run via vitest, not pytest.
2026-04-30 13:58:03 +02:00
Nicolò Boschi 7f30dcc780 feat: self-driving agents (part1) (#1302)
* feat(claude-code): add wiki script + agent-knowledge skill

wiki.py: CLI for knowledge pages, recall, ingest, documents.
Uses the existing plugin lib/ for bank resolution and API calls.
No separate config — reads from the same settings.json as retain/recall hooks.

agent-knowledge skill: teaches the agent to use wiki.py commands.
Bank resolution is automatic (same as retain hooks).
Pages default to: delta mode, observation-only, exclude mental models.

* feat: hindsight-agent-sdk (Python + TypeScript) + Claude Code wiki integration

* refactor: move skill to SDK, remove harness-specific skill from claude-code

* feat: add trigger params to MCP create_mental_model + MCP-based skill

- MCP create_mental_model now accepts trigger_mode, trigger_exclude_mental_models,
  trigger_fact_types params (both multi-bank and single-bank modes)
- Skill uses mcp__hindsight__* tools directly — no CLI, no scripts
- Bank scoped via MCP URL: /mcp/banks/{bank_id}/

* feat(openclaw): register wiki tools via registerTool API

* feat: standalone hindsight-agent-setup (npx-able) for all harnesses

* fix(openclaw): static import for wiki-tools (ESM compat)

* rename: agent_knowledge_* tools + cleaner skill (no hindsight/wiki/mental_model confusion)

* fix(openclaw): set tools optional=false so they're not filtered by allowlist

* refactor: setup reads directory layout (bank-template.json + content/), agent name from dir

* rename: @vectorize-io/self-driving-agents, setup→install

* cleanup: remove setup backwards compat

* fix: list_pages uses detail=metadata to avoid blowing up context

* chore: publish-ready package.json, README, .gitignore for self-driving-agents

* rename: hindsight-agent-setup → self-driving-agents

* cleanup: remove MCP tool changes, Python/TS SDKs, Claude Code wiki — keep only openclaw tools + skill + CLI

* cleanup: remove Rust CLI + Python CLI (superseded by self-driving-agents TS CLI)

* cleanup: rename wiki→knowledge, add release-tool.sh, interactive cloud setup, remove SDKs

* refactor: CLI does zero API calls, plugin bootstraps template+content on first session

* feat: CLI checks plugin install+config, runs wizard if needed

* feat(self-driving-agents): TUI wizard, TS client, GitHub agent sources

- Replace raw HTTP with @vectorize-io/hindsight-client SDK
- Add @clack/prompts for polished terminal UI (spinners, confirms, notes)
- Support GitHub agent sources: bare name defaults to vectorize-io/self-driving-agents,
  org/repo/path fetches from any public repo, local paths still work
- Remove bootstrap code from openclaw plugin (CLI handles all API calls)
- Fix ANSI-polluted JSON parsing for openclaw agents list
- Run setup wizard inline when user declines current config

* feat(self-driving-agents): recursive content discovery, drop content/ convention

Content files (.md, .txt, etc.) are now found recursively from the
agent directory root. No special content/ subdirectory needed.

This enables nested agent repos where pointing at any level ingests
all files below it:
- install marketing → all 30 files + root bank-template.json
- install marketing/seo → only SEO files + seo/bank-template.json

* cleanup: remove unrelated files (screenshots, PDF, pretext-poc)

* refactor(self-driving-agents): bundle SKILL.md as file, read at runtime

Move the skill from a hardcoded string to a bundled file at skill/SKILL.md.
Each CLI version ships its own skill — re-running install upgrades it.

* cleanup: remove hindsight-agent-sdk/skill, now bundled in self-driving-agents

* feat: knowledge tools opt-in via enableKnowledgeTools config flag

Plugin: agent_knowledge_* tools only register when enableKnowledgeTools
is true in the plugin config (default: false).

CLI: automatically sets enableKnowledgeTools=true in openclaw.json
during install.

* feat: create hindsight-agent-sdk, move tools under hindsight-tools/

- New @vectorize-io/hindsight-agent-sdk package with harness-agnostic
  knowledge tools using @vectorize-io/hindsight-client (no raw HTTP)
- OpenClaw plugin now imports from the SDK instead of inline knowledge-tools.ts
- Move self-driving-agents and hindsight-agent-sdk under hindsight-tools/
- Update release-tool.sh for new paths

* test: add tests for hindsight-agent-sdk and self-driving-agents

Agent SDK (11 tests): tool creation, endpoint routing, request bodies,
auth headers, page defaults (delta mode, observation facts).

Self-driving-agents CLI (23 tests): recursive content discovery,
local/GitHub path detection, ANSI JSON parsing, bank ID resolution
from plugin config.

CI: add test-hindsight-agent-sdk and test-self-driving-agents jobs
with detect-changes filtering.

* refactor: move tests to tests/ dirs, add prettier for hindsight-tools

- Move tests from src/ to tests/ matching repo conventions
- Add hindsight-tools/ prettier block to lint.sh
- Format all files with prettier

* fix(ci): add hindsight-tools to npm workspaces, build agent-sdk before openclaw

- Add hindsight-tools/* to root workspaces so npm resolves the agent-sdk
- Build agent-sdk before openclaw in all 3 openclaw CI jobs
- Use root npm ci + workspace builds for tool CI jobs
- Regenerate lockfiles

* fix(ci): use file: dep for agent-sdk in openclaw, whitelist in lockfile checker

- openclaw depends on @vectorize-io/hindsight-agent-sdk via file: ref
  (matching how control-plane depends on hindsight-client)
- Lockfile checker whitelists hindsight-tools/* workspace deps
- Regenerate openclaw lockfile
2026-04-29 15:53:56 +02:00
Ben 8314de5e06 feat: add SmolAgents integration with Hindsight memory tools (#658)
* feat(smolagents): add SmolAgents integration with Hindsight memory tools

Adds hindsight-integrations/smolagents with retain, recall, and reflect tools
for HuggingFace SmolAgents.

- hindsight_smolagents/: config, errors, and tools (retain/recall/reflect, plus
  memory_instructions helper for prompt-time injection)
- 81 unit tests (all passing)
- Docs page at hindsight-docs/docs-integrations/smolagents.md
- Icon at hindsight-docs/static/img/icons/smolagents.png
- Entry in integrations.json so it appears on the listing page
- CI workflow job test-smolagents-integration
- Wired into scripts/release-integration.sh VALID_INTEGRATIONS

Replaces the earlier draft commits (originally opened March 23) with a clean
single commit rebased on latest main, dropping unrelated package-lock.json
changes that had been bundled in by mistake.

* fix(smolagents): add title and description to docs frontmatter

build-docs CI requires every integration page to have both 'title' and
'description' in its frontmatter. Without them, check-integration-seo.mjs
fails the docusaurus build.

* ci: re-trigger CI after flaky test-python-client

* fix(smolagents): wire integration into release + sidebar; lint fixes

- Add smolagents to the INTEGRATIONS table in generate_changelog.py so
  the release script can cut a tag (release-integration.sh already had
  it after the rebase, but the changelog generator needs its own entry).
- Add a sidebar link in hindsight-docs/sidebars.ts so the docs page is
  reachable from navigation, matching the agentcore pattern.
- examples/interactive_test.py: import-order + drop f-prefix on a
  no-placeholder f-string (ruff F541, I001).
- ruff format adjustments in tools.py.

---------

Co-authored-by: Nicolò Boschi <boschi1997@gmail.com>
2026-04-29 11:37:49 +02:00
Ben c91696f53d feat(agentcore): add hindsight-agentcore integration for Bedrock AgentCore Runtime (#822)
* feat(agentcore): add hindsight-agentcore Python integration

Adds durable cross-session memory for Amazon Bedrock AgentCore Runtime
agents. Runtime sessions are ephemeral; this adapter persists memory
across session churn keyed to stable user identity.

- HindsightRuntimeAdapter with before_turn() / after_turn() / run_turn()
- TurnContext: maps AgentCore invocation identity to Hindsight banks
- default_bank_resolver: tenant:user:agent format (session ID never used)
- RecallPolicy: recall (default) or reflect mode with configurable budget
- RetentionPolicy: context label, tags, metadata, user message inclusion
- Async-by-default retention — never delays the turn response
- Graceful degradation throughout — memory failures never surface to user
- 41 unit tests covering adapter, bank resolution, and config

* feat(agentcore): add CI job, release entry, and docs page

* Add AgentCore icon to sidebar

* fix(agentcore): add pytest to dependency-groups, fix paperclip.md diff

* feat(agentcore): add LICENSE, CHANGELOG, example, live test, and listing entry

Brings PR #822 to parity with the Pipecat reference (commit f7cc9ad6):

- LICENSE (MIT) for community distribution readiness
- CHANGELOG.md: initial 0.1.0 release notes
- examples/basic_runtime_handler.py: minimal AgentCore Runtime handler
  showing TurnContext + adapter.run_turn() with a stub agent_callable
- tests/test_live_integration.py: pytest-skipif live test gated on
  HINDSIGHT_API_KEY; verifies retain (turn 1) -> recall (new session, same user)
  surfaces the planted fact via memory_context
- integrations.json: agentcore entry so it appears on the listings page

Verified: 41 unit tests pass (live test skips cleanly without the key);
ruff clean.
2026-04-29 10:13:22 +02:00
Nicolò Boschi c308e473a8 Release v0.5.5
- Update version to 0.5.5 in all components
- Regenerate OpenAPI spec and client SDKs
- Python packages: hindsight-api, hindsight-dev, hindsight-all, hindsight-embed
- Python client: hindsight-clients/python
- TypeScript client: hindsight-clients/typescript
- hindsight-all npm wrapper: hindsight-all-npm
- Rust CLI: hindsight-cli
- Control Plane: hindsight-control-plane
- Helm chart
- Sync documentation to version-0.5

scripts/generate-clients.sh: generate the Python client into a tmp dir
then sync into place. The previous direct bind mount of the client dir
worked on Linux CI but failed on macOS Docker Desktop with
NoSuchFileException when openapi-generator wrote api_client.py and
related supporting files; generating into /tmp avoids that.
2026-04-28 13:24:08 +02:00
Nicolò Boschi 461b00d4d9 fix(llm): omit tool_choice="auto" and add deepseek as first-class provider (#1294)
* fix(llm): omit tool_choice="auto" and add deepseek as first-class provider

DeepSeek's reasoner pathway (which deepseek-v4-flash enters by default
with thinking mode) returns HTTP 400 for any tool_choice value, including
"auto". Since omitting tool_choice is semantically equivalent to "auto"
per the OpenAI API spec, we now omit it whenever the caller passes "auto",
which fixes reflect for deepseek-v4-flash without changing behaviour for
compliant providers.

Also promotes DeepSeek to a first-class provider: provider="deepseek"
auto-configures base_url=https://api.deepseek.com and the default model
to deepseek-v4-flash. Documented in configuration.md and .env.example.

* docs(deepseek): add to LLMProvidersGrid, default-models table, and config examples

The LLMProvidersGrid component on the Models page is the canonical visual
list of supported LLM providers; it was missing DeepSeek. Also add it to
the provider default-models table and the per-provider configuration
example block in models.mdx so the page is internally consistent.

* docs: single-source-of-truth for LLM providers (data file + table component)

Adds hindsight-docs/src/data/llmProviders.tsx as the canonical list of
supported providers with id, label, icon, and default model. Both
LLMProvidersGrid (icon grid on the Models page) and the new
LLMProvidersTable component (used in models.mdx for the default-models
table) consume it, so adding a provider now means editing one file
instead of three.

While converting, also added the providers that were missing from the
icon grid: Vertex AI, OpenAI Codex, Claude Code, OpenRouter.

* fix(docs-skill): render LLM provider grid + table in agent skill mirror

The agent-facing skill at skills/hindsight-docs/ is plain markdown — the
MDX-to-MD converter in scripts/generate-docs-skill.sh was leaving
<LLMProvidersTable /> and <LLMProvidersGrid /> as literal JSX, breaking
the verify-generated-files CI check and hiding the supported-providers
data from agents that rely on the skill.

Move the provider data out of llmProviders.tsx into llmProviders.json so
both the React components and the Python skill generator read from the
same source. Teach the converter to render <LLMProvidersTable /> as a
markdown table and <LLMProvidersGrid /> as a bullet list, sourced from
that JSON. Adding a provider is still one-file: edit llmProviders.json.

* chore(pipecat): apply ruff format

Files added in f7cc9ad6 (feat(pipecat)) have unformatted whitespace and
line lengths that the shared ruff config rewrites. Local lint.sh only
re-formats integrations with uncommitted changes, so the drift slipped
in; CI runs with LINT_ALL=1 and surfaces it via verify-generated-files.
2026-04-28 11:42:58 +02:00
Ben f7cc9ad663 feat(pipecat): add Pipecat voice AI pipeline memory integration (#921)
* feat(pipecat): add Pipecat voice AI pipeline memory integration

* fix(pipecat): make OpenAILLMContextFrame import optional for forward compat

* feat(pipecat): add LICENSE, CHANGELOG, examples, and live integration test

- LICENSE (MIT) + CHANGELOG.md for community distribution readiness
- examples/basic_pipeline.py: full Daily/Deepgram/OpenAI/Cartesia voice pipeline
- examples/interactive_chat.py: text-based REPL for manual memory validation
- tests/test_live_integration.py: pytest-skipped live test, verifies Retain/Recall/Inject/Idempotency against a running Hindsight instance

Verified: 17/17 unit tests pass; live integration test passes all 4 checks against localhost:8888.

* chore(pipecat): add docs page, integrations listing entry, and icon

- hindsight-docs/docs-integrations/pipecat.md: docs page for the integrations site
- hindsight-docs/src/data/integrations.json: entry so Pipecat appears on the listing
- hindsight-docs/static/img/icons/pipecat.png: icon for the listing
2026-04-28 10:07:40 +02:00
Nicolò Boschi 794b83d839 chore(lint): cover all npm packages with prettier in lint.sh (#1279)
So formatting violations in hindsight-clients/typescript and
hindsight-all-npm now fail CI via verify-generated-files (same
git-status-after-lint pattern Python uses).

- Add prettier-ts-client and prettier-all-npm tasks to lint.sh
- Delete hindsight-clients/typescript/.prettierrc local override so
  openapi-ts auto-discovers the shared root .prettierrc.json (was
  printWidth 80 / trailingComma "all", now 100 / "es5")
- Reformat affected files (mostly mechanical)
2026-04-27 16:23:15 +02:00
Nicolò Boschi 9c33a7c730 feat(perf): add system performance test runner (#1201)
* feat(perf): add system performance test runner and CI workflow

Add `uv run perf-test` command that orchestrates retain throughput and
recall latency benchmarks using mock LLM + pg0 for deterministic,
LLM-independent baselines. Wraps existing recall_perf/retain_perf
building blocks without duplicating benchmark logic.

Also fixes _RRFReranker in recall_perf.py to include the cross_encoder
attribute now required by the engine's combined scoring path.

* feat(perf): add run-perf-test.sh script

* feat(perf): use run-perf-test.sh in CI, remove run-retain-perf.sh

Replace ad-hoc retain perf wrapper with the new system perf test
script in CI workflow and docs. The standalone retain_perf.py is still
available for ad-hoc document benchmarking.

* feat(perf): add suite input to workflow dispatch
2026-04-22 17:37:58 +02:00
DK09876 b8da88c854 feat: add OpenAI Agents SDK integration (#842)
* feat: add OpenAI Agents SDK integration for Hindsight

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(openai-agents): add memory_instructions, fix bugs, add CI, harden tests

- Add memory_instructions() for auto-injecting memories into agent system
  prompt via a callable compatible with Agent(instructions=...)
- Fix or-vs-is-not-None bugs in reflect_max_tokens and reflect_tags_match
  that silently ignored falsy values like 0
- Surface entity data in recall output when recall_include_entities=True
- Add user_agent tracking in _client.py for analytics
- Tighten openai-agents dependency to >=0.7.0
- Add CI test job for openai-agents integration in test.yml
- Add 9 new unit tests (31→40 total): entity surfacing, memory_instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(openai-agents): address review findings from PR #842

- Deduplicate version string into _version.py to prevent drift
- Fix memory_instructions to fall back to config.max_tokens
- Simplify error handling: remove misleading HindsightError re-raise
- Use `is not None` check for reflect response.text (empty != missing)
- Use getattr for entity access instead of fragile hasattr chain
- Add tests for memory_instructions config fallback (max_tokens, tags)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Nicolò Boschi <boschi1997@gmail.com>
2026-04-17 10:15:25 +02:00
Nicolò Boschi 654e4c0cfa feat(mental-models): staleness signal + history reflect snapshot + UI revamp (#1089)
* feat(mental-models): staleness signal + history reflect snapshot + UI revamp

Backend
- Add MemoryEngine.compute_mental_model_is_stale(): scope-aware check
  using MM tags + trigger.tags_match (+ fact_types filter). Replaces the
  bank-wide `pending_consolidation > 0` shortcut that falsely flagged
  unrelated MMs and missed the "consolidation done, MM not refreshed"
  case.
- MentalModelResponse.is_stale (detail=full) exposes the flag on the API.
- Consolidation refresh trigger and tool_search_mental_models now use the
  shared helper, so refreshes only fire for MMs whose scope actually has
  new memories.
- history entries now snapshot previous_reflect_response (based_on +
  answer) alongside previous_content, so the UI can show per-version
  grounding.

UI (control plane)
- Replace the right-side MentalModelDetailPanel with a near-fullscreen
  Dialog (Content / Configuration / History tabs).
- Content tab: stored-content card with In sync / Stale badge, relative
  "last refreshed" timestamp, Based On list.
- Configuration tab: 4 cards surfacing id, source query, tags, trigger
  (fact_types, exclude rules, recall params, tag_groups).
- History tab: content diff + per-version based_on diff (+added, -removed,
  kept).
- Shared CompactMarkdown + relative-time helpers; card previews use the
  same renderer as the detail modal.
- Dialog border removed, shared delete-item styling for dark mode.

Tests
- 8 new unit tests for compute_mental_model_is_stale covering untagged
  scope, tagged scope, any_strict / all_strict, fact_types filter, plus a
  tool_search_mental_models regression test.
- test_history_snapshots_previous_reflect_response verifies history rows
  capture the prior reflect_response.

Regenerated OpenAPI spec and Python/Go/TypeScript clients.

* chore: regen hindsight-docs skill openapi snapshot
2026-04-15 18:25:04 +02:00
Nicolò Boschi 70a7411659 chore(lint): share ruff/prettier config across integrations (#1072)
* chore(lint): share ruff/prettier config across integrations

Adds root ruff.toml and .prettierrc.json so every integration package is
formatted with the same rules. lint.sh now also lints integration
packages — only those with modified files locally, all of them in CI
(when $CI is set, or via LINT_ALL_INTEGRATIONS=1).

* style(integrations): apply shared ruff/prettier formatting

Mechanical reformat — output of ruff format / prettier --write under the
new shared configs. No behavior changes.

* chore: regenerate docs skill
2026-04-15 10:39:34 +02:00
Mr. Khachaturov 16ed93b9a2 fix(docs): regenerate bank-template-schema.json and guard drift (#1065)
hindsight-docs/static/bank-template-schema.json is hand-edited.
Nothing regenerates it and nothing checks it. Three PRs have
changed BankTemplateManifest since it was last touched:
#902 flipped entity_labels from list[str] to list[dict[str, Any]],
#1044 added ten BankTemplateConfig fields, #1048 added three
MentalModelTrigger fields.

None of the bundled templates use the new fields, so Ajv in
check-templates.mjs still passes. A template that uses the
dict-shaped label format fails with 'should be string' on
every label.

Regenerate from BankTemplateManifest.model_json_schema() and
hook the generator into verify-generated-files alongside
generate-openapi and generate-clients.
2026-04-15 09:18:19 +02:00
Nicolò Boschi 0c4b79b6d3 chore(ci): guard against workspace-resolved deps in integration lockfiles (#1020)
The openclaw 0.6.0 release workflow failed at `npm run build` because
`hindsight-integrations/openclaw/package-lock.json` had
`@vectorize-io/hindsight-client` resolved as a workspace symlink
(`link: true`) instead of a registry URL. npm had silently preferred the
workspace over the declared registry version when `npm install` was
originally run from the monorepo root, even though openclaw isn't in
the root `workspaces` array. The release runner has no pre-built
workspace `dist/`, so tsc couldn't find the types and the publish never
happened. (The test CI job masked this because it explicitly pre-builds
workspace deps before `npm ci`.)

Add two guards so it can't recur:

1. `scripts/check-integration-lockfiles.sh` — scans every
   `hindsight-integrations/*/package-lock.json` and fails if any dep's
   `resolved` URL is empty, a `file:` URL, a relative path, or the entry
   is a `link: true` workspace symlink. Prints the exact fix (regenerate
   the lockfile from inside the integration directory, not the monorepo
   root).

2. `check-integration-lockfiles` job in `.github/workflows/test.yml` —
   runs the script on every PR that touches an integration lockfile or
   package.json. Gated on the new `integrations-lockfiles` detect-changes
   output. Added to `report-pr-status` needs list.

3. Inline `Check integration lockfile` step in `release-integration.yml`
   for the TypeScript branch — belt + suspenders in case a bad lockfile
   ever slips past PR gating.

Verified: regression-tested the script against the broken pre-release
lockfile from commit da21e072 and it correctly identifies
`node_modules/@vectorize-io/hindsight-client: (link=true — workspace
symlink)` and exits non-zero. On the current tree (post-fix) all 7
integration lockfiles pass.
2026-04-13 11:35:46 +02:00
Nicolò Boschi 773ef0cb63 test(cloudflare-oauth-proxy): add tests, CI, and security hardening (#975)
Follow-up to #922. The initial PR was merged without the tests, CI
job, or release-script entry that CLAUDE.md mandates for new
integrations, and the source had a handful of code-quality issues
flagged in review.

Testing & CI
- Split src/index.ts into env/html/cors/proxy/auth/router modules so
  each unit can be exercised in plain Node without the Workers runtime
- Add 50 vitest tests covering html escaping, CORS application /
  stripping, the /authorize GET+POST flow with a mocked OAuth provider,
  the MCP proxy's header sanitisation, and the outer router's
  preflight + metadata hardening
- Add tsconfig.json, vitest.config.ts, typecheck+test scripts, and a
  test-cloudflare-oauth-proxy-integration job wired into detect-changes
  and report-pr-status
- Add cloudflare-oauth-proxy to VALID_INTEGRATIONS

Hardening
- Remove `any` types; introduce an explicit OAuthHelpers interface
- Replace the plain `!==` password check with a constant-time
  SHA-256-based comparison
- Drop the PII (email) log line from the MCP proxy
- CORS: list explicit methods instead of `*`, include `Mcp-Session-Id`
  in Allow-Headers, emit `Vary: Origin`
- Proxy: strip client Authorization + X-Proxy-Secret + hop-by-hop
  headers, filter upstream response headers through an allowlist
  (drops Set-Cookie and upstream CORS), buffer request body to avoid
  needing `duplex: "half"`
- Override OAuth metadata to advertise S256 only
- README: align PKCE wording with reality and document the single-user
  threat model; wrangler.toml defaults to workers_dev=false
2026-04-13 08:58:24 +02:00
r266-tech d054b88403 fix: add PEP 561 py.typed marker to all Python packages (#973)
* fix: add PEP 561 py.typed marker to all Python packages

Add empty py.typed marker files to all 13 Python packages that were
missing them. Only hindsight-integrations/autogen already had one.

Per PEP 561, packages that wish to support type checking must include
a py.typed marker file. Without it, type checkers (mypy, pyright) treat
the package as untyped and skip all inline type annotations.

Fixes #965

* fix: ensure py.typed markers survive client regeneration

Add touch commands in generate-clients.sh to recreate PEP 561 py.typed
marker files after the OpenAPI generator runs, since the script deletes
and regenerates the hindsight_client_api directory.

---------

Co-authored-by: r266-tech <r266-tech@users.noreply.github.com>
2026-04-10 23:24:46 +02:00
Nicolò Boschi 576016f5dc feat: add @vectorize-io/hindsight-all daemon lifecycle package (#949)
* feat: add @vectorize-io/hindsight-embed daemon lifecycle package

Create a new top-level `hindsight-embed-npm/` package that owns the daemon
lifecycle for the Python `hindsight-embed` CLI: spawning via `uvx`, writing
the profile, waiting for `/health`, and shutting down. Nothing more.

Deliberately does not ship an HTTP client — `@vectorize-io/hindsight-client`
already covers retain / recall / reflect / createBank against the Hindsight
API, and the two packages compose: once `manager.start()` returns, consumers
talk to the daemon via `new HindsightClient({ baseUrl: manager.getBaseUrl() })`.

`HindsightEmbedManagerOptions.env` forwards an arbitrary `Record<string,
string>` to both the daemon process and the profile config via `--env K=V`,
and `extraProfileCreateArgs` / `extraDaemonStartArgs` escape hatches cover
any new CLI flag without waiting for a wrapper release.

Refactor `hindsight-integrations/openclaw` to consume both packages:
`HindsightEmbedManager` for daemon lifecycle in local mode, `HindsightClient`
for all HTTP memory operations. Drop the bespoke subprocess/HTTP client that
used to live in openclaw. The retain queue stays local to openclaw (it's a
client-side reliability workaround with a single consumer today — will move
to the client package or server-side when a second consumer needs it).

Wire the new package into the main release pipeline (versioned alongside
the other core packages, published from `v*` tags) and add a CI build job.

* docs: add Embedded Node.js SDK page for @vectorize-io/hindsight-embed

* refactor: rename hindsight-embed-npm to hindsight-all, restructure docs sidebar

The Node package previously named @vectorize-io/hindsight-embed was
semantically misnamed: hindsight-embed (Python) is a CLI tool, while what
this Node package actually provides is the Node equivalent of hindsight-all
— a programmatic lifecycle manager for a local Hindsight daemon. Rename to
match.

Package rename
  - hindsight-embed-npm/ → hindsight-all-npm/ (git mv, history preserved)
  - @vectorize-io/hindsight-embed → @vectorize-io/hindsight-all
  - class HindsightEmbedManager → HindsightServer (matches Python hindsight-all)
  - HindsightEmbedManagerOptions → HindsightServerOptions
  - src/manager.ts → src/server.ts, src/manager.test.ts → src/server.test.ts
  - openclaw (index.ts, backfill.ts, tests) and the claude-code Python port
    updated to reference the new names

Docs restructure
  - Split sdks/python.md: now client-only content. New sdks/hindsight-all.md
    covers the programmatic hindsight-all Python package (HindsightServer and
    HindsightEmbedded).
  - Rename sdks/embed-npm.md → sdks/hindsight-all-npm.md with HindsightServer
    examples.
  - New "Installation" sidebar section, placed after Hosting, containing
    Docker / Kubernetes / Bare Metal (anchor links into developer/installation)
    plus Programmatic API (Python), Programmatic API (Node.js), and Daemon CLI.
  - Add si-docker, si-kubernetes, si-nodedotjs, lu-hard-drive to the sidebar
    ICON_MAP.

Docs dev-server fix
  - docusaurus.config.ts: drop the flaky NODE_ENV sniff for including the
    "Next" version. Use INCLUDE_CURRENT_VERSION exclusively. NODE_ENV was
    unreliable across hot-reload paths and caused the Next version to
    disappear intermittently when editing files.
  - scripts/dev/start-docs.sh: export INCLUDE_CURRENT_VERSION=true so local
    dev always shows Next; production builds leave it unset.

Lockfile cleanup
  - package-lock.json and hindsight-integrations/openclaw/package-lock.json
    had extraneous hindsight-embed-npm blocks left over from the rename.
    Removed manually and verified with npm install.

* ci: fix openclaw jobs by pre-building workspace deps; regenerate docs-skill

The build-openclaw-integration and test-openclaw-integration jobs failed
with "Failed to resolve entry for package @vectorize-io/hindsight-all"
because openclaw depends on two monorepo workspaces via `file:` deps
(@vectorize-io/hindsight-client and @vectorize-io/hindsight-all) whose
`dist/` directories are gitignored and never built before openclaw's npm ci.
Both jobs now install the root workspace and build the two deps first,
mirroring the release-control-plane pattern.

Also regenerate skills/hindsight-docs/references/* via
./scripts/generate-docs-skill.sh:
  - new skill pages for sdks/hindsight-all{.md,-npm.md}
  - updated skill pages for sdks/embed.md and sdks/python.md to match
    the new H1s and split content
  - incidental refreshes to changelog/index.md, developer/models.md,
    openapi.json, and uv.lock that verify-generated-files picked up

* ci: build openclaw before running tests so symlink test can realpath dist
2026-04-10 15:51:44 +02:00
Nicolò Boschi cf0537ba7e chore: drop hindsight-hermes integration (#931)
* chore: drop hindsight-hermes integration in favor of native Hermes memory provider

Hermes Agent now ships with a native Hindsight memory provider (NousResearch/hermes-agent#5094),
making our pip-installable hindsight-hermes package redundant.

Removes:
- hindsight-integrations/hermes/ (source, tests, config)
- CI job, release script entry, changelog generator references
- Cookbook page and pip package changelog (referenced deleted code)

Keeps:
- Integration docs (updated by #881 for native provider)
- Blog posts (historical, already have deprecation notices)
- Sidebar/banner entries (still valid for native integration)

* fix(docs): remove broken cookbook link to deleted hermes-memory page
2026-04-08 11:59:35 +02:00
Nicolò Boschi 7e23f8e149 fix(config): validate entity_labels structure on PATCH (#902)
* test: add regression tests for #874 and #894

Add tests for None event_date in fact extraction (AttributeError fix)
and for _register_profile skipping .env overwrite with short config keys.

* fix(config): validate entity_labels structure on PATCH (#891)

Config PATCH accepted bare strings in entity_labels values without
validation, causing silent failures at retain time. Now validates
via parse_entity_labels() before writing to DB, and fixes the
BankTemplateConfig type from list[str] to list[dict[str, Any]].

* fix(scripts): handle Python client generator README crash gracefully

The openapi-generator sometimes crashes writing README_onlypackage.mustache.
Allow the failure with || true since all API/model files are generated
before that step, and add a verification check for api_client.py.

* chore: regenerate docs skill openapi.json
2026-04-07 11:58:02 +02:00
DK09876 e1c6220f0e feat: add OpenCode persistent memory plugin (#853)
* feat: add OpenCode persistent memory plugin

Add hindsight-opencode integration with:
- Three custom tools: hindsight_retain, hindsight_recall, hindsight_reflect
- Auto-retain on session.idle with document_id deduplication
- Memory injection on session start via system transform hook
- Memory preservation during context window compaction
- Sliding window retain with retainOverlapTurns support
- 4-level config hierarchy (defaults, user file, plugin options, env vars)
- Dynamic bank ID derivation (agent, project, channel, user dimensions)
- CI job, release script entry, docs page

79 tests across 6 test files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address review findings for opencode integration

1. Pre-compaction retain now uses shared retainSession() helper,
   respecting retainMode, documentId, and session_id metadata
   consistently with idle-retain (was bypassing retention policy).

2. System transform recall is only consumed after successful injection.
   If Hindsight is briefly unavailable, the plugin retries on the next
   LLM call instead of permanently skipping recall for the session.

3. Config validation for retainMode and recallBudget — typos like
   "full_session" or "maximum" now log a warning and fall back to
   the default instead of silently changing retention semantics.

85 tests (6 new covering compaction documentId, recall retry, and
config validation).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: docs/tools findings from second review round

1. Remove "session" from supported dynamic bank fields in docs —
   the implementation can't vary bank ID per session since it's
   derived once at plugin startup.

2. Explicit tools (retain, reflect) now call ensureBankMission()
   before API calls, so bankMission/retainMission are applied even
   when the agent uses tools exclusively without triggering hooks.

3. Added tests for mission setup via tools path.

88 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: recall retry semantics and README bank scoping clarity

1. recallForContext now returns { context, ok } to distinguish
   "no results" (ok=true) from "API error" (ok=false). System
   transform consumes the session on ok=true even with 0 results,
   so empty banks don't cause repeated queries. Only transient API
   failures preserve retry.

2. README clarifies that channel/user bank dimensions are process-
   scoped (set via env vars before launch), not per-session dynamic
   within a running OpenCode process.

89 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: review fixes for opencode integration

- Rename CI job from build-opencode-integration to test-opencode-integration
  to match naming convention for integrations that run tests
- Fix tsconfig module resolution to Node16 (consistent with other integrations)
- Extract shared makeConfig test helper to avoid duplication across 3 test files

* fix: remove unused PluginState import from tools.ts

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Nicolò Boschi <boschi1997@gmail.com>
2026-04-07 10:11:57 +02:00
Nicolò Boschi 7863ffeb49 fix(paperclip): address review fixes for paperclip integration (#900)
- Add CI job for paperclip integration tests with change detection
- Add paperclip to valid release integrations
- Validate hindsightApiUrl is set in loadConfig()
- Log warnings on recall/retain failures instead of silently swallowing
- Remove hardcoded timeout from reflect call
- Fix tsconfig module resolution to Node16
- Update tests to pass required hindsightApiUrl
2026-04-07 09:32:24 +02:00
Nicolò Boschi 7990381f6a fix(ci): resolve all CI failures (#847)
* fix(ci): resolve all CI failures — unversioned integrations, test retries

- Move integration docs to separate unversioned docs plugin (docs-integrations/)
  so new integrations don't need to be duplicated across versioned_docs
- Remove integration pages from versioned_docs (v0.3, v0.4) — sidebar
  entries now use links instead of doc refs
- Add missing title/description SEO frontmatter to autogen.md
- Add retry logic (2 attempts) to test-doc-examples.sh for transient
  LLM timeouts
- Add pytest-rerunfailures to test-api with --reruns 2 for flaky
  Gemini-dependent integration tests

* ci: retrigger

* fix: graph entity inheritance, SyncTaskBackend error propagation, fact_type test regressions

- Fix observation entity inheritance in get_graph_data: the unit_entities
  query only fetched entities for visible observation IDs, not their source
  memory IDs, so the inheritance loop always found an empty entity_map
- Remove error swallowing in SyncTaskBackend._execute_task so test failures
  surface instead of being silently logged
- Wrap remaining consolidation submission call sites with try/except since
  consolidation is non-critical for those operations
- Fix test_sync_backend test to expect errors to propagate
- Remove fact_type=["world"] filter from test_document_upsert_behavior and
  test_mentioned_at_from_context_string (same PR #848 regression)
- Remove flaky marker from consolidation test (now deterministic)
2026-04-02 17:17:42 +02:00
DK09876 a757765ab2 feat: add AutoGen integration for Hindsight (#719)
* feat: add AutoGen integration for Hindsight

Adds hindsight-autogen package providing FunctionTool instances that give
AutoGen agents persistent long-term memory via retain/recall/reflect APIs.

- Package: hindsight_autogen with create_hindsight_tools() factory
- 31 unit tests covering tool creation, invocation, config fallback, errors
- Docs page and integrations.json entry
- README with quickstart and configuration reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review feedback for autogen integration

- Fix install instructions to include autogen-agentchat and autogen-ext[openai]
- Add autogen.svg icon to prevent broken image in integrations grid
- Change icon reference from .png to .svg in integrations.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add sleep between retain/recall and close clients in examples

- Add time.sleep(3) between retain and recall to wait for async processing
- Close Hindsight client and model client to avoid unclosed session warnings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use asyncio.sleep instead of time.sleep in async examples

time.sleep blocks the event loop; asyncio.sleep yields control.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review feedback - validation, defaults, release script

- Add autogen to VALID_INTEGRATIONS in release-integration.sh
- Remove unused verbose config field
- Extract DEFAULT_BUDGET/MAX_TOKENS/RECALL_TAGS_MATCH constants in config.py,
  import from tools.py to eliminate default duplication
- Add Literal types for budget and recall_tags_match validation
- Modernize type hints to X | None with from __future__ import annotations
- Add [tool.ruff] line-length = 120 to match monorepo convention
- Add py.typed PEP 561 marker
- Re-raise HindsightError before broad Exception catch
- Expand asyncio.sleep(3) comment explaining when/why it's needed
- Remove verbose from docs configure() reference table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 17:48:11 +02:00
Nicolò Boschi 73460fa4e6 chore: add hermes to release and changelog valid lists 2026-03-30 14:49:33 +02:00
Nicolò Boschi 66071fec9d feat(scripts): support patch/minor/major bump keywords in release-integration 2026-03-30 14:43:43 +02:00
Nicolò Boschi b739b9e36a chore: add llamaindex to release-integration valid list 2026-03-30 14:35:18 +02:00
Nicolò Boschi ecf16ea1e6 fix(codex): cleanup dead code, add release lifecycle and docs (#753)
* fix(codex): cleanup dead code and add to release lifecycle

- Remove orphaned reflect() method from client.py (leftover from dropped auto-mode)
- Remove dead retainToolCalls config default (never wired through)
- Add codex to release-integration.sh valid integrations
- Add settings.json version fallback to release script
- Add codex CI test job in test.yml
- Add codex to integrations.json registry

* docs(codex): add changelog page and link from integration docs

* feat(codex): add hosted installer script (get-codex)

Add self-contained installer at hindsight.vectorize.io/get-codex that
downloads scripts from GitHub, configures hooks, and supports local/cloud
mode selection — no git clone required.

Update docs and README to use the one-liner install:
  curl -fsSL https://hindsight.vectorize.io/get-codex | bash

* chore(codex): remove install.sh in favor of hosted get-codex

* fix(docs): use /next/ prefix for codex changelog link

* fix(docs): use GitHub link for codex changelog back-link
2026-03-30 11:34:43 +02:00
Nicolò Boschi 1cac35728f fix: silence noisy google_genai.models INFO logging (#727)
* fix: silence noisy google_genai.models INFO logging

The google-genai SDK logs "AFC is enabled with max remote calls: 10"
at INFO level on every initialization. Set its logger to WARNING.

* fix: regenerate docs skill in release-integration script

The release script generates changelog/SDK pages but never re-ran
generate-docs-skill.sh, causing CI to fail with out-of-sync skill
files after every integration release. Now it regenerates the skill
and includes the output in the release commit.

Also adds the missing ag2 skill files from the latest release.
2026-03-27 16:01:23 +01:00
Nicolò Boschi e5c7e166c5 fix(ag2): code cleanup and CI/release integration (#721)
- Remove unnecessary `pass` in HindsightError
- Add `Callable` return type annotations to create/register functions
- Use lazy logger formatting instead of f-strings
- Add test-ag2-integration CI job in test.yml
- Add ag2 to release-integration.sh valid integrations
2026-03-27 10:10:14 +01:00
Nicolò Boschi 246912f596 chore: add claude-code to release-integration script
Support plugin.json version bumping for Claude Code plugin releases.
2026-03-26 12:08:23 +01:00
Ben 7fe773c0ee feat: add Strands Agents SDK integration with Hindsight memory tools (#659)
* feat: add Strands Agents SDK integration with Hindsight memory tools

* fix: add strands docs to versioned docs so build link check passes

* fix(strands): run hindsight client calls in thread pool to avoid event loop conflict with Strands
2026-03-24 17:21:30 +01:00
Nicolò Boschi 36b5627d2c fix nemoclaw release 2026-03-20 15:18:44 +01:00
DK09876 b4320254b2 feat: add LangGraph integration (#610)
* feat: add LangGraph integration with tools, nodes, and store patterns

Add hindsight-langgraph SDK providing three integration patterns:
- Tools: retain/recall/reflect as LangChain tools for ReAct agents
- Nodes: automatic memory injection and storage as graph steps
- Store: LangGraph BaseStore implementation for checkpoint-based memory

Fix: remove `from __future__ import annotations` in nodes.py which
prevented LangGraph from passing RunnableConfig to node functions
(runtime type inspection saw string annotations instead of actual types).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: register langgraph with independent versioning system

- Set version to 0.1.0 (integrations are versioned independently)
- Add langgraph to VALID_INTEGRATIONS in release-integration.sh
- Add changelog page for langgraph integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove manual cookbook recipe page

The sync-cookbook script will auto-generate this from the notebook
in hindsight-cookbook once PR #17 is merged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: comprehensive improvements to langgraph integration

Code fixes:
- Retain node only stores latest messages instead of all history (prevents duplicates)
- Handle multimodal msg.content (list type) in nodes
- Fix store docstring separator "/" → "."
- Apply search filters before pagination in store
- Add ttl parameter to store.aput for LangGraph BaseStore compat
- Fix _ensure_bank to not cache failed bank creations
- Fix falsy value bugs (or → is not None) in tools
- Remove from __future__ import annotations from all files
- Consistent default budget="mid" across tools/nodes/store
- Bump langgraph floor to >=0.3.0, remove duplicate dev deps

Docs fixes:
- Fix broken Cloud client example (base_url is required)
- Complete API reference tables with all parameters
- Add Limitations and Notes section (async-only store, etc.)
- Add Requirements section
- Fix broken cookbook link and Cloud claim in blog post

All 61 unit tests pass. E2E tested against Hindsight Cloud:
tools, nodes, store, configure(), multimodal content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove blog post (lives in hindsight-marketing-content)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove Hindsight Cloud section from langgraph docs

Keep OSS docs self-hosted-first, consistent with other integration
docs (crewai, pydantic-ai, agno). Cloud setup details live in the
cookbook notebooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: explicitly mention LangChain compatibility in langgraph integration

The tools pattern (create_hindsight_tools) only depends on
langchain-core and works with plain LangChain via bind_tools() —
no LangGraph required. Update docs to make this clear with both
LangGraph and LangChain quick start examples.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review findings

1. Guard manual test files with if __name__ == "__main__" so pytest
   doesn't collect and execute them during test runs
2. Remove semantic fallback in HindsightStore.aget() — only return
   exact document_id matches, not unrelated semantic search hits
3. Make langgraph an optional dependency — tools pattern only needs
   langchain-core. Install with pip install hindsight-langgraph[langgraph]
   for nodes and store patterns. Lazy imports with clear error messages.
4. Clean up README to be self-hosted-first, consistent with other
   integration docs
5. Update docs requirements section to reflect optional langgraph dep

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review feedback for langgraph integration

- Fix #2: Add per-bank asyncio.Lock to _ensure_bank for concurrency safety
- Fix #3: Clamp search score to max(0.0, ...) to prevent negative values
- Fix #4: Implement suffix matching in _handle_list_namespaces
- Fix #5: Truncate namespaces to max_depth instead of filtering (per BaseStore contract)
- Fix #6: Remove list_namespaces/alist_namespaces overrides — let base class handle prefix=/suffix= kwargs
- Fix #7: Document ephemeral namespace tracking and get() limitations in class docstring
- Fix #8: Add stable ID to recall node SystemMessage, document ordering behavior
- Fix #9: Change budget/max_tokens/recall_tags_match defaults to None so global config fallback works
- Fix #10: Conditionally populate __all__ so import * works without langgraph installed
- Fix #11: Bump langgraph lower bound from >=0.3.0 to >=0.5.0
- Fix #12: Extract _resolve_client to shared _client.py module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address remaining review gaps for langgraph integration

- Add output_key parameter to create_recall_node for prompt ordering control
- Add prefix/suffix/combined filter tests for list_namespaces
- Add output_key unit tests (memory text, none on empty, none on error)
- Remove unused imports and backward-compat alias in tools.py
- Update docs with output_key usage example and API reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: relax langgraph version constraint to >=0.3.0

Research confirmed all required APIs (BaseStore, SearchItem, Result,
GetOp, PutOp, SearchOp, ListNamespacesOp) are available since
langgraph-checkpoint 2.0.7, which maps to langgraph >=0.2.63.
Using >=0.3.0 as a clean semver boundary — >=0.5.0 was unnecessarily
conservative and excluded many compatible versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:36:57 +01:00
Nicolò Boschi a706905653 feat(skill): validate links, strip images, include openapi.json and changelog (#614)
* feat(skill): validate links, strip images, include openapi.json and changelog

- Add post-processing step to rewrite Docusaurus site-root paths (e.g.
  /developer/foo) to proper relative .md paths within the skill
- Strip markdown and HTML images from all generated files since assets
  are not bundled with the skill
- Copy hindsight-docs/static/openapi.json into references/openapi.json
  and map /api-reference links to it
- Include changelog.md from src/pages/ alongside faq and best-practices
- Add final validation step that fails the build if any link still
  points outside the skill directory

* ci: run generate-docs-skill in verify-generated-files job

* fix(skill): strip unresolvable site-root links instead of leaving them broken

* fix(skill): write file when images stripped but no links rewritten

* chore(skill): regenerate with fixed links, stripped images, changelog and openapi

* fix(skill): handle changelog as directory, add agno/hermes integrations, rebase on main
2026-03-19 12:32:33 +01:00
Nicolò Boschi 31f1c53c8f feat: independent versioning for integrations (#565)
* feat: independent versioning for integrations

- Add per-integration changelog pages at /changelog/integrations/<name>
- Move main changelog to changelog/index.md (URL unchanged)
- Add --integration flag to generate-changelog for LLM-based per-integration changelog generation
- Add scripts/release-integration.sh <name> <version> for cutting integration releases
- Add .github/workflows/release-integration.yml to publish on integrations/** tags
- Remove integrations from main release.sh and release.yml cycle

* fix: add agno and hermes integration docs to version-0.4 for production build

* chore: apply ruff formatting to generate_changelog.py
2026-03-18 17:53:46 +01:00
Nicolò Boschi 72c25c97e3 feat(typescript-client): Deno compatibility (#607)
* feat(typescript-client): add Deno compatibility

- Switch build from tsc to tsup for dual CJS + ESM output with proper exports field
- Add deno_setup.ts preload that injects Jest-compatible globals (describe/test/expect) via @std/testing/bdd and @std/expect
- Fix generated client.gen.ts: exclude hey-api internal `client` field from RequestInit spread to avoid conflict with Deno.HttpClient
- Add test:deno npm script using --unstable-sloppy-imports and --preload
- Add test-typescript-client-deno CI job using denoland/setup-deno@v2 (v2.x)
- Update docs: rename page to TypeScript / JavaScript Client, add Deno installation section

* feat: add Deno compatibility to ai-sdk and chat integrations

- Switch ai-sdk and chat builds from tsc to tsup (ESM bundle, eliminates
  extension-less import issues in Deno)
- Add deno.json import map to ai-sdk redirecting 'vitest' to a custom
  vitest-compat.ts shim and bare npm specifiers to npm: URLs
- Add vitest-compat.ts shim implementing vi.fn()/vi.spyOn()/vi.mocked()
  using @std/expect's Symbol.for("@MOCK") interface so toHaveBeenCalledWith
  and other mock matchers work under Deno
- Add test:deno script to ai-sdk (all 30 tests pass under Deno)

* ci: add Deno test job for ai-sdk integration

Adds a new test-ai-sdk-integration-deno CI job that runs the ai-sdk
unit tests under Deno LTS, verifying Deno compatibility of the package.

* fix: remove broken link to non-existent n8n blog post in streamlit post

* fix: patch client.gen.ts for Deno compatibility during generation

Add a post-generation patch step to generate-clients.sh that removes
the hey-api internal 'client' field from the RequestInit spread in
client.gen.ts. Deno's Request constructor rejects 'client' because it
conflicts with the Deno.HttpClient option name.
2026-03-18 14:25:35 +01:00
Ben 8c378b981a feat: add Agno integration with Hindsight memory toolkit (#596)
* feat: add Agno integration with Hindsight memory toolkit

Add hindsight-agno package providing Hindsight memory tools (retain,
recall, reflect) as an Agno Toolkit, following the same pattern as
Agno's Mem0Tools. Includes per-user bank isolation, global config,
bank auto-creation, and memory_instructions() for system prompt
injection.

Also adds cookbook documentation page with architecture diagrams,
quick start examples, and configuration reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove n8n blog post, add Agno icon, bind to release process

- Remove n8n blog post from the agno integration branch
- Add Agno logo icon and map hindsight-agno SDK tag in CookbookGrid
- Add hindsight-agno to release.sh PYTHON_PACKAGES array
- Add build, publish, artifact upload, and release asset steps in release.yml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove cookbook page (moved to hindsight-cookbook repo)

The Agno cookbook application now lives in
vectorize-io/hindsight-cookbook/applications/agno-memory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 11:17:23 +01:00