ltcai 4.3.1 → 4.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +186 -278
- package/docs/CHANGELOG.md +91 -0
- package/docs/V4_3_2_DEADCODE_AUDIT_REPORT.md +174 -0
- package/docs/V4_3_2_DOCUMENTATION_CLEANUP_REPORT.md +81 -0
- package/docs/V4_3_2_GITHUB_VERCEL_CHECK_REPORT.md +75 -0
- package/docs/V4_3_2_GRAPH_UX_REPORT.md +48 -0
- package/docs/V4_3_2_INDEPENDENT_AUDIT_PACKAGE.md +209 -0
- package/docs/V4_3_2_PRODUCT_POLISH_REPORT.md +57 -0
- package/docs/V4_3_2_SELF_AUDIT_REPORT.md +63 -0
- package/docs/V4_3_2_VALIDATION_REPORT.md +97 -0
- package/docs/V4_3_3_VALIDATION_REPORT.md +46 -0
- package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +18 -19
- package/frontend/openapi.json +1 -1
- package/frontend/src/components/primitives.tsx +92 -10
- package/frontend/src/pages/Act.tsx +11 -9
- package/frontend/src/pages/Ask.tsx +2 -2
- package/frontend/src/pages/Brain.tsx +607 -65
- package/frontend/src/pages/Capture.tsx +11 -7
- package/frontend/src/pages/Library.tsx +3 -3
- package/frontend/src/pages/System.tsx +186 -23
- package/lattice_brain/__init__.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/multi_agent.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/package.json +3 -6
- package/scripts/build_vercel_static.mjs +77 -0
- package/scripts/check_markdown_links.mjs +75 -0
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/main.rs +12 -2
- package/src-tauri/tauri.conf.json +1 -1
- package/static/app/asset-manifest.json +5 -5
- package/static/app/assets/index-CHHal8Zl.css +2 -0
- package/static/app/assets/index-pdzil9ac.js +333 -0
- package/static/app/assets/index-pdzil9ac.js.map +1 -0
- package/static/app/index.html +2 -2
- package/latticeai/api/deps.py +0 -15
- package/scripts/capture/README.md +0 -28
- package/scripts/capture/capture_enterprise.js +0 -8
- package/scripts/capture/capture_graph.js +0 -8
- package/scripts/capture/capture_onboarding.js +0 -8
- package/scripts/capture/capture_page.js +0 -43
- package/scripts/capture/capture_release_media.js +0 -125
- package/scripts/capture/capture_skills.js +0 -8
- package/scripts/capture/capture_v340.js +0 -88
- package/scripts/capture/capture_workspace.js +0 -8
- package/scripts/generate_diagrams.py +0 -512
- package/scripts/release-0.3.1.sh +0 -105
- package/scripts/take_screenshots.js +0 -69
- package/static/app/assets/index-BhPuj8rT.js +0 -333
- package/static/app/assets/index-BhPuj8rT.js.map +0 -1
- package/static/app/assets/index-yZswHE3d.css +0 -2
- package/static/css/tokens.3ba22e37.css +0 -260
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Lattice AI v4.3.2 Self-Audit Report
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-13
|
|
4
|
+
|
|
5
|
+
## Method
|
|
6
|
+
|
|
7
|
+
The audit used the built v4.3.2 product, not source-code claims. It started a
|
|
8
|
+
local FastAPI backend with an isolated data directory, seeded a real document
|
|
9
|
+
through the upload API, opened the React SPA, exercised product flows, captured
|
|
10
|
+
screenshots/GIF evidence, launched the rebuilt Tauri app, and verified desktop
|
|
11
|
+
sidecar startup/shutdown.
|
|
12
|
+
|
|
13
|
+
## Runtime Inputs
|
|
14
|
+
|
|
15
|
+
- API base: `http://127.0.0.1:4932`
|
|
16
|
+
- Audit data dir: `/tmp/lattice-v432-audit`
|
|
17
|
+
- Desktop data dir: `/tmp/lattice-v432-desktop3`
|
|
18
|
+
- Uploaded note: `/tmp/lattice-v432-files/v432-audit-note.md`
|
|
19
|
+
- Archive path: `/tmp/lattice-v432-audit/self-audit.latticebrain`
|
|
20
|
+
|
|
21
|
+
## Observed Results
|
|
22
|
+
|
|
23
|
+
| Scenario | Result | Evidence |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| First startup | PASS | `output/audits/v4.3.2-rc/screenshots/01-first-startup.png` |
|
|
26
|
+
| Graph exploration baseline | PASS | `output/audits/v4.3.2-rc/screenshots/02-graph-explorer-before.png` |
|
|
27
|
+
| Graph search/collapse/focus | PASS | `output/audits/v4.3.2-rc/screenshots/03-graph-search.png`, `04-graph-collapse-group.png`, `05-graph-focus-neighborhood.png` |
|
|
28
|
+
| Ask no-model honesty and graph context | PASS | `output/audits/v4.3.2-rc/screenshots/14-ask-context.png` |
|
|
29
|
+
| Capture document ingestion | PASS | `output/audits/v4.3.2-rc/screenshots/15-capture-ingestion.png` |
|
|
30
|
+
| Brain backup and graph portability | PASS | `output/audits/v4.3.2-rc/screenshots/06-brain-portability-backup.png` |
|
|
31
|
+
| System archive export/inspect/verify/import/restore dry-run | PASS | `output/audits/v4.3.2-rc/screenshots/07-system-archive-flows.png` |
|
|
32
|
+
| Storage and Postgres optional status | PASS | `output/audits/v4.3.2-rc/screenshots/08-system-storage-status.png` |
|
|
33
|
+
| Workflow create/run surfaces | PASS | `output/audits/v4.3.2-rc/screenshots/09-workflow-create-run.png` |
|
|
34
|
+
| Agent runtime availability | PASS | `output/audits/v4.3.2-rc/screenshots/10-agent-runtime-status.png` |
|
|
35
|
+
| Brain Network and device identity | PASS | `output/audits/v4.3.2-rc/screenshots/11-brain-network-device-identity.png` |
|
|
36
|
+
| Library model unavailable honesty | PASS | `output/audits/v4.3.2-rc/screenshots/12-library-model-status.png` |
|
|
37
|
+
| Desktop sidecar startup | PASS | `output/audits/v4.3.2-rc/screenshots/13-desktop-sidecar-startup.png` |
|
|
38
|
+
| Desktop sidecar shutdown | PASS | `output/audits/v4.3.2-rc/logs/desktop-shutdown-after-fix.txt` |
|
|
39
|
+
|
|
40
|
+
## Runtime Logs
|
|
41
|
+
|
|
42
|
+
- Upload result: `output/audits/v4.3.2-rc/logs/upload-note.json`
|
|
43
|
+
- README evidence upload: `output/audits/v4.3.2-rc/logs/readme-upload-note.json`
|
|
44
|
+
- Graph after upload: `output/audits/v4.3.2-rc/logs/graph-after-upload.json`
|
|
45
|
+
- Archive create: `output/audits/v4.3.2-rc/logs/archive-create.json`
|
|
46
|
+
- Archive verify: `output/audits/v4.3.2-rc/logs/archive-verify.json`
|
|
47
|
+
- Archive import dry-run: `output/audits/v4.3.2-rc/logs/archive-import-dry-run.json`
|
|
48
|
+
- Storage: `output/audits/v4.3.2-rc/logs/storage.json`
|
|
49
|
+
- Backup health: `output/audits/v4.3.2-rc/logs/backup-health-after-ui.json`
|
|
50
|
+
- Workflow create: `output/audits/v4.3.2-rc/logs/workflow-create.json`
|
|
51
|
+
- Browser automation results: `output/audits/v4.3.2-rc/logs/self-audit-browser-results.json`
|
|
52
|
+
- Desktop health: `output/audits/v4.3.2-rc/logs/desktop-sidecar-health-after-shutdown-fix.json`
|
|
53
|
+
|
|
54
|
+
## Media
|
|
55
|
+
|
|
56
|
+
- Graph walkthrough GIF: `output/audits/v4.3.2-rc/gifs/graph-product-walkthrough.gif`
|
|
57
|
+
- Graph walkthrough video: `output/audits/v4.3.2-rc/videos/graph-product-walkthrough.webm`
|
|
58
|
+
|
|
59
|
+
## Result
|
|
60
|
+
|
|
61
|
+
PASS. The observed product behavior supports the v4.3.2 RC claims. No placeholder
|
|
62
|
+
or fake functionality was accepted as complete. Optional capabilities remain
|
|
63
|
+
honestly unavailable unless their runtime dependencies and user consent exist.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Lattice AI v4.3.2 Validation Report
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-13
|
|
4
|
+
|
|
5
|
+
## Summary
|
|
6
|
+
|
|
7
|
+
v4.3.2 validation is green for the implemented product polish, graph UX, desktop
|
|
8
|
+
shutdown, exact-version release artifacts, and the release-prep documentation /
|
|
9
|
+
Vercel static-build fixes.
|
|
10
|
+
|
|
11
|
+
## Release-Prep Fix Validation
|
|
12
|
+
|
|
13
|
+
These checks were rerun after the README badge restore, diagram-first
|
|
14
|
+
`ARCHITECTURE.md` rewrite, Vercel static-only configuration fix, and linked-doc
|
|
15
|
+
cleanup.
|
|
16
|
+
|
|
17
|
+
| Check | Result |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `node -e "JSON.parse(require('fs').readFileSync('vercel.json','utf8'))"` | PASS |
|
|
20
|
+
| `npm run vercel:build` | PASS, generated `vercel-static/index.html` |
|
|
21
|
+
| `npm run docs:check-links` | PASS, README plus 15 README-linked Markdown files |
|
|
22
|
+
| Mermaid structural sanity check for `ARCHITECTURE.md` | PASS, 13 Mermaid blocks; `mmdc` was not installed locally |
|
|
23
|
+
| README badge link validation | PASS for PyPI, VS Code Marketplace, Open VSX, CI, license, and badge images; npm package page returned a CLI-only Cloudflare 403, so package identity was validated through `npm view ltcai` and `https://registry.npmjs.org/ltcai` |
|
|
24
|
+
| Registry version check | PASS, PyPI/npm/VS Code Marketplace/Open VSX currently report `4.3.1`; README does not claim v4.3.2 external registry publication |
|
|
25
|
+
| `node scripts/run_python.mjs -m pytest tests/unit/test_server_app_v14_decomposition.py::test_markdown_current_release_references_match_release tests/unit/test_truth_floor_t1_static.py::test_readme_does_not_overclaim_llm_driven_agents -v` | PASS, 2 passed |
|
|
26
|
+
| `npm run lint` | PASS |
|
|
27
|
+
| `npm pack --dry-run` | PASS, `ltcai-4.3.2.tgz`, 305 files, 2.9 MB |
|
|
28
|
+
| `npx --yes vercel@54.12.2 build` | BLOCKED by local Vercel linkage only: `project_settings_required`; no `.vercel` project settings or credentials are present in this checkout. Static build/config validation above passed. |
|
|
29
|
+
|
|
30
|
+
No product runtime code changed in this release-prep fix, and release artifacts
|
|
31
|
+
were not rebuilt.
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
| Check | Result |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `npm run check:python` | PASS, compiled 691 modules |
|
|
38
|
+
| `node scripts/run_python.mjs -m ruff check .` | PASS |
|
|
39
|
+
| `npm run lint` | PASS |
|
|
40
|
+
| `npm run typecheck` | PASS |
|
|
41
|
+
| `npm run test:unit` | PASS, 602 passed, 2 warnings |
|
|
42
|
+
| `LTCAI_TEST_BASE_URL=http://127.0.0.1:4932 npm run test:integration` | PASS, 9 passed, 1 skipped |
|
|
43
|
+
| `npm run test:visual` | PASS, 12 Playwright tests |
|
|
44
|
+
| `npm run desktop:tauri:check` | PASS |
|
|
45
|
+
| `npm run release:artifacts` | PASS |
|
|
46
|
+
| `npm run release:validate` | PASS |
|
|
47
|
+
| `node scripts/run_python.mjs scripts/wheel_smoke.py --wheel dist/ltcai-4.3.2-py3-none-any.whl` | PASS |
|
|
48
|
+
| `npm pack --dry-run` | PASS |
|
|
49
|
+
| Rebuilt desktop app startup/shutdown verification | PASS |
|
|
50
|
+
| `npm run vercel:build` | PASS |
|
|
51
|
+
| Markdown link check for README-linked docs | PASS |
|
|
52
|
+
|
|
53
|
+
## Artifact Validation
|
|
54
|
+
|
|
55
|
+
Exact v4.3.2 artifacts were found:
|
|
56
|
+
|
|
57
|
+
- `dist/ltcai-4.3.2-py3-none-any.whl`
|
|
58
|
+
- `dist/ltcai-4.3.2.tar.gz`
|
|
59
|
+
- `dist/ltcai-4.3.2.vsix`
|
|
60
|
+
- `ltcai-4.3.2.tgz`
|
|
61
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_4.3.2_aarch64.dmg`
|
|
62
|
+
|
|
63
|
+
The release validator warned that `dist/` also contains older historical
|
|
64
|
+
artifacts. This is not a v4.3.2 artifact failure, but release uploads must use
|
|
65
|
+
only the exact filenames above and never a wildcard over the `dist/` directory.
|
|
66
|
+
|
|
67
|
+
## Desktop Verification
|
|
68
|
+
|
|
69
|
+
- The rebuilt Tauri app launched from
|
|
70
|
+
`src-tauri/target/release/bundle/macos/Lattice AI.app/Contents/MacOS/lattice-ai-desktop`.
|
|
71
|
+
- `/health` responded on `127.0.0.1:8765` with version `4.3.2`, local mode, and
|
|
72
|
+
the isolated data dir `/tmp/lattice-v432-desktop3`.
|
|
73
|
+
- Normal macOS quit released port 8765.
|
|
74
|
+
- Evidence:
|
|
75
|
+
- `output/audits/v4.3.2-rc/logs/desktop-sidecar-health-after-shutdown-fix.json`
|
|
76
|
+
- `output/audits/v4.3.2-rc/logs/desktop-shutdown-after-fix.txt`
|
|
77
|
+
- `output/audits/v4.3.2-rc/screenshots/13-desktop-sidecar-startup.png`
|
|
78
|
+
|
|
79
|
+
## Notes
|
|
80
|
+
|
|
81
|
+
- The live Postgres migration test remained skipped because v4.3.2 did not
|
|
82
|
+
request fresh Docker consent. Postgres remains optional and was not changed by
|
|
83
|
+
this RC.
|
|
84
|
+
- Wheel smoke emitted optional MLX warnings inside the isolated venv, then
|
|
85
|
+
passed imports and `/health`.
|
|
86
|
+
- Rust reported a future-incompatibility warning from transitive crate
|
|
87
|
+
`block v0.1.6`; `cargo check` passed.
|
|
88
|
+
- GitHub Actions for the v4.3.2 RC commit were green before release-prep doc
|
|
89
|
+
cleanup: `CI` and `Visual Smoke` both completed successfully for
|
|
90
|
+
`8f3d182ee81bb395722ebab792dfd70f35e19e96`.
|
|
91
|
+
- Vercel config is intentionally documentation-only: it builds
|
|
92
|
+
`vercel-static/index.html`, pins the Framework Preset to "Other", and does
|
|
93
|
+
not attempt to auto-detect or host `server.py` / the desktop runtime.
|
|
94
|
+
|
|
95
|
+
## Result
|
|
96
|
+
|
|
97
|
+
PASS. v4.3.2 RC artifacts and runtime behavior are validated.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Lattice AI v4.3.3 Validation Report
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-13
|
|
4
|
+
|
|
5
|
+
v4.3.3 validation is green for the post-cleanup release tree. The release
|
|
6
|
+
rebuilds exact-current-main artifacts after the independent dead-code,
|
|
7
|
+
architecture, and runtime audit cleanup; v4.3.2 artifacts are intentionally not
|
|
8
|
+
reused.
|
|
9
|
+
|
|
10
|
+
## Validation Results
|
|
11
|
+
|
|
12
|
+
| Check | Result |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `npm run check:python` | PASS, compiled 689 modules |
|
|
15
|
+
| `node scripts/run_python.mjs -m ruff check .` | PASS |
|
|
16
|
+
| `npm run lint` | PASS |
|
|
17
|
+
| `npm run typecheck` | PASS, frontend TypeScript and VS Code extension build |
|
|
18
|
+
| `npm run test:unit` | PASS, 602 tests |
|
|
19
|
+
| `LTCAI_TEST_BASE_URL=http://127.0.0.1:4932 npm run test:integration` | PASS, 9 tests and 1 consent-gated Postgres migration test skipped |
|
|
20
|
+
| `npm run test:visual` | PASS, 12 Playwright tests |
|
|
21
|
+
| `npm run desktop:tauri:check` | PASS |
|
|
22
|
+
| `npm run release:artifacts` | PASS |
|
|
23
|
+
| `npm run release:validate` | PASS for exact v4.3.3 wheel, sdist, npm tgz, VSIX, and DMG |
|
|
24
|
+
| `node scripts/run_python.mjs scripts/wheel_smoke.py --wheel dist/ltcai-4.3.3-py3-none-any.whl` | PASS, `/health` reported 4.3.3 |
|
|
25
|
+
| `npm pack --dry-run` | PASS, `ltcai-4.3.3.tgz`, 292 files, 2.9 MB |
|
|
26
|
+
| `node scripts/run_python.mjs -m twine check dist/ltcai-4.3.3-py3-none-any.whl dist/ltcai-4.3.3.tar.gz` | PASS |
|
|
27
|
+
| `npm run docs:check-links` | PASS, README and 16 README-linked Markdown files |
|
|
28
|
+
| `npm run vercel:build` | PASS, static placeholder generated for 4.3.3 |
|
|
29
|
+
|
|
30
|
+
## Artifacts
|
|
31
|
+
|
|
32
|
+
| Artifact | SHA-256 |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| `dist/ltcai-4.3.3-py3-none-any.whl` | `716d0029a6053edacde13cad978f38e41a9c67b458eba37421ae5594e7b99948` |
|
|
35
|
+
| `dist/ltcai-4.3.3.tar.gz` | `77c19e9ad3e0cea757265b707b6414aef53a9d132f0456b7f0c36bcf09ece6b4` |
|
|
36
|
+
| `ltcai-4.3.3.tgz` | `fb29c81152fe13854e6c3ba07f5ba8b8b14f25eedbb1920600d05ef768bec044` |
|
|
37
|
+
| `dist/ltcai-4.3.3.vsix` | `28f243dbea1d0c49f78eb09176ae5c1f95d0d8530e49a103664dd338e53eac88` |
|
|
38
|
+
| `src-tauri/target/release/bundle/dmg/Lattice AI_4.3.3_aarch64.dmg` | `e717a53f83762799a32e2fa1e23c9a6fd5b2b2221bb503d12e7940e57a3455a2` |
|
|
39
|
+
|
|
40
|
+
## Notes
|
|
41
|
+
|
|
42
|
+
- `npm run release:validate` warned that historical artifacts remain in
|
|
43
|
+
`dist/`; uploads must use only the exact v4.3.3 filenames above.
|
|
44
|
+
- The live Postgres migration test remains skipped unless the owner explicitly
|
|
45
|
+
sets Docker/Postgres consent for that destructive external dependency path.
|
|
46
|
+
- External registry publishing was not attempted.
|
|
@@ -5,22 +5,21 @@
|
|
|
5
5
|
> completed analysis. **Update this file before ending any phase and before any
|
|
6
6
|
> likely session/context/usage limit.**
|
|
7
7
|
>
|
|
8
|
-
> Last updated: 2026-06-
|
|
8
|
+
> Last updated: 2026-06-13 — v4.3.3 Dead-Code Cleanup Release; Remaining Gaps remain empty
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
## 0. RELEASE STATUS (v4.3.
|
|
13
|
-
|
|
14
|
-
**v4.3.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
deploy to production targets.
|
|
12
|
+
## 0. RELEASE STATUS (v4.3.3)
|
|
13
|
+
|
|
14
|
+
**v4.3.3 promotes the post-cleanup main tree after the independent dead-code,
|
|
15
|
+
architecture, and runtime audit without redesigning the Digital Brain frontend,
|
|
16
|
+
Brain Core, storage, or agent/workflow architecture.** Latest implementation
|
|
17
|
+
milestone: v4.3.2 product polish plus post-audit cleanup, architecture
|
|
18
|
+
documentation correction, Vercel/static-docs readiness, README badge
|
|
19
|
+
restoration, and exact-current-main release artifacts.
|
|
20
|
+
The v4.3.3 process creates a GitHub Release from locally validated artifacts.
|
|
21
|
+
PyPI, npm Registry, VS Code Marketplace, Open VSX, and production deployments
|
|
22
|
+
remain owner-only external publishing steps.
|
|
24
23
|
Remaining implementation gaps: **none**.
|
|
25
24
|
Owner-only blockers: pptx history rewrite (requires force-push/owner decision)
|
|
26
25
|
and consent-gated production embedder provisioning (silent default download is
|
|
@@ -28,12 +27,12 @@ not permitted).
|
|
|
28
27
|
|
|
29
28
|
## Remaining Gaps
|
|
30
29
|
|
|
31
|
-
None. v4.3.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
intentionally not implementation gaps.
|
|
30
|
+
None. v4.3.3 preserves the already-empty v4.3.2 gap list and promotes the
|
|
31
|
+
post-cleanup tree: Brain graph exploration remains real and API-backed, raw
|
|
32
|
+
product JSON dumps remain replaced with readable state, archive import/restore
|
|
33
|
+
flows remain exposed through existing APIs, desktop sidecar behavior remains
|
|
34
|
+
validated, and exact v4.3.3 release artifacts are the release target.
|
|
35
|
+
Owner-only blockers above are intentionally not implementation gaps.
|
|
37
36
|
|
|
38
37
|
## 1. Program Charter (from the user's v4.0.0 directive)
|
|
39
38
|
|
package/frontend/openapi.json
CHANGED
|
@@ -5,7 +5,7 @@ import { ApiResult } from "@/api/client";
|
|
|
5
5
|
import { Badge } from "@/components/ui/badge";
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
8
|
-
import { cn, asArray, fmtNumber, titleize } from "@/lib/utils";
|
|
8
|
+
import { cn, asArray, fmtNumber, shortId, titleize } from "@/lib/utils";
|
|
9
9
|
|
|
10
10
|
export function SourceBadge({ result }: { result?: Pick<ApiResult, "source" | "ok" | "status"> }) {
|
|
11
11
|
if (!result) return <Badge variant="muted">not loaded</Badge>;
|
|
@@ -81,12 +81,41 @@ export function StatGrid({ stats }: { stats: Array<{ label: string; value: unkno
|
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
);
|
|
84
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
85
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function scalarText(value: unknown) {
|
|
89
|
+
if (value === null || value === undefined || value === "") return "-";
|
|
90
|
+
if (typeof value === "number") return Number.isFinite(value) ? fmtNumber(value) : "-";
|
|
91
|
+
if (typeof value === "boolean") return value ? "Enabled" : "Disabled";
|
|
92
|
+
return String(value);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function ValuePreview({ value }: { value: unknown }) {
|
|
96
|
+
if (typeof value === "boolean") {
|
|
97
|
+
return <Badge variant={value ? "success" : "muted"}>{value ? "enabled" : "disabled"}</Badge>;
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
if (!value.length) return <span className="text-muted-foreground">None</span>;
|
|
101
|
+
const primitive = value.every((item) => item === null || ["string", "number", "boolean"].includes(typeof item));
|
|
102
|
+
if (primitive) {
|
|
103
|
+
return (
|
|
104
|
+
<span className="flex flex-wrap gap-1">
|
|
105
|
+
{value.slice(0, 5).map((item, index) => <Badge key={`${String(item)}-${index}`} variant="muted">{scalarText(item)}</Badge>)}
|
|
106
|
+
{value.length > 5 ? <Badge variant="muted">+{value.length - 5}</Badge> : null}
|
|
107
|
+
</span>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return <span className="text-muted-foreground">{fmtNumber(value.length)} records</span>;
|
|
111
|
+
}
|
|
112
|
+
if (isRecord(value)) {
|
|
113
|
+
const keys = Object.keys(value);
|
|
114
|
+
if (!keys.length) return <span className="text-muted-foreground">No fields</span>;
|
|
115
|
+
return <span className="text-muted-foreground">{keys.slice(0, 4).map(titleize).join(", ")}{keys.length > 4 ? ` +${keys.length - 4}` : ""}</span>;
|
|
116
|
+
}
|
|
117
|
+
const text = scalarText(value);
|
|
118
|
+
return <span className="break-words">{text.length > 96 ? shortId(text, 96) : text}</span>;
|
|
90
119
|
}
|
|
91
120
|
|
|
92
121
|
export function KeyValueList({ data, limit = 8 }: { data: Record<string, unknown>; limit?: number }) {
|
|
@@ -97,13 +126,63 @@ export function KeyValueList({ data, limit = 8 }: { data: Record<string, unknown
|
|
|
97
126
|
{rows.map(([key, value]) => (
|
|
98
127
|
<div key={key} className="grid grid-cols-[minmax(9rem,0.5fr)_1fr] gap-3 p-3 text-sm">
|
|
99
128
|
<span className="font-medium text-muted-foreground">{titleize(key)}</span>
|
|
100
|
-
<span className="break-words"
|
|
129
|
+
<span className="min-w-0 break-words"><ValuePreview value={value} /></span>
|
|
101
130
|
</div>
|
|
102
131
|
))}
|
|
103
132
|
</div>
|
|
104
133
|
);
|
|
105
134
|
}
|
|
106
135
|
|
|
136
|
+
export function StructuredView({
|
|
137
|
+
value,
|
|
138
|
+
titleKey = "title",
|
|
139
|
+
metaKey = "status",
|
|
140
|
+
limit = 8,
|
|
141
|
+
}: {
|
|
142
|
+
value: unknown;
|
|
143
|
+
titleKey?: string;
|
|
144
|
+
metaKey?: string;
|
|
145
|
+
limit?: number;
|
|
146
|
+
}) {
|
|
147
|
+
if (Array.isArray(value)) {
|
|
148
|
+
if (!value.length) return <EmptyState title="No records" detail="The API returned an empty collection." />;
|
|
149
|
+
if (value.every((item) => isRecord(item))) {
|
|
150
|
+
return <EntityList items={value} titleKey={titleKey} metaKey={metaKey} limit={limit} />;
|
|
151
|
+
}
|
|
152
|
+
return (
|
|
153
|
+
<div className="flex flex-wrap gap-1 rounded-md border border-border bg-background p-3">
|
|
154
|
+
{value.slice(0, limit).map((item, index) => <Badge key={`${String(item)}-${index}`} variant="muted">{scalarText(item)}</Badge>)}
|
|
155
|
+
{value.length > limit ? <Badge variant="muted">+{value.length - limit}</Badge> : null}
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
if (isRecord(value)) return <KeyValueList data={value} limit={limit} />;
|
|
160
|
+
return (
|
|
161
|
+
<div className="rounded-md border border-border bg-background p-3 text-sm">
|
|
162
|
+
<ValuePreview value={value} />
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function OperationResult({
|
|
168
|
+
result,
|
|
169
|
+
successLabel = "Request completed",
|
|
170
|
+
}: {
|
|
171
|
+
result?: ApiResult<unknown> | null;
|
|
172
|
+
successLabel?: string;
|
|
173
|
+
}) {
|
|
174
|
+
if (!result) return null;
|
|
175
|
+
if (!result.ok) {
|
|
176
|
+
return <EmptyState title="Request unavailable" detail={result.error || <ValuePreview value={result.data} />} />;
|
|
177
|
+
}
|
|
178
|
+
return (
|
|
179
|
+
<div className="space-y-2 rounded-md border border-border bg-background p-3">
|
|
180
|
+
<Badge variant="success">{successLabel}</Badge>
|
|
181
|
+
<StructuredView value={result.data} />
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
107
186
|
export function EntityList({
|
|
108
187
|
items,
|
|
109
188
|
titleKey = "title",
|
|
@@ -125,8 +204,11 @@ export function EntityList({
|
|
|
125
204
|
<div className="font-medium">{String(item[titleKey] || item.name || item.id || `Record ${index + 1}`)}</div>
|
|
126
205
|
<Badge variant="muted">{String(item[metaKey] || item.status || item.state || "record")}</Badge>
|
|
127
206
|
</div>
|
|
128
|
-
{item.summary || item.description || item.path ? (
|
|
129
|
-
<p className="mt-1 text-sm text-muted-foreground">{String(item.summary || item.description || item.path)}</p>
|
|
207
|
+
{item.summary || item.description || item.path || (item.id && item[titleKey] !== item.id) ? (
|
|
208
|
+
<p className="mt-1 text-sm text-muted-foreground">{String(item.summary || item.description || item.path || item.id)}</p>
|
|
209
|
+
) : null}
|
|
210
|
+
{item.id && item[titleKey] !== item.id ? (
|
|
211
|
+
<div className="mt-1 text-xs text-muted-foreground">{shortId(item.id, 48)}</div>
|
|
130
212
|
) : null}
|
|
131
213
|
</div>
|
|
132
214
|
))}
|
|
@@ -3,7 +3,7 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
3
3
|
import ReactFlow, { Background, Controls, Edge, Node } from "reactflow";
|
|
4
4
|
import { Bot, GitBranch, PauseCircle, Play, Workflow } from "lucide-react";
|
|
5
5
|
import { latticeApi } from "@/api/client";
|
|
6
|
-
import { ActionButton, DataPanel, EntityList,
|
|
6
|
+
import { ActionButton, DataPanel, EntityList, KeyValueList, OperationResult, StructuredView, Tabs } from "@/components/primitives";
|
|
7
7
|
import { Badge } from "@/components/ui/badge";
|
|
8
8
|
import { Button } from "@/components/ui/button";
|
|
9
9
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
@@ -81,11 +81,11 @@ function AgentsPanel() {
|
|
|
81
81
|
>
|
|
82
82
|
<Play className="h-4 w-4" /> {runtimeReady ? "Run pipeline" : "Agent execution unavailable"}
|
|
83
83
|
</Button>
|
|
84
|
-
{run.data ? <
|
|
84
|
+
{run.data ? <OperationResult result={run.data} successLabel="Agent run request completed" /> : null}
|
|
85
85
|
</CardContent>
|
|
86
86
|
</Card>
|
|
87
87
|
<DataPanel title="Runtime status" result={runtime.data}>
|
|
88
|
-
{(data) => <
|
|
88
|
+
{(data) => <StructuredView value={data} />}
|
|
89
89
|
</DataPanel>
|
|
90
90
|
<DataPanel title="Agent registry" result={registry.data}>
|
|
91
91
|
{(data) => (
|
|
@@ -99,7 +99,7 @@ function AgentsPanel() {
|
|
|
99
99
|
)}
|
|
100
100
|
</DataPanel>
|
|
101
101
|
<DataPanel title="Agent capabilities" result={caps.data}>
|
|
102
|
-
{(data) => <
|
|
102
|
+
{(data) => <StructuredView value={data} />}
|
|
103
103
|
</DataPanel>
|
|
104
104
|
</div>
|
|
105
105
|
);
|
|
@@ -129,7 +129,9 @@ function RunsPanel() {
|
|
|
129
129
|
<div key={token} className="flex flex-wrap items-center justify-between gap-3 rounded-md border border-border p-3">
|
|
130
130
|
<div>
|
|
131
131
|
<div className="font-medium">{shortId(token, 16)}</div>
|
|
132
|
-
<div className="
|
|
132
|
+
<div className="mt-2">
|
|
133
|
+
<KeyValueList data={(value || {}) as Record<string, unknown>} limit={5} />
|
|
134
|
+
</div>
|
|
133
135
|
</div>
|
|
134
136
|
<div className="flex gap-2">
|
|
135
137
|
<ActionButton label="Approve" action={() => latticeApi.approvePermission(token)} invalidate={["permissions"]} />
|
|
@@ -228,8 +230,8 @@ function WorkflowsPanel() {
|
|
|
228
230
|
</div>
|
|
229
231
|
<Textarea value={importText} onChange={(event) => setImportText(event.target.value)} placeholder="Paste exported workflow JSON" />
|
|
230
232
|
<Button variant="outline" disabled={!importText.trim() || importWorkflow.isPending} onClick={() => importWorkflow.mutate()}>Import</Button>
|
|
231
|
-
{create.data ? <
|
|
232
|
-
{importWorkflow.data ? <
|
|
233
|
+
{create.data ? <OperationResult result={create.data} successLabel="Workflow created" /> : null}
|
|
234
|
+
{importWorkflow.data ? <OperationResult result={importWorkflow.data} successLabel="Workflow imported" /> : null}
|
|
233
235
|
</div>
|
|
234
236
|
{workflows.length ? workflows.map((workflow) => {
|
|
235
237
|
const id = String(workflow.id || workflow.workflow_id);
|
|
@@ -247,7 +249,7 @@ function WorkflowsPanel() {
|
|
|
247
249
|
)}
|
|
248
250
|
</DataPanel>
|
|
249
251
|
<DataPanel title="Trigger configuration" result={triggers.data} className="xl:col-span-2">
|
|
250
|
-
{(data) => <
|
|
252
|
+
{(data) => <StructuredView value={data} />}
|
|
251
253
|
</DataPanel>
|
|
252
254
|
</div>
|
|
253
255
|
);
|
|
@@ -300,7 +302,7 @@ function ToolsPanel() {
|
|
|
300
302
|
const tools = useQuery({ queryKey: ["toolPermissions"], queryFn: latticeApi.toolPermissions });
|
|
301
303
|
return (
|
|
302
304
|
<DataPanel title="Tool governance" result={tools.data}>
|
|
303
|
-
{(data) => <
|
|
305
|
+
{(data) => <EntityList items={(data as Record<string, unknown>).permissions || data} titleKey="tool" metaKey="risk" />}
|
|
304
306
|
</DataPanel>
|
|
305
307
|
);
|
|
306
308
|
}
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
3
3
|
import { ImagePlus, MessageSquare, Send, Trash2 } from "lucide-react";
|
|
4
4
|
import { latticeApi } from "@/api/client";
|
|
5
|
-
import { DataPanel, EmptyState, EntityList,
|
|
5
|
+
import { DataPanel, EmptyState, EntityList, SourceBadge, StructuredView } from "@/components/primitives";
|
|
6
6
|
import { Badge } from "@/components/ui/badge";
|
|
7
7
|
import { Button } from "@/components/ui/button";
|
|
8
8
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
@@ -193,7 +193,7 @@ function ContextPreview({ question, trace }: { question: string; trace: unknown
|
|
|
193
193
|
<CardTitle>Why this context</CardTitle>
|
|
194
194
|
<CardDescription>Trace emitted by `/chat` when the backend includes it.</CardDescription>
|
|
195
195
|
</CardHeader>
|
|
196
|
-
<CardContent>{trace ? <
|
|
196
|
+
<CardContent>{trace ? <StructuredView value={trace} /> : <EmptyState title="No trace yet" />}</CardContent>
|
|
197
197
|
</Card>
|
|
198
198
|
</>
|
|
199
199
|
);
|