ltcai 1.0.1 → 1.2.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 +34 -0
- package/docs/CHANGELOG.md +99 -0
- package/docs/EDITION_STRATEGY.md +56 -0
- package/docs/ENTERPRISE.md +78 -0
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/health.py +45 -0
- package/latticeai/api/workspace.py +748 -0
- package/latticeai/core/enterprise.py +152 -0
- package/latticeai/core/workspace_os.py +409 -38
- package/latticeai/server_app.py +73 -530
- package/latticeai/services/__init__.py +6 -0
- package/latticeai/services/chat_service.py +53 -0
- package/latticeai/services/model_service.py +51 -0
- package/latticeai/services/workspace_service.py +117 -0
- package/package.json +1 -1
- package/static/scripts/workspace.js +149 -0
- package/static/sw.js +1 -1
- package/static/workspace.css +31 -0
- package/static/workspace.html +41 -2
package/README.md
CHANGED
|
@@ -36,6 +36,40 @@ Automatic knowledge graph
|
|
|
36
36
|
Graph-aware chat, snapshots, memory, agents, workflows, skills, and timeline
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
### New in 1.2.0: Server App Modularization
|
|
40
|
+
|
|
41
|
+
- **server_app.py modularized** — Workspace/Organization and health/engine
|
|
42
|
+
endpoints extracted into dedicated routers (`latticeai/api/*`) backed by a
|
|
43
|
+
service layer (`latticeai/services/*`); `server_app` is now app assembly +
|
|
44
|
+
router include (~6,585 → ~5,948 lines)
|
|
45
|
+
- **Routers / services split** — `create_workspace_router`,
|
|
46
|
+
`create_health_router`, `WorkspaceService`, `ModelService`, `ChatService`
|
|
47
|
+
- **Workspace API service layer** — scope resolution and role/permission checks
|
|
48
|
+
centralized in `WorkspaceService`
|
|
49
|
+
- **Workspace / org guardrails** — non-members can't read/write org data,
|
|
50
|
+
viewers can't write, owners/admins manage members; no-auth local owner
|
|
51
|
+
fallback preserved
|
|
52
|
+
- **Health / model / chat modularization** — `/health`, `/mode`,
|
|
53
|
+
`/runtime_features`, `/engines` via the health router; chat trace recording
|
|
54
|
+
via the chat service (streaming behavior unchanged)
|
|
55
|
+
- **Compatibility preserved** — `server:app` import path, all API routes, CLI,
|
|
56
|
+
Knowledge Graph / Admin / Security routers, and VS Code integration unchanged
|
|
57
|
+
|
|
58
|
+
### New in 1.1.0: Organization Workspace Foundation
|
|
59
|
+
|
|
60
|
+
- **Organization Workspace** alongside Personal Workspace — create shared org
|
|
61
|
+
workspaces, list/switch between them, and archive (non-destructively)
|
|
62
|
+
- **Workspace roles & permissions** — `owner`, `admin`, `member`, `viewer`
|
|
63
|
+
mapped to read / write / manage-members / manage-workspace
|
|
64
|
+
- **Workspace-scoped data** — snapshots, memory, agent runs, workflows, traces,
|
|
65
|
+
and timeline carry a `workspace_id`; reads scope via the `X-Workspace-Id` header
|
|
66
|
+
- **CI / release hardening** — Node.js 24 ready workflow, version-scoped
|
|
67
|
+
artifact upload (never `dist/*`), and a release artifact validator
|
|
68
|
+
- **Enterprise extension foundation (open-core)** — a stable seam for a future
|
|
69
|
+
Enterprise plugin; Community ships everything it has today, unrestricted
|
|
70
|
+
(see [docs/ENTERPRISE.md](docs/ENTERPRISE.md) and
|
|
71
|
+
[docs/EDITION_STRATEGY.md](docs/EDITION_STRATEGY.md))
|
|
72
|
+
|
|
39
73
|
### New in 1.0.0: AI Workspace OS
|
|
40
74
|
|
|
41
75
|
- Workspace OS command center at `/workspace`
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,104 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0] - 2026-05-31
|
|
4
|
+
|
|
5
|
+
> Server app modularization (routers + service layer) and workspace/org guardrail hardening.
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **server_app.py modularization (phase 2)** — reduced
|
|
10
|
+
`latticeai/server_app.py` from ~6,585 to ~5,948 lines by extracting the
|
|
11
|
+
Workspace OS / Organization API and the health/engine-summary endpoints into
|
|
12
|
+
dedicated routers backed by a new service layer. `server_app` now focuses on
|
|
13
|
+
app assembly, lifespan, middleware, and router include. The historical
|
|
14
|
+
`server:app` import path, all API paths, and request/response shapes are
|
|
15
|
+
unchanged.
|
|
16
|
+
- **Workspace/Organization guardrails strengthened** — workspace-scoped reads
|
|
17
|
+
and writes now go through `WorkspaceService`, which gates explicitly-named
|
|
18
|
+
workspaces: non-members cannot read or write organization data, viewers
|
|
19
|
+
cannot write, members can write, and only owners/admins manage members. The
|
|
20
|
+
no-auth local-owner fallback for ownerless org workspaces is preserved, but a
|
|
21
|
+
*named* stranger never bypasses membership. `set_active_workspace` continues
|
|
22
|
+
to enforce membership.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **New API routers** — `latticeai/api/workspace.py`
|
|
27
|
+
(`create_workspace_router`) and `latticeai/api/health.py`
|
|
28
|
+
(`create_health_router`), mirroring the existing auth/admin router-factory
|
|
29
|
+
convention (no import cycle: routers receive dependencies, never import the
|
|
30
|
+
app).
|
|
31
|
+
- **New service layer** — `latticeai/services/workspace_service.py`
|
|
32
|
+
(`WorkspaceService`: scope resolution + permission guardrails),
|
|
33
|
+
`latticeai/services/model_service.py` (`ModelService`: health/engine summary
|
|
34
|
+
payloads), and `latticeai/services/chat_service.py` (`ChatService`: history +
|
|
35
|
+
answer-trace seam; the streaming chat path is unchanged and now records traces
|
|
36
|
+
through this façade).
|
|
37
|
+
- **Shared-global areas made explicit** — the local knowledge graph and
|
|
38
|
+
installed skills remain machine-global shared state (not partitioned per
|
|
39
|
+
workspace); this is now surfaced in `WorkspaceService.SHARED_GLOBAL_AREAS`,
|
|
40
|
+
the `/workspace/os` summary (`shared_global_areas`), and code comments.
|
|
41
|
+
- **Startup/modularization tests** — `tests/unit/test_server_app_modularization.py`
|
|
42
|
+
(import path, router registration, key route presence, no import cycle) and
|
|
43
|
+
`tests/unit/test_workspace_service.py` (read/write/member guardrails).
|
|
44
|
+
|
|
45
|
+
### Notes
|
|
46
|
+
|
|
47
|
+
- Release metadata aligned to `1.2.0`; `APP_VERSION` continues to derive from
|
|
48
|
+
`WORKSPACE_OS_VERSION` and `/health` reports `1.2.0`.
|
|
49
|
+
- CI release hardening from 1.0.1/1.1.0 is retained (VSIX compile guard, Node.js
|
|
50
|
+
24, version-scoped artifact validation — no `dist/*` glob).
|
|
51
|
+
|
|
52
|
+
## [1.1.0] - 2026-05-31
|
|
53
|
+
|
|
54
|
+
> Organization Workspace foundation, open-core Enterprise seam, and CI/release hardening.
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **Organization Workspace foundation** — Workspace OS now distinguishes
|
|
59
|
+
`personal` and `organization` workspace types. A full workspace model
|
|
60
|
+
(`workspace_id`, `name`, `type`, `owner_user_id`, `members`, `roles`,
|
|
61
|
+
`settings`, `created_at`, `updated_at`, `status`) is stored in the existing
|
|
62
|
+
local-first JSON store.
|
|
63
|
+
- **Organization Workspace API** — create org workspace, list workspaces, get
|
|
64
|
+
workspace, update, archive (soft, non-destructive), add/remove member, update
|
|
65
|
+
member role, get workspace summary, activate workspace, and an edition info
|
|
66
|
+
endpoint, exposed under `/workspace/orgs/*`, `/workspace/registry`,
|
|
67
|
+
`/workspace/activate`, and `/workspace/editions`.
|
|
68
|
+
- **Workspace roles and permissions** — `owner`, `admin`, `member`, `viewer`
|
|
69
|
+
mapped to `read` / `write` / `manage_members` / `manage_workspace`. Owners and
|
|
70
|
+
admins manage settings and members; members use the workspace; viewers are
|
|
71
|
+
read-only. Personal workspaces always grant their local user owner rights.
|
|
72
|
+
- **Workspace-scoped data** — Snapshots, Memories, Agent runs, Workflows, answer
|
|
73
|
+
Traces, and Timeline events now carry a `workspace_id`. Reads accept an
|
|
74
|
+
optional `X-Workspace-Id` header / `workspace_id` query to scope results.
|
|
75
|
+
- **Enterprise extension seam (open-core)** — new `latticeai/core/enterprise.py`
|
|
76
|
+
defines an `Edition` enum (`community`/`enterprise`), an
|
|
77
|
+
`EnterpriseCapability` enum, and a runtime `CapabilityRegistry` that a future,
|
|
78
|
+
separately-distributed Enterprise plugin can attach a provider to. The
|
|
79
|
+
Community build ships **zero** enabled Enterprise capabilities and restricts no
|
|
80
|
+
Community feature. Documented in `docs/ENTERPRISE.md` and
|
|
81
|
+
`docs/EDITION_STRATEGY.md`.
|
|
82
|
+
- **Release artifact validator** — `scripts/validate_release_artifacts.py`
|
|
83
|
+
verifies that exactly the expected `whl`/`tar.gz`/`vsix`/`tgz` exist for a
|
|
84
|
+
single version, that internal versions match, that the VSIX contains
|
|
85
|
+
`extension/out/extension.js`, and warns when `dist/` mixes other versions.
|
|
86
|
+
- **Workspace OS UI** — Personal/Organization workspace switcher, current
|
|
87
|
+
workspace indicator, and a minimal organization create / member / role panel
|
|
88
|
+
wired into the existing Workspace OS command center.
|
|
89
|
+
|
|
90
|
+
### Changed
|
|
91
|
+
|
|
92
|
+
- **CI / release hardening** — `release.yml` opts into Node.js 24
|
|
93
|
+
(`FORCE_JAVASCRIPT_ACTIONS_TO_NODE24`) and bumps `actions/checkout@v5`,
|
|
94
|
+
`actions/setup-node@v5`, `actions/setup-python@v6`. Artifact upload and
|
|
95
|
+
`twine check` are now scoped to the tagged version only — never a `dist/*`
|
|
96
|
+
glob — and the build runs the release artifact validator before upload.
|
|
97
|
+
- Existing 1.0.x Workspace OS state is migrated non-destructively to the v1.1
|
|
98
|
+
workspace model on load; legacy records map to the Personal workspace.
|
|
99
|
+
- Release metadata aligned to `1.1.0` across Python, npm, VS Code extension,
|
|
100
|
+
FastAPI app metadata, and `/health`.
|
|
101
|
+
|
|
3
102
|
## [1.0.1] - 2026-05-31
|
|
4
103
|
|
|
5
104
|
> CI packaging fix for the VS Code extension build.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Lattice AI — Edition Strategy (Open Core)
|
|
2
|
+
|
|
3
|
+
This document records the principles behind the Community / Enterprise split so
|
|
4
|
+
the boundary stays predictable for contributors and users.
|
|
5
|
+
|
|
6
|
+
## Editions
|
|
7
|
+
|
|
8
|
+
- **Community** — this repository, MIT licensed. Local-first AI Workspace OS:
|
|
9
|
+
local LLMs, knowledge graph, Personal **and** Organization workspaces,
|
|
10
|
+
role-based membership, snapshots, memory, agents, workflows, skills, and the
|
|
11
|
+
auditable timeline. Community is a complete product.
|
|
12
|
+
- **Enterprise** — a separately-distributed plugin adding organization-scale
|
|
13
|
+
governance, identity, compliance, and deployment capabilities. Distributed and
|
|
14
|
+
licensed separately. See [ENTERPRISE.md](ENTERPRISE.md).
|
|
15
|
+
|
|
16
|
+
## Principles
|
|
17
|
+
|
|
18
|
+
1. **Community is never crippled.** No existing Community feature is removed,
|
|
19
|
+
throttled, or gated to push Enterprise. The capability seam only answers "is
|
|
20
|
+
this *Enterprise* capability available?" — `False` in the open build — and
|
|
21
|
+
never disables a Community code path.
|
|
22
|
+
2. **Open-core boundary is a runtime seam, not a fork.** Enterprise attaches via
|
|
23
|
+
`capability_registry.register_provider(...)`
|
|
24
|
+
(`latticeai/core/enterprise.py`). The Community repository contains no
|
|
25
|
+
Enterprise implementation and imports no Enterprise code.
|
|
26
|
+
3. **Capabilities are declared, not hidden.** `EnterpriseCapability` enumerates
|
|
27
|
+
reserved capabilities so the contract is visible and stable, even though
|
|
28
|
+
Community implements none of them.
|
|
29
|
+
4. **Local-first stays the default.** Enterprise adds options (tenant isolation,
|
|
30
|
+
air-gapped deployment, SIEM export); it does not move the default experience
|
|
31
|
+
off the user's machine.
|
|
32
|
+
5. **Graceful by default.** A misbehaving or absent provider must never break a
|
|
33
|
+
Community request; the registry falls back to the Community provider.
|
|
34
|
+
|
|
35
|
+
## What lives where
|
|
36
|
+
|
|
37
|
+
| Concern | Community (this repo) | Enterprise (separate) |
|
|
38
|
+
|--------|------------------------|------------------------|
|
|
39
|
+
| Personal & Organization workspaces | ✅ | — |
|
|
40
|
+
| Base roles (owner/admin/member/viewer) | ✅ | — |
|
|
41
|
+
| Snapshots / memory / agents / workflows / skills | ✅ | — |
|
|
42
|
+
| Audit timeline (local) | ✅ | — |
|
|
43
|
+
| Capability seam & enum | ✅ (declares) | ✅ (implements) |
|
|
44
|
+
| SSO/SCIM/IdP provisioning | seam only | ✅ |
|
|
45
|
+
| Tenant isolation, compliance retention, eDiscovery | seam only | ✅ |
|
|
46
|
+
| SIEM export, DLP, admin policy packs | seam only | ✅ |
|
|
47
|
+
| Private VPC / air-gapped deployment | seam only | ✅ |
|
|
48
|
+
|
|
49
|
+
## Detecting edition at runtime
|
|
50
|
+
|
|
51
|
+
- `GET /workspace/editions` → edition + per-capability matrix.
|
|
52
|
+
- `GET /workspace/os` → `edition` block in the Workspace OS summary.
|
|
53
|
+
- `latticeai.core.enterprise.detect_edition()` for in-process checks.
|
|
54
|
+
|
|
55
|
+
In the Community build all of the above report `community` with every Enterprise
|
|
56
|
+
capability `false`.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Lattice AI — Enterprise Edition
|
|
2
|
+
|
|
3
|
+
> **Status:** Foundation / extension seam only. The open-source Community
|
|
4
|
+
> edition in this repository ships **none** of the capabilities below enabled,
|
|
5
|
+
> and contains **no** Enterprise implementation. This document describes the
|
|
6
|
+
> boundary and the roadmap, not shipped code.
|
|
7
|
+
|
|
8
|
+
Lattice AI follows an **open-core** model:
|
|
9
|
+
|
|
10
|
+
- **Community** (this repository, MIT) is fully functional on its own: local
|
|
11
|
+
LLMs, knowledge graph, Personal and Organization workspaces, roles, snapshots,
|
|
12
|
+
memory, agents, workflows, skills, and the auditable timeline.
|
|
13
|
+
- **Enterprise** is a separately-distributed plugin that attaches advanced,
|
|
14
|
+
organization-scale governance and deployment capabilities through a stable
|
|
15
|
+
runtime seam. It is never bundled into the Community build.
|
|
16
|
+
|
|
17
|
+
See [EDITION_STRATEGY.md](EDITION_STRATEGY.md) for the principles that keep this
|
|
18
|
+
boundary honest (Community is never crippled to upsell Enterprise).
|
|
19
|
+
|
|
20
|
+
## The extension seam
|
|
21
|
+
|
|
22
|
+
The seam lives in [`latticeai/core/enterprise.py`](../latticeai/core/enterprise.py):
|
|
23
|
+
|
|
24
|
+
- `Edition` — `community` (default) or `enterprise`.
|
|
25
|
+
- `EnterpriseCapability` — the enum of reserved capabilities (below).
|
|
26
|
+
- `CapabilityProvider` — the protocol an Enterprise plugin implements.
|
|
27
|
+
- `capability_registry` — a process-wide registry. An Enterprise plugin calls
|
|
28
|
+
`capability_registry.register_provider(...)` at startup. Until then, the
|
|
29
|
+
default `CommunityCapabilityProvider` answers every capability query with
|
|
30
|
+
"Community / disabled".
|
|
31
|
+
|
|
32
|
+
Community code consults the seam at extension points via
|
|
33
|
+
`is_capability_enabled(EnterpriseCapability.X)`. In the Community build this is
|
|
34
|
+
always `False`, so the Community code path is taken and nothing is gated off.
|
|
35
|
+
|
|
36
|
+
The live edition + capability matrix is exposed at `GET /workspace/editions`
|
|
37
|
+
and surfaced in the Workspace OS summary (`GET /workspace/os` → `edition`).
|
|
38
|
+
|
|
39
|
+
## Enterprise capability roadmap
|
|
40
|
+
|
|
41
|
+
These are declared in `EnterpriseCapability` so the seam is stable and
|
|
42
|
+
discoverable. None are implemented in Community.
|
|
43
|
+
|
|
44
|
+
| Capability | Enum | Summary |
|
|
45
|
+
|-----------|------|---------|
|
|
46
|
+
| Advanced SSO | `SSO_ADVANCED` | Enforced SSO, session policy, SAML/OIDC federation |
|
|
47
|
+
| IdP provisioning | `IDP_PROVISIONING` | Entra ID / Okta user & group provisioning |
|
|
48
|
+
| SCIM | `SCIM` | SCIM 2.0 user/group lifecycle sync |
|
|
49
|
+
| Advanced RBAC/ABAC | `RBAC_ABAC_ADVANCED` | Custom roles, attribute-based policy beyond the 4 base roles |
|
|
50
|
+
| Tenant isolation | `TENANT_ISOLATION` | Hard multi-tenant data isolation |
|
|
51
|
+
| Compliance retention | `COMPLIANCE_RETENTION` | Legal-hold, retention windows, immutable audit |
|
|
52
|
+
| SIEM export | `SIEM_EXPORT` | Streaming audit/event export to Splunk/Sentinel/etc. |
|
|
53
|
+
| Private VPC | `PRIVATE_VPC` | Private-network / customer-VPC deployment controls |
|
|
54
|
+
| Air-gapped deployment | `AIR_GAPPED_DEPLOYMENT` | Fully offline install & update channel |
|
|
55
|
+
| DLP policy | `DLP_POLICY` | Data-loss-prevention scanning & enforcement |
|
|
56
|
+
| eDiscovery | `EDISCOVERY` | Search, hold, and export for legal discovery |
|
|
57
|
+
| Admin policy packs | `ADMIN_POLICY_PACKS` | Centrally-managed org policy bundles |
|
|
58
|
+
|
|
59
|
+
## How an Enterprise plugin attaches (illustrative)
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from latticeai.core.enterprise import (
|
|
63
|
+
Edition, EnterpriseCapability, capability_registry,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
class EnterpriseProvider:
|
|
67
|
+
def edition(self) -> Edition:
|
|
68
|
+
return Edition.ENTERPRISE
|
|
69
|
+
|
|
70
|
+
def is_enabled(self, capability: EnterpriseCapability) -> bool:
|
|
71
|
+
return capability in MY_LICENSED_CAPABILITIES
|
|
72
|
+
|
|
73
|
+
# Enterprise package startup:
|
|
74
|
+
capability_registry.register_provider(EnterpriseProvider())
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
No Enterprise code or credentials live in this repository; the Community build
|
|
78
|
+
imports none of the above.
|
package/latticeai/__init__.py
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Health / status / engine-summary router.
|
|
2
|
+
|
|
3
|
+
Extracted from ``server_app.py`` in v1.2.0. Paths unchanged: ``/health``,
|
|
4
|
+
``/mode``, ``/runtime_features``, ``/engines`` (GET). Heavier engine *mutation*
|
|
5
|
+
endpoints (install / verify-cloud / pull-model) stay in server_app for now.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
from typing import Any, Callable, List, Optional
|
|
12
|
+
|
|
13
|
+
from fastapi import APIRouter, Request
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_health_router(
|
|
17
|
+
*,
|
|
18
|
+
model_service,
|
|
19
|
+
engine_status: Callable[[], List[dict]],
|
|
20
|
+
get_current_user: Callable[[Request], Optional[str]],
|
|
21
|
+
require_auth: bool,
|
|
22
|
+
app_version: str,
|
|
23
|
+
app_mode: str,
|
|
24
|
+
) -> APIRouter:
|
|
25
|
+
router = APIRouter()
|
|
26
|
+
svc = model_service
|
|
27
|
+
|
|
28
|
+
@router.get("/health")
|
|
29
|
+
async def health(request: Request):
|
|
30
|
+
base = svc.health_base(version=app_version, mode=app_mode)
|
|
31
|
+
if not get_current_user(request) and require_auth:
|
|
32
|
+
return base
|
|
33
|
+
engines = await asyncio.to_thread(engine_status)
|
|
34
|
+
return svc.health_full(base, engines)
|
|
35
|
+
|
|
36
|
+
@router.get("/mode")
|
|
37
|
+
@router.get("/runtime_features")
|
|
38
|
+
async def mode():
|
|
39
|
+
return svc.runtime()
|
|
40
|
+
|
|
41
|
+
@router.get("/engines")
|
|
42
|
+
async def engines():
|
|
43
|
+
return svc.engines_payload(await asyncio.to_thread(engine_status))
|
|
44
|
+
|
|
45
|
+
return router
|