forked from jason/echo
ver 1.2
This commit is contained in:
@@ -8,6 +8,21 @@ The endpoint has a **valid TLS certificate** — `-k` is not required. Paths add
|
||||
|
||||
---
|
||||
|
||||
## Client performance (echo.py) — pooling & concurrency
|
||||
|
||||
`echo.request()` keeps **one persistent keep-alive connection per thread** and reuses it across calls, instead of opening a fresh TCP+TLS connection per request. Against a remote HTTPS endpoint the repeated handshake was the dominant cost, so a full-vault pass used to make hundreds of serial handshakes and exceed the agent/tool timeout (which kills the run mid-flight). A stale pooled connection reconnects transparently; the `(status, body)` contract is unchanged (status `0` still means transport failure, so the offline write-queue still triggers).
|
||||
|
||||
For bulk reads, **`echo.read_many(paths)`** fans GETs across a thread pool and returns `{path: text_or_None}` — resilient (one unreadable file becomes `None` rather than aborting the batch). `sweep.py` and `vault_lint.py` prefetch the whole vault once with it and share that single cache across every pass, so no note is fetched more than once. Net effect: a several-minute full-vault sweep becomes sub-second on a few-hundred-note vault.
|
||||
|
||||
Tuning knobs (env overrides):
|
||||
|
||||
- `ECHO_TIMEOUT` (default `30`) — per-request socket timeout in seconds. With concurrency, one slow file only blocks its own worker, not the run.
|
||||
- `ECHO_WORKERS` (default `8`) — `read_many` thread-pool size. Raise it for very large vaults; lower it to be gentler on the backend.
|
||||
|
||||
For a vault large enough that even the concurrent pass approaches the tool timeout, run the script with the harness's background-execution option rather than blocking the turn.
|
||||
|
||||
---
|
||||
|
||||
## Reading Files
|
||||
|
||||
```bash
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
└── locks/ ← vault.lock — cooperative advisory multi-writer lock
|
||||
```
|
||||
|
||||
**Entity index:** `_agent/index/entities.json` is a machine-maintained registry mapping each entity slug to its `{path, kind, title, aliases, last_seen}`. It makes routing/resolve an O(1), alias-aware lookup (no fuzzy search per write) and supplies the name→path map for cross-linking and recall. It is rebuilt automatically by `echo.py capture` and by `sweep.py`; do not hand-edit. The only JSON file in the vault.
|
||||
**Entity index:** `_agent/index/entities.json` is a machine-maintained registry mapping each entity slug to its `{path, kind, title, aliases, last_seen}`. It makes routing/resolve an O(1), alias-aware lookup and supplies the name→path map for cross-linking and recall. `resolve` matches slug/title/alias exactly; when nothing matches exactly it falls back to **fuzzy candidates** — entities sharing a distinctive token with the mention — so a shortened name ("echo memory" → the project `echo`) surfaces the existing note instead of spawning a duplicate. Aliases are auto-derived from titles, learned from mentions on update, and re-folded from note frontmatter on `sweep`. It is rebuilt automatically by `echo.py capture` and by `sweep.py`; do not hand-edit. The only JSON file in the vault.
|
||||
|
||||
**Heartbeat:** `_agent/heartbeat/last-session.md` is a one-line pointer (`<session-log-path> @ <ISO-timestamp>`) the **session-logging procedure writes (PUT, overwrite) at session end** and the **loading procedure reads first (Step 4)** as an O(1) shortcut to the latest session log. It is a hint, not a source of truth — fall back to the `sessions/` directory listing if it's missing or stale. Because it's PUT-overwritten, it never grows or duplicates.
|
||||
|
||||
@@ -70,11 +70,15 @@ status: # active | draft | done | archived | complete
|
||||
created: # YYYY-MM-DD (or YYYY-MM-DDTHH:mm for sessions)
|
||||
updated: # YYYY-MM-DD
|
||||
tags: []
|
||||
aliases: [] # optional — other names this entity is called (Obsidian-native). Folded
|
||||
# into the entity index so a shortened/expanded name resolves to this note.
|
||||
agent_written: false
|
||||
source_notes: [] # plain relative paths as strings — NEVER [[wikilinks]]
|
||||
---
|
||||
```
|
||||
|
||||
`aliases:` is the **durable, Obsidian-native home for alternate names** of an entity (e.g. the project `echo` is also "echo-memory" / "echo plugin"). `capture` auto-derives the obvious case/punctuation variants of the title and writes them here; `sweep` folds frontmatter aliases back into the entity index, so they survive an index rebuild. List plain strings, never `[[wikilinks]]`.
|
||||
|
||||
`agent_written: true` + a populated `source_notes` is the key signal separating
|
||||
agent-managed content from human-authored content. When appending with POST, do
|
||||
not rewrite frontmatter — the append goes after existing content. To change
|
||||
|
||||
Reference in New Issue
Block a user