DomainPluginService is the gRPC service for external domain plugins
Proto file: plugin/grpc/protocol/domain.proto
| Method | Request | Response | Streaming |
|---|---|---|---|
| Metadata | Empty | MetadataResponse | No |
| Initialize | InitializeRequest | InitializeResponse | No |
| Shutdown | Empty | Empty | No |
| HandleHTTP | HTTPRequest | HTTPResponse | No |
| HandleWebSocket | WebSocketMessage | WebSocketMessage | Bidirectional |
| Health | Empty | HealthResponse | No |
| ConfigSchema | Empty | ConfigSchemaResponse | No |
| RegisterGlyphs | Empty | GlyphDefResponse | No |
| ExecuteJob | ExecuteJobRequest | ExecuteJobResponse | No |
| ParseAxQuery | ParseAxQueryRequest | ParseAxQueryResponse | No |
Metadata returns plugin metadata
EmptyMetadataResponseInitialize initializes the plugin with config and ATS endpoint. Called once per process lifetime. Plugins must handle re-init: stop previous state first. See ADR-018 for the full lifecycle contract.
InitializeRequestInitializeResponseShutdown shuts down the plugin
EmptyEmptyHandleHTTP handles an HTTP request
HTTPRequestHTTPResponseHandleWebSocket handles a WebSocket connection (bidirectional streaming). QNTX sends PING messages on the incoming stream and expects PONG responses. Plugins must read the incoming stream and reply to PING with PONG. See ADR-018 for the keepalive contract.
WebSocketMessageWebSocketMessageHealth checks plugin health
EmptyHealthResponseConfigSchema returns the configuration schema for this plugin
EmptyConfigSchemaResponseRegisterGlyphs returns custom glyph type definitions provided by this plugin
EmptyGlyphDefResponseExecuteJob executes an async job Used by Pulse to route jobs to plugin-registered handlers
ExecuteJobRequestExecuteJobResponseParseAxQuery parses an Ax query string and returns the AST as JSON. Used by kern (OCaml parser) to replace the Rust WASM parser path.
ParseAxQueryRequestParseAxQueryResponse| Field | Type | Description |
|---|---|---|
| name | string | - |
| version | string | - |
| qntx_version | string | - |
| description | string | - |
| author | string | - |
| license | string | - |
| Field | Type | Description |
|---|---|---|
| ats_store_endpoint | string | Service endpoints the plugin can call back to QNTX core Format: "host:port" for TCP (e.g., "localhost:50051") Note: Database access is not provided - database is a hard boundary. Plugins should use attestations via ats_store_endpoint instead. ats_store_endpoint: gRPC endpoint for ATSStoreService Provides: Attestation creation, querying, and streaming |
| queue_endpoint | string | queue_endpoint: gRPC endpoint for QueueService Provides: Async job enqueue, status, and management |
| auth_token | string | auth_token: Simple token for authenticating with service endpoints Plugins must include this token in all service RPC calls |
| config | map<string, string> | Plugin-specific configuration values Simple types (string, int, bool) passed as string representations Complex types (maps, slices) JSON-encoded as strings Plugins should parse and validate values appropriate to their schema |
| schedule_endpoint | string | schedule_endpoint: gRPC endpoint for ScheduleService Provides: Runtime schedule creation, pause, resume, delete |
| file_service_endpoint | string | file_service_endpoint: gRPC endpoint for FileService Provides: Read stored files (for multimodal attachments) |
| llm_endpoint | string | llm_endpoint: gRPC endpoint for LLMService Provides: Provider-agnostic LLM chat (routed through core to provider plugins) |
| embedding_endpoint | string | embedding_endpoint: gRPC endpoint for EmbeddingService Provides: Text-to-vector embedding generation |
| vector_search_endpoint | string | vector_search_endpoint: gRPC endpoint for VectorSearchService Provides: Nearest-neighbor search over dense vector indexes (ADR-016) |
| ground_endpoint | string | ground_endpoint: gRPC endpoint for GroundService Provides: Write attestations to Ground's deferred news database |
| search_endpoint | string | search_endpoint: gRPC endpoint for SearchService Provides: Full-text search over indexed documents (routed through core to provider plugin) |
| fetch_endpoint | string | fetch_endpoint: gRPC endpoint for FetchService Provides: HTTP GET with attestation — QNTX fetches and attests, plugins stay pure orchestration |
| Field | Type | Description |
|---|---|---|
| method | string | - |
| path | string | - |
| headers | HTTPHeader | - |
| body | bytes | - |
| Field | Type | Description |
|---|---|---|
| status_code | int32 | - |
| headers | HTTPHeader | - |
| body | bytes | - |
HTTPHeader represents an HTTP header with support for multiple values. HTTP headers can have multiple values (e.g., Set-Cookie, Accept).
| Field | Type | Description |
|---|---|---|
| name | string | - |
| values | string | - |
| Field | Type | Description |
|---|---|---|
| healthy | bool | - |
| message | string | - |
| details | map<string, string> | - |
| Field | Type | Description |
|---|---|---|
| fields | map<string, ConfigFieldSchema> | Map of config field name to schema definition |
| Field | Type | Description |
|---|---|---|
| type | string | Field type: "string", "number", "boolean", "array" |
| description | string | Human-readable description of what this field does |
| default_value | string | Default value (as string representation) |
| required | bool | Whether this field is required |
| min_value | string | For number types: minimum value (optional) |
| max_value | string | For number types: maximum value (optional) |
| pattern | string | For string types: validation pattern (regex, optional) |
| element_type | string | For array types: element type (optional) |
ScheduleInfo describes a schedule that a plugin wants QNTX to create
| Field | Type | Description |
|---|---|---|
| handler_name | string | - |
| interval_seconds | int32 | - |
| enabled_by_default | bool | - |
| description | string | - |
| ats_code | string | - |
InitializeResponse is returned by Initialize RPC
| Field | Type | Description |
|---|---|---|
| handler_names | string | Handler names this plugin can execute Examples: ["python.script", "python.webhook", "ixgest.git"] Empty list means plugin provides no async handlers (backward compatible) |
| schedules | ScheduleInfo | Schedules this plugin wants QNTX to create QNTX will auto-create schedule.Job entries for these |
| llm_provider | bool | llm_provider indicates this plugin implements LLMProvider (Chat RPC). Core registers it as an LLM backend in the service mesh. |
| watchers | WatcherRegistration | Watchers this plugin wants registered on its behalf. Core creates watchers with action_type=plugin_execute targeting this plugin. On match, core calls ExecuteJob with the matching attestation as payload. |
| vector_search_provider | bool | vector_search_provider indicates this plugin implements VectorSearchService (ADR-016). Core registers it as a vector search backend in the service mesh. |
| search_provider | bool | search_provider indicates this plugin implements SearchProvider (Search RPCs). Core registers it as the search backend in the service mesh. |
| embedding_provider | bool | embedding_provider indicates this plugin implements EmbeddingService (Embed, BatchEmbed, Cluster, ModelInfo RPCs). Core routes embedding calls to it instead of using the builtin CGO/FFI path. |
| http_routes | RouteInfo | http_routes lists the HTTP endpoints this plugin handles via HandleHTTP. Core exposes these under /api/{plugin}/ and makes them discoverable via GET /api/plugins/routes. |
| python_provider | bool | python_provider indicates this plugin can execute Python code. Core registers "py" glyph type when any loaded plugin declares this. |
RouteInfo describes an HTTP endpoint a plugin handles
| Field | Type | Description |
|---|---|---|
| method | string | - |
| path | string | - |
| description | string | - |
WatcherRegistration declares a watcher a plugin wants core to manage. Core creates/updates the watcher on Initialize and routes matches to the plugin via ExecuteJob.
| Field | Type | Description |
|---|---|---|
| id | string | - |
| handler_name | string | - |
| subjects | string | - |
| predicates | string | - |
| contexts | string | - |
| actors | string | - |
| max_fires_per_second | int32 | - |
ExecuteJobRequest is sent to plugins to execute an async job
| Field | Type | Description |
|---|---|---|
| job_id | string | - |
| handler_name | string | - |
| payload | bytes | - |
ExecuteJobResponse is returned after job execution
| Field | Type | Description |
|---|---|---|
| success | bool | - |
| error | string | - |
| result | bytes | - |
| progress_current | int32 | Progress tracking (optional) - Pulse updates job.Progress |
| progress_total | int32 | - |
| cost_actual | double | Cost tracking (optional) - Pulse updates job.CostActual |
| log_entries | JobLogEntry | Execution logs — written to task_logs table by PluginProxyHandler |
| plugin_version | string | Plugin version that produced this result (e.g., "0.2.14") |
JobLogEntry is a single log line from plugin job execution
| Field | Type | Description |
|---|---|---|
| timestamp | string | - |
| level | string | - |
| message | string | - |
| stage | string | - |
| metadata | string | - |
GlyphDefResponse contains custom glyph type definitions from a plugin
| Field | Type | Description |
|---|---|---|
| glyphs | GlyphDef | - |
GlyphDef defines a custom glyph type provided by a plugin
| Field | Type | Description |
|---|---|---|
| symbol | string | Symbol is the glyph identifier (e.g., "⚗" for a chemistry plugin) |
| title | string | Title is the human-readable name shown in the title bar |
| label | string | Label is a short identifier for logs and the spawn menu |
| content_path | string | ContentPath is the HTTP path (relative to /api/{plugin}/) that returns the HTML fragment for this glyph's content area |
| css_path | string | CSSPath is an optional HTTP path to a stylesheet for this glyph type |
| default_width | int32 | DefaultWidth and DefaultHeight in pixels (0 = use system default) |
| default_height | int32 | - |
| module_path | string | ModulePath is the HTTP path to a JS/TS module exporting a render function. When set, the frontend dynamically imports it with SDK injection, bypassing the server-rendered HTML pipeline. |
ParseAxQueryRequest is sent to a parser plugin to parse an Ax query string.
| Field | Type | Description |
|---|---|---|
| query | string | - |
ParseAxQueryResponse contains the parsed result as JSON matching rustAxQuery shape.
| Field | Type | Description |
|---|---|---|
| result | bytes | - |
| error | string | - |