Files
LangBot/dev-docs/architecture/application-api.md
T

119 lines
6.5 KiB
Markdown

# Application API foundation
The application package provides a callable business boundary inside Core. A
consumer supplies a trusted identity and operation arguments, then receives a
validated result or a stable application error. HTTP, MCP, the management
assistant and `lbctl` retain their existing entrypoints in this change; their
adoption of this boundary belongs in separate changes.
## Workspace operations
`ap.application_api.operation_catalog()` returns the explicit operation allowlist,
with version, permission, principal constraints, side effects, execution mode,
and JSON schemas for inputs and results. The catalog covers the existing
Workspace management capabilities:
| Area | Capabilities |
| --- | --- |
| Pipelines and agents | CRUD, metadata, extension configuration, migration preview/execute, diagnostic runs, run history and events |
| Models and providers | LLM/embedding/rerank CRUD and tests, defaults, discovery, provider credential authorization |
| Bots and platforms | CRUD, routes and dry runs, messages, administrators, adapter metadata and credential setup sessions |
| Knowledge | Bases, ingestion tasks, files, retrieval, engine schemas and parser discovery |
| Extensions | Plugin installation/configuration/assets/logs, MCP servers/resources, skills and files, tools |
| Workspace | Current workspace, language, membership, invitations, API keys and webhooks |
| Operations | Monitoring and exports, governance and audit, task status, Box visibility, setup wizard and storage statistics |
| Conversations | Management-assistant conversations/runs and Pipeline chat history, reset, connections and broadcast |
Service-backed operations reuse existing business signatures to build strict
Pydantic inputs. Only methods explicitly listed in `service_operations.py` are
exposed; adding a public service method does not publish an operation. Domain
configuration objects remain dictionaries because their schemas are owned by
providers, plugins or the existing resource services. Those services retain
validation, quotas, secret placeholder restoration and runtime side effects.
```python
# context is established by a trusted authenticator, never from request JSON.
result = await ap.application_api.execute(
'pipeline.get', context, {'pipeline_uuid': pipeline_uuid}
)
async for frame in ap.application_api.stream(
'agent.debug.stream', context,
{'agent_uuid': agent_uuid, 'payload': {'text': 'hello'}},
):
consume(frame)
```
The Workspace comes only from `RequestContext`. Each invocation checks the
operation permission and the current execution binding/generation, then carries
that tenant and its message language through the business call. Additional
identity constraints remain where required by the business service: membership,
interactive provider authorization, assistant conversations and Pipeline
migration require an account. API-key grants are not replaced by the creator's
role. Authentication, key revocation/expiry and current account membership must
be resolved by the trusted caller before constructing the context.
Secret reads require the corresponding secret-management permission. Mutating
operations preserve the domain's existing authorization and resource ownership
checks. Audit recording uses the existing Workspace configuration and bounded
writer, with operation identity and outcome; raw arguments are not copied into
the generic trace. Queued tasks retain their Workspace/generation and revalidate
runtime admission before accessing plugins.
`ApplicationAPIException.error` carries `code`, `message`, `status_code` and
optional structured `details`. Protocol adapters map that object to their own
response shape. Invalid inputs and outputs fail explicitly. Cancellation is not
converted into success, and writes are never automatically retried. Pipeline
run timeouts retain the existing `unknown` outcome: a timeout does not establish
that execution failed or was rolled back.
Streaming scopes live in isolated producer tasks with bounded queues. Closing
an Agent debug stream cancels its execution. Management-assistant streaming
retains its existing detached-run behavior; use the explicit stop operation to
cancel an assistant run. Consumers should close partially consumed iterators
with `contextlib.aclosing`.
## Execution-context operations
`ExecutionAPI` publishes the existing Core business actions available to an
installed plugin or a running processor. Its catalog describes each action's
input/output schema, streaming mode and required plugin/run scope. It includes
model and RAG access, tools, event replies and platform actions, state/history,
run control and interactions, and Box/file operations.
```python
from langbot.pkg.api.application.execution import ExecutionAPI, ExecutionAPIContext
api = ExecutionAPI(ap)
catalog = api.catalog()
context = ExecutionAPIContext(binding=trusted_installation_binding, run_id=run_id)
result = await api.invoke(operation_id, context, arguments)
```
The caller must supply the trusted installation binding established by Core.
The foundation invokes the existing secured action dispatcher, preserving
installation revision/grant checks, active placement and frozen run resources.
A run-bound context also verifies that the run belongs to that installation's
Workspace and plugin. Arguments cannot override the run ID or fall back to the
legacy plugin path by omitting it. Plugin-only operations remain explicit and
cannot be called with a run-bound context. Stream isolation also prevents one
consumer's context from escaping into another consumer's task.
## Scope and adoption
This foundation covers the Workspace and execution business capabilities listed
in its explicit catalogs. Plugin publishing to Space and Git synchronization
remain in their existing HTTP routes. Instance administration, account login/bootstrap, public ingress,
OAuth callbacks, transport assets and internal Runtime handshake/chunk/ping
messages remain with their owning boundaries. Composite HTTP response layouts
(such as a combined monitoring page) are consumer projections of these
operations. This does not add new platform APIs or new instance-level powers.
Existing routes do not call the new application dispatcher. No SDK protocol or `lbctl` command is
changed by this foundation.
Consumer adoption should verify the same operation through each selected
transport, including denied access, missing resources, invalid inputs,
cancellation and secret handling. The existing Core smoke exercises current
consumers; it does not by itself prove a new consumer integration.