57 lines
6.8 KiB
Markdown
57 lines
6.8 KiB
Markdown
# Advanced Hope chat surfaces
|
||
|
||
Implementation contract, not a deployment receipt. All routes authenticate via existing current_user (bearer or cookie with mutation Origin checks). Owner is derived server-side. Missing/cross-account/deleted objects return404; revoked sessions401. Hermes alone runs tools/reasoning. Provider credentials, URLs, raw job configuration and disk paths are never public.
|
||
|
||
## Attachments
|
||
|
||
- POST `/api/attachments`: raw bytes, MIME `Content-Type`, `X-Filename` display name. Returns201 `{attachment}`. No multipart wrapper.
|
||
- GET `/api/attachments`: `{attachments:[],next_cursor:null}` (bounded first200).
|
||
- GET `/api/attachments/{id}`: `{attachment}`.
|
||
- GET `/api/attachments/{id}/content`: private bytes, download disposition, no-store, nosniff.
|
||
- DELETE `/api/attachments/{id}`: `{ok:true}`. Removes stored bytes and tombstones metadata.
|
||
|
||
Attachment exactly `{id,filename,mime,size,extraction_status,created_at}`. IDs UUID hex32, Unix timestamps. Extraction statuses ready|truncated|image|unavailable|encrypted|failed. Supported MIME text/plain,text/markdown,application/pdf,image/png,image/jpeg,image/webp. Defaults8MiB per upload,64MiB per account,512MiB global disk; MIME mismatch415, invalid filename422, limit413. No HTML/SVG, arbitrary paths or remote fetch. UTF8 text extracted, PDFs via pypdf (encrypted/failure explicitly blocked as provider input). Text capped100000 characters. Images are inline image_url payloads only for explicitly qualified selected model; otherwise409. Signature validation does not imply antivirus or full image decoder validation.
|
||
|
||
Core integration `FeatureStore.provider_content(owner, attachment_ids, vision=False)` is async. At most8 distinct IDs. Never provider-input another owner's upload. Images use OpenAI message-content shape, not guessed Responses schema. Core supplies qualified vision flag. Local store persists in injected Accounts DB with FK plus private flat files. Account deletion denies access immediately and retains disk data by policy; no implicit erase.
|
||
|
||
## Artifacts
|
||
|
||
- GET `/api/artifacts`: `{artifacts:[],next_cursor:null}` (bounded first200). List entries metadata only, omitting content; select GET detail to load content.
|
||
- POST `/api/artifacts` JSON `{title,kind?:"markdown",content?:""}` →201 `{artifact}`.
|
||
- GET `/api/artifacts/{id}?revision=N`: `{artifact}`, historical content optional.
|
||
- GET `/api/artifacts/{id}/versions`: `{versions:[{revision,created_at}],next_cursor:null}`, descending revision.
|
||
- PATCH `/api/artifacts/{id}` JSON `{revision,title?,kind?,content?}` → `{artifact}`; missing/stale revision409.
|
||
- GET `/api/artifacts/{id}/export?revision=N`: UTF8 download, text/plain with .md for markdown, otherwise .txt. No executable inline HTML, PDF/DOCX generation claims.
|
||
- DELETE `/api/artifacts/{id}` → `{ok:true}`; historical versions inaccessible after tombstone.
|
||
|
||
Artifact `{id,title,kind,revision,content,created_at,updated_at}`. kind text|markdown|code. Title1–160 chars, default512KiB UTF8 content,200 artifacts including retained tombstones/account,100 versions/artifact. Cumulative retained version UTF8 bytes max32MiB/account and256MiB globally. Versions are not silently trimmed: explicit version limit/storage quota returns413, including deleted retained versions. Revision starts1, increments each edit. Historical versions currently retain content and time but title/kind reflect current metadata (not historical title).
|
||
|
||
## Scheduled tasks
|
||
|
||
Qualified gateway exact mapping `/api/jobs`; no second scheduler. Provider operations authenticated with account's private Hermes key. Public delivery is forced local; client cannot select providers, scripts, base URLs, external recipients or tools.
|
||
|
||
- GET `/api/tasks` → `{tasks:[],next_cursor:null}`; gateway query include_disabled=true.
|
||
- POST `/api/tasks` `{name,schedule,prompt,repeat?,paused?}` →201 `{task}`. Schedule is a Hermes schedule string, not a fabricated UI cron dialect. name1–200 chars, schedule1–200 chars, prompt1–5000 chars, repeat positive integer, paused boolean.
|
||
- PATCH `/api/tasks/{id}` `{name?,schedule?,prompt?,repeat?,enabled?}` → `{task}`. No optimistic revision supported by pinned Hermes jobs API.
|
||
- DELETE `/api/tasks/{id}` → `{ok:true}`.
|
||
- POST `/api/tasks/{id}/pause|resume|run` → `{task}`. Run triggers Hermes execution, not a Hope agent loop.
|
||
|
||
Task projection whitelist `{id,name?,schedule?,prompt?,enabled?,repeat?,created_at?,last_run_at?,next_run_at?}`. IDs hex12. Only id is guaranteed; optional fields preserve exact gateway type, clients must tolerate absent timestamps. No task-output-history API has been qualified. Invalid remote scheduling errors sanitized; unsupported capability501, unavailable503, upstream failure502.
|
||
|
||
## Memory controls
|
||
|
||
No gateway memory API exists. Trusted control adapter accesses only retained account `home/memories/MEMORY.md` and `USER.md`, never arbitrary file paths or separately authenticated WebUI.
|
||
|
||
- GET `/api/memory` → `{sections:[{section:"memory",content,revision},{section:"user",content,revision}]}`.
|
||
- PUT `/api/memory/{section}` `{content,revision}` → `{section,content,revision}`.
|
||
|
||
Revision SHA256 hex content digest. Empty content explicitly clears that section. UTF8 max64KiB/section. Unknown section404, stale revision409, unavailable storage503, unqualified adapter501. Updates persist files; already-running Hermes sessions may retain cached memory until a later run/session reload. No claim of live memory-cache invalidation. Do not confuse clearing files with deleting conversation history or all data. Protected fixed directories and no-follow file opens; runtime has independent filesystem writes, so revision is best-effort against concurrent Hermes edits, not cross-process transaction locking.
|
||
|
||
## Honest statuses and sync
|
||
|
||
- GET `/api/connectors` → `{connectors:[],available:false,reason}`. No qualified connector management API; do not present fabricated working integration switches.
|
||
- GET `/api/research` → `{available:false,reason}`. Normal Hermes web/browser tools remain available; dedicated research-mode API is not qualified.
|
||
- GET `/api/features/sync?after=0` → `{changes:[{sequence,kind:"attachment"|"artifact",id,deleted,created_at}],cursor}`; max200 per response, owner-filtered tombstones. This cursor is independent of core conversation sync.
|
||
|
||
Core merges `local_capabilities(store)` and account-qualified `FeatureProvider.feature_capabilities(owner)` into its one `/api/capabilities`. Local helper reports image/tasks/memory false by default; provider qualifies jobs, managed auto vision, and available fixed memory storage. Constructor `FeatureStore(accounts, root_path, limits=None)`; router `create_feature_router(store, provider=None)`; default `FeatureProvider(accounts,http_client=None,state_dir=None)` has `aclose()` which app shutdown must call. Memory root defaults HOPE_HERMES_DATA_DIR matching provisioner. No live/deploy qualification performed here.
|