Type Aliases
ProtoLink centralizes the small vocabularies shared by agents, transports, request specifications, LLM adapters, state modules, models, security declarations, and structured flows. These aliases make accepted values visible to type checkers and IDEs while keeping public signatures consistent across packages.
The literal and alias vocabulary used to keep roles, transports, backends, MIME types, auth schemes, state modules, and flow targets stable across public APIs.
protolink.typesAgentRoleTypeTransportTypeMimeTypeStateModeHow the typing layer works
Every alias on this page is exported from protolink.types:
from protolink.types import (
AgentRoleType,
BackendType,
ContentType,
FlowTarget,
HttpAuthScheme,
HttpMethod,
LLMProvider,
LLMType,
MessageRoleType,
MimeType,
PartType,
ReasoningLevel,
RequestSourceType,
SecuritySchemeType,
StateMode,
TransportType,
)
Most are Literal aliases. They help static type checkers reject unsupported spelling and let IDEs offer completion, but typing.Literal does not validate a value at runtime. Whether an unknown string raises, falls back, or is preserved depends on the consuming constructor or factory and is called out below.
FlowTarget is different: it is stored as a string forward reference so importing protolink.types does not import Agent and Flow and create a circular dependency.
The aliases are exported from protolink.types, not from the top-level protolink package. Importing from the central types package is the stable public path; protolink.types.types is the defining implementation module.
Table of Contents
Topology
AgentRoleType
AgentRoleType: TypeAlias = Literal[
"gateway",
"interface",
"observer",
"orchestrator",
"worker",
]Agent roles describe why an agent exists in the system topology. They do not describe its tools, memory, model, transport, policy, or actual capabilities. AgentCard.role uses this alias as native runtime metadata.
Values
| Role | Architectural purpose | Typical responsibilities |
|---|---|---|
gateway | External trust and protocol boundary | Ingress/egress, authentication, authorization, validation, rate limits, redaction, and protocol translation |
interface | User- or application-facing interaction surface | Presenting input/output, adapting product interactions, and mediating a focused interface without owning global orchestration |
observer | Read-only system visibility | Logs, metrics, traces, evaluation, auditing, compliance, and human review |
orchestrator | Global coordination | Interpreting goals, selecting agents, managing branches/retries/termination, and aggregating results |
worker | Concrete task execution | Domain work, tool use, retrieval, computation, and producing outputs |
Used by
AgentCard.roleAgentRoleTypedefault: "worker"Labels the agent's responsibility for native discovery and application logic.
Role values do not enable behavior or grant authority. A gateway still needs an authenticator and policy; an observer is read-only only if the application enforces that boundary; a worker may still have an LLM or tools.
AgentCard.role is currently retained in memory but omitted by the native AgentCard.to_dict() and from_dict() paths. See the Models reference for the full card behavior.
Examples
from protolink import AgentCard
from protolink.types import AgentRoleType
role: AgentRoleType = "orchestrator"
card = AgentCard(
name="coordinator",
description="Routes work across a specialist agent team.",
url="runtime://coordinator",
role=role,
)
Role design notes
The role vocabulary is intentionally small and stable:
- An orchestrator owns global flow, but should normally delegate domain execution.
- A worker produces concrete results, but does not need authority over system-wide routing.
- An observer watches or evaluates execution without being part of the decision path.
- A gateway marks an external boundary where trust, policy, and protocol adaptation commonly belong.
- An interface provides a user or application interaction surface without necessarily being the perimeter security boundary.
- Tools, retrieval, code execution, model access, and memory remain capabilities or implementation details rather than roles.
Systems may omit roles they do not need. Applications can maintain additional domain-specific role metadata, but the public alias remains the common ProtoLink vocabulary.
Orchestrator
An orchestrator owns the global flow of execution. It interprets high-level goals, selects and invokes workers, manages branching and retries, decides when work is complete, and aggregates intermediate results.
It normally should not perform every domain operation itself. Keeping planning and coordination separate from privileged or specialized execution makes policy, testing, and failure recovery easier to reason about.
Worker
A worker performs concrete work when invoked. It may call tools, retrieve information, run a model, transform data, or produce artifacts, but it does not inherently own global routing or task-system policy.
Worker is the default AgentCard role because a focused execution unit is the most common agent shape.
Observer
An observer has visibility into execution for monitoring, evaluation, auditing, compliance, or human review. Typical observers collect events, metrics, traces, and outputs.
The role name alone does not make an agent read-only. Applications must still withhold write tools and enforce a policy that prevents the observer from changing runtime state.
Gateway
A gateway marks the boundary between external systems and the agent mesh. It commonly accepts inbound requests, translates protocols, authenticates principals, enforces authorization and limits, validates or redacts content, and returns the final external response.
A gateway is not automatically an orchestrator: it may hand accepted work to a coordinator without deciding the execution plan itself.
Interface
An interface is a user- or application-facing interaction layer inside the topology. It can adapt a product-specific input or presentation model to ProtoLink tasks without necessarily owning perimeter security or global orchestration.
Use gateway when the trust and protocol boundary is the defining responsibility; use interface when interaction and presentation are the defining responsibility.
Protocols and requests
BackendType
BackendType: TypeAlias = Literal[
"starlette",
"fastapi",
]Selects the ASGI backend used by HTTPTransport to bind transport-neutral endpoint declarations to concrete server routes.
Values
| Backend | Behavior |
|---|---|
starlette | Lightweight default backend. Request parsers and ProtoLink model normalization remain explicit. |
fastapi | FastAPI-backed routes with optional schema validation through validate_schema=True. |
Used by
HTTPTransport.backendBackendTypedefault: "starlette"Chooses the backend instance created during HTTP transport initialization.
HTTPTransport lowercases the supplied value and selects FastAPI only when it equals fastapi. Any other runtime string currently falls back to Starlette instead of raising. Static checking is therefore stricter than the constructor's runtime behavior.
The chosen backend requires its corresponding optional dependency. FastAPI schema validation may require additional Pydantic support.
Examples
from protolink.transport import HTTPTransport
from protolink.types import BackendType
backend: BackendType = "fastapi"
transport = HTTPTransport(
url="http://localhost:8000",
backend=backend,
validate_schema=True,
)
ContentType
ContentType: TypeAlias = Literal[
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data",
"text/plain",
]Media-type vocabulary for outbound request and response headers. ClientRequestSpec.content_type controls Content-Type; ClientRequestSpec.accept controls Accept.
Values
| Content type | Intended wire content |
|---|---|
application/json | JSON request or response documents |
application/x-www-form-urlencoded | URL-encoded form data |
multipart/form-data | Multipart form and file upload bodies |
text/plain | Unstructured text |
Used by
ClientRequestSpec.content_typeContentType | Nonedefault: NoneOptional outbound
Content-Typeheader.ClientRequestSpec.acceptContentType | Nonedefault: NoneOptional outbound
Acceptheader describing the expected response media type.
The alias does not select a request encoder. Current HTTPTransport.send() serializes request_source="body" through its JSON path even when another content-type header is declared. Form and multipart payload construction requires transport or application handling beyond this alias.
ContentType is the narrow request-header vocabulary. MimeType is the broader media capability vocabulary advertised by AgentCard.input_formats and output_formats.
HttpAuthScheme
HttpAuthScheme: TypeAlias = Literal[
"bearer",
"basic",
"digest",
"hmac",
"negotiate",
"ntlm",
"aws4auth",
"hawk",
"edgegrid",
]Names the HTTP authentication scheme inside a SecurityScheme whose top-level auth_type is http. The value describes a scheme; it does not construct an authenticator or credentials.
Values
| Scheme | Meaning |
|---|---|
bearer | Bearer token carried in the Authorization header, commonly OAuth access tokens or JWTs |
basic | Base64-encoded username and password credentials |
digest | HTTP Digest challenge-response authentication |
hmac | Application-defined HMAC request signing |
negotiate | SPNEGO/Kerberos negotiation |
ntlm | NT LAN Manager authentication |
aws4auth | AWS Signature Version 4 |
hawk | Hawk message authentication code scheme |
edgegrid | Akamai EdgeGrid request signing |
Used by
SecurityScheme.auth_schemeHttpAuthScheme | NonerequiredDescribes the HTTP-specific scheme exposed by an authenticator.
ProtoLink includes built-in bearer and basic authenticators. The wider literal set allows custom authenticators and discovery metadata; names such as digest, HMAC, Negotiate, NTLM, AWS4Auth, Hawk, and EdgeGrid do not imply a built-in implementation.
Examples
from protolink.security.auth import SecurityScheme
from protolink.types import HttpAuthScheme
scheme: HttpAuthScheme = "bearer"
security = SecurityScheme(
auth_type="http",
auth_scheme=scheme,
description="Bearer JWT authentication",
)
HttpMethod
HttpMethod: TypeAlias = Literal[
"GET",
"POST",
"DELETE",
"PUT",
"PATCH",
]HTTP-style verbs shared by inbound EndpointSpec declarations and outbound ClientRequestSpec operations. Keeping the same alias at both boundaries prevents client and server request definitions from drifting.
Values
| Method | Typical use |
|---|---|
GET | Retrieve a resource or status without a request body |
POST | Submit work, create a resource, or invoke a control operation |
DELETE | Remove or cancel a resource |
PUT | Replace a resource |
PATCH | Partially update a resource |
The literal values are uppercase. Dataclass construction does not normalize or validate method strings, so lowercase values may reach a backend despite failing static checking.
Examples
from protolink.models import EndpointSpec
from protolink.types import HttpMethod
method: HttpMethod = "POST"
endpoint = EndpointSpec(
name="create_task",
path="/tasks/",
method=method,
handler=handle_task,
request_source="body",
)
RequestSourceType
RequestSourceType: TypeAlias = Literal[
"none",
"body",
"query_params",
"form",
"headers",
"path_params",
"request",
]Describes which part of an inbound or outbound request supplies an operation's data. Endpoint backends use it to choose handler input; clients use it to choose how request data is marshalled.
Values
| Source | Intended value |
|---|---|
none | No request-derived handler argument |
body | Parsed JSON request body |
query_params | URL query-parameter mapping |
form | Form fields |
headers | Request-header mapping |
path_params | Route-parameter mapping |
request | Transport-neutral EndpointRequest containing body, query, path, headers, method, URL, and authenticated principal ID |
Used by
EndpointSpec.request_sourceRequestSourceTypedefault: "none"Selects the value passed to an inbound endpoint handler.
ClientRequestSpec.request_sourceRequestSourceTypedefault: "body"Selects how outbound request data is marshalled by a transport.
Current Starlette and FastAPI endpoint binders extract body, query parameters, headers, path parameters, and the complete request view. The alias includes form, but those binders do not currently implement form extraction; it falls through to no payload.
Current HTTP client marshalling sends data only for body and query_params. Other source names are primarily server-side declarations or require a transport-specific implementation.
SecuritySchemeType
SecuritySchemeType: TypeAlias = Literal[
"apiKey",
"http",
"oauth2",
"mutualTLS",
"openIdConnect",
]Top-level authentication scheme categories used by AgentCard.security_schemes and SecurityScheme.auth_type. Names follow the OpenAPI-style discovery vocabulary.
Values
| Category | Meaning |
|---|---|
apiKey | API key supplied in a header, query parameter, or another declared location |
http | HTTP authentication with a nested HttpAuthScheme, such as bearer or basic |
oauth2 | OAuth 2.0 flow declaration |
mutualTLS | Client certificate authentication |
openIdConnect | OpenID Connect discovery |
apiKey, mutualTLS, and openIdConnect are case-sensitive literal values. The alias does not accept snake-case alternatives such as api_key.
Adding a scheme to an AgentCard advertises it but does not protect endpoints. Configure an Authenticator and transport security separately.
Examples
from protolink import AgentCard
from protolink.types import SecuritySchemeType
scheme_type: SecuritySchemeType = "http"
card = AgentCard(
name="secure-agent",
description="Agent protected by bearer authentication.",
url="https://agent.example",
security_schemes={
scheme_type: {
"type": "http",
"scheme": "bearer",
}
},
)
TransportType
TransportType: TypeAlias = Literal[
"http",
"websocket",
"sse",
"json-rpc",
"sse-json-rpc",
"grpc",
"runtime",
]Built-in transport names used by agent configuration, discovery cards, registry clients, and the lazy transport factory.
Values
| Transport | Factory mapping | Communication model |
|---|---|---|
http | HTTPTransport | HTTP request/response |
websocket | WebSocketTransport | Persistent bidirectional connection with streaming |
sse | SSEJSONRPCTransport | Server-Sent Events using JSON-RPC-style envelopes |
json-rpc | SSEJSONRPCTransport | Alias for the SSE JSON-RPC implementation |
sse-json-rpc | SSEJSONRPCTransport | Explicit alias for the SSE JSON-RPC implementation |
grpc | GRPCTransport | gRPC unary and unary-stream JSON envelopes over grpc.aio |
runtime | RuntimeTransport | In-process agent composition without network I/O |
Used by
AgentCard.transportTransportTypedefault: "http"Advertises the primary route for an agent.
Agent.transportTransportType | Transport | Nonedefault: NoneSelects a built-in factory name or accepts an already constructed transport.
get_transport()strLazily resolves names case-insensitively and constructs the registered class.
register_transport() can add runtime transport names that are not part of this static literal alias. Conversely, a literal value may still require an optional dependency, valid URL, credentials, or TLS configuration before it can operate.
Secure deployments continue to use the same transport literal. Choose https:// for HTTP, SSE, and JSON-RPC aliases; wss:// for WebSocket; and grpcs:// for gRPC.
Examples
from protolink.transport import get_transport
from protolink.types import TransportType
transport_name: TransportType = "runtime"
transport = get_transport(
transport_name,
url="runtime://local-agent",
)
LLM classification
LLMProvider
LLMProvider: TypeAlias = Literal[
"anthropic",
"deepseek",
"gemini",
"grok",
"huggingface",
"llama.cpp-local",
"llama.cpp-server",
"lmstudio",
"mock",
"ollama",
"openai",
"openai-compatible",
"vllm",
]Provider identifier stored on concrete LLM adapters and mirrored by the lazy LLM factory's registered names.
Values
| Provider | Adapter and deployment |
|---|---|
anthropic | AnthropicLLM, Anthropic Messages API |
deepseek | DeepSeekLLM, DeepSeek Chat Completions API |
gemini | GeminiLLM, Google GenAI API |
grok | GrokLLM, xAI Chat Completions API |
huggingface | HuggingFaceLLM, Hugging Face Inference API |
llama.cpp-local | LlamaCPPLocalLLM, in-process GGUF execution |
llama.cpp-server | LlamaCPPServerLLM, remote or local llama-server |
lmstudio | LMStudioLLM, LM Studio's OpenAI-compatible server |
mock | MockLLM, deterministic offline testing |
ollama | OllamaLLM, Ollama /api/chat server |
openai | OpenAILLM, OpenAI Responses API |
openai-compatible | OpenAICompatibleLLM, /v1/chat/completions and /v1/models server |
vllm | VLLMLLM, vLLM's OpenAI-compatible server |
Used by
LLM.providerClassVar[LLMProvider]Concrete adapter identifier used in metrics, events, prompts, and diagnostics.
protolink.types.LLMProvider is a Literal alias. protolink.llms.factory.LLMProvider is a separate string enum containing the same names. They serve different typing roles and are not the same object.
Pass provider names as strings to create_llm(). The current factory lowercases string input, rejects unknown names with ValueError, and lazily imports the selected adapter. Its separate enum instances are not currently normalized correctly.
Examples
from protolink import create_llm
from protolink.types import LLMProvider
provider: LLMProvider = "openai"
llm = create_llm(provider, model="gpt-4o-mini")
LLMType
LLMType: TypeAlias = Literal[
"api",
"local",
"server",
]Classifies where an LLM adapter executes or connects. It is adapter metadata rather than a factory selector.
Values
| Type | Meaning | Examples |
|---|---|---|
api | Remote hosted provider API | OpenAI, Anthropic, Gemini, DeepSeek, Grok, Hugging Face |
local | Model executes inside the Python process | LlamaCPPLocalLLM |
server | Adapter connects to a model server managed separately | Ollama, llama.cpp server, LM Studio, vLLM, OpenAI-compatible servers |
Used by
LLM.model_typeClassVar[LLMType]Set by API, local, and server base classes for introspection and shared runtime behavior.
create_llm() selects a concrete adapter with LLMProvider values such as openai or ollama. It does not accept api, local, or server as provider selectors.
Examples
from protolink import create_llm
api_llm = create_llm(
"openai",
model="gpt-4o-mini",
)
local_llm = create_llm(
"llama.cpp-local",
model="./model.gguf",
)
server_llm = create_llm(
"ollama",
base_url="http://localhost:11434",
model="llama3",
)
print(api_llm.model_type) # "api"
print(local_llm.model_type) # "local"
print(server_llm.model_type) # "server"
ReasoningLevel
ReasoningLevel: TypeAlias = Literal[
"none",
"low",
"medium",
"high",
]Selects the reasoning instruction family compiled into the shared LLM system prompt. It is an instruction-level configuration, not a guarantee that a provider exposes private chain-of-thought or follows a particular reasoning depth.
Values
| Level | Prompt behavior |
|---|---|
none | Omits the optional reasoning instruction block |
low | Adds concise reasoning guidance |
medium | Adds more structured multi-step guidance |
high | Adds the most detailed reasoning guidance in the built-in prompt family |
Used by
LLM.__init__.reasoningReasoningLeveldefault: "none"Stored privately as
_reasoningand consulted when the system prompt is built.
The base LLM constructor accepts this value, but current concrete provider constructors do not expose a public reasoning parameter. It is mainly relevant to custom subclasses.
The base class stores the value as supplied. An unknown runtime string currently resolves to an empty reasoning instruction because prompt maps use a default lookup.
Messages and media
MessageRoleType
MessageRoleType: TypeAlias = Literal[
"agent",
"assistant",
"system",
"user",
]Sender roles for task-level Message objects. The alias preserves the distinction between the broader agent runtime and its embedded LLM assistant.
Values
| Role | Meaning |
|---|---|
user | Human or calling-client input |
agent | Response or control message produced by the agent runtime |
assistant | Response attributed specifically to an embedded LLM assistant |
system | System-level instruction or control context |
Used by
Message.roleMessageRoleTypedefault: "user"Serialized verbatim in task protocol messages.
Message does not validate the literal at construction or deserialization. Prefer Message.user(), Message.agent(), and Message.assistant() when a convenience constructor matches the intended role.
Examples
from protolink import Message
from protolink.types import MessageRoleType
role: MessageRoleType = "system"
system_message = Message(role=role).add_text("Answer concisely.")
user_message = Message.user("Hello")
agent_message = Message.agent("Hello!")
assistant_message = Message.assistant("Draft response")
MimeType
MimeType: TypeAlias = Literal[
"text/plain",
"text/markdown",
"text/html",
"application/json",
"image/png",
"image/jpeg",
"image/webp",
"audio/wav",
"audio/mpeg",
"audio/ogg",
"video/mp4",
"video/webm",
"application/pdf",
]Media capability vocabulary advertised by AgentCard.input_formats and AgentCard.output_formats. It tells discovery consumers what an agent says it can accept or produce; it does not transcode or inspect content.
Values
| Category | MIME types |
|---|---|
| Text | text/plain, text/markdown, text/html |
| Structured data | application/json |
| Images | image/png, image/jpeg, image/webp |
| Audio | audio/wav, audio/mpeg, audio/ogg |
| Video | video/mp4, video/webm |
| Documents | application/pdf |
Used by
AgentCard.input_formatslist[MimeType]default: ["text/plain"]Media formats the agent advertises as accepted input.
AgentCard.output_formatslist[MimeType]default: ["text/plain"]Media formats the agent advertises as possible output.
AgentCard stores format strings without runtime validation and does not reject content that falls outside the advertised list. Transports and application handlers remain responsible for actual media parsing.
Examples
from protolink import AgentCard
from protolink.types import MimeType
input_formats: list[MimeType] = [
"text/plain",
"application/json",
"image/png",
]
card = AgentCard(
name="multimedia-agent",
description="Analyzes text, JSON, and PNG images.",
url="http://localhost:8000",
input_formats=input_formats,
output_formats=["text/plain", "application/json"],
)
PartType
PartType: TypeAlias = Literal[
"text",
"json",
"file",
"bytes",
"uri",
"image",
"audio",
"video",
"status",
"error",
"warning",
"route",
"decision",
"infer",
"infer_output",
"tool_call",
"tool_output",
"trace",
"summary",
"confidence",
"schema",
]Discriminator vocabulary for atomic Part content inside messages and artifacts. The selected value tells agents, flows, transports, and renderers how the accompanying content should be interpreted.
Core content
| Type | Meaning | Typical content |
|---|---|---|
text | Plain text | User messages and simple responses |
json | Structured data | JSON-compatible mappings and lists |
Files and references
| Type | Meaning | Typical content |
|---|---|---|
file | File attachment or descriptor | File metadata plus represented data |
bytes | Raw binary data | Upload or generated binary content |
uri | Resource reference | URL, object-store URI, or other resolvable identifier |
Media
| Type | Meaning | Typical content |
|---|---|---|
image | Image content or reference | Screenshots, charts, and visual inputs |
audio | Audio content or reference | Voice input and generated audio |
video | Video content or reference | Video messages and recordings |
Control and metadata
| Type | Meaning | Typical content |
|---|---|---|
status | Runtime status update | State plus optional message |
error | Structured failure | Code, message, and retryability |
warning | Non-fatal issue | Warning code or explanatory data |
route | Explicit flow route selection | Typed RouteDecision |
decision | General structured branching decision | Typed RouteDecision |
LLM operations
| Type | Meaning | Typical content |
|---|---|---|
infer | Instruction to invoke the agent's LLM | Prompt, user context, output schema, and metadata |
infer_output | Result of an LLM inference | Text or structured output |
Tool operations
| Type | Meaning | Typical content |
|---|---|---|
tool_call | Tool invocation request | Typed tool name, arguments, and correlation ID |
tool_output | Tool execution result | Correlated result or structured error |
Reasoning and observability
| Type | Meaning | Typical content |
|---|---|---|
trace | Execution trace | Debug or step-level observability data |
summary | Condensed context or result | Summary text or structured summary |
confidence | Reliability indicator | Score plus optional explanation |
Contracts
| Type | Meaning | Typical content |
|---|---|---|
schema | Schema definition | Validation or API contract data |
Used by
Part.typePartTyperequiredSerialized discriminator used to dispatch structured content.
Part preserves arbitrary content during direct construction. Factories such as Part.error(), Part.route(), Part.tool_call(), and Part.infer() create the expected shape, while Part.from_dict() hydrates selected structured types.
The literal is the supported ProtoLink vocabulary for static checking. A runtime Part can still carry an unknown string because the dataclass does not validate it, but built-in agents, transports, or renderers may not understand that value.
Examples
from protolink import Part
from protolink.types import PartType
part_type: PartType = "text"
text = Part(type=part_type, content="Hello, world!")
structured = Part.json({"key": "value"})
failure = Part.error(
"validation_error",
"The location field is required.",
)
route = Part.route(
"review",
reason="Draft is ready for quality review.",
)
- Use
textfor ordinary user-visible text andjsonfor structured application data. - Use
tool_callandtool_outputfor executable tool interactions rather than placing tool arguments in a generic JSON part. - Use
inferwhen a task explicitly asks an agent to run its LLM, andinfer_outputfor the resulting content. - Use
routeordecisionfor structured flow branching instead of parsing labels from prose. - Use
error,warning, andstatusfor inspectable control information.
State
StateMode
StateMode: TypeAlias = Literal[
"conversation",
"tools",
"task",
"flow",
]Names the persistent state modules an agent can enable. Each selected mode creates a module over the agent's shared storage backend.
Values
| Mode | Persisted concern |
|---|---|
conversation | LLM conversation history partitioned by session |
tools | Tool-specific persistent state |
task | Task-related metadata and operational state |
flow | Structured-flow progress and checkpoint data |
Used by
Agent.statelist[StateMode] | State | Nonedefault: NoneEnables selected modules or accepts a preconfigured
Statecontainer.State.enabledlist[StateMode]requiredInstantiates modules from the internal state registry.
Unlike many model fields, the State constructor checks each name against its registry and raises ValueError for an unknown module.
Enabling a mode creates access to its state store; it does not imply that every framework operation writes to every store automatically. Conversation state has the deepest automatic integration with agent inference and session IDs.
Examples
from protolink import Agent
from protolink.types import StateMode
modes: list[StateMode] = ["conversation", "tools"]
agent = Agent(
card=card,
llm=llm,
storage=storage,
state=modes,
)
Structured flows
FlowTarget
FlowTarget: TypeAlias = "Agent | str | Flow"Polymorphic execution target used by Pipeline, Parallel, Router, and Graph. A flow can call a local agent, dispatch to a remote or registry-discovered agent named by a string, or recursively execute another flow.
Variants
Agentprotolink.agents.base.AgentExecutes locally with
await agent.handle_task(task). Before dispatch, the flow can bridge a previous non-executable result into a new infer message for the downstream agent.stragent URL or registry nameDirect URLs are sent through an
AgentClient. Other strings are resolved by agent name through the configured registry, then dispatched remotely.Flowprotolink.flows.base.FlowExecutes recursively. Missing client and registry configuration is inherited from the parent flow before the nested flow runs.
Used by
Pipeline.stepslist[FlowTarget]Ordered sequential execution targets.
Parallel.brancheslist[FlowTarget]Concurrent fan-out targets whose new messages and artifacts are merged back into one task.
Router.routesdict[str, FlowTarget]Branch map selected by a structured route decision.
Graph.nodesdict[str, FlowTarget]Named graph execution nodes.
The exact definition is one string, "Agent | str | Flow". Agent and Flow are imported only under TYPE_CHECKING, avoiding circular imports when protolink.types is loaded at runtime.
The centralized flow dispatcher checks concrete targets with isinstance() and raises ValueError for unsupported objects. The string forward reference itself cannot perform validation or provide useful typing.get_args() runtime introspection.
The current flow resolver recognizes http://, https://, ws://, wss://, and runtime:// strings as direct URLs. Other strings are treated as registry names.
Examples
from protolink import Agent
from protolink.flows import Parallel, Pipeline
from protolink.types import FlowTarget
researcher: Agent = ...
quality_url = "https://quality.example"
review: FlowTarget = Parallel(
branches=[
researcher,
quality_url,
]
)
flow = (
Pipeline()
.add_step(researcher)
.add_step("writer_agent")
.add_step(review)
)
Why use these aliases?
Static safety
A type checker can catch unsupported values before execution:
from protolink.types import BackendType
backend: BackendType = "invalid" # Static type error
IDE completion
Literal aliases let an editor suggest valid values at call sites:
transport = HTTPTransport(
url="http://localhost:8000",
backend="", # IDE can suggest "starlette" or "fastapi"
)
Clear public signatures
Aliases communicate intent more precisely than an unrestricted string:
from protolink.types import LLMProvider
def build_model(provider: LLMProvider, model: str):
return create_llm(provider, model=model)
One source of truth
Consumers import shared definitions instead of duplicating literal unions:
from protolink.types import MimeType, SecuritySchemeType, TransportType
When ProtoLink adds or removes a built-in value, updating the alias updates type checking and generated documentation across every consumer.
Use aliases for annotations and editor support. Use a validating constructor, parser, registry, enum, or schema when untrusted runtime input must be rejected.
See also
- Models - fields that consume message, media, role, security, and transport aliases.
- Transports - built-in transport implementations and registration.
- Authentication - authenticators and security scheme models.
- LLMs - provider adapters, LLM types, and reasoning behavior.
- State - persistent state modules.
- Flows - execution semantics for
FlowTarget.