ltcai 7.4.0 → 7.5.0
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 +25 -23
- package/docs/CHANGELOG.md +26 -0
- package/docs/ROADMAP_RECOMMENDATIONS.md +15 -1
- package/lattice_brain/__init__.py +1 -1
- package/lattice_brain/retrieval_benchmark_fixtures.py +48 -12
- package/lattice_brain/runtime/agent_runtime.py +20 -4
- package/lattice_brain/runtime/contracts.py +55 -1
- package/lattice_brain/runtime/multi_agent.py +1 -1
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/agents.py +3 -3
- package/latticeai/api/realtime.py +3 -1
- package/latticeai/core/marketplace.py +1 -1
- package/latticeai/core/workspace_os.py +1 -1
- package/package.json +6 -3
- package/scripts/brain_quality_eval.py +11 -8
- package/src-tauri/Cargo.lock +626 -1089
- package/src-tauri/Cargo.toml +3 -6
- package/src-tauri/src/main.rs +1 -1
- package/src-tauri/tauri.conf.json +1 -1
- package/static/app/asset-manifest.json +1 -1
- package/static/app/assets/core-CwxXejkd.js.map +1 -1
package/README.md
CHANGED
|
@@ -69,42 +69,42 @@ You need Lattice AI when:
|
|
|
69
69
|
Choose the owner of the Brain. The profile is not a SaaS account by default; it
|
|
70
70
|
is the local identity for the knowledge you keep.
|
|
71
71
|
|
|
72
|
-

|
|
73
73
|
|
|
74
74
|
### 2. Environment Analysis
|
|
75
75
|
|
|
76
76
|
See what kind of local AI experience this computer can support before choosing a
|
|
77
77
|
model.
|
|
78
78
|
|
|
79
|
-

|
|
80
80
|
|
|
81
81
|
### 3. Recommended Models
|
|
82
82
|
|
|
83
83
|
Start with a short list: safest recommendation, faster model, stronger model.
|
|
84
84
|
Advanced details stay available without overwhelming first-time users.
|
|
85
85
|
|
|
86
|
-

|
|
87
87
|
|
|
88
88
|
### 4. Install And Load
|
|
89
89
|
|
|
90
90
|
Download and load only after consent. Lattice explains model size, local
|
|
91
91
|
execution, and network use before work starts.
|
|
92
92
|
|
|
93
|
-

|
|
94
94
|
|
|
95
95
|
### 5. Brain Chat
|
|
96
96
|
|
|
97
97
|
Talk normally. Useful decisions and context become memory, then appear later as
|
|
98
98
|
topics, relationships, and graph structure.
|
|
99
99
|
|
|
100
|
-

|
|
101
101
|
|
|
102
102
|
### 6. Review Center
|
|
103
103
|
|
|
104
104
|
Automation results are staged for review before they become durable decisions.
|
|
105
105
|
Snooze, unsnooze, run now, approve, and dismiss actions stay explicit.
|
|
106
106
|
|
|
107
|
-

|
|
108
108
|
|
|
109
109
|
## Brain Depths
|
|
110
110
|
|
|
@@ -120,10 +120,10 @@ The user travels inward from everyday memory to deeper structure:
|
|
|
120
120
|
|
|
121
121
|
Walkthrough:
|
|
122
122
|
|
|
123
|
-

|
|
124
124
|
|
|
125
125
|
Screenshot index and capture notes:
|
|
126
|
-
[output/release/v7.
|
|
126
|
+
[output/release/v7.5.0/SCREENSHOT_INDEX.md](output/release/v7.5.0/SCREENSHOT_INDEX.md)
|
|
127
127
|
|
|
128
128
|
## Install
|
|
129
129
|
|
|
@@ -200,33 +200,34 @@ See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for developer workflow details.
|
|
|
200
200
|
|
|
201
201
|
## Current Release
|
|
202
202
|
|
|
203
|
-
The current release is **7.
|
|
203
|
+
The current release is **7.5.0 Runtime Debt Burn-down & Release Risk Cleanup**:
|
|
204
204
|
|
|
205
205
|
- Agent runs, workflow runs, audit events, and realtime events now carry the
|
|
206
206
|
`agent-run-contract/v1` family envelope, so replay, admin review, and live
|
|
207
207
|
feeds can inspect run identity, runtime, status, timeline, and artifacts
|
|
208
208
|
through one contract shape.
|
|
209
|
-
-
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
metadata; realtime SSE events keep `area`, `event_type`, `workspace_id`, and
|
|
213
|
-
`payload` while adding the same contract family.
|
|
209
|
+
- AgentRuntime and realtime API responses now expose compact `contracts` views
|
|
210
|
+
so downstream consumers can read the common envelope instead of re-parsing
|
|
211
|
+
surface-specific records.
|
|
214
212
|
- Brain quality evaluation now runs a real KnowledgeGraphStore + SearchService
|
|
215
|
-
corpus fixture with judged queries, recall, precision, NDCG,
|
|
216
|
-
hit-rate thresholds.
|
|
213
|
+
corpus fixture with 250+ records, judged queries, recall, precision, NDCG,
|
|
214
|
+
and must-include hit-rate thresholds.
|
|
215
|
+
- Release risk cleanup removes stale-artifact upload ambiguity, clears npm audit
|
|
216
|
+
findings, and updates the Tauri 2 stack so the old `block v0.1.6`
|
|
217
|
+
future-incompatibility warning is gone.
|
|
217
218
|
|
|
218
|
-
Expected artifacts for 7.
|
|
219
|
+
Expected artifacts for 7.5.0 release must use exact filenames:
|
|
219
220
|
|
|
220
|
-
- `dist/ltcai-7.
|
|
221
|
-
- `dist/ltcai-7.
|
|
222
|
-
- `ltcai-7.
|
|
223
|
-
- `dist/ltcai-7.
|
|
224
|
-
- `src-tauri/target/release/bundle/dmg/Lattice AI_7.
|
|
221
|
+
- `dist/ltcai-7.5.0-py3-none-any.whl`
|
|
222
|
+
- `dist/ltcai-7.5.0.tar.gz`
|
|
223
|
+
- `ltcai-7.5.0.tgz`
|
|
224
|
+
- `dist/ltcai-7.5.0.vsix`
|
|
225
|
+
- `src-tauri/target/release/bundle/dmg/Lattice AI_7.5.0_aarch64.dmg`
|
|
225
226
|
|
|
226
227
|
Do not upload `dist/*`. Package registry publishing remains owner-run.
|
|
227
228
|
|
|
228
229
|
See [docs/ROADMAP_RECOMMENDATIONS.md](docs/ROADMAP_RECOMMENDATIONS.md) for the
|
|
229
|
-
strategic roadmap slices applied through 7.
|
|
230
|
+
strategic roadmap slices applied through 7.5.0 and the follow-up tracks.
|
|
230
231
|
|
|
231
232
|
## Known Limitations
|
|
232
233
|
|
|
@@ -243,6 +244,7 @@ strategic roadmap slices applied through 7.4.0 and the follow-up tracks.
|
|
|
243
244
|
|
|
244
245
|
| Version | Theme |
|
|
245
246
|
| --- | --- |
|
|
247
|
+
| 7.5.0 | Runtime Debt Burn-down & Release Risk Cleanup: API consumers get normalized contract views, retrieval quality uses a 250+ record corpus fixture, stale artifact risk is removed, npm audit is clean, and Tauri is updated past the old block warning |
|
|
246
248
|
| 7.4.0 | Runtime Contract Convergence & Corpus Retrieval: agent/workflow/audit/realtime records share the agent-run-contract/v1 family, and retrieval quality gates run against a real corpus-scale fixture |
|
|
247
249
|
| 7.3.0 | Runtime Contract & Retrieval Quality: shared agent-run contract across runtimes plus deterministic hybrid recall/ranking regression gates |
|
|
248
250
|
| 7.2.0 | Runtime Trust Baseline: agent run preview/readiness, simulation-mode guardrails, live ToolRegistry manifest/diagnostics, and tests for dispatch/governance/catalog drift |
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ The top entry is either the current unreleased main-branch work or the current
|
|
|
4
4
|
release line. Older entries are historical and may describe behavior as it
|
|
5
5
|
existed at that release.
|
|
6
6
|
|
|
7
|
+
## [7.5.0] - 2026-06-20
|
|
8
|
+
|
|
9
|
+
> Runtime Debt Burn-down & Release Risk Cleanup. Turns the 7.4.0 contract
|
|
10
|
+
> envelope into a consumed API surface, expands retrieval quality to a 250+
|
|
11
|
+
> record local corpus fixture, and removes release/security warnings.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- `extract_contract`, `require_contract`, `contract_view`, and `contract_views`
|
|
15
|
+
helpers for consumers that need a surface-agnostic `agent-run-contract/v1`
|
|
16
|
+
projection.
|
|
17
|
+
- AgentRuntime status/list/detail/events and realtime feed responses now expose
|
|
18
|
+
compact `contracts` views alongside legacy payloads.
|
|
19
|
+
- Deterministic 250+ record retrieval benchmark corpus while keeping 12 judged
|
|
20
|
+
queries and real `KnowledgeGraphStore` + `SearchService` execution.
|
|
21
|
+
- Refreshed README release evidence screenshots and walkthrough GIF under
|
|
22
|
+
`output/release/v7.5.0/`.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Tauri Rust/CLI dependencies are updated within the Tauri 2 line, removing the
|
|
26
|
+
old transitive `block v0.1.6` future-incompatibility warning.
|
|
27
|
+
- npm dependency overrides move `js-yaml` to a non-vulnerable version; `npm
|
|
28
|
+
audit` reports 0 vulnerabilities.
|
|
29
|
+
- CI lint compatibility is restored for the Brain quality gate script.
|
|
30
|
+
- Package/runtime/static metadata is synchronized to 7.5.0; package publish and
|
|
31
|
+
deployment remain owner-run only.
|
|
32
|
+
|
|
7
33
|
## [7.4.0] - 2026-06-20
|
|
8
34
|
|
|
9
35
|
> Runtime Contract Convergence & Corpus Retrieval. Completes the
|
|
@@ -30,6 +30,19 @@ small release-sized work. The operating principle stays unchanged:
|
|
|
30
30
|
Knowledge Graph corpus and scores SearchService hybrid retrieval with judged
|
|
31
31
|
queries, recall, precision, NDCG, and must-include hit-rate thresholds.
|
|
32
32
|
|
|
33
|
+
## 7.5.0 Applied Slice
|
|
34
|
+
|
|
35
|
+
7.5.0 burns down the remaining 7.4.0 risk instead of deferring it:
|
|
36
|
+
|
|
37
|
+
- Contract consumption: AgentRuntime and realtime feed APIs now emit compact
|
|
38
|
+
`contracts` views so UI, replay, admin, and export consumers can depend on the
|
|
39
|
+
shared family envelope directly.
|
|
40
|
+
- Retrieval scale: the corpus fixture now runs against 250+ local records while
|
|
41
|
+
keeping judged queries, graded relevance, and must-include expectations.
|
|
42
|
+
- Release trust: stale artifact mixing is handled through clean exact-version
|
|
43
|
+
artifact generation, npm audit findings are cleared, and the Tauri 2 stack is
|
|
44
|
+
updated past the old `block v0.1.6` future-incompatibility warning.
|
|
45
|
+
|
|
33
46
|
## Near-Term Tracks
|
|
34
47
|
|
|
35
48
|
1. Retrieval quality and scale
|
|
@@ -43,7 +56,8 @@ small release-sized work. The operating principle stays unchanged:
|
|
|
43
56
|
- Surface conflict resolution for contradictory memories.
|
|
44
57
|
|
|
45
58
|
3. Runtime convergence
|
|
46
|
-
-
|
|
59
|
+
- Migrate remaining UI run/replay/admin components to read the API-level
|
|
60
|
+
compact contract views as their primary source.
|
|
47
61
|
- Keep simulation mode explicit and never record it as product success.
|
|
48
62
|
- Route tools through explicit registry/governance contracts.
|
|
49
63
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"""Corpus-scale retrieval fixture for the 7.
|
|
1
|
+
"""Corpus-scale retrieval fixture for the 7.5.0 Brain quality gate."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
FIXTURE_NAME = "7.
|
|
5
|
+
FIXTURE_NAME = "7.5.0-corpus-scale-hybrid-retrieval"
|
|
6
6
|
TOP_K = 5
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
CORE_DOCUMENTS = [
|
|
9
9
|
{"id": "doc:agent-runtime-contract", "type": "Decision", "title": "Agent runtime contract", "content": "Workflow run, agent run, audit event, and realtime event records must carry the agent-run-contract/v1 family envelope with run id, runtime, status, timeline, and artifacts."},
|
|
10
10
|
{"id": "doc:workflow-observability", "type": "Document", "title": "Workflow observability", "content": "Workflow Designer persists queued, running, awaiting approval, cancelled, interrupted, partial, failed, and ok runs with replayable timeline events."},
|
|
11
11
|
{"id": "doc:audit-trust", "type": "Security", "title": "Audit trust", "content": "Audit events are append-only, redacted before persistence, and linked to execution contracts for admin review without leaking secrets."},
|
|
@@ -33,24 +33,60 @@ DOCUMENTS = [
|
|
|
33
33
|
{"id": "doc:docker-tauri", "type": "Deployment", "title": "Deployment operations", "content": "Docker Compose deployment, one-click installation, Tauri auto-updates, rollback support, and exact release artifacts improve operations."},
|
|
34
34
|
{"id": "doc:model-routing", "type": "Runtime", "title": "Model orchestration", "content": "Ollama, LM Studio, MLX, and cloud models need automatic fallback, routing, and replaceable model boundaries."},
|
|
35
35
|
{"id": "doc:strict-quality", "type": "Quality", "title": "Strict code quality", "content": "Async-first architecture, dependency injection, centralized exceptions, mypy or pyright, TypeScript strict mode, E2E tests, and property tests reduce regressions."},
|
|
36
|
-
{"id": "distractor:theme-editor", "type": "Distractor", "title": "Theme editor", "content": "Color palettes, typography, and sidebar icon sizing are useful
|
|
37
|
-
{"id": "distractor:calendar", "type": "Distractor", "title": "Calendar reminders", "content": "Calendar reminders and meeting agenda formatting are integrations
|
|
36
|
+
{"id": "distractor:theme-editor", "type": "Distractor", "title": "Theme editor", "content": "Color palettes, typography, and sidebar icon sizing are useful visual polish topics."},
|
|
37
|
+
{"id": "distractor:calendar", "type": "Distractor", "title": "Calendar reminders", "content": "Calendar reminders and meeting agenda formatting are productivity integrations."},
|
|
38
38
|
{"id": "distractor:billing", "type": "Distractor", "title": "Billing invoices", "content": "Invoices, payment receipts, and subscription emails can be stored but are not the Brain quality gate."},
|
|
39
|
-
{"id": "distractor:mobile-shell", "type": "Distractor", "title": "Mobile shell", "content": "A mobile companion can improve access
|
|
40
|
-
{"id": "distractor:marketing", "type": "Distractor", "title": "Marketing landing page", "content": "Landing pages and hero copy
|
|
39
|
+
{"id": "distractor:mobile-shell", "type": "Distractor", "title": "Mobile shell", "content": "A mobile companion can improve access with push notifications and offline cache."},
|
|
40
|
+
{"id": "distractor:marketing", "type": "Distractor", "title": "Marketing landing page", "content": "Landing pages and hero copy shape positioning and campaign messaging."},
|
|
41
41
|
]
|
|
42
42
|
|
|
43
|
+
_DISTRACTOR_TOPICS = [
|
|
44
|
+
("finance", "quarterly planning", "budget variance vendor renewal procurement forecast"),
|
|
45
|
+
("design", "component polish", "spacing typography icon density color token accessibility"),
|
|
46
|
+
("support", "customer escalation", "ticket triage priority response macro satisfaction"),
|
|
47
|
+
("ops", "incident rotation", "oncall handoff status page maintenance window"),
|
|
48
|
+
("sales", "pipeline review", "lead scoring opportunity stage forecast account"),
|
|
49
|
+
("calendar", "meeting schedule", "agenda reminder availability invite followup"),
|
|
50
|
+
("email", "inbox policy", "thread label archive template unsubscribe"),
|
|
51
|
+
("mobile", "companion shell", "push notification offline cache deep link"),
|
|
52
|
+
("billing", "invoice lifecycle", "receipt tax subscription entitlement payment"),
|
|
53
|
+
("analytics", "dashboard report", "cohort funnel metric annotation export"),
|
|
54
|
+
("theme", "appearance settings", "palette contrast sidebar density motion"),
|
|
55
|
+
("legal", "compliance packet", "clause obligation renewal signature counterparty"),
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _generated_distractors() -> list[dict[str, str]]:
|
|
60
|
+
"""Create a deterministic local corpus large enough to exercise ranking."""
|
|
61
|
+
docs: list[dict[str, str]] = []
|
|
62
|
+
for batch in range(20):
|
|
63
|
+
for topic, title, terms in _DISTRACTOR_TOPICS:
|
|
64
|
+
docs.append({
|
|
65
|
+
"id": f"distractor:{topic}:{batch:02d}",
|
|
66
|
+
"type": "Distractor",
|
|
67
|
+
"title": f"{title.title()} {batch + 1}",
|
|
68
|
+
"content": (
|
|
69
|
+
f"{title} note {batch + 1}. This record discusses {terms}. "
|
|
70
|
+
"It is intentionally unrelated to the judged Brain quality topics "
|
|
71
|
+
"and exists to make local ranking tests compete against realistic noise."
|
|
72
|
+
),
|
|
73
|
+
})
|
|
74
|
+
return docs
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
DOCUMENTS = CORE_DOCUMENTS + _generated_distractors()
|
|
78
|
+
|
|
43
79
|
QUERIES = [
|
|
44
80
|
{"query": "agent workflow audit realtime contract run status timeline", "relevant": {"doc:agent-runtime-contract": 3, "doc:workflow-observability": 2, "doc:audit-trust": 2, "doc:realtime-feed": 2}, "must_include": ["doc:agent-runtime-contract"]},
|
|
45
81
|
{"query": "workflow queued running cancelled interrupted replay approval", "relevant": {"doc:workflow-observability": 3, "doc:agentic-hitl": 2}, "must_include": ["doc:workflow-observability"]},
|
|
46
|
-
{"query": "audit log redacted secrets admin review contract", "relevant": {"doc:audit-trust": 3
|
|
82
|
+
{"query": "audit log redacted secrets admin review contract", "relevant": {"doc:audit-trust": 3}, "must_include": ["doc:audit-trust"]},
|
|
47
83
|
{"query": "SSE realtime workspace event payload sequence contract", "relevant": {"doc:realtime-feed": 3, "doc:agent-runtime-contract": 2}, "must_include": ["doc:realtime-feed"]},
|
|
48
84
|
{"query": "hybrid retrieval keyword vector graph weighted scoped search", "relevant": {"doc:hybrid-search": 3, "doc:knowledge-graph": 2, "doc:retrieval-benchmark": 2}, "must_include": ["doc:hybrid-search"]},
|
|
49
|
-
{"query": "corpus scale recall precision ndcg judged queries", "relevant": {"doc:retrieval-benchmark": 3
|
|
85
|
+
{"query": "corpus scale recall precision ndcg judged queries", "relevant": {"doc:retrieval-benchmark": 3}, "must_include": ["doc:retrieval-benchmark"]},
|
|
50
86
|
{"query": "local first model independent durable memory brain proof citation", "relevant": {"doc:local-first": 3, "doc:brain-proof": 2}, "must_include": ["doc:local-first"]},
|
|
51
|
-
{"query": "incremental indexing duplicate conflict merge background ingestion", "relevant": {"doc:incremental-ingestion": 3
|
|
52
|
-
{"query": "workspace admin profile organization members roles permissions", "relevant": {"doc:workspace-admin": 3
|
|
87
|
+
{"query": "incremental indexing duplicate conflict merge background ingestion", "relevant": {"doc:incremental-ingestion": 3}, "must_include": ["doc:incremental-ingestion"]},
|
|
88
|
+
{"query": "workspace admin profile organization members roles permissions", "relevant": {"doc:workspace-admin": 3}, "must_include": ["doc:workspace-admin"]},
|
|
53
89
|
{"query": "tool registry separation dependency injection runtime context", "relevant": {"doc:tool-registry": 3, "doc:server-decomposition": 2, "doc:config-centralization": 2}, "must_include": ["doc:tool-registry"]},
|
|
54
|
-
{"query": "human in the loop approval review queue rollback", "relevant": {"doc:agentic-hitl": 3
|
|
90
|
+
{"query": "human in the loop approval review queue rollback", "relevant": {"doc:agentic-hitl": 3}, "must_include": ["doc:agentic-hitl"]},
|
|
55
91
|
{"query": "model routing ollama lm studio mlx cloud fallback replaceable", "relevant": {"doc:model-routing": 3, "doc:local-first": 2}, "must_include": ["doc:model-routing"]},
|
|
56
92
|
]
|
|
@@ -37,7 +37,7 @@ from .multi_agent import (
|
|
|
37
37
|
MULTI_AGENT_VERSION,
|
|
38
38
|
ROLE_AGENT_IDS,
|
|
39
39
|
)
|
|
40
|
-
from .contracts import multi_agent_contract
|
|
40
|
+
from .contracts import contract_view, contract_views, extract_contract, multi_agent_contract
|
|
41
41
|
|
|
42
42
|
ROLE_DESCRIPTIONS = {
|
|
43
43
|
"researcher": "Gathers workspace context and memory for the goal.",
|
|
@@ -227,6 +227,7 @@ class AgentRuntime:
|
|
|
227
227
|
"roles": self.roles(),
|
|
228
228
|
"agents": self._roster(runs),
|
|
229
229
|
"runs": runs[:25],
|
|
230
|
+
"contracts": contract_views(runs[:25]),
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
def preview(
|
|
@@ -282,13 +283,27 @@ class AgentRuntime:
|
|
|
282
283
|
|
|
283
284
|
# ── events / state ────────────────────────────────────────────────────
|
|
284
285
|
def list_runs(self, *, scope: Optional[str] = None) -> Dict[str, Any]:
|
|
285
|
-
|
|
286
|
+
listing = self._store.list_agents(workspace_id=scope)
|
|
287
|
+
runs = list(listing.get("runs") or [])
|
|
288
|
+
payload = dict(listing)
|
|
289
|
+
payload["contracts"] = contract_views(runs)
|
|
290
|
+
return payload
|
|
286
291
|
|
|
287
292
|
def get_run(self, run_id: str, *, scope: Optional[str] = None) -> Dict[str, Any]:
|
|
288
|
-
|
|
293
|
+
run = self._store.get_agent_run(run_id, workspace_id=scope)
|
|
294
|
+
payload = {"run": run}
|
|
295
|
+
contract = extract_contract(run)
|
|
296
|
+
if contract is not None:
|
|
297
|
+
payload["contract"] = contract_view(contract)
|
|
298
|
+
return payload
|
|
289
299
|
|
|
290
300
|
def replay(self, run_id: str, *, scope: Optional[str] = None) -> Dict[str, Any]:
|
|
291
|
-
|
|
301
|
+
replay = self._store.replay_agent_run(run_id, workspace_id=scope)
|
|
302
|
+
payload = {"replay": replay}
|
|
303
|
+
contract = extract_contract(replay)
|
|
304
|
+
if contract is not None:
|
|
305
|
+
payload["contract"] = contract_view(contract)
|
|
306
|
+
return payload
|
|
292
307
|
|
|
293
308
|
def events(self, run_id: str, *, scope: Optional[str] = None) -> Dict[str, Any]:
|
|
294
309
|
run = self._store.get_agent_run(run_id, workspace_id=scope)
|
|
@@ -300,6 +315,7 @@ class AgentRuntime:
|
|
|
300
315
|
"current_role": run.get("current_role"),
|
|
301
316
|
"timeline": run.get("timeline") or [],
|
|
302
317
|
"handoffs": run.get("handoffs") or [],
|
|
318
|
+
"contract": contract_view(run),
|
|
303
319
|
}
|
|
304
320
|
|
|
305
321
|
# ── execution ─────────────────────────────────────────────────────────
|
|
@@ -30,7 +30,7 @@ from __future__ import annotations
|
|
|
30
30
|
|
|
31
31
|
from dataclasses import dataclass, field
|
|
32
32
|
from datetime import datetime
|
|
33
|
-
from typing import Any, Dict, List, Optional
|
|
33
|
+
from typing import Any, Dict, Iterable, List, Optional
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def runtime_timestamp() -> str:
|
|
@@ -52,6 +52,22 @@ CONTRACT_KINDS = ("agent_run", "workflow_run", "audit_event", "realtime_event")
|
|
|
52
52
|
|
|
53
53
|
# The envelope keys every family member is guaranteed to expose.
|
|
54
54
|
CONTRACT_ENVELOPE_KEYS = ("family", "schema_version", "kind", "id", "status", "timestamp")
|
|
55
|
+
CONTRACT_VIEW_KEYS = (
|
|
56
|
+
"family",
|
|
57
|
+
"schema_version",
|
|
58
|
+
"kind",
|
|
59
|
+
"id",
|
|
60
|
+
"run_id",
|
|
61
|
+
"agent_id",
|
|
62
|
+
"runtime",
|
|
63
|
+
"mode",
|
|
64
|
+
"status",
|
|
65
|
+
"goal",
|
|
66
|
+
"current_role",
|
|
67
|
+
"timestamp",
|
|
68
|
+
"is_terminal",
|
|
69
|
+
"blocking_reasons",
|
|
70
|
+
)
|
|
55
71
|
|
|
56
72
|
_SCHEMA_FOR_KIND = {
|
|
57
73
|
"agent_run": AGENT_RUN_SCHEMA,
|
|
@@ -102,6 +118,44 @@ def is_contract_member(record: Any) -> bool:
|
|
|
102
118
|
return all(key in record for key in CONTRACT_ENVELOPE_KEYS)
|
|
103
119
|
|
|
104
120
|
|
|
121
|
+
def extract_contract(record: Any) -> Optional[Dict[str, Any]]:
|
|
122
|
+
"""Return the normalized family contract carried by ``record``.
|
|
123
|
+
|
|
124
|
+
Consumers should call this instead of branching on whether they received an
|
|
125
|
+
agent run, workflow run, audit row, or realtime event. The function accepts
|
|
126
|
+
either a raw contract dict or a surface record with a nested ``contract``.
|
|
127
|
+
"""
|
|
128
|
+
if is_contract_member(record):
|
|
129
|
+
return dict(record)
|
|
130
|
+
if isinstance(record, dict) and is_contract_member(record.get("contract")):
|
|
131
|
+
return dict(record["contract"])
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def require_contract(record: Any) -> Dict[str, Any]:
|
|
136
|
+
"""Return a valid family contract or raise a precise error."""
|
|
137
|
+
contract = extract_contract(record)
|
|
138
|
+
if contract is None:
|
|
139
|
+
raise ValueError("record is missing an agent-run-contract/v1 family contract")
|
|
140
|
+
return contract
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def contract_view(record: Any) -> Dict[str, Any]:
|
|
144
|
+
"""Return a compact, surface-agnostic view for API and UI consumers."""
|
|
145
|
+
contract = require_contract(record)
|
|
146
|
+
return {key: contract.get(key) for key in CONTRACT_VIEW_KEYS if key in contract}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def contract_views(records: Iterable[Any]) -> List[Dict[str, Any]]:
|
|
150
|
+
"""Return compact views for every valid contract in ``records``."""
|
|
151
|
+
views: List[Dict[str, Any]] = []
|
|
152
|
+
for record in records:
|
|
153
|
+
contract = extract_contract(record)
|
|
154
|
+
if contract is not None:
|
|
155
|
+
views.append({key: contract.get(key) for key in CONTRACT_VIEW_KEYS if key in contract})
|
|
156
|
+
return views
|
|
157
|
+
|
|
158
|
+
|
|
105
159
|
@dataclass(frozen=True)
|
|
106
160
|
class AgentRunContract:
|
|
107
161
|
run_id: Optional[str]
|
|
@@ -21,7 +21,7 @@ from typing import Any, Callable, Dict, List, Optional
|
|
|
21
21
|
from .contracts import multi_agent_contract
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
MULTI_AGENT_VERSION = "7.
|
|
24
|
+
MULTI_AGENT_VERSION = "7.5.0"
|
|
25
25
|
|
|
26
26
|
AGENT_ROLES = ("researcher", "planner", "executor", "reviewer", "release")
|
|
27
27
|
CORE_PIPELINE = ("planner", "executor", "reviewer")
|
package/latticeai/__init__.py
CHANGED
package/latticeai/api/agents.py
CHANGED
|
@@ -111,7 +111,7 @@ def create_agents_router(
|
|
|
111
111
|
async def agent_runs(request: Request):
|
|
112
112
|
require_user(request)
|
|
113
113
|
scope = gate_read(request)
|
|
114
|
-
return
|
|
114
|
+
return runtime.list_runs(scope=scope)
|
|
115
115
|
|
|
116
116
|
@router.get("/agents/api/handoffs")
|
|
117
117
|
async def agent_handoffs(request: Request, run_id: str = ""):
|
|
@@ -124,7 +124,7 @@ def create_agents_router(
|
|
|
124
124
|
require_user(request)
|
|
125
125
|
scope = gate_read(request)
|
|
126
126
|
try:
|
|
127
|
-
return
|
|
127
|
+
return runtime.get_run(run_id, scope=scope)
|
|
128
128
|
except FileNotFoundError as exc:
|
|
129
129
|
raise HTTPException(status_code=404, detail=f"Agent run not found: {run_id}") from exc
|
|
130
130
|
|
|
@@ -133,7 +133,7 @@ def create_agents_router(
|
|
|
133
133
|
require_user(request)
|
|
134
134
|
scope = gate_read(request)
|
|
135
135
|
try:
|
|
136
|
-
return
|
|
136
|
+
return runtime.replay(run_id, scope=scope)
|
|
137
137
|
except FileNotFoundError as exc:
|
|
138
138
|
raise HTTPException(status_code=404, detail=f"Agent run not found: {run_id}") from exc
|
|
139
139
|
|
|
@@ -17,6 +17,7 @@ from fastapi.responses import StreamingResponse
|
|
|
17
17
|
from pydantic import BaseModel
|
|
18
18
|
|
|
19
19
|
from latticeai.api.ui_redirects import app_redirect
|
|
20
|
+
from lattice_brain.runtime.contracts import contract_views
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class PresenceRequest(BaseModel):
|
|
@@ -63,7 +64,8 @@ def create_realtime_router(
|
|
|
63
64
|
async def realtime_feed(request: Request, limit: int = 50):
|
|
64
65
|
user = require_user(request)
|
|
65
66
|
scope = allowed_scopes(user or None)
|
|
66
|
-
|
|
67
|
+
events = bus.recent(limit=limit, workspace_scope=scope)
|
|
68
|
+
return {"events": events, "contracts": contract_views(events), "stats": bus.stats()}
|
|
67
69
|
|
|
68
70
|
@router.get("/realtime/presence")
|
|
69
71
|
async def realtime_presence(request: Request):
|
|
@@ -21,7 +21,7 @@ from typing import Any, Callable, Dict, Iterable, List, Optional
|
|
|
21
21
|
from lattice_brain.runtime.contracts import realtime_event_contract, run_record_contract, workflow_run_contract
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
WORKSPACE_OS_VERSION = "7.
|
|
24
|
+
WORKSPACE_OS_VERSION = "7.5.0"
|
|
25
25
|
|
|
26
26
|
# Workspace types separate single-user Personal workspaces from shared
|
|
27
27
|
# Organization workspaces. Both keep the same local-first JSON store; the type
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ltcai",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"description": "Lattice AI — local-first Digital Brain that keeps your knowledge durable across any AI model.",
|
|
5
5
|
"homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
|
|
6
6
|
"repository": {
|
|
@@ -115,8 +115,8 @@
|
|
|
115
115
|
"@playwright/test": "^1.60.0",
|
|
116
116
|
"@tailwindcss/postcss": "^4.3.0",
|
|
117
117
|
"@tanstack/react-query": "^5.101.0",
|
|
118
|
-
"@tauri-apps/api": "^2.
|
|
119
|
-
"@tauri-apps/cli": "^2.
|
|
118
|
+
"@tauri-apps/api": "^2.11.1",
|
|
119
|
+
"@tauri-apps/cli": "^2.11.3",
|
|
120
120
|
"@types/cytoscape": "^3.21.9",
|
|
121
121
|
"@types/react": "^19.2.17",
|
|
122
122
|
"@types/react-dom": "^19.2.3",
|
|
@@ -138,5 +138,8 @@
|
|
|
138
138
|
"typescript": "^5.9.3",
|
|
139
139
|
"vite": "^8.0.16",
|
|
140
140
|
"zustand": "^5.0.14"
|
|
141
|
+
},
|
|
142
|
+
"overrides": {
|
|
143
|
+
"js-yaml": "^4.2.0"
|
|
141
144
|
}
|
|
142
145
|
}
|
|
@@ -16,11 +16,11 @@ REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
|
16
16
|
if str(REPO_ROOT) not in sys.path:
|
|
17
17
|
sys.path.insert(0, str(REPO_ROOT))
|
|
18
18
|
|
|
19
|
-
from knowledge_graph import KnowledgeGraphStore
|
|
20
|
-
from lattice_brain.quality import RetrievalBenchmarkRunner
|
|
21
|
-
from latticeai.services.search_service import SearchService
|
|
22
|
-
from latticeai.services.memory_service import MemoryService
|
|
23
|
-
from lattice_brain.retrieval_benchmark_fixtures import DOCUMENTS, FIXTURE_NAME, QUERIES, TOP_K
|
|
19
|
+
from knowledge_graph import KnowledgeGraphStore # noqa: E402
|
|
20
|
+
from lattice_brain.quality import RetrievalBenchmarkRunner # noqa: E402
|
|
21
|
+
from latticeai.services.search_service import SearchService # noqa: E402
|
|
22
|
+
from latticeai.services.memory_service import MemoryService # noqa: E402
|
|
23
|
+
from lattice_brain.retrieval_benchmark_fixtures import DOCUMENTS, FIXTURE_NAME, QUERIES, TOP_K # noqa: E402
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class _EvalStore:
|
|
@@ -173,11 +173,14 @@ def main() -> int:
|
|
|
173
173
|
|
|
174
174
|
with tempfile.TemporaryDirectory() as tmp:
|
|
175
175
|
corpus_metrics = _corpus_scale_retrieval_metrics(Path(tmp))
|
|
176
|
-
|
|
176
|
+
recall_key = f"recall@{TOP_K}"
|
|
177
|
+
precision_key = f"precision@{TOP_K}"
|
|
178
|
+
ndcg_key = f"ndcg@{TOP_K}"
|
|
179
|
+
if corpus_metrics.get(recall_key, 0.0) < 0.80:
|
|
177
180
|
return _fail(f"corpus hybrid recall below threshold: {corpus_metrics}")
|
|
178
|
-
if corpus_metrics.get(
|
|
181
|
+
if corpus_metrics.get(precision_key, 0.0) < 0.25:
|
|
179
182
|
return _fail(f"corpus hybrid precision below threshold: {corpus_metrics}")
|
|
180
|
-
if corpus_metrics.get(
|
|
183
|
+
if corpus_metrics.get(ndcg_key, 0.0) < 0.70:
|
|
181
184
|
return _fail(f"corpus hybrid ndcg below threshold: {corpus_metrics}")
|
|
182
185
|
if corpus_metrics.get("must_include_hit_rate", 0.0) < 0.90:
|
|
183
186
|
return _fail(f"corpus must-include hit rate below threshold: {corpus_metrics}")
|