* feat: entity labels * feat: entity labels — optional, free_values, multi_value, UI polish Completes the entity labels system: **Schema & extraction** - Dynamic Pydantic Labels model per fact: each group becomes a typed field (Literal | None, list[Literal], str | None, or list[str]) - `optional: bool` flag per group — non-optional enum fields appear in JSON schema required array so structured-output providers enforce them - `free_values: bool` flag per group — accepts any LLM-generated string instead of a predefined enum; example values shown as hints in prompt - New `is_label_entity()` helper for labels-only mode filtering that handles both enum lookup and free_values key-prefix matching - Sentinel rejection: "None"/"null"/"n/a" strings dropped in post-processing **BM25 / dense retrieval** - `text_signals` column on memory_units: entity names + date tokens for enriched BM25 indexing without polluting stored fact text - Dense embedding includes occurred_end when it differs from occurred_start - Alembic migration z1u2v3w4x5y6 (merge revision fixing two heads) **UI (bank-config-view)** - Shadcn Switch replaces custom Toggle for both entity-labels and observations - Shadcn Checkbox for multi/optional/free_values per group - Input heights bumped to h-8 throughout the editor - "Label Groups" → "Entity Labels", "Free-form entities" → "Entities" - Free-text groups show "Example hints" banner in values section **Tests (45 unit + 3 LLM integration)** - build_labels_model: single, multi, mixed, free_values optional/required/multi - is_label_entity: enum match, free_values prefix match, no false positives - Post-processing: null/absent/string-None/free_values/sentinels/multi-value - Schema: labels in required, structured object, no labels when unconfigured - LLM integration: single-value enum, multi-value enum, free_values retain **Docs** - retain.md: new Entity Labels section covering groups, flags, examples - configuration.md: retain_free_form_entities env var + entity_labels note * fix(tests): update hierarchical fields count for entity_labels additions entity_labels and retain_free_form_entities are hierarchical fields, bumping the expected count from 11 to 13. * fix(migration): rename text_signals revision to avoid collision with main Main branch claimed z1u2v3w4x5y6 for observation_scopes. Rename our text_signals migration to a2b3c4d5e6f7, chaining after z1u2v3w4x5y6. * refactor(entity-labels): simplify free_values — always str|None, no multi - free_values groups always produce str | None (multi_value and optional flags are ignored for free text groups — always optional, never multi) - Prompt section for free_values groups shows only key + description, no values list (users put examples in the description instead) - UI: section title "Entities", toggle "Free Form Entities", replace per-group checkboxes with a type dropdown (Enum / Free text); only show multi checkbox and values list when type is Enum - Update tests to reflect new behaviour * refactor(entity-labels): replace free_values/multi_value booleans with type field - LabelGroup now uses type: "value" | "multi-values" | "text" instead of free_values/multi_value boolean pair - Backward-compat migration converts legacy dicts automatically - Rename retain_free_form_entities → entities_allow_free_form throughout - Update UI dropdown to show Single value / Multi-values / Free text - Remove separate multi checkbox (captured by type selection) - Update docs examples and configuration.md - Update all tests to use new field names * fix(migration): backfill observation_scopes column for DBs with swapped z1u2v3w4x5y6 Local DBs that had z1u2v3w4x5y6 applied when it referred to the old text_signals migration (before it was renamed to a2b3c4d5e6f7) won't have observation_scopes in their memory_units table. This migration adds the column with IF NOT EXISTS so it's a no-op on clean installs. * feat(entity-labels): add tag field to auto-populate memory unit tags from labels When a LabelGroup has tag=True, extracted key:value entities for that group are automatically written to the memory unit's tags array. This lets entity labels double as tags, enabling immediate filtering via the existing tags/tags_match API params with no extra infrastructure. - Add tag: bool = False to LabelGroup - _inject_label_tags() helper called in both sync and batch extraction paths - UI: add Tag checkbox per label group row - Docs: document the new tag field - Tests: 4 new unit tests covering all tag injection paths * style: ruff format migration file * fix(migration): fix multiple alembic heads after rebase — point text_signals after nullable_event_date * fix(clients): update timestamp field to use Timestamp wrapper type after timestamp=unset feature * style: ruff format agent.py * fix(docs): update Go quickstart example to use NullableTimestamp for timestamp field
84 lines
3 KiB
JSON
84 lines
3 KiB
JSON
{
|
|
"name": "@vectorize-io/hindsight-control-plane",
|
|
"version": "0.4.14",
|
|
"description": "Control plane for Hindsight - Semantic memory system",
|
|
"bin": {
|
|
"hindsight-control-plane": "./bin/cli.js"
|
|
},
|
|
"files": [
|
|
"bin",
|
|
"standalone",
|
|
"public"
|
|
],
|
|
"scripts": {
|
|
"dev": "next dev --turbopack -p ${PORT:-9999}",
|
|
"build": "next build && npm run build:standalone",
|
|
"build:standalone": "rm -rf standalone && SERVER_JS=$(find .next/standalone -path '*/node_modules' -prune -o -name 'server.js' -print | head -1) && test -n \"$SERVER_JS\" || (echo 'Error: server.js not found in .next/standalone - standalone build failed' && exit 1) && STANDALONE_ROOT=$(dirname \"$SERVER_JS\") && cp -r \"$STANDALONE_ROOT\" standalone && cp -r .next/standalone/node_modules standalone/node_modules && mkdir -p standalone/.next && cp -r .next/static standalone/.next/static && mkdir -p standalone/public && (cp -r public/* standalone/public/ 2>/dev/null || true)",
|
|
"start": "next start",
|
|
"lint": "next lint",
|
|
"prepublishOnly": "npm run build"
|
|
},
|
|
"keywords": [
|
|
"hindsight",
|
|
"memory",
|
|
"semantic",
|
|
"ai"
|
|
],
|
|
"author": "Hindsight Team",
|
|
"license": "ISC",
|
|
"dependencies": {
|
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
"@radix-ui/react-label": "^2.1.8",
|
|
"@radix-ui/react-popover": "^1.1.15",
|
|
"@radix-ui/react-radio-group": "^1.3.8",
|
|
"@radix-ui/react-select": "^2.2.6",
|
|
"@radix-ui/react-slider": "^1.3.6",
|
|
"@radix-ui/react-slot": "^1.2.4",
|
|
"@radix-ui/react-switch": "^1.2.6",
|
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
"@tailwindcss/postcss": "^4.1.17",
|
|
"@tailwindcss/typography": "^0.5.19",
|
|
"@types/cytoscape": "^3.21.9",
|
|
"@types/node": "^24.10.0",
|
|
"@types/react": "^19.2.2",
|
|
"@types/react-dom": "^19.2.2",
|
|
"autoprefixer": "^10.4.21",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"cmdk": "^1.1.1",
|
|
"cytoscape": "^3.33.1",
|
|
"cytoscape-fcose": "^2.2.0",
|
|
"eslint": "^9.39.1",
|
|
"eslint-config-next": "^16.0.1",
|
|
"lucide-react": "^0.553.0",
|
|
"next": "^16.1.6",
|
|
"next-themes": "^0.4.6",
|
|
"postcss": "^8.5.6",
|
|
"react": "^19.2.0",
|
|
"react-chrono": "^2.9.1",
|
|
"react-dom": "^19.2.0",
|
|
"react-markdown": "^10.1.0",
|
|
"react18-json-view": "^0.2.9",
|
|
"recharts": "^3.5.1",
|
|
"remark-gfm": "^4.0.1",
|
|
"sonner": "^2.0.7",
|
|
"tailwind-merge": "^3.4.0",
|
|
"tailwindcss": "^4.1.17",
|
|
"tailwindcss-animate": "^1.0.7",
|
|
"three": "^0.182.0",
|
|
"typescript": "^5.9.3"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/eslintrc": "^3.3.3",
|
|
"@eslint/js": "^9.39.2",
|
|
"@vectorize-io/hindsight-client": "file:../hindsight-clients/typescript",
|
|
"eslint-plugin-react": "^7.37.5",
|
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
"prettier": "^3.7.4",
|
|
"typescript-eslint": "^8.50.0"
|
|
}
|
|
}
|