AbstractGateway — API overview¶
The HTTP API is implemented with FastAPI under the /api prefix:
- Health: GET /api/health
- Gateway surface: /api/gateway/* (durable runs + operator tooling)
The API is documented at runtime:
- OpenAPI JSON: GET /openapi.json
- Swagger UI: GET /docs (use Authorize to paste the bearer token)
Context: - In the AbstractFramework ecosystem, UIs and automations call this API to operate AbstractRuntime runs. - Architecture diagram and core concepts: architecture.md
Auth¶
By default, /api/gateway/* is protected by GatewaySecurityMiddleware (bearer token + origin allowlist).
See: security.md.
All examples below assume:
export BASE_URL="http://127.0.0.1:8080"
export AUTH="Authorization: Bearer $(cat "$ABSTRACTGATEWAY_DATA_DIR/auth/bootstrap-admin-token")"
Provider connections¶
Gateway-owned provider connections let users create reusable cloud, local, or
OpenAI-compatible endpoints without putting raw API keys in workflow JSON or
browser storage. The API route keeps the historical
provider-endpoint-profiles name; the Console presents them as provider
connections.
GET /api/gateway/config/provider-endpoint-profiles: list visible profiles.POST /api/gateway/config/provider-endpoint-profiles: create a user- or admin-owned profile.POST /api/gateway/config/provider-endpoint-profiles/discover-models: discover models for a draft or saved profile by calling the configured provider family and base URL with the entered or server-side key. The raw key is never returned.PUTorDELETE /api/gateway/config/provider-endpoint-profiles/{profile_id}: update or delete a profile.
Enabled profiles appear in GET /api/gateway/discovery/providers as virtual
providers such as endpoint:office-vllm. Model discovery through
GET /api/gateway/discovery/providers/{provider_name}/models returns either the
fixed profile allowlist or the live endpoint model catalog.
Core workflow lifecycle¶
1) List bundles (bundle mode)¶
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/bundles"
Upload a bundle:
curl -sS -H "$AUTH" \
-F "file=@./my-bundle@0.1.0.flow" \
-F "overwrite=false" \
-F "reload=true" \
"$BASE_URL/api/gateway/bundles/upload"
2) Start a run¶
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"bundle_id":"my-bundle","input_data":{"prompt":"Hello"}}' \
"$BASE_URL/api/gateway/runs/start"
If you need a specific entrypoint:
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"bundle_id":"my-bundle","flow_id":"ac-echo","input_data":{"prompt":"Hello"}}' \
"$BASE_URL/api/gateway/runs/start"
Evidence: request/response models live in src/abstractgateway/routes/gateway.py (StartRunRequest, start_run).
For VisualFlow bundles, Gateway runs the packed JSON through AbstractRuntime.
Structured LLM/Agent schemas are Runtime/Core-owned: response remains textual,
and schema-conformant object values are available through the node data output
for data edges such as Break Object and Switch.
2b) Schedule a run (bundle mode)¶
POST /api/gateway/runs/schedule starts a scheduled parent run that launches the target workflow as child runs over time.
Example (run 3 times, every hour, starting now):
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"bundle_id":"my-bundle","flow_id":"ac-echo","input_data":{"prompt":"Ping"},"start_at":"now","interval":"1h","repeat_count":3,"share_context":true,"session_id":"sess-1"}' \
"$BASE_URL/api/gateway/runs/schedule"
Notes:
- start_at: ISO 8601 timestamp (recommended) or "now".
- interval: e.g. "15m", "1h", "2d". If omitted, runs once.
- repeat_count: if omitted and interval is set, repeats forever. Alternatively use repeat_until (ISO 8601).
- To stop a schedule, cancel the scheduled parent run via POST /api/gateway/commands with type cancel.
Evidence: ScheduleRunRequest, start_scheduled_run in src/abstractgateway/routes/gateway.py.
2c) Shared workflow catalog¶
Private /api/gateway/bundles routes are scoped to the signed-in user's routed
runtime. Shared/default workflows use the Gateway workflow catalog instead:
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/workflow-catalog"
Admin-only catalog operations live under
/api/gateway/admin/workflow-catalog/*:
- upload or promote immutable
.flowversions; - move a bundle's default pointer;
- set ACLs;
- deprecate, block, or tombstone a version without deleting bundle bytes.
Start a catalog workflow in the requesting user's runtime by setting
registry_scope:
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"registry_scope":"tenant_catalog","bundle_id":"basic-agent","flow_id":"root","input_data":{"prompt":"Hello"}}' \
"$BASE_URL/api/gateway/runs/start"
If bundle_version is omitted, Gateway uses the admin-managed catalog default
pointer. Exact older versions keep working until that specific version is
deprecated, blocked, or tombstoned.
Catalog scope is explicit: omitting registry_scope starts only private
runtime bundles. Flow/schema inspection for catalog workflows should use the
ACL-aware catalog endpoints:
GET /api/gateway/workflow-catalog/{bundle_id}/versions/{bundle_version}/flows/{flow_id}GET /api/gateway/workflow-catalog/{bundle_id}/versions/{bundle_version}/flows/{flow_id}/input_schema
framework_catalog is reserved but not loadable yet; use tenant_catalog.
3) Replay the ledger (cursor-based)¶
Ledger pages are replayed using after as “number of items already consumed”.
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/runs/<run_id>/ledger?after=0&limit=200"
Response shape:
- items: list of durable ledger records
- next_after: the next cursor to use
Evidence: src/abstractgateway/routes/gateway.py (get_ledger).
3b) Replay ledgers for multiple runs (batch)¶
Use POST /api/gateway/runs/ledger/batch to reduce request fanout when observing many runs/subflows.
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"limit":200,"runs":[{"run_id":"<run_id_1>","after":0},{"run_id":"<run_id_2>","after":0}]}' \
"$BASE_URL/api/gateway/runs/ledger/batch"
Evidence: src/abstractgateway/routes/gateway.py (get_ledger_batch).
4) Stream ledger updates (SSE)¶
SSE is an optimization; clients should always be able to reconnect by replaying from the last next_after.
curl -N -H "$AUTH" "$BASE_URL/api/gateway/runs/<run_id>/ledger/stream?after=0"
Evidence: src/abstractgateway/routes/gateway.py (stream_ledger).
Artifacts and filesystem handoff¶
Gateway artifacts are the cross-package representation for files, media, and large payloads. Thin clients should pass artifact refs across runs instead of raw bytes or local paths:
{
"$artifact": "abc123",
"artifact_id": "abc123",
"run_id": "session_memory_sess-1",
"content_type": "image/png",
"filename": "input.png"
}
Gateway uses three distinct file-like source terms:
Artifact: a durable runtime-owned payload reference.Local File: a browser/client upload source. Hosted clients should upload bytes; browser-local paths are never interpreted as server paths.Server File/Server Folder: user-facing wording for a workspace-scoped server path under Gateway policy. The engineering contract is the canonicalWorkspacePathstring returned by/files/*, artifact import/export, and Runtime file nodes.
Hosted local uploads stay artifact-backed:
- one local file upload creates one artifact ref;
- multiple local files create an ordered list of artifact refs in Flow;
- a local folder uploads one artifact per file and may send
source_path(for examplereports/2026/summary.md) so relative member paths survive in artifact provenance without exposing browser-local absolute paths.
Upload a local file or folder member:
curl -sS -H "$AUTH" \
-F "session_id=sess-1" \
-F "source_path=reports/summary.md" \
-F "file=@./summary.md" \
"$BASE_URL/api/gateway/attachments/upload"
List run artifacts:
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/runs/<run_id>/artifacts"
List artifacts visible to a session:
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/sessions/sess-1/artifacts"
Browse server workspace files/folders:
curl -sS -H "$AUTH" \
"$BASE_URL/api/gateway/files/list?path=&include_directories=true&limit=200"
Optional filters:
- path: browse a specific workspace folder or mount alias.
- recursive=true
- family=image|video|audio|document|text|code|json|archive|other
- extensions=png,jpg or newline-separated values
- query=substring
- max_depth=<n>
Search artifacts across Gateway storage:
curl -sS -H "$AUTH" \
"$BASE_URL/api/gateway/artifacts/search?scope=all&artifact_kind=image&query=logo&tags=pin_id=image&include_stats=true&limit=500"
scope can be all, session, or run. Use session_id with
scope=session and run_id with scope=run; omit both for scope=all.
Search responses preserve the legacy row fields and also include
artifact_envelope_v1, a normalized projection of Runtime-owned descriptors,
access stats, and Gateway action links.
Useful query parameters:
- artifact_kind: UI-oriented kind filter. Comma-separated values match
semantic_kind, render_kind, or modality; generic audio means
unclassified audio and does not match canonical voice, music, or sound.
Single canonical kinds such as music, voice, image, markdown, or
json map to Runtime catalog filters. Multi-kind unions are supported, but
may be Gateway post-filters until Runtime exposes OR filters.
- semantic_kind / render_kind: canonical descriptor filters when the caller
wants the two dimensions separately.
- modality, content_type, workflow_id, node_id, created_after,
created_before, and tags: server filters for indexed descriptor fields.
- query: case-insensitive metadata search. Gateway may post-filter this field
when Runtime cannot index it directly.
- include_stats=true: include exact stats.total, byte totals, and facet
counts for the selected server-side filter set, independent of limit.
- limit, offset, and cursor: bounded paging. The default Runtime Explorer
page size is 500; limit<=0 is bounded unless debug_unlimited=true is used
by an admin/debug caller.
artifact_envelope_v1 contains normalized fields such as semantic_kind,
render_kind, workflow_id, node_id, turn_id, ledger_cursor,
generation, producer, media, source_refs, access, and links.
Sparse producer metadata is represented as missing fields; Gateway does not
invent provider/model provenance from filenames.
Generated-media artifacts created by child runs and projected into the parent run preserve Runtime descriptors and structured metadata. Direct transcription routes store transcript artifacts with source-audio refs, language/prompt hints, provider/model when available, and bounded route parameters. Descriptor-provided action links are sanitized to relative Gateway/UI links before they appear in envelopes; raw external provider URLs should be represented as trace availability or Gateway-owned trace records.
Content reads can label the access type for Runtime access stats:
curl -sS -H "$AUTH" \
"$BASE_URL/api/gateway/runs/<run_id>/artifacts/<artifact_id>/content?access_action=preview"
Supported access actions are content, preview, and download. The shorter
access=preview alias is also accepted.
Import a server workspace path into a session artifact:
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"session_id":"sess-1","source":{"kind":"workspace_path","path":"inputs/photo.png"},"pin_id":"image"}' \
"$BASE_URL/api/gateway/artifacts/import"
Export an artifact back into the server workspace:
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"path":"outputs/photo.png","create_parent_dirs":true,"overwrite":false}' \
"$BASE_URL/api/gateway/runs/<run_id>/artifacts/<artifact_id>/export"
Import and export use the same Gateway workspace policy as file helpers:
workspace roots, mounted roots, ignored paths, and size limits are enforced on
the server. Browser-local files should be uploaded through
POST /api/gateway/attachments/upload; browser-local file paths are not
interpreted as Gateway workspace paths. In hosted user-auth mode, server
workspace import/export and /files/* helpers require an admin principal.
Ordinary users can still upload browser-local files and list/search artifacts in
their own routed runtime.
Canonical Gateway server paths use rel/path for the main workspace root and
mount_alias/rel/path for approved mounts. When two allowed mounts share the
same basename, Gateway emits deterministic digest-suffixed aliases so the same
public path string can round-trip through /files/*, artifact import/export,
and Runtime file nodes.
Durable commands (POST /api/gateway/commands)¶
Commands are appended to a durable inbox and applied asynchronously by the runner.
Request fields (see SubmitCommandRequest in src/abstractgateway/routes/gateway.py):
- command_id: client-supplied idempotency key (UUID recommended)
- run_id: target run id (or session id for some event use-cases)
- type: pause|resume|cancel|emit_event|update_schedule|compact_memory
- payload: command-specific object
Pause / cancel¶
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"command_id":"'"$(python -c 'import uuid; print(uuid.uuid4())')"'", "run_id":"<run_id>", "type":"pause", "payload":{"reason":"operator_pause"}}' \
"$BASE_URL/api/gateway/commands"
Resume a paused run¶
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"command_id":"'"$(python -c 'import uuid; print(uuid.uuid4())')"'", "run_id":"<run_id>", "type":"resume", "payload":{}}' \
"$BASE_URL/api/gateway/commands"
Resume a WAITING run with a payload (WAIT resume)¶
When payload.payload is present, the runner interprets this as “resume a WAITING run with a durable payload”:
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"command_id":"'"$(python -c 'import uuid; print(uuid.uuid4())')"'", "run_id":"<run_id>", "type":"resume", "payload":{"wait_key":"<optional_wait_key>", "payload":{"approved":true}}}' \
"$BASE_URL/api/gateway/commands"
Evidence: src/abstractgateway/runner.py (_apply_command, _apply_run_control).
Emit an external event¶
Minimal form:
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"command_id":"'"$(python -c 'import uuid; print(uuid.uuid4())')"'", "run_id":"<session_id>", "type":"emit_event", "payload":{"name":"chat.message","payload":{"text":"hi"}}}' \
"$BASE_URL/api/gateway/commands"
Evidence: src/abstractgateway/runner.py (_apply_emit_event).
Beyond the core¶
/api/gateway/* also includes optional operator/tooling endpoints (reports inbox, triage queue, backlog browsing + exec runner, process manager, file/attachment helpers, embeddings, voice, discovery, …).
See: maintenance.md.
Discovery endpoints (optional)¶
These exist to help thin clients adapt to the deployed gateway.
- Capabilities (best-effort):
GET /api/gateway/discovery/capabilities - Providers/models discovery (best-effort):
GET /api/gateway/discovery/providers,GET /api/gateway/discovery/providers/{provider}/models - Dynamic capability catalogs:
GET /api/gateway/voice/voices,GET /api/gateway/audio/speech/models,GET /api/gateway/audio/transcriptions/models,GET /api/gateway/audio/music/providers,GET /api/gateway/audio/music/models,GET /api/gateway/vision/provider_models
The capabilities payload includes package presence (abstractruntime,
abstractcore, abstractmemory, abstractvoice, abstractvision), existing
gateway helpers (tools, visualflow, media), memory-store readiness, and
AbstractCore capability plugin status for voice, audio, vision, and
music.
Today the route paths and contract descriptors are the stable part of this surface. Catalog routes now also include a stable Gateway-owned envelope:
catalog.contract = gateway_catalog_v1catalog.version = 1items = [...]
Legacy lower-layer fields are still preserved for compatibility. New thin
clients should read catalog plus items; older clients can keep using route-
specific fields like models, provider_models, profiles, or voices.
Provider discovery also reports the resolved default provider/model when one is
configured. The resolver follows request values, flow pins, and the execution-host
input.text capability route; if no pair exists, the response includes
default_error rather than a hardcoded local model.
It also includes a versioned thin-client contract:
capabilities.contracts.version: currently1capabilities.contracts.common: shared run start/list/summary/input/history, ledger, artifact, attachment, workspace, discovery, and provider prompt-cache controls.common.artifactsincludes run listing/content, session artifact listing, artifact search withartifact_envelope_v1, exact stats/facets,artifact_kindUI filtering, workspace import, and workspace export descriptors when available. Permission-sensitive descriptors are principal-aware: ordinary users see admin-only workspace import/export and provider prompt-cache controls marked unavailable withadmin_requiredmetadata.capabilities.contracts.common.readiness: compact Gateway-ownedgateway_surface_readiness_v1summary derived from the shared endpoint/media/ residency descriptorscapabilities.contracts.flow_editor: the AbstractFlow editor/runtime surfacecapabilities.contracts.assistant: assistant-facing voice/audio/media/cache feature gatescapabilities.contracts.abstractcode: code-client run/history/workspace/cache feature gates
Contract booleans are intentionally conservative. Package installed=true is
not the same thing as endpoint available=true; clients should branch on the
versioned contract fields when enabling controls.
common.readiness is intentionally narrower than provider/backend health. It
summarizes Gateway surface availability from existing descriptors, but it does
not invent selected backend/provider/model truth or stable degraded-state
reason codes.
Evidence: src/abstractgateway/routes/gateway.py (discovery_capabilities, discovery_providers).
AbstractFlow gateway-first editor contract¶
The browser editor can use AbstractGateway as its runtime and storage host.
Draft VisualFlow records:
GET /api/gateway/visualflowsPOST /api/gateway/visualflowsGET /api/gateway/visualflows/{flow_id}PUT /api/gateway/visualflows/{flow_id}DELETE /api/gateway/visualflows/{flow_id}POST /api/gateway/visualflows/{flow_id}/publish
Bundle inspection and editor run-schema helpers:
GET /api/gateway/bundlesGET /api/gateway/bundles/{bundle_id}GET /api/gateway/bundles/{bundle_id}/flows/{flow_id}GET /api/gateway/bundles/{bundle_id}/flows/{flow_id}/input_schema
The input-schema endpoint returns a versioned payload with:
versionbundle_id,bundle_version,bundle_ref,flow_id,workflow_idinputs: entrypoint input pins derived from theon_flow_startnodedefaults: pin defaults from VisualFlow JSONinput_data_schema: a small JSON Schema object for the Run Flow modal
Example:
curl -sS -H "$AUTH" \
"$BASE_URL/api/gateway/bundles/my-bundle/flows/ac-echo/input_schema"
The editor observes runs with the core lifecycle endpoints above:
/runs/start, /runs/{run_id}, /runs/{run_id}/ledger,
/runs/{run_id}/ledger/stream, /runs/ledger/batch,
/runs/{run_id}/input_data, /runs/{run_id}/history_bundle, and
/runs/{run_id}/artifacts.
Optional multimodal scope¶
Current direct Gateway endpoints:
- POST /api/gateway/runs/{run_id}/voice/tts
- POST /api/gateway/runs/{run_id}/audio/transcribe
- POST /api/gateway/runs/{run_id}/images/generate
- POST /api/gateway/runs/{run_id}/images/edit
- POST /api/gateway/runs/{run_id}/images/upscale
- POST /api/gateway/runs/{run_id}/videos/generate
- POST /api/gateway/runs/{run_id}/videos/from_image
- POST /api/gateway/runs/{run_id}/music/generate
- GET /api/gateway/voice/voices
- GET /api/gateway/audio/speech/models
- GET /api/gateway/audio/transcriptions/models
- GET /api/gateway/audio/music/providers
- GET /api/gateway/audio/music/models
- GET /api/gateway/vision/provider_models
- GET /api/gateway/vision/adapters
The catalog endpoints proxy AbstractCore Server routes when
ABSTRACTCORE_SERVER_BASE_URL
is configured. Gateway uses explicit Core auth settings for that hop and never
reuses the Gateway bearer token as a Core/provider secret. Without a configured
Core server, the voice/model routes return bounded static descriptors from
Gateway and capability-package environment variables.
Each route now adds:
catalog: Gateway-owned route metadata (contract,version,kind,scope,route_source, optionalupstream_source, and route filters)items: one canonical primary array for thin clients
Examples:
/voice/voices:itemscontain voice/profile records withid,label, optionalprovider, optionalmodel, andvoice_kind/audio/*/models:itemscontain model records withid,label, optionalprovider, optionaltasks, and optionalparameters/audio/music/providersand/discovery/providers:itemscontain provider records withid,label, andprovider
Generated images are available through Runtime workflows when a compatible
image backend is installed and configured. Gateway also exposes a direct image
generation endpoint that uses the Runtime/Core output-selector contract rather
than a provider-specific image client. The route creates a durable child run,
stores the generated image as a run artifact, and returns
event_name="abstract.progress" so thin clients can stream the child-run ledger
for progress:
run_id,request_id,prompt- optional
provider,model,size,width,height,format, batchcount/n,seeds, and orderedlora_adapters image_artifact: first generated image for compatibilityimage_artifacts: full ordered image artifact list for batch generation
size, width, and height are optional passthrough request overrides. Do
not inject a client-side default size. Different image providers/models accept
different size sets; when the client leaves dimensions unset, Runtime/Core lets
the configured backend use its default or auto behavior.
If the active workflow runtime already has an AbstractCore LLM client, the route
uses it. For tools-only workflows, the route can create a direct Runtime/Core
client from request provider/model or the execution-host capability route
default. Unsupported or unconfigured deployments return a structured ok=false
response instead of a failed run.
Gateway also exposes a direct image-edit sibling route:
POST /api/gateway/runs/{run_id}/images/edit
The request uses a source image_artifact, optional mask_artifact, the same
provider/model and image backend selectors as image generation, plus optional
batch count / n, seeds, and ordered lora_adapters, and returns an
artifact-backed edited image. Batch responses also return image_artifacts.
Thin clients should feature-detect it from
capabilities.contracts.flow_editor.media.edited_image or
capabilities.contracts.assistant.media.edited_image. It uses the same
child-run abstract.progress progress contract as direct image generation.
Gateway also exposes a direct image-upscale sibling route:
POST /api/gateway/runs/{run_id}/images/upscale
The request uses a run-visible source image_artifact, optional provider/model
selectors, and optional upscaler controls such as scale, resolution,
softness, seed, quantize, and vae_tiling; resolution may be a
shortest-edge integer or a scale factor such as 2x. Thin clients should
feature-detect it from capabilities.contracts.flow_editor.media.upscaled_image
or capabilities.contracts.assistant.media.upscaled_image, list models with
GET /api/gateway/vision/provider_models?task=image_upscale, and stream the
returned child-run ledger for abstract.progress events.
Generated music follows the same direct child-run pattern. Thin clients should
discover it from capabilities.contracts.flow_editor.media.generated_music or
capabilities.contracts.assistant.media.generated_music, list providers/models
from the music catalog routes, and treat the returned child_run_id plus
music_artifact as the durable output handle.
Generated video also follows the direct child-run pattern:
POST /api/gateway/runs/{run_id}/videos/generateuses the Runtime/Coreoutput.modality=video/task=text_to_videocontract and accepts optional batchcount/n,seeds, orderedlora_adapters, andflow_shift.POST /api/gateway/runs/{run_id}/videos/from_imageaccepts a run-visible sourceimage_artifact, accepts the same optional batch/adapter/video control fields, and usestask=image_to_video.- Thin clients should discover these routes from
capabilities.contracts.flow_editor.media.generated_videoandcapabilities.contracts.flow_editor.media.image_to_video(or the matchingassistant.media.*entries), useGET /api/gateway/vision/provider_models?task=text_to_video|image_to_videofor model catalogs, useGET /api/gateway/vision/adaptersfor compatible installed adapter catalogs, stream the returnedchild_run_idledger forabstract.progressevents, and readvideo_artifactswhen batch generation is requested.
STT and listen contract notes:
POST /api/gateway/runs/{run_id}/audio/transcribeaccepts a run-visibleaudio_artifactplus optionallanguage,prompt,response_format,temperature,format,provider, andmodelhints.capabilities.contracts.flow_editor.voice.sttandcapabilities.contracts.assistant.voice.sttpoint to that upload route.capabilities.contracts.flow_editor.voice.listenandcapabilities.contracts.assistant.voice.listenare host-capture contracts, not a live microphone socket. They tell higher apps to capture locally and emit an event or upload the resulting audio artifact.
KG memory¶
POST /api/gateway/kg/query queries the configured AbstractMemory TripleStore.
Gateway resolves the store through:
ABSTRACTGATEWAY_MEMORY_STORE_BACKEND=lancedb|memory(sqlitewhen the installed AbstractMemory build exposesSQLiteTripleStore)ABSTRACTGATEWAY_MEMORY_STORE_PATHABSTRACTGATEWAY_MEMORY_REQUIRE_VECTOR
Structured queries work with LanceDB and in-memory stores. SQLite also works
when the installed AbstractMemory build exposes SQLiteTripleStore. Semantic
query_text requires a vector-capable backend plus the execution-host
embedding.text route; SQLite returns a clear 400 instead of pretending to
support semantic recall.
Capability discovery reports KG memory as available when AbstractMemory is installed and the configured backend can be resolved. A fresh persistent store does not need to exist yet; empty-store structured queries return an empty result rather than making Flow authoring nodes unavailable.
Prompt-cache control plane (operator API)¶
The gateway exposes prompt-cache operator endpoints under /api/gateway/prompt_cache/*.
Provider prompt-cache controls affect process-local or remote provider state
and require an admin principal in hosted user-auth mode.
Core endpoints:
GET /api/gateway/prompt_cache/capabilities?provider=...&model=...GET /api/gateway/prompt_cache/stats?provider=...&model=...POST /api/gateway/prompt_cache/setPOST /api/gateway/prompt_cache/updatePOST /api/gateway/prompt_cache/forkPOST /api/gateway/prompt_cache/clearPOST /api/gateway/prompt_cache/prepare_modules
Behavior:
- These routes use the runtime's AbstractCore prompt-cache client contract rather than directly depending on provider-instance access.
- In local mode they delegate to the in-process provider.
- In remote/hybrid mode they follow whatever
/acore/prompt_cache/*surface the configured AbstractCore server exposes. - All core prompt-cache responses include
operationandcapabilities, with structured unsupported/error cases (code="prompt_cache_unsupported"/code="prompt_cache_error"/code="prompt_cache_unavailable"). - These endpoints remain provider/model controls, not a Gateway-owned CachedSession persistence system.
Session lifecycle endpoints:
GET /api/gateway/sessions/{session_id}/prompt_cache/statusPOST /api/gateway/sessions/{session_id}/prompt_cache/preparePOST /api/gateway/sessions/{session_id}/prompt_cache/rebuildPOST /api/gateway/sessions/{session_id}/prompt_cache/clear
These routes derive a deterministic bounded namespace/key from session_id,
bundle_id, bundle_version, flow_id, provider, model, optional
template_id, and version. The private hash also includes the authenticated
principal scope, so two hosted users using the same session id/provider/model do
not collide in a shared provider control plane; the returned identity remains
portable app-level data and does not expose that private scope. These routes
expose three honest modes:
unsupported: provider/model does not expose prompt-cache support; responses includesupported=false,ok=false, and capabilities.keyed: gateway returns a stableruntime_hint/prompt_cache_keyfor Runtime/Core injection, but does not claim module preparation occurred.local_control_plane: gateway uses supported provider operations such asprepare_modules,fork,set,clear, andstats.
status is read-only. prepare accepts optional modules (system_prompt,
workflow_instructions, tools, pinned_attachments) and returns either
provider operation results or a key hint. rebuild is clear-plus-prepare for
providers that expose clear controls.
Durable bloc exact-reuse endpoints:
POST /api/gateway/blocs/upsert_textGET /api/gateway/blocs/recordGET /api/gateway/blocsPOST /api/gateway/blocs/deleteGET /api/gateway/blocs/kv/manifestGET /api/gateway/blocs/kv/listPOST /api/gateway/blocs/kv/ensurePOST /api/gateway/blocs/kv/loadPOST /api/gateway/blocs/kv/deletePOST /api/gateway/blocs/kv/prune
These routes are the primary app-facing durable prompt-cache path:
- create or identify a durable text bloc;
- ensure or load a KV artifact for a target local provider/model;
- use the returned
prompt_cache_bindingin later Runtime-backed generation; - list/delete/prune artifacts without reaching into provider-private cache state.
They delegate through Runtime's public AbstractCore host facade rather than
proxying Core directly. They are operator-style host controls, so the routes
themselves are not ledgered run execution; the ledgered exact-reuse path is the
later LLM_CALL.params.prompt_cache_binding used inside real Runtime runs.
Host-local prompt-cache export/import admin aliases:
GET /api/gateway/prompt_cache/savedPOST /api/gateway/prompt_cache/savePOST /api/gateway/prompt_cache/load
These remain explicitly local/operator-oriented:
- the route paths are compatibility aliases, but the implementation delegates to Runtime's public host facade:
saved->list_prompt_cache_exports(...)save->prompt_cache_export(...)load->prompt_cache_import(...)- local bundle/file runtimes store these exports under the Gateway data dir at
prompt_cache_exports/ - remote and hybrid runtimes return
code=prompt_cache_local_only - response payloads follow Runtime's host-local export/import contract, including
operation,local_only,artifact_*,capabilities, andprovider_response
Email inbox (operator UI; optional)¶
These endpoints power AbstractObserver’s Inbox → Email UI. They are account-scoped: the browser cannot supply arbitrary IMAP/SMTP host/user credentials. The gateway host must be configured with one or more email accounts (multi-account YAML or env vars).
Endpoints:
- GET /api/gateway/email/accounts
- GET /api/gateway/email/messages?account=…&mailbox=…&since=…&status=…&limit=…
- GET /api/gateway/email/messages/{uid}?account=…&mailbox=…&max_body_chars=…
- POST /api/gateway/email/send
Examples:
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/email/accounts"
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/email/messages?status=unread&since=7d&limit=20"
curl -sS -H "$AUTH" "$BASE_URL/api/gateway/email/messages/12345?max_body_chars=20000"
curl -sS -H "$AUTH" -H "Content-Type: application/json" \
-d '{"to":"you@example.com","subject":"Hello","body_text":"Hi!"}' \
"$BASE_URL/api/gateway/email/send"
Configuration notes (gateway host):
- Multi-account: set ABSTRACT_EMAIL_ACCOUNTS_CONFIG=/path/to/emails.yaml (recommended).
- Single-account env fallback: set ABSTRACT_EMAIL_IMAP_* and/or ABSTRACT_EMAIL_SMTP_*.
- The secret itself must be present in the env var referenced by *_PASSWORD_ENV_VAR (e.g. EMAIL_PASSWORD=...).
Evidence: src/abstractgateway/routes/gateway.py (/email/accounts|messages|send) which proxies to the Runtime AbstractCore comms facade.
Troubleshooting and common questions: faq.md.