pi-vault-mind 0.15.0 → 0.16.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/CHANGELOG.md +223 -0
- package/README.md +4 -5
- package/agents/broadcaster.agent.md +2 -2
- package/agents/heavy-lifter.agent.md +1 -1
- package/agents/main.agent.md +29 -0
- package/agents/manager.agent.md +1 -1
- package/agents/miner.agent.md +1 -1
- package/dist/packages/obsidian/src/client.js +331 -0
- package/dist/packages/obsidian/src/types.js +1 -0
- package/dist/src/activity.d.ts +49 -0
- package/dist/src/activity.js +175 -0
- package/dist/src/agent-bus/Agent.d.ts +9 -1
- package/dist/src/agent-bus/Agent.js +18 -2
- package/dist/src/agent-bus/index.d.ts +5 -5
- package/dist/src/agent-bus/index.js +1 -1
- package/dist/src/agent-queue.js +1 -1
- package/dist/src/agents/BroadcasterAgent.d.ts +1 -1
- package/dist/src/agents/BroadcasterAgent.js +2 -2
- package/dist/src/agents/HeavyLifterAgent.d.ts +1 -1
- package/dist/src/agents/HeavyLifterAgent.js +2 -2
- package/dist/src/agents/ManagerAgent.js +1 -1
- package/dist/src/agents/MinerAgent.d.ts +1 -1
- package/dist/src/agents/MinerAgent.js +2 -2
- package/dist/src/agents/index.d.ts +2 -2
- package/dist/src/agents/index.js +2 -2
- package/dist/src/auth.d.ts +7 -5
- package/dist/src/auth.js +12 -19
- package/dist/src/autosync.js +1 -1
- package/dist/src/commands.d.ts +2 -25
- package/dist/src/commands.js +223 -288
- package/dist/src/config-keys.d.ts +16 -0
- package/dist/src/config-keys.js +45 -0
- package/dist/src/edits.d.ts +21 -0
- package/dist/src/edits.js +75 -0
- package/dist/src/embedding-probe.d.ts +34 -0
- package/dist/src/embedding-probe.js +142 -0
- package/dist/src/embedding-providers.d.ts +133 -0
- package/dist/src/embedding-providers.js +173 -0
- package/dist/src/embedding-secrets.d.ts +38 -0
- package/dist/src/embedding-secrets.js +291 -0
- package/dist/src/engine.d.ts +6 -0
- package/dist/src/engine.js +78 -6
- package/dist/src/events.js +1 -1
- package/dist/src/extension-packages.d.ts +9 -0
- package/dist/src/extension-packages.js +14 -0
- package/dist/src/git.d.ts +19 -0
- package/dist/src/git.js +78 -0
- package/dist/src/graph.d.ts +2 -1
- package/dist/src/graph.js +47 -13
- package/dist/src/identities-config.d.ts +6 -0
- package/dist/src/identities-config.js +39 -0
- package/dist/src/identity-injector.js +1 -1
- package/dist/src/index.js +4 -8
- package/dist/src/lance.d.ts +9 -0
- package/dist/src/lance.js +143 -203
- package/dist/src/modal-client.d.ts +16 -0
- package/dist/src/modal-client.js +16 -0
- package/dist/src/modal-config.d.ts +16 -10
- package/dist/src/modal-config.js +31 -25
- package/dist/src/models.d.ts +42 -0
- package/dist/src/models.js +78 -0
- package/dist/src/scaffold.d.ts +48 -0
- package/dist/src/scaffold.js +246 -0
- package/dist/src/server.d.ts +46 -3
- package/dist/src/server.js +962 -183
- package/dist/src/session-search.d.ts +63 -0
- package/dist/src/session-search.js +379 -0
- package/dist/src/settings-ui.d.ts +1 -1
- package/dist/src/settings-ui.js +54 -107
- package/dist/src/sync.js +3 -3
- package/dist/src/tool-catalog.d.ts +18 -0
- package/dist/src/tool-catalog.js +232 -0
- package/dist/src/tools/marksman.js +1 -1
- package/dist/src/tools.js +108 -62
- package/dist/src/types.d.ts +106 -73
- package/dist/src/utils.d.ts +2 -12
- package/dist/src/utils.js +7 -60
- package/dist/src/vault-tools.d.ts +34 -0
- package/dist/src/vault-tools.js +99 -0
- package/dist/src/vm-handlers.js +138 -41
- package/dist/src/watcher.js +7 -7
- package/dist/test/activity-tool.test.js +54 -0
- package/dist/test/agent-bus/Agent.test.js +174 -0
- package/dist/test/agent-bus/AgentLoader.test.js +180 -0
- package/dist/test/agent-bus/AgentRegistry.test.js +86 -0
- package/dist/test/agent-bus/LLMProvider.test.js +162 -0
- package/dist/test/agent-bus/TaskQueue.test.js +256 -0
- package/dist/test/agent-dispatch-context.test.js +73 -0
- package/dist/test/agent-queue.test.js +1 -1
- package/dist/test/agents/Agents.test.js +282 -0
- package/dist/test/auth.test.js +28 -25
- package/dist/test/bridge-identity.test.js +31 -2
- package/dist/test/classify-search-mode.test.js +51 -0
- package/dist/test/commands.test.js +410 -0
- package/dist/test/config-merge.test.js +98 -0
- package/dist/test/context-capture.test.js +56 -0
- package/dist/test/dispatch.test.js +39 -89
- package/dist/test/edits.test.js +144 -0
- package/dist/test/embedding-probe.test.js +424 -0
- package/dist/test/embedding-providers.test.js +157 -0
- package/dist/test/embedding-secrets.test.js +210 -0
- package/dist/test/engine-identity.test.js +1 -1
- package/dist/test/events.test.js +675 -0
- package/dist/test/git-bridge.test.js +160 -0
- package/dist/test/graph.test.js +464 -0
- package/dist/test/helpers/server.js +81 -0
- package/dist/test/identity-injector.test.js +197 -0
- package/dist/test/index.test.js +1 -5
- package/dist/test/lance-modal.test.js +67 -2
- package/dist/test/lance.test.js +429 -0
- package/dist/test/modal-client.test.js +1 -1
- package/dist/test/modal-config.test.js +92 -79
- package/dist/test/model-readiness.test.js +122 -0
- package/dist/test/obsidian-client.test.js +42 -0
- package/dist/test/personalize.test.js +1 -1
- package/dist/test/rest-models.test.js +153 -0
- package/dist/test/rest-queue.test.js +128 -79
- package/dist/test/rest-setup.test.js +613 -101
- package/dist/test/rest-vm.test.js +343 -79
- package/dist/test/server-cors.test.js +48 -0
- package/dist/test/server-ws.test.js +55 -31
- package/dist/test/session-crud.test.js +323 -0
- package/dist/test/session-search.test.js +139 -0
- package/dist/test/settings-ui.test.js +61 -15
- package/dist/test/sync.test.js +2 -1
- package/dist/test/tombstone.test.js +1 -1
- package/dist/test/tool-catalog.test.js +86 -0
- package/dist/test/utils.test.js +588 -0
- package/dist/test/vault-tools.test.js +96 -3
- package/dist/test/vault-writer.test.js +371 -0
- package/dist/test/vm-handlers.test.js +620 -0
- package/extension-packages.json +9 -0
- package/package.json +20 -10
- package/pi-vault-mind.config.example.json +9 -1
- package/scripts/check-deps.sh +35 -32
- package/scripts/cli-e2e.mjs +215 -0
- package/scripts/configuration-e2e.mjs +783 -0
- package/scripts/e2e-commands.mjs +391 -0
- package/scripts/generate-config-keys-json.mjs +45 -0
- package/scripts/generate-extension-packages-json.mjs +55 -0
- package/scripts/setup-vault-pi.sh +34 -17
- package/scripts/test-slash-commands.mjs +2 -2
- package/skills/github-release-notes-file/SKILL.md +42 -0
- package/skills/obsidian-guided-test-session/SKILL.md +110 -0
- package/skills/obsidian-interactive-test/SKILL.md +88 -0
- package/skills/obsidian-plugin-publish/SKILL.md +58 -0
- package/skills/pi-vault-mind-release/SKILL.md +141 -0
- package/skills/pre-test-release/SKILL.md +116 -0
- package/dist/test/auto-indexer.test.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,228 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.3 / 0.6.5 — 2026-07-16
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`GET /vault-mind/models` endpoint.** Auth-gated route returns pi's
|
|
8
|
+
provider/model catalog (`{ providers: ProviderInfo[] }`, plus an
|
|
9
|
+
`error` field when a `models.json` exists but fails to parse), merged
|
|
10
|
+
from the agent-dir and project-level `models.json` (project overrides
|
|
11
|
+
agent-dir for same-named providers). `src/models.ts`
|
|
12
|
+
`readModelProviders()` mirrors the plugin's `pi-config-reader.ts`
|
|
13
|
+
flattened shape (`$`-stripped `envVarName`, model `name` falls back to
|
|
14
|
+
`id`, providers sorted by name). New `VaultMindClient.getModels()`
|
|
15
|
+
(typed `VmModelsResponse`) is the client bridge so the plugin can
|
|
16
|
+
replace synchronous `models.json` disk reads with a live call. Covered
|
|
17
|
+
by `test/rest-models.test.ts` (auth, empty, parse, override, malformed).
|
|
18
|
+
|
|
19
|
+
- **Extension-owned setup and configuration surfaces.** Added masked
|
|
20
|
+
provider-credential status and atomic extension-owned secret storage,
|
|
21
|
+
Local/Remote live embedding probes, complete typed setup/configuration
|
|
22
|
+
client methods, default-vault sibling preservation, and a deterministic
|
|
23
|
+
configuration E2E smoke. Added the portable seven-step Arrow setup
|
|
24
|
+
wizard and twelve-category section-save Settings UI, then ported it into
|
|
25
|
+
the Obsidian plugin behind a thin `RestConfigurationAdapter`. The plugin
|
|
26
|
+
now uses typed runtime model discovery instead of synchronous
|
|
27
|
+
`models.json` reads or writes, routes model selection through Pi RPC,
|
|
28
|
+
mounts Settings through one adapter boundary, renders retryable offline
|
|
29
|
+
recovery rather than a blank pane, and keeps plugin/extension bridge
|
|
30
|
+
credentials separate from embedding-provider credentials. Added
|
|
31
|
+
port-parity canonicalization for type re-exports, CSS/import guards,
|
|
32
|
+
intrinsic SVG icon bounds, and focused regression coverage across the
|
|
33
|
+
extension, sandbox, and plugin.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **Un-imported `modalUrl` in `src/server.ts`** — the
|
|
38
|
+
`handleVaultMindConfig` function destructured `modalUrl` from
|
|
39
|
+
`../modal-config.js` without ever importing it. Would have crashed
|
|
40
|
+
with `TypeError: Cannot read properties of undefined (reading 'space')`
|
|
41
|
+
if the modal config branch was hit. Caught by
|
|
42
|
+
`/tmp/pvm-e2e-http-setup-test.mjs`. Import is now in place.
|
|
43
|
+
|
|
44
|
+
### Documentation
|
|
45
|
+
|
|
46
|
+
- **`vault-mind-config-index.md` §12 — Modal extraction question.** New
|
|
47
|
+
section documenting the open architectural question: should
|
|
48
|
+
`pi-vault-mind`'s Modal-specific code (HTTP client, sync engine,
|
|
49
|
+
`ModalProvider`, `/vm remote *` slash commands, `embedding.sync`
|
|
50
|
+
config block, Python `modal/` app) move into a separate package
|
|
51
|
+
(`pi-vault-mind-remote-modal/`) so the extension is truly
|
|
52
|
+
provider-agnostic? Three options documented (A: namespace in-tree /
|
|
53
|
+
B: extract to a package / C: server+client out, CLI stays). Smaller
|
|
54
|
+
win called out regardless of option: drop `/vm remote *` in favor of
|
|
55
|
+
`--remoteUrl` / `--remoteApiKey` flags on `/vm setup`. Awaiting
|
|
56
|
+
user decision; no work committed.
|
|
57
|
+
- **§7.1 scope column.** Every `/vm *` slash command is now tagged
|
|
58
|
+
`🟢 agnostic` / `🟡 Modal-specific` / `🔵 token` so the reader can
|
|
59
|
+
see exactly which commands depend on Modal.
|
|
60
|
+
|
|
61
|
+
## 0.16.2 — 2026-07-07
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- **`ModalEmbeddingConfig` flattened into `EmbeddingConfig`.** Modal
|
|
66
|
+
is just an OpenAI-compatible endpoint, so the `embedding.modal: {
|
|
67
|
+
baseUrl, workspace, apiToken, readToken, writeToken, model, dim,
|
|
68
|
+
fallback, sync }` wrapper is gone. All fields are now top-level on
|
|
69
|
+
`EmbeddingConfig` itself: `workspace`, `remoteApiKey`,
|
|
70
|
+
`remoteReadApiKey`, `remoteWriteApiKey`, `model`, `dim`, `fallback`
|
|
71
|
+
(now a simplified `{ enabled?: boolean }` — the `provider`
|
|
72
|
+
discriminator was already removed in 0.16.1+), and `sync`. **`apiKey`
|
|
73
|
+
is now explicitly the local-Ollama bearer** (defaults to `"ollama"`
|
|
74
|
+
in `OpenAICompatibleProvider`); the remote-endpoint token is
|
|
75
|
+
`remoteApiKey` so a single config can carry distinct local-vs-remote
|
|
76
|
+
credentials. The Modal-only blocks that remain as their own
|
|
77
|
+
inline objects are `sync` (pull-down watermark behavior) and
|
|
78
|
+
`fallback` (offline degrade policy). The `MODAL_APP_NAME` URL
|
|
79
|
+
helper stays in `src/modal-config.ts` (`modalUrl(workspace)`); the
|
|
80
|
+
Obsidian plugin keeps a small local mirror because it can't import
|
|
81
|
+
from the extension at runtime. `isModal()` is now simply
|
|
82
|
+
`!!cfg.embedding.remoteUrl`. The Obsidian plugin's
|
|
83
|
+
`provider: "ollama" | "modal" | "skip"` UI discriminator was renamed
|
|
84
|
+
to `"local" | "remote" | "skip"` (display labels stay user-friendly).
|
|
85
|
+
On save, the Modal wizard removes the old `embedding.modal` block
|
|
86
|
+
so existing configs upgrade cleanly on next `/vm setup`. The index
|
|
87
|
+
doc `vault-mind-config-index.md` §2.4 is updated; the per-setting
|
|
88
|
+
plan `vault-mind-config-plugin-surface.md` is reconciled.
|
|
89
|
+
|
|
90
|
+
### Removed
|
|
91
|
+
|
|
92
|
+
- **`ModalEmbeddingConfig` and `ModalFallbackConfig` types removed
|
|
93
|
+
from `src/types.ts`.** Fields are inlined on `EmbeddingConfig` (see
|
|
94
|
+
above). `FallbackConfig` (`{ enabled?: boolean }`) is the new
|
|
95
|
+
simplified fallback shape; `ModalSyncConfig` is unchanged.
|
|
96
|
+
|
|
97
|
+
### Tests
|
|
98
|
+
|
|
99
|
+
- 268 tests pass (no change in count — the migration was mechanical).
|
|
100
|
+
Three test files migrated from `modal: { ... }` fixtures to the
|
|
101
|
+
flat shape: `test/auth.test.ts`, `test/lance-modal.test.ts`,
|
|
102
|
+
`test/modal-config.test.ts`. The `ModalFallbackConfig["provider"]`
|
|
103
|
+
type-level regression test was removed (the type no longer exists).
|
|
104
|
+
One collateral fixture in `test/sync.test.ts`. One collateral
|
|
105
|
+
fixture in `test/vault-tools.test.ts` (the `writeConfig` helper
|
|
106
|
+
needed `model: "testmodel"` added so `resolveModel` returns the
|
|
107
|
+
right value for the test's `searchFts` assertion). The provider-cache
|
|
108
|
+
leak in `src/lance.ts`'s `resetConnection()` was fixed (the cache
|
|
109
|
+
was module-level and survived across tests).
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## 0.16.1 — 2026-07-07
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
|
|
116
|
+
- **`src/embedding-providers.ts`** — new store-agnostic `EmbeddingProvider`
|
|
117
|
+
interface (`embed` / `dim` / `init`) and the three concrete providers
|
|
118
|
+
(`OpenAICompatibleProvider`, `TransformersProvider`, `ModalProvider`)
|
|
119
|
+
plus a `createProvider(cfg)` factory. The vector-store layer
|
|
120
|
+
(`src/lance.ts`) now consumes providers through a 35-line
|
|
121
|
+
`LanceEmbeddingAdapter` that wraps them into LanceDB's
|
|
122
|
+
`TextEmbeddingFunction`. **Adding a new vector store (Qdrant, Pinecone,
|
|
123
|
+
pgvector, …) means writing a new adapter; adding a new embedding
|
|
124
|
+
provider means implementing the interface.** No downstream code (lance,
|
|
125
|
+
coalescer, plugin) needs to change for either.
|
|
126
|
+
- **`/vm remote config fallback`** accepts `"ollama"` as a friendlier
|
|
127
|
+
alias for `"openai-compatible"` (rewritten to the enum value before
|
|
128
|
+
write). Help text and error messages updated.
|
|
129
|
+
|
|
130
|
+
### Removed
|
|
131
|
+
|
|
132
|
+
- **`ModalFallbackConfig.provider` enum reduced to `"openai-compatible"`.**
|
|
133
|
+
The legacy `"transformers"` value was dead code (no runtime path
|
|
134
|
+
selected it). The offline transformers path lives separately under
|
|
135
|
+
`EmbeddingConfig.useTransformers`. `/vm remote config fallback` parser
|
|
136
|
+
no longer accepts `"transformers"`. Type-level regression test
|
|
137
|
+
prevents the dead value from being added back.
|
|
138
|
+
|
|
139
|
+
### Fixed
|
|
140
|
+
|
|
141
|
+
- **`LanceEmbeddingFunction` now defaults `apiKey` to `"ollama"`** for
|
|
142
|
+
local endpoints, matching `AgentModelProvider`'s behavior and the
|
|
143
|
+
JSDoc contract. The previous `string | undefined` field would have
|
|
144
|
+
sent `Authorization: Bearer undefined` for any vault without an
|
|
145
|
+
explicit `apiKey`; Ollama happened to ignore the malformed header,
|
|
146
|
+
but stricter `/v1/embeddings`-compatible servers would have rejected
|
|
147
|
+
it. Pass `apiKey: null` to opt out (some local servers reject
|
|
148
|
+
`Bearer ollama` as invalid auth).
|
|
149
|
+
- **`IdentityConfig.role` made optional.** It was required at the type
|
|
150
|
+
level but `mergeIdentityProfiles` always pulls `role` (and `id`) from
|
|
151
|
+
the base — config cannot rename an agent. Required type was dead.
|
|
152
|
+
- **Index doc §2.6 `vaultMind.identities` reframed as "wired but
|
|
153
|
+
unenforced"** — the block is read at engine start
|
|
154
|
+
(`engine.ts:124-137` calls `mergeIdentityProfiles` and
|
|
155
|
+
`bridge.ts:100` registers the merged identity), but the registered
|
|
156
|
+
identity is never read back (`getAgentIdentity` in `bridge.ts:117`
|
|
157
|
+
has no callers). The block stays typed; future runtime enforcement
|
|
158
|
+
reuses it. New regression test in `test/bridge-identity.test.ts`
|
|
159
|
+
pins the merge contract (layer values override, empty array is
|
|
160
|
+
explicit deny, role/id always from base, undefined layer is a no-op).
|
|
161
|
+
- **Config example drift closed.** `pi-vault-mind.config.example.json`
|
|
162
|
+
now shows the scaffolded `draft-context` injector instead of an
|
|
163
|
+
empty array — matches the live `src/scaffold.ts` output so a user
|
|
164
|
+
hand-rolling a config from the example doesn't silently miss a
|
|
165
|
+
built-in.
|
|
166
|
+
|
|
167
|
+
## 0.16.0 — 2026-07-06
|
|
168
|
+
|
|
169
|
+
### Added
|
|
170
|
+
|
|
171
|
+
- **New `src/scaffold.ts`** — the single, UI-agnostic implementation of vault
|
|
172
|
+
config scaffolding (default collections/injectors, `.gitignore`), shared
|
|
173
|
+
by the CLI `/vm setup` command, the HTTP `POST /vm/setup` route, and any
|
|
174
|
+
future consumer. Robust to caller order: seeds default collections/
|
|
175
|
+
injectors whenever they're empty, not only when the config file is brand
|
|
176
|
+
new, so no future caller can silently end up with `"collections": {}`
|
|
177
|
+
again by writing embedding/vault fields before calling it.
|
|
178
|
+
|
|
179
|
+
### Removed
|
|
180
|
+
|
|
181
|
+
- **Legacy config/token migration dropped entirely.** `migrateLegacyState()`
|
|
182
|
+
and the `CONFIG_FILES` legacy-filename list are gone; pi-vault-mind no
|
|
183
|
+
longer rescues config/token from a vault-root `pi-vault-mind.config.json`,
|
|
184
|
+
`.pi/vault-mind.config.json`, or the global `~/.pi/agent/`. `.vault-mind/`
|
|
185
|
+
is now the only place pi-vault-mind ever reads its own config/token from —
|
|
186
|
+
no backward-compat fallback path.
|
|
187
|
+
- **`/vm init` removed as a standalone command.** It only ever duplicated
|
|
188
|
+
part of `/vm setup`'s work with a deprecation notice; fully consolidated
|
|
189
|
+
onto `/vm setup`, which now also accepts `--collection <name>` (previously
|
|
190
|
+
only available via `/vm init --collection`). Every "Run /vm init first"
|
|
191
|
+
message across `commands.ts`, `settings-ui.ts`, `tools.ts`,
|
|
192
|
+
`vm-handlers.ts`, and `tools/marksman.ts` now says `/vm setup`.
|
|
193
|
+
- **`POST /vm/init` removed from the HTTP API.** It duplicated a third copy
|
|
194
|
+
of the collections/injectors scaffold template (alongside the CLI's and
|
|
195
|
+
the Obsidian plugin's own copies). `POST /vm/setup` now calls the same
|
|
196
|
+
shared `scaffoldVaultConfig()` after writing embedding/vault fields, so it
|
|
197
|
+
does everything `/vm/init` did plus its own job, and its response now
|
|
198
|
+
includes `created`/`updated`/`skipped`/`collectionName`. The Obsidian
|
|
199
|
+
plugin's `VaultMindClient.init()` (only caller: the chat composer's
|
|
200
|
+
`/reindex` command) is removed too — it now calls `client.setup({})`
|
|
201
|
+
directly, since the reindex flow never used `init()`'s return value.
|
|
202
|
+
|
|
203
|
+
### Fixed
|
|
204
|
+
|
|
205
|
+
- **`/vm setup` never actually scaffolded default collections.** `handleInit`
|
|
206
|
+
(the scaffold logic) only populates the default `main`/`pending`/
|
|
207
|
+
`context_events` collections and the `draft-context` injector when the
|
|
208
|
+
config file doesn't exist yet — but `setupWizard` always wrote the config
|
|
209
|
+
file *first*, so `handleInit` permanently saw an existing file and took its
|
|
210
|
+
merge-safe (no-op-for-collections) branch instead. Every `/vm setup` run,
|
|
211
|
+
CLI or interactive, ended with `"collections": {}`. Reordered so
|
|
212
|
+
`handleInit` runs before `setupWizard`; verified end-to-end (fresh vault →
|
|
213
|
+
`/vm setup` → all three default collections + injector scaffolded with the
|
|
214
|
+
vault-derived file name, confirmed via direct JSONL read-back).
|
|
215
|
+
- **`loadConfig` returned duplicate injector entries, causing them to fire
|
|
216
|
+
twice.** `mergeConfigLayer` concatenated `DEFAULT_CONFIG.injectors` with
|
|
217
|
+
the vault's own config-file injectors with zero deduplication. Since every
|
|
218
|
+
vault's config now always has its own `draft-context` injector (scaffolded
|
|
219
|
+
by `/vm setup`), `loadConfig()` returned it twice — and `events.ts`
|
|
220
|
+
processes every injector's regex match independently, so a matching note
|
|
221
|
+
would trigger the injector's capture/artifact-sync logic twice per prompt.
|
|
222
|
+
Fixed by deduplicating by `name` in the merge (layer's entry wins on a
|
|
223
|
+
collision), mirroring the existing dedupe pattern in `auditConfig`.
|
|
224
|
+
Verified via `loadConfig` on a freshly-scaffolded vault: exactly one
|
|
225
|
+
`draft-context` injector, not two.
|
|
3
226
|
|
|
4
227
|
## 0.15.0 / 0.6.4 — 2026-07-06
|
|
5
228
|
|
package/README.md
CHANGED
|
@@ -260,9 +260,9 @@ Edit `pi-vault-mind.config.json` to match your domain:
|
|
|
260
260
|
"vaultMind": {
|
|
261
261
|
"dataDir": ".lancedb",
|
|
262
262
|
"embedding": {
|
|
263
|
-
"
|
|
264
|
-
"
|
|
265
|
-
"
|
|
263
|
+
"remoteUrl": "http://127.0.0.1:11434",
|
|
264
|
+
"model": "embeddinggemma",
|
|
265
|
+
"dim": 768
|
|
266
266
|
},
|
|
267
267
|
"ftsEnabled": true,
|
|
268
268
|
"graph": { "enabled": true, "canvasSync": false }
|
|
@@ -347,7 +347,6 @@ Edit `pi-vault-mind.config.json` to match your domain:
|
|
|
347
347
|
| ------------------------------ | -------------------------------------------------------- |
|
|
348
348
|
| `/vm help` | Show usage help |
|
|
349
349
|
| `/vm setup` | **Interactive global config wizard** (vault, embedding) |
|
|
350
|
-
| `/vm init` | Scaffold project config + collections |
|
|
351
350
|
| `/vm validate` | Health check LanceDB, config, and all collection paths |
|
|
352
351
|
| `/vm approve [collection]` | Batch-review pending entries |
|
|
353
352
|
| `/vm settings` | Open interactive settings dashboard |
|
|
@@ -358,7 +357,7 @@ Edit `pi-vault-mind.config.json` to match your domain:
|
|
|
358
357
|
| `/vm injector create` | Interactive wizard to create a new injector |
|
|
359
358
|
| `/vm context enable \| disable \| status` | Manage pi-context integration |
|
|
360
359
|
| `/vm embedding status \| use \| model \| models \| pull` | Manage embedding provider |
|
|
361
|
-
| `/vm
|
|
360
|
+
| `/vm remote status \| config \| sync \| jobs \| migrate` | Manage remote embedding + vector sync |
|
|
362
361
|
| `/vm watcher start \| stop \| status` | Manage the passive file watcher |
|
|
363
362
|
| `/vm server status` | Show HTTP server status, port, and uptime |
|
|
364
363
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: BroadcasterAgent
|
|
3
3
|
role: broadcaster
|
|
4
4
|
capabilities: [read, write, edit]
|
|
5
|
-
allowed_tools: [read, write, edit, vm_search
|
|
5
|
+
allowed_tools: [read, write, edit, vm_search]
|
|
6
6
|
write_collections: []
|
|
7
7
|
can_publish: false
|
|
8
8
|
llm_provider: ollama
|
|
@@ -16,7 +16,7 @@ and external-facing content from vault knowledge.
|
|
|
16
16
|
## Capability Boundary
|
|
17
17
|
|
|
18
18
|
- **MAY**: read files, write files, edit files
|
|
19
|
-
- **MAY**: search collections via vm_search
|
|
19
|
+
- **MAY**: search collections via vm_search
|
|
20
20
|
- **MUST NOT**: run bash commands, grep, or find
|
|
21
21
|
- **MUST NOT**: write to the durable knowledge store
|
|
22
22
|
- **MUST NOT**: publish or spawn sub-agents
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: HeavyLifterAgent
|
|
3
3
|
role: heavy-lifter
|
|
4
4
|
capabilities: [read, write, edit, grep, find, ls, bash]
|
|
5
|
-
allowed_tools: [read, write, edit, grep, find, ls, bash, vm_search
|
|
5
|
+
allowed_tools: [read, write, edit, grep, find, ls, bash, vm_search]
|
|
6
6
|
write_collections: []
|
|
7
7
|
can_publish: false
|
|
8
8
|
llm_provider: ollama
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ManagerAgent
|
|
3
|
+
role: main
|
|
4
|
+
capabilities: [read, write, edit, bash, grep, find, ls]
|
|
5
|
+
allowed_tools: [read, write, edit, bash, grep, find, ls, vm_search, vm_query, vm_append, vm_stats, vm_status, vm_describe, vm_configure]
|
|
6
|
+
write_collections: []
|
|
7
|
+
can_publish: false
|
|
8
|
+
llm_provider: ollama
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Main Agent
|
|
12
|
+
|
|
13
|
+
Primary interactive agent for pi-vault-mind. The default role used by the
|
|
14
|
+
Obsidian plugin's chat interface and the CLI `/vm chat` command.
|
|
15
|
+
|
|
16
|
+
## Capability Boundary
|
|
17
|
+
|
|
18
|
+
- **MAY**: all 7 built-in tools (read, write, edit, bash, grep, find, ls)
|
|
19
|
+
- **MAY**: vm_search, vm_query (read paths)
|
|
20
|
+
- **MAY**: vm_append, vm_stats, vm_status, vm_describe, vm_configure (write/config paths)
|
|
21
|
+
- **MAY**: read from the "main" collection
|
|
22
|
+
- **MUST NOT**: write to collections, publish, or access arbitrary vault paths
|
|
23
|
+
|
|
24
|
+
## Tool Calling Convention
|
|
25
|
+
|
|
26
|
+
When calling pi-vault-mind tools, always include your role:
|
|
27
|
+
```
|
|
28
|
+
vm_search({ query: "...", role: "main" })
|
|
29
|
+
```
|
package/agents/manager.agent.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: ManagerAgent
|
|
3
3
|
role: manager
|
|
4
4
|
capabilities: [read, write, edit, grep, find, ls]
|
|
5
|
-
allowed_tools: [read, write, edit, grep, find, ls, vm_search,
|
|
5
|
+
allowed_tools: [read, write, edit, grep, find, ls, vm_search, vm_append, vm_sync, vm_promote, vm_query, vm_configure, vm_describe, vm_stats, vm_export, vm_ingest, vm_status]
|
|
6
6
|
write_collections: [main, research, presentations]
|
|
7
7
|
can_publish: true
|
|
8
8
|
llm_provider: ollama
|
package/agents/miner.agent.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
type: MinerAgent
|
|
3
3
|
role: miner
|
|
4
4
|
capabilities: [read, write, edit, grep, find, ls]
|
|
5
|
-
allowed_tools: [read, write, edit, grep, find, ls, vm_search,
|
|
5
|
+
allowed_tools: [read, write, edit, grep, find, ls, vm_search, vm_append]
|
|
6
6
|
write_collections: [main, research]
|
|
7
7
|
can_publish: false
|
|
8
8
|
llm_provider: ollama
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP + WebSocket client for the pi-vault-mind extension.
|
|
3
|
+
*
|
|
4
|
+
* REST calls use `fetch`. WebSocket events use the native `WebSocket` global
|
|
5
|
+
* with exponential backoff on disconnect (1, 2, 4, 8, 16, 30 s).
|
|
6
|
+
*/
|
|
7
|
+
export class VaultMindClient {
|
|
8
|
+
config;
|
|
9
|
+
ws = null;
|
|
10
|
+
reconnectTimer = null;
|
|
11
|
+
reconnectDelay = 1000;
|
|
12
|
+
intentionalClose = false;
|
|
13
|
+
eventHandlers = new Set();
|
|
14
|
+
stateHandlers = new Set();
|
|
15
|
+
_state = { connected: false };
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
get baseUrl() {
|
|
20
|
+
return `http://${this.config.host}:${this.config.port}`;
|
|
21
|
+
}
|
|
22
|
+
get wsUrl() {
|
|
23
|
+
return `ws://${this.config.host}:${this.config.port}/agent/stream`;
|
|
24
|
+
}
|
|
25
|
+
get authHeaders() {
|
|
26
|
+
return {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
Authorization: `Bearer ${this.config.token}`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
setState(state) {
|
|
32
|
+
this._state = state;
|
|
33
|
+
for (const h of this.stateHandlers)
|
|
34
|
+
h(state);
|
|
35
|
+
}
|
|
36
|
+
get state() {
|
|
37
|
+
return this._state;
|
|
38
|
+
}
|
|
39
|
+
subscribeEvents(handler) {
|
|
40
|
+
this.eventHandlers.add(handler);
|
|
41
|
+
return () => this.eventHandlers.delete(handler);
|
|
42
|
+
}
|
|
43
|
+
subscribeState(handler) {
|
|
44
|
+
this.stateHandlers.add(handler);
|
|
45
|
+
return () => this.stateHandlers.delete(handler);
|
|
46
|
+
}
|
|
47
|
+
emit(event) {
|
|
48
|
+
for (const h of this.eventHandlers) {
|
|
49
|
+
try {
|
|
50
|
+
h(event);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// never let a bad listener break others
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
connect() {
|
|
58
|
+
if (this.ws)
|
|
59
|
+
return;
|
|
60
|
+
try {
|
|
61
|
+
this.ws = new WebSocket(this.wsUrl, [`Authorization: Bearer ${this.config.token}`]);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
this.setState({ connected: false, error: String(err), reconnecting: true });
|
|
65
|
+
this.scheduleReconnect();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.ws.onopen = () => {
|
|
69
|
+
this.reconnectDelay = 1000;
|
|
70
|
+
this.setState({ connected: true, reconnecting: false });
|
|
71
|
+
};
|
|
72
|
+
this.ws.onmessage = (event) => {
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(event.data);
|
|
75
|
+
this.emit(parsed);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// ignore malformed events
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
this.ws.onclose = (event) => {
|
|
82
|
+
this.ws = null;
|
|
83
|
+
if (this.intentionalClose) {
|
|
84
|
+
this.setState({ connected: false, error: undefined, reconnecting: false });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const wasConnected = this._state.connected;
|
|
88
|
+
this.setState({ connected: false, error: `closed ${event.code}`, reconnecting: true });
|
|
89
|
+
if (wasConnected || event.code !== 4401) {
|
|
90
|
+
this.scheduleReconnect();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
this.ws.onerror = () => {
|
|
94
|
+
this.setState({ connected: this.ws?.readyState === WebSocket.OPEN, error: "socket error" });
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
disconnect() {
|
|
98
|
+
if (this.reconnectTimer) {
|
|
99
|
+
clearTimeout(this.reconnectTimer);
|
|
100
|
+
this.reconnectTimer = null;
|
|
101
|
+
}
|
|
102
|
+
this.intentionalClose = true;
|
|
103
|
+
if (this.ws) {
|
|
104
|
+
this.ws.close();
|
|
105
|
+
this.ws = null;
|
|
106
|
+
}
|
|
107
|
+
this.setState({ connected: false, error: undefined, reconnecting: false });
|
|
108
|
+
this.intentionalClose = false;
|
|
109
|
+
}
|
|
110
|
+
scheduleReconnect() {
|
|
111
|
+
if (this.reconnectTimer)
|
|
112
|
+
return;
|
|
113
|
+
this.reconnectTimer = setTimeout(() => {
|
|
114
|
+
this.reconnectTimer = null;
|
|
115
|
+
this.connect();
|
|
116
|
+
}, this.reconnectDelay);
|
|
117
|
+
this.reconnectDelay = Math.min(this.reconnectDelay * 2, 30000);
|
|
118
|
+
}
|
|
119
|
+
async httpJson(method, path, body) {
|
|
120
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
121
|
+
method,
|
|
122
|
+
headers: this.authHeaders,
|
|
123
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
124
|
+
});
|
|
125
|
+
const text = await res.text();
|
|
126
|
+
if (!res.ok) {
|
|
127
|
+
let serverMessage = text;
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(text);
|
|
130
|
+
if (typeof parsed.message === "string")
|
|
131
|
+
serverMessage = parsed.message;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// keep raw text as the server message
|
|
135
|
+
}
|
|
136
|
+
// Never echo the request body or secret material in the thrown error.
|
|
137
|
+
throw new Error(`${res.status} ${serverMessage}`);
|
|
138
|
+
}
|
|
139
|
+
return text ? JSON.parse(text) : undefined;
|
|
140
|
+
}
|
|
141
|
+
async status() {
|
|
142
|
+
return (await this.httpJson("GET", "/vm/status"));
|
|
143
|
+
}
|
|
144
|
+
async setup(body) {
|
|
145
|
+
return (await this.httpJson("POST", "/vm/setup", body));
|
|
146
|
+
}
|
|
147
|
+
async probeEmbedding(body) {
|
|
148
|
+
return (await this.httpJson("POST", "/vm/embedding/probe", body));
|
|
149
|
+
}
|
|
150
|
+
async putEmbeddingSecrets(body) {
|
|
151
|
+
return (await this.httpJson("PUT", "/vm/embedding/secrets", body));
|
|
152
|
+
}
|
|
153
|
+
async startServer() {
|
|
154
|
+
return (await this.httpJson("POST", "/server/start"));
|
|
155
|
+
}
|
|
156
|
+
async toggleWatcher() {
|
|
157
|
+
return (await this.httpJson("POST", "/vm/watcher/toggle"));
|
|
158
|
+
}
|
|
159
|
+
async listQueue(status) {
|
|
160
|
+
const query = status ? `?status=${status}` : "";
|
|
161
|
+
return (await this.httpJson("GET", `/agent/queue${query}`));
|
|
162
|
+
}
|
|
163
|
+
async retryJob(id) {
|
|
164
|
+
return (await this.httpJson("POST", `/agent/jobs/${encodeURIComponent(id)}/retry`));
|
|
165
|
+
}
|
|
166
|
+
async cancelJob(id) {
|
|
167
|
+
return (await this.httpJson("POST", `/agent/jobs/${encodeURIComponent(id)}/cancel`));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Unified search with mode dispatch. Calls POST /vm/search with mode param.
|
|
171
|
+
* mode='hybrid' (default) = vector+FTS rank-merge, 'semantic' = vector-only,
|
|
172
|
+
* 'fts' = keyword, 'graph' = entity traversal, 'full' = all merged.
|
|
173
|
+
*/
|
|
174
|
+
async searchWithMode(params) {
|
|
175
|
+
return (await this.httpJson("POST", "/vm/search", {
|
|
176
|
+
collection: params.collection ?? "main",
|
|
177
|
+
query: params.query,
|
|
178
|
+
mode: params.mode ?? "hybrid",
|
|
179
|
+
limit: params.limit ?? 5,
|
|
180
|
+
...(params.entity ? { entity: params.entity } : {}),
|
|
181
|
+
...(params.depth ? { depth: params.depth } : {}),
|
|
182
|
+
...(params.sources ? { sources: params.sources } : {}),
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
async gitStatus() {
|
|
186
|
+
return (await this.httpJson("GET", "/git/status"));
|
|
187
|
+
}
|
|
188
|
+
async gitBranches() {
|
|
189
|
+
return (await this.httpJson("GET", "/git/branches"));
|
|
190
|
+
}
|
|
191
|
+
async gitCheckout(branch) {
|
|
192
|
+
return (await this.httpJson("POST", "/git/checkout", { branch }));
|
|
193
|
+
}
|
|
194
|
+
async listSessions() {
|
|
195
|
+
return (await this.httpJson("GET", "/sessions"));
|
|
196
|
+
}
|
|
197
|
+
async getSession(id) {
|
|
198
|
+
return (await this.httpJson("GET", `/sessions/${encodeURIComponent(id)}`));
|
|
199
|
+
}
|
|
200
|
+
async renameSession(id, name) {
|
|
201
|
+
return (await this.httpJson("PATCH", `/sessions/${encodeURIComponent(id)}`, { name }));
|
|
202
|
+
}
|
|
203
|
+
async deleteSession(id) {
|
|
204
|
+
return (await this.httpJson("DELETE", `/sessions/${encodeURIComponent(id)}`));
|
|
205
|
+
}
|
|
206
|
+
async exportSession(id) {
|
|
207
|
+
return (await this.httpJson("POST", `/sessions/${encodeURIComponent(id)}/export`));
|
|
208
|
+
}
|
|
209
|
+
async archiveSession(id) {
|
|
210
|
+
return (await this.httpJson("POST", `/sessions/${encodeURIComponent(id)}/archive`));
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* List pending edits, optionally filtered by vault-relative file path.
|
|
214
|
+
*/
|
|
215
|
+
async listEdits(filePath) {
|
|
216
|
+
const query = filePath ? `?path=${encodeURIComponent(filePath)}` : "";
|
|
217
|
+
const res = await this.httpJson("GET", `/vm/edits${query}`);
|
|
218
|
+
return res.edits;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get a specific pending edit by ID.
|
|
222
|
+
*/
|
|
223
|
+
async getEdit(id) {
|
|
224
|
+
const res = await this.httpJson("GET", `/vm/edits/${encodeURIComponent(id)}`);
|
|
225
|
+
return res.edit;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Apply a pending edit to the target file.
|
|
229
|
+
*/
|
|
230
|
+
async applyEdit(id) {
|
|
231
|
+
return (await this.httpJson("POST", `/vm/edits/${encodeURIComponent(id)}/apply`));
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Reject a pending edit.
|
|
235
|
+
*/
|
|
236
|
+
async rejectEdit(id) {
|
|
237
|
+
return (await this.httpJson("POST", `/vm/edits/${encodeURIComponent(id)}/reject`));
|
|
238
|
+
}
|
|
239
|
+
async listPending() {
|
|
240
|
+
const res = await this.httpJson("GET", "/vm/pending");
|
|
241
|
+
return res.pending;
|
|
242
|
+
}
|
|
243
|
+
async approveEntry(id, collection, action) {
|
|
244
|
+
await this.httpJson("POST", "/vm/approve", { id, collection, action });
|
|
245
|
+
}
|
|
246
|
+
async pushContext(filePath, selection, cursor) {
|
|
247
|
+
return (await this.httpJson("POST", "/vault-mind/context", {
|
|
248
|
+
filePath,
|
|
249
|
+
selection,
|
|
250
|
+
cursor,
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
async scan(file, vault) {
|
|
254
|
+
try {
|
|
255
|
+
return (await this.httpJson("POST", "/vault-mind/scan", { file, vault }));
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
return { error: String(err) };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async dispatch(role, instruction, file, vault) {
|
|
262
|
+
try {
|
|
263
|
+
return (await this.httpJson("POST", "/vault-mind/dispatch", {
|
|
264
|
+
role,
|
|
265
|
+
instruction,
|
|
266
|
+
file,
|
|
267
|
+
vault,
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
return { error: String(err) };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async vmStats() {
|
|
275
|
+
return (await this.httpJson("GET", "/vm/stats"));
|
|
276
|
+
}
|
|
277
|
+
/** GET /vault-mind/config — full config + hasToken + remote block */
|
|
278
|
+
async getConfig() {
|
|
279
|
+
return (await this.httpJson("GET", "/vault-mind/config"));
|
|
280
|
+
}
|
|
281
|
+
/** GET /vault-mind/paths — vault/agent/env paths */
|
|
282
|
+
async paths() {
|
|
283
|
+
return (await this.httpJson("GET", "/vault-mind/paths"));
|
|
284
|
+
}
|
|
285
|
+
/** GET /vault-mind/models — provider/model catalog parsed from pi's models.json */
|
|
286
|
+
async getModels() {
|
|
287
|
+
return (await this.httpJson("GET", "/vault-mind/models"));
|
|
288
|
+
}
|
|
289
|
+
/** POST /vm/token — write PVM_API_TOKEN to vault-mind.env */
|
|
290
|
+
async writeToken(token) {
|
|
291
|
+
return (await this.httpJson("POST", "/vm/token", { token }));
|
|
292
|
+
}
|
|
293
|
+
/** PATCH /vm/config — partial config update (deep-merged on vaultMind) */
|
|
294
|
+
async updateConfig(partial) {
|
|
295
|
+
return (await this.httpJson("PATCH", "/vm/config", partial));
|
|
296
|
+
}
|
|
297
|
+
/** GET /vault-mind/tools — full tool catalog + per-role allowlists */
|
|
298
|
+
async listTools() {
|
|
299
|
+
return (await this.httpJson("GET", "/vault-mind/tools"));
|
|
300
|
+
}
|
|
301
|
+
/** GET /vault-mind/identities — identity registry */
|
|
302
|
+
async listIdentities() {
|
|
303
|
+
return (await this.httpJson("GET", "/vault-mind/identities"));
|
|
304
|
+
}
|
|
305
|
+
/** PUT /vault-mind/identities/:role/allowedTools — update per-role allowlist */
|
|
306
|
+
async setAllowedTools(role, allowedTools) {
|
|
307
|
+
return (await this.httpJson("PUT", `/vault-mind/identities/${encodeURIComponent(role)}/allowedTools`, { allowedTools }));
|
|
308
|
+
}
|
|
309
|
+
/** POST /vault-mind/reload-identities — reload bridge registry */
|
|
310
|
+
async reloadIdentities() {
|
|
311
|
+
return (await this.httpJson("POST", "/vault-mind/reload-identities"));
|
|
312
|
+
}
|
|
313
|
+
/** POST /vm/reindex — trigger a remote reindex of all collections */
|
|
314
|
+
async reindex() {
|
|
315
|
+
return (await this.httpJson("POST", "/vm/reindex"));
|
|
316
|
+
}
|
|
317
|
+
/** GET /agent/activity — list activity events, optionally filtered by jobId and limited. */
|
|
318
|
+
async listActivity(opts = {}) {
|
|
319
|
+
const params = new URLSearchParams();
|
|
320
|
+
if (opts.jobId !== undefined)
|
|
321
|
+
params.set("jobId", opts.jobId);
|
|
322
|
+
if (opts.limit !== undefined)
|
|
323
|
+
params.set("limit", String(opts.limit));
|
|
324
|
+
const qs = params.toString();
|
|
325
|
+
return (await this.httpJson("GET", `/agent/activity${qs ? `?${qs}` : ""}`));
|
|
326
|
+
}
|
|
327
|
+
/** GET /vault-mind/model-readiness — returns model registry status and current selected model */
|
|
328
|
+
async getModelReadiness() {
|
|
329
|
+
return (await this.httpJson("GET", "/vault-mind/model-readiness"));
|
|
330
|
+
}
|
|
331
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|