loki-mode 7.0.2 → 7.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/SKILL.md +4 -4
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/static/index.html +464 -73
- package/docs/INSTALLATION.md +22 -68
- package/mcp/__init__.py +1 -1
- package/memory/managed_memory/client.py +30 -5
- package/memory/managed_memory/events.py +48 -1
- package/package.json +1 -1
- package/skills/memory.md +2 -2
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v7.0
|
|
5
|
+
**Version:** v7.2.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -34,7 +34,7 @@ The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installa
|
|
|
34
34
|
- [Quick Start](#quick-start)
|
|
35
35
|
- [Verify Installation](#verify-installation)
|
|
36
36
|
- [Other Methods](#other-methods)
|
|
37
|
-
- [VS Code Extension](#vs-code-extension)
|
|
37
|
+
- [VS Code Extension (Deprecated)](#vs-code-extension-deprecated)
|
|
38
38
|
- [Sandbox Mode](#sandbox-mode)
|
|
39
39
|
- [Multi-Provider Support](#multi-provider-support)
|
|
40
40
|
- [Claude Code (CLI)](#claude-code-cli)
|
|
@@ -117,79 +117,33 @@ loki doctor # Check skill symlinks, providers, and system prerequisites
|
|
|
117
117
|
|
|
118
118
|
## Other Methods
|
|
119
119
|
|
|
120
|
-
Git clone
|
|
120
|
+
Git clone and Docker installation methods are also available. See
|
|
121
|
+
[alternative-installations.md](alternative-installations.md) for details and
|
|
122
|
+
trade-offs.
|
|
121
123
|
|
|
122
124
|
---
|
|
123
125
|
|
|
124
|
-
## VS Code Extension
|
|
126
|
+
## VS Code Extension (Deprecated)
|
|
125
127
|
|
|
126
|
-
|
|
128
|
+
> **DEPRECATED as of v7.2.0.** The Loki Mode VS Code extension is no longer
|
|
129
|
+
> maintained. Use the dashboard at `loki dashboard start` instead.
|
|
130
|
+
>
|
|
131
|
+
> The marketplace listing remains for users on v7.2.0 and earlier but will
|
|
132
|
+
> not receive further updates. The `vscode-extension/` source remains in the
|
|
133
|
+
> repository for contributors who want to build the extension locally; it is
|
|
134
|
+
> no longer published to the VS Code Marketplace and is not included in npm
|
|
135
|
+
> tarballs.
|
|
127
136
|
|
|
128
|
-
###
|
|
137
|
+
### Recommended replacement: the dashboard
|
|
129
138
|
|
|
130
|
-
**From VS Code:**
|
|
131
|
-
1. Open Extensions (`Cmd+Shift+X` / `Ctrl+Shift+X`)
|
|
132
|
-
2. Search for "loki-mode"
|
|
133
|
-
3. Click **Install**
|
|
134
|
-
|
|
135
|
-
**From Command Line:**
|
|
136
139
|
```bash
|
|
137
|
-
|
|
140
|
+
loki dashboard start
|
|
141
|
+
# Then open http://localhost:57374 in your browser.
|
|
138
142
|
```
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
### Features
|
|
144
|
-
|
|
145
|
-
- **Activity Bar Icon**: Dedicated Loki Mode panel in the sidebar
|
|
146
|
-
- **Session View**: Real-time session status, provider, phase, and duration
|
|
147
|
-
- **Task View**: Tasks grouped by status (In Progress, Pending, Completed)
|
|
148
|
-
- **Status Bar**: Current state and progress at a glance
|
|
149
|
-
- **Quick Actions**: Start/Stop/Pause/Resume from command palette
|
|
150
|
-
- **Keyboard Shortcut**: `Cmd+Shift+L` (Mac) / `Ctrl+Shift+L` (Windows/Linux)
|
|
151
|
-
|
|
152
|
-
### Usage
|
|
153
|
-
|
|
154
|
-
1. Open a project folder in VS Code
|
|
155
|
-
2. Click the Loki Mode icon in the activity bar (or press `Cmd+Shift+L`)
|
|
156
|
-
3. Click "Start Session" and select your PRD file
|
|
157
|
-
4. Choose your AI provider (Claude, Codex, or Gemini)
|
|
158
|
-
5. Watch progress in the sidebar and status bar
|
|
159
|
-
|
|
160
|
-
### Configuration
|
|
161
|
-
|
|
162
|
-
Open VS Code Settings and search for "loki":
|
|
163
|
-
|
|
164
|
-
| Setting | Default | Description |
|
|
165
|
-
|---------|---------|-------------|
|
|
166
|
-
| `loki.provider` | `claude` | Default AI provider |
|
|
167
|
-
| `loki.apiPort` | `57374` | API server port |
|
|
168
|
-
| `loki.apiHost` | `localhost` | API server host |
|
|
169
|
-
| `loki.autoConnect` | `true` | Auto-connect on activation |
|
|
170
|
-
| `loki.showStatusBar` | `true` | Show status bar item |
|
|
171
|
-
| `loki.pollingInterval` | `2000` | Status polling interval (ms) |
|
|
172
|
-
|
|
173
|
-
### Requirements
|
|
174
|
-
|
|
175
|
-
**The VS Code extension requires the Loki Mode API server to be running.**
|
|
176
|
-
|
|
177
|
-
Before using the extension, start the server:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
# Option A: Using Loki CLI (if installed via npm or Homebrew)
|
|
181
|
-
loki start
|
|
182
|
-
|
|
183
|
-
# Option B: Using the autonomous runner (from source)
|
|
184
|
-
./autonomy/run.sh
|
|
185
|
-
|
|
186
|
-
# Option C: Direct API server start
|
|
187
|
-
loki serve
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
The extension will automatically connect when it detects the server is running at `localhost:57374`.
|
|
191
|
-
|
|
192
|
-
**Troubleshooting:** If you see "API server is not running" errors, make sure you started the server first using one of the commands above.
|
|
144
|
+
The dashboard provides session monitoring, task views, the completion
|
|
145
|
+
council, log streaming, and the managed-memory panel -- the same surface
|
|
146
|
+
the extension exposed, plus everything added since v7.2.0.
|
|
193
147
|
|
|
194
148
|
---
|
|
195
149
|
|
|
@@ -507,13 +461,13 @@ Loki Mode uses two network ports for different services:
|
|
|
507
461
|
|
|
508
462
|
| Port | Service | Description |
|
|
509
463
|
|------|---------|-------------|
|
|
510
|
-
| **57374** | Dashboard + API (FastAPI) | Unified server serving both the web dashboard UI (real-time monitoring, task board, Completion Council, memory browser, log streaming) and the REST API (used by
|
|
464
|
+
| **57374** | Dashboard + API (FastAPI) | Unified server serving both the web dashboard UI (real-time monitoring, task board, Completion Council, memory browser, log streaming) and the REST API (used by CLI tools, programmatic access, and the deprecated VS Code extension). Served by `dashboard/server.py`. |
|
|
511
465
|
|
|
512
466
|
### When to Use Which Port
|
|
513
467
|
|
|
514
468
|
- **Browser access** (dashboard, monitoring): Use port **57374** -- `http://localhost:57374`
|
|
515
469
|
- **API calls** (REST, programmatic): Use port **57374** -- `http://localhost:57374`
|
|
516
|
-
- **VS Code extension
|
|
470
|
+
- **VS Code extension** (deprecated as of v7.2.0): Connects to API on port **57374** automatically (configurable via `loki.apiPort` setting). No new releases will be published; see the deprecation notice above.
|
|
517
471
|
- The server is started automatically when you run `loki start` or `./autonomy/run.sh`. No manual configuration is needed.
|
|
518
472
|
|
|
519
473
|
### Port Configuration
|
package/mcp/__init__.py
CHANGED
|
@@ -101,7 +101,12 @@ class ManagedClient:
|
|
|
101
101
|
stores = getattr(beta, "memory_stores", None) or getattr(beta, "stores", None)
|
|
102
102
|
if stores is None or not hasattr(stores, "list"):
|
|
103
103
|
raise ManagedDisabled("memory_stores API not available in SDK")
|
|
104
|
-
|
|
104
|
+
try:
|
|
105
|
+
result = stores.list()
|
|
106
|
+
except ManagedDisabled:
|
|
107
|
+
raise
|
|
108
|
+
except Exception as e:
|
|
109
|
+
raise ManagedDisabled(f"stores_list failed: {e!s}") from e
|
|
105
110
|
# SDK returns a pydantic model; normalize to list of dicts.
|
|
106
111
|
data = getattr(result, "data", result)
|
|
107
112
|
return [self._to_dict(x) for x in (data or [])]
|
|
@@ -117,7 +122,12 @@ class ManagedClient:
|
|
|
117
122
|
stores = getattr(beta, "memory_stores", None) or getattr(beta, "stores", None)
|
|
118
123
|
if stores is None or not hasattr(stores, "create"):
|
|
119
124
|
raise ManagedDisabled("memory_stores.create not available in SDK")
|
|
120
|
-
|
|
125
|
+
try:
|
|
126
|
+
created = stores.create(name=name, description=description, scope=scope)
|
|
127
|
+
except ManagedDisabled:
|
|
128
|
+
raise
|
|
129
|
+
except Exception as e:
|
|
130
|
+
raise ManagedDisabled(f"stores_get_or_create failed: {e!s}") from e
|
|
121
131
|
return self._to_dict(created)
|
|
122
132
|
|
|
123
133
|
# ---------- memories ------------------------------------------------
|
|
@@ -148,7 +158,12 @@ class ManagedClient:
|
|
|
148
158
|
}
|
|
149
159
|
if sha256_precondition:
|
|
150
160
|
kwargs["if_match_sha256"] = sha256_precondition
|
|
151
|
-
|
|
161
|
+
try:
|
|
162
|
+
created = memories.create(**kwargs)
|
|
163
|
+
except ManagedDisabled:
|
|
164
|
+
raise
|
|
165
|
+
except Exception as e:
|
|
166
|
+
raise ManagedDisabled(f"memory_create failed: {e!s}") from e
|
|
152
167
|
return self._to_dict(created)
|
|
153
168
|
|
|
154
169
|
def memory_read(self, store_id: str, memory_id: str) -> Dict[str, Any]:
|
|
@@ -156,7 +171,12 @@ class ManagedClient:
|
|
|
156
171
|
memories = getattr(beta, "memories", None)
|
|
157
172
|
if memories is None or not hasattr(memories, "retrieve"):
|
|
158
173
|
raise ManagedDisabled("memories.retrieve not available in SDK")
|
|
159
|
-
|
|
174
|
+
try:
|
|
175
|
+
got = memories.retrieve(store_id=store_id, memory_id=memory_id)
|
|
176
|
+
except ManagedDisabled:
|
|
177
|
+
raise
|
|
178
|
+
except Exception as e:
|
|
179
|
+
raise ManagedDisabled(f"memory_read failed: {e!s}") from e
|
|
160
180
|
return self._to_dict(got)
|
|
161
181
|
|
|
162
182
|
def memories_list(
|
|
@@ -169,7 +189,12 @@ class ManagedClient:
|
|
|
169
189
|
kwargs: Dict[str, Any] = {"store_id": store_id}
|
|
170
190
|
if path_prefix:
|
|
171
191
|
kwargs["path_prefix"] = path_prefix
|
|
172
|
-
|
|
192
|
+
try:
|
|
193
|
+
result = memories.list(**kwargs)
|
|
194
|
+
except ManagedDisabled:
|
|
195
|
+
raise
|
|
196
|
+
except Exception as e:
|
|
197
|
+
raise ManagedDisabled(f"memories_list failed: {e!s}") from e
|
|
173
198
|
data = getattr(result, "data", result)
|
|
174
199
|
return [self._to_dict(x) for x in (data or [])]
|
|
175
200
|
|
|
@@ -21,6 +21,45 @@ from typing import Any, Dict, Optional
|
|
|
21
21
|
_ROTATE_BYTES = 10 * 1024 * 1024
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def _load_loki_version() -> str:
|
|
25
|
+
"""
|
|
26
|
+
Read the repo VERSION file once at module import.
|
|
27
|
+
|
|
28
|
+
Resolves to <repo_root>/VERSION assuming this file lives at
|
|
29
|
+
<repo_root>/memory/managed_memory/events.py. If the file is missing
|
|
30
|
+
or unreadable for any reason, returns the literal string "unknown"
|
|
31
|
+
so the correlation field is ALWAYS present on emitted events.
|
|
32
|
+
"""
|
|
33
|
+
try:
|
|
34
|
+
version_path = Path(__file__).resolve().parents[2] / "VERSION"
|
|
35
|
+
return version_path.read_text(encoding="utf-8").strip() or "unknown"
|
|
36
|
+
except Exception:
|
|
37
|
+
return "unknown"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Cached at module load: never re-read per-event. The repo version does not
|
|
41
|
+
# change during a single Python process lifetime.
|
|
42
|
+
_LOKI_VERSION: str = _load_loki_version()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _correlation_stamp() -> Dict[str, Any]:
|
|
46
|
+
"""
|
|
47
|
+
Build the correlation fields to merge into every payload.
|
|
48
|
+
|
|
49
|
+
Reads LOKI_ITERATION_COUNT and LOKI_SESSION_ID from the environment.
|
|
50
|
+
Missing env vars are OMITTED (not set to None) so callers can tell
|
|
51
|
+
"unset" apart from "explicitly null". loki_version is always present.
|
|
52
|
+
"""
|
|
53
|
+
stamp: Dict[str, Any] = {"loki_version": _LOKI_VERSION}
|
|
54
|
+
iteration = os.environ.get("LOKI_ITERATION_COUNT")
|
|
55
|
+
if iteration is not None and iteration != "":
|
|
56
|
+
stamp["iteration_id"] = iteration
|
|
57
|
+
session = os.environ.get("LOKI_SESSION_ID")
|
|
58
|
+
if session is not None and session != "":
|
|
59
|
+
stamp["session_id"] = session
|
|
60
|
+
return stamp
|
|
61
|
+
|
|
62
|
+
|
|
24
63
|
def _events_dir(target_dir: Optional[str] = None) -> Path:
|
|
25
64
|
base = target_dir or os.environ.get("LOKI_TARGET_DIR") or os.getcwd()
|
|
26
65
|
return Path(base) / ".loki" / "managed"
|
|
@@ -66,10 +105,18 @@ def emit_managed_event(
|
|
|
66
105
|
path = dir_path / "events.ndjson"
|
|
67
106
|
_maybe_rotate(path)
|
|
68
107
|
|
|
108
|
+
# Stamp correlation fields (loki_version always; iteration_id and
|
|
109
|
+
# session_id when env vars are set). Caller-supplied keys win: if
|
|
110
|
+
# the payload already carries iteration_id / session_id / loki_version
|
|
111
|
+
# the explicit caller value is preserved. Single-writer invariant
|
|
112
|
+
# is preserved because we only mutate the in-memory dict here; the
|
|
113
|
+
# write path (file handle, lock-free append) is unchanged.
|
|
114
|
+
merged_payload = {**_correlation_stamp(), **(payload or {})}
|
|
115
|
+
|
|
69
116
|
record = {
|
|
70
117
|
"ts": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
71
118
|
"type": event_type,
|
|
72
|
-
"payload":
|
|
119
|
+
"payload": merged_payload,
|
|
73
120
|
}
|
|
74
121
|
# Line-buffered append; JSONL.
|
|
75
122
|
with open(path, "a", encoding="utf-8") as f:
|
package/package.json
CHANGED
package/skills/memory.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Memory Integration (v7.0
|
|
1
|
+
# Memory Integration (v7.2.0+)
|
|
2
2
|
|
|
3
3
|
Loki Mode ships two memory layers:
|
|
4
4
|
|
|
@@ -184,4 +184,4 @@ Dashboard endpoints (read-only, view-layer merge):
|
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
|
-
**v7.0
|
|
187
|
+
**v7.2.0** | Opt-in, additive, rollback-safe. Default behavior unchanged.
|