Skip to content

rename to hindsight#2

Merged
nicoloboschi merged 6 commits into
mainfrom
renaming-pre-launch
Nov 25, 2025
Merged

rename to hindsight#2
nicoloboschi merged 6 commits into
mainfrom
renaming-pre-launch

Conversation

@nicoloboschi

Copy link
Copy Markdown
Collaborator

No description provided.

@nicoloboschi nicoloboschi merged commit b1ff2e8 into main Nov 25, 2025
1 of 2 checks passed
@mrlubos

mrlubos commented Dec 18, 2025

Copy link
Copy Markdown

@nicoloboschi just noticed you're using Hey API – feedback is always welcome!

DK09876 added a commit that referenced this pull request Mar 19, 2026
- 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>
nicoloboschi pushed a commit that referenced this pull request Mar 20, 2026
* 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>
nicoloboschi added a commit that referenced this pull request Jun 3, 2026
… always shown

The residual near-duplicate observations were recall misses, not LLM errors:
the existing near-identical observation (the merge 'twin') is semantic rank #1
for the new fact, but shares no source-fact graph link and little lexical
overlap, so RRF averaged it below the per-fact recall budget (512 tokens, ~8
observations) and the LLM never saw it -> created a duplicate. The cross-encoder
demoted it the same way (semantic #1 -> reranked #37).

Add round-robin interleave fusion: take each retrieval arm's #1, then each #2,
... (semantic, bm25, graph, temporal), de-duplicating, until the budget fills.
This guarantees every arm's top hit a slot, so the semantic-#1 twin is always
shown and the LLM UPDATEs instead of creating a duplicate.

Replace the recall 'rerank: bool' / ad-hoc passthrough with a single named
'reranking' strategy: 'cross_encoder' (default), 'rrf', 'interleave'.
Consolidation dedup recall uses 'interleave'. For interleave the fusion order is
authoritative — combined scoring's recency/temporal re-sort is skipped (that
re-sort is what buried the twin).

Measured on an English translation of the hermes transcript (removes the
cross-lingual embedding confound): near-dup observations 4% (@0.97) -> 0% at both
1/10 and 1/4 cuts, coverage 89% -> 94%, no false merges (heavy observations are
coherent single themes; distinct facets stay separate).
nicoloboschi added a commit that referenced this pull request Jun 3, 2026
… always shown

The residual near-duplicate observations were recall misses, not LLM errors:
the existing near-identical observation (the merge 'twin') is semantic rank #1
for the new fact, but shares no source-fact graph link and little lexical
overlap, so RRF averaged it below the per-fact recall budget (512 tokens, ~8
observations) and the LLM never saw it -> created a duplicate. The cross-encoder
demoted it the same way (semantic #1 -> reranked #37).

Add round-robin interleave fusion: take each retrieval arm's #1, then each #2,
... (semantic, bm25, graph, temporal), de-duplicating, until the budget fills.
This guarantees every arm's top hit a slot, so the semantic-#1 twin is always
shown and the LLM UPDATEs instead of creating a duplicate.

Replace the recall 'rerank: bool' / ad-hoc passthrough with a single named
'reranking' strategy: 'cross_encoder' (default), 'rrf', 'interleave'.
Consolidation dedup recall uses 'interleave'. For interleave the fusion order is
authoritative — combined scoring's recency/temporal re-sort is skipped (that
re-sort is what buried the twin).

Measured on an English translation of the hermes transcript (removes the
cross-lingual embedding confound): near-dup observations 4% (@0.97) -> 0% at both
1/10 and 1/4 cuts, coverage 89% -> 94%, no false merges (heavy observations are
coherent single themes; distinct facets stay separate).
benfrank241 added a commit that referenced this pull request Jun 11, 2026
…(review notes 2 & 4)

#2 — Webhook signature verification (was: relying only on Zapier's unguessable URL):
- performSubscribe now generates a random 32-byte secret and registers it with
  the webhook; the secret is stored in subscribeData.
- perform verifies the X-Hindsight-Signature: sha256=<hmac> header (HMAC-SHA256
  of the raw body) and rejects mismatches. (Corrected the header name — the API
  sends X-Hindsight-Signature, not X-Webhook-Signature; body is delivered
  byte-for-byte via content=, so the recomputed HMAC matches.)

#4 — Optional 'Process asynchronously' toggle on Retain (default false). Lets
users with very large content avoid Zapier's action timeout; pairs with the
Retain Completed trigger.

17 unit tests pass (added valid/invalid signature cases); zapier validate clean.
benfrank241 added a commit that referenced this pull request Jun 15, 2026
…#2119)

* feat(zapier): add Hindsight Zapier app (actions + REST Hook triggers)

A Zapier Platform CLI app that brings Hindsight memory into Zaps.

Actions:
- Retain Memory (create) -> POST /v1/default/banks/{bank}/memories
- Recall Memories (search) -> POST .../memories/recall
- Reflect (search) -> POST .../reflect

Triggers (instant, via Hindsight's webhook API — subscribe POSTs /webhooks,
unsubscribe DELETEs it):
- Retain Completed, Consolidation Completed, Memory Defense Triggered

Auth: API key as Bearer token, Cloud default with self-hosted override; the
Bank field is a dynamic dropdown from GET /v1/default/banks.

Built on zapier-platform-core 19; 'private': true so the npm release path can
never publish it (Zapier publishing is manual via zapier push/promote, not
release-integration.yml — and zapier is intentionally NOT in VALID_INTEGRATIONS).

Adds test-zapier-integration CI job (npm install -> zapier validate -> npm test)
and a repo README row. 15 mocha/nock unit tests; 'zapier validate' is
structurally clean.

Docs-site gallery card + doc page + icon are a follow-up (need the official
Zapier brand asset; omitted here to keep build-docs green).

* fix(zapier): make apiKey optional for no-auth self-hosted + prettier-clean

- authentication.js: apiKey now optional (required: false). The middleware only
  adds the Bearer header when a key is present, so you can connect to a
  self-hosted instance running without auth by leaving it blank; Cloud still
  requires a working key (blank -> 401 fails the connection test).
- README: document self-hosted / localhost usage, the optional key, and correct
  the CLI binary name to 'zapier-platform' (v19 renamed it from 'zapier'); show
  the .env approach so 'zapier invoke' needs no global install.
- Run prettier across the integration (fixes pre-existing format drift that was
  failing verify-generated-files on this branch).

zapier validate still structurally sound; 15 tests pass.

* fix(zapier): correct reflect answer field + recall output shape (found via live test)

Extensive live testing against Hindsight Cloud surfaced two response-shape bugs
the mocked unit tests missed (they mocked the wrong shapes):

- reflect: the synthesized answer is in the response's `text` field, not
  `answer`. searches/reflect read `data.answer` (undefined), so a Zap got no
  answer. Now reads `data.text` and surfaces it as `answer`. Test mock fixed to
  use the real `text` field so it actually guards this.
- recall: results carry no numeric `score`, and the fact-type field is `type`
  (not `fact_type`). Corrected the sample + outputFields so the Zap editor only
  advertises fields that actually populate; test mock made realistic.

Verified live end-to-end: auth, bank dropdown, retain (full + minimal), recall
(real fact extraction), reflect (now returns the grounded answer), and the
webhook subscribe/list/delete lifecycle. 15 unit tests pass; zapier validate clean.

* docs(zapier): correct .env auth-field prefix to authData_ in README

zapier invoke reads .env auth fields with the authData_ prefix (e.g.
authData_apiKey, authData_apiUrl), not bare apiKey/apiUrl. Confirmed against a
working local .env during live testing.

* docs(zapier): add integrations gallery card + doc page

- gallery entry in integrations.json (id zapier, official, category framework)
- doc page docs-integrations/zapier.md (actions + REST Hook triggers, setup)
- official Zapier logo at static/img/icons/zapier.png

check-integrations passes (forward: entry → doc page); JSON valid; prettier-clean.

* feat(zapier): verify webhook HMAC signatures + optional async retain (review notes 2 & 4)

#2 — Webhook signature verification (was: relying only on Zapier's unguessable URL):
- performSubscribe now generates a random 32-byte secret and registers it with
  the webhook; the secret is stored in subscribeData.
- perform verifies the X-Hindsight-Signature: sha256=<hmac> header (HMAC-SHA256
  of the raw body) and rejects mismatches. (Corrected the header name — the API
  sends X-Hindsight-Signature, not X-Webhook-Signature; body is delivered
  byte-for-byte via content=, so the recomputed HMAC matches.)

#4 — Optional 'Process asynchronously' toggle on Retain (default false). Lets
users with very large content avoid Zapier's action timeout; pairs with the
Retain Completed trigger.

17 unit tests pass (added valid/invalid signature cases); zapier validate clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants