Status: Runnable
Define a Service
A Service Card is the root of your declaration. It names the components your service is built from, each pinned to an exact Card version, and the tables it records rows into. You write it in YAML whatever language the service is written in, and wyrd declare --check checks it without a server.
This page builds the support-desk Service from the quickstart. The finished files are in examples/support-desk-app/service/.
1. Write the components
Each component is its own Card file with an exact metadata.version. The support desk has an Agent and the Prompt it runs. The Agent points at the Prompt by relative path:
apiVersion: wyrd/v1
kind: Agent
metadata:
name: support-agent
version: 1.0.0
space: default
spec:
prompt: ./support-prompt.yaml
execution_route:
kind: wyrd_gateway
deployment: openai
tool_names: []
run_config:
max_iterations: 1
apiVersion: wyrd/v1
kind: Prompt
metadata:
name: support-prompt
version: 1.0.0
space: default
spec:
provider: openai
model: gpt-4o
messages:
- role: user
content: 'Answer the customer: {{question}}'
execution_route says how the Agent reaches its model: wyrd_gateway sends it through the gateway deployment named openai, which Set up the LLM gateway creates. Use {kind: native} when your own code calls the model.
The Prompt’s provider and model name a hosted model, such as openai and gpt-4o, and the gateway resolves openai/gpt-4o at call time. That string is not a Model Card and needs none. Declare a Model Card only for a model artifact you own and version, such as a trained classifier or a fine-tune, so verdicts and drift attach to its exact version.
2. Write the Service
The Service gives each component an alias, the name your code uses at runtime, such as state.run("agent"):
apiVersion: wyrd/v1
kind: Service
metadata:
name: support-desk
version: 1.0.0
space: default
spec:
service_type: agent
tables:
- name: tickets
schema:
type: object
properties:
question: {type: string}
answer: {type: string}
required: [question, answer]
components:
- alias: agent
ref: ./support-agent.yaml
- alias: prompt
ref: ./support-prompt.yaml| Field | Holds |
|---|---|
components[].alias | The runtime name of the component, unique within the Service |
components[].ref | A path to the component’s Card file, or a declared Card such as {kind: Model, name: churn-classifier, version: 1.4.2} |
tables[].name | A table to create as vala.datasets.<name> when the Service registers |
tables[].schema | A JSON Schema object; the order of properties is the column order |
service_type | A free-form label, such as agent or api |
A path is relative to the file that contains it. Every reference names one exact version: Wyrd has no version ranges, so a declared Service always records exactly what it was built from.
Verifiers attach through verified_by, which Bind a Verifier adds next.
3. Check it locally
wyrd declare --check support-desk.yamlwyrd declare --check loads the Service and every Card it references, validates them, and contacts no server. It prints check valid: 3 card(s), then one line per Card, such as Service default/support-desk@1.0.0. Fix anything it reports before you declare.
Set the space once
space groups related Cards, such as a team’s. Instead of writing it in every file, put a wyrd.toml next to your Cards or in any parent directory:
[defaults]
space = "support"
[kind.Verifier]
space = "support-verifiers"A Card’s own metadata.space wins, then the [kind.<Kind>] value, then [defaults], then default. wyrd.toml can also set labels and annotations, but never name or version.
If it fails
| You see | Cause | Fix |
|---|---|---|
WYRD_LOADER_400_INVALID_ENVELOPE | A file is missing apiVersion or kind, a path points at no Card, a referenced Card has no exact version, or two Cards reference each other. details.diagnostics names each file | Fix the file it names |
WYRD_LOADER_400_PATH_ESCAPE | A ref path leaves the declaration’s directory tree | Move the Card inside it, or reference the declared Card instead |
Next
Bind a Verifier to say how the Service is checked.
Last updated