fleet-memory/hindsight-docs/examples/api/retain.go
Nicolò Boschi a56cd044e5
feat: 4-tab code parity across all documentation examples (#613)
* 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

* feat: add 4-tab code parity across all documentation examples

Every code snippet Tabs block now has Python, Node.js, CLI, and Go variants.
Raw HTTP/curl tabs replaced with proper SDK calls.

New example files:
- Go: retain.go, recall.go, reflect.go, memory-banks.go, directives.go,
  mental-models.go, documents.go, main-methods.go
- Shell: memory-banks.sh, directives.sh, mental-models.sh
- Node.js: mental-models.mjs

Extended example files with missing sections:
- recall.mjs/sh: world/experience/observation types, token-budget, all tag modes
- reflect.sh: reflect-with-params, reflect-disposition, reflect-sources, reflect-with-tags
- reflect.mjs: reflect-with-tags, fixed reflect-sources API usage
- retain.mjs/sh: retain-conversation, retain-batch, retain-files-batch

SDK/CLI additions:
- TypeScript: getMentalModelHistory method
- CLI recall: --tags, --tags-match flags
- CLI reflect: --tags, --tags-match, --include-facts flags
- CLI directive update: --is-active flag
- CLI bank set-config: --retain-mission, --retain-extraction-mode,
  --observations-mission, --reflect-mission, --disposition-* flags

Build validation:
- scripts/check-code-parity.mjs validates 4-tab parity across all MDX files
- Integrated into npm run build — fails if any Tabs block is missing a variant

* fix: fix doc examples for Go, Node.js, CLI + add mental model with-id examples

- Fix Go Budget constants: BUDGET_HIGH/LOW/MID → HIGH/LOW/MID
- Fix Go documents.go: ListDocuments returns []map[string]interface{}, use map access
- Fix Go retain.go: use correct relative path for sample.pdf
- Fix Node.js createMentalModel: use positional args (name, sourceQuery) not object
- Add CLI 'history' subcommand for mental models (api.rs, main.rs, mental_model.rs)
- Rebuild TypeScript/Python clients to support id param in createMentalModel
- Add create-mental-model-with-id examples across all 4 languages and docs

* fix: move id param to end of create_mental_model signature for backwards compat
2026-03-19 11:31:51 +01:00

137 lines
4.7 KiB
Go

package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
hindsight "github.com/vectorize-io/hindsight/hindsight-clients/go"
)
func main() {
apiURL := os.Getenv("HINDSIGHT_API_URL")
if apiURL == "" {
apiURL = "http://localhost:8888"
}
cfg := hindsight.NewConfiguration()
cfg.Servers = hindsight.ServerConfigurations{{URL: apiURL}}
client := hindsight.NewAPIClient(cfg)
ctx := context.Background()
// =============================================================================
// Doc Examples
// =============================================================================
// [docs:retain-basic]
client.MemoryAPI.RetainMemories(ctx, "my-bank").
RetainRequest(hindsight.RetainRequest{
Items: []hindsight.MemoryItem{
{Content: "Alice works at Google as a software engineer"},
},
}).Execute()
// [/docs:retain-basic]
// [docs:retain-conversation]
// Retain an entire conversation as a single document.
conversation := "Alice (2024-03-15T09:00:00Z): Hi Bob! Did you end up going to the doctor last week?\n" +
"Bob (2024-03-15T09:01:00Z): Yes, finally. Turns out I have a mild peanut allergy.\n" +
"Alice (2024-03-15T09:02:00Z): Oh no! Are you okay?\n" +
"Bob (2024-03-15T09:03:00Z): Yeah, nothing serious. Just need to carry an antihistamine.\n" +
"Alice (2024-03-15T09:04:00Z): Good to know. We'll avoid peanuts at the team lunch."
docID := "chat-2024-03-15-alice-bob"
context_ := "team chat"
ts := "2024-03-15T09:04:00Z"
client.MemoryAPI.RetainMemories(ctx, "my-bank").
RetainRequest(hindsight.RetainRequest{
Items: []hindsight.MemoryItem{
{
Content: conversation,
Context: *hindsight.NewNullableString(&context_),
DocumentId: *hindsight.NewNullableString(&docID),
Timestamp: *hindsight.NewNullableTimestamp(&hindsight.Timestamp{
String: &ts,
}),
},
},
}).Execute()
// [/docs:retain-conversation]
// [docs:retain-with-context]
ctxLabel := "career update"
ts2 := "2024-03-15T10:00:00Z"
client.MemoryAPI.RetainMemories(ctx, "my-bank").
RetainRequest(hindsight.RetainRequest{
Items: []hindsight.MemoryItem{
{
Content: "Alice got promoted to senior engineer",
Context: *hindsight.NewNullableString(&ctxLabel),
Timestamp: *hindsight.NewNullableTimestamp(&hindsight.Timestamp{
String: &ts2,
}),
},
},
}).Execute()
// [/docs:retain-with-context]
// [docs:retain-batch]
doc1 := "conversation_001_msg_1"
doc2 := "conversation_001_msg_2"
doc3 := "conversation_001_msg_3"
ctx1 := "career"
ctx2 := "relationship"
client.MemoryAPI.RetainMemories(ctx, "my-bank").
RetainRequest(hindsight.RetainRequest{
Items: []hindsight.MemoryItem{
{Content: "Alice works at Google", Context: *hindsight.NewNullableString(&ctx1), DocumentId: *hindsight.NewNullableString(&doc1)},
{Content: "Bob is a data scientist at Meta", Context: *hindsight.NewNullableString(&ctx1), DocumentId: *hindsight.NewNullableString(&doc2)},
{Content: "Alice and Bob are friends", Context: *hindsight.NewNullableString(&ctx2), DocumentId: *hindsight.NewNullableString(&doc3)},
},
}).Execute()
// [/docs:retain-batch]
// [docs:retain-async]
// Start async ingestion (returns immediately)
asyncTrue := true
largeDoc1 := "large-doc-1"
largeDoc2 := "large-doc-2"
retainResp, _, _ := client.MemoryAPI.RetainMemories(ctx, "my-bank").
RetainRequest(hindsight.RetainRequest{
Items: []hindsight.MemoryItem{
{Content: "Large batch item 1", DocumentId: *hindsight.NewNullableString(&largeDoc1)},
{Content: "Large batch item 2", DocumentId: *hindsight.NewNullableString(&largeDoc2)},
},
Async: &asyncTrue,
}).Execute()
// Check if it was processed asynchronously
fmt.Println("Async:", retainResp.GetAsync())
// [/docs:retain-async]
// [docs:retain-files]
// Open a file and upload it — Hindsight converts it to text and extracts memories.
// Supports: PDF, DOCX, PPTX, XLSX, images (OCR), audio (transcription), and text formats.
f, err := os.Open("../../hindsight-docs/examples/api/sample.pdf")
if err != nil {
log.Fatalf("Failed to open file: %v", err)
}
defer f.Close()
fileResp, _, _ := client.FilesAPI.FileRetain(ctx, "my-bank").
Files([]*os.File{f}).
Request(`{"files_metadata": [{"context": "quarterly report"}]}`).
Execute()
fmt.Println("Operation IDs:", fileResp.GetOperationIds()) // Track processing via the operations endpoint
// [/docs:retain-files]
// =============================================================================
// Cleanup (not shown in docs)
// =============================================================================
req, _ := http.NewRequest("DELETE", fmt.Sprintf("%s/v1/default/banks/my-bank", apiURL), nil)
http.DefaultClient.Do(req)
fmt.Println("retain.go: All examples passed")
}