Skip to content

Template format#

A template is YAML (or JSON). Strings are filled in from the inputs with {{ … }} expressions, and parts are kept or left out with conditions. Nothing in a template is code that runs when it is installed: it only fills in resources' specifications.

docs-search.yaml
apiVersion: astralyx.cloud/v1
kind: Template
metadata:
  name: docs-search
  title: Docs search
  summary: Search our documentation, from a model.
  category: data
  tags: [search, docs]
inputs:
  - name: sites
    type: text
    format: urls
    title: Sites
    required: true
  - name: attach_to
    type: deployment
    title: Give it to a model now
resources:
  - id: index
    kind: replica-group
    name: "{{ install }}-index"
    wait: ready                  # what needs it waits for its workers to be healthy
    spec:
      template:
        lifetime: Service
        task_template:
          image: python:3.12-slim
          command: python
          args: ["-u", "/app/index.py"]
          env:
            SITES: "{{ inputs.sites }}"
          configs:
            - {mounts: [/app/index.py], value: "…"}
      scaling: {min: 1, max: 1}
  - id: index-endpoint
    kind: endpoint
    name: "{{ install }}-index"
    needs: [index]
    spec:
      selector:
        astralyx.cloud/installation: "{{ install }}"
        astralyx.cloud/part: index
      mode: headless
      port: 8080
      target_port: 8080
  - id: function
    kind: function
    name: "{{ install }}"
    spec:
      runtime: python
      code: |
        def handler(query: str) -> dict:
            """Search our documentation.

            Args:
                query: What to look for.
            """
            …
      env:
        INDEX_URL: "http://{{ resources.index-endpoint.name }}:8080"
    publish: {aliases: [prod]}
links:
  - kind: tool
    function: function
    deployment: "{{ inputs.attach_to }}"
    needs: [index]               # given to the model once the index serves
    when: {attach_to: {set: true}}
test:
  function: function
  input: {query: "getting started"}

metadata#

Field Type Default Description
name string required Its id in the organisation: lower-case letters, digits and -, at most 40. Not an official template's.
version integer 1 Set by the organisation when it is published (its next version).
title string required 1 to 80 characters.
summary string "" What it gives, in a sentence (at most 300).
description string "" Markdown (paragraphs, lists, bold, code), at most 20,000 characters.
category string required to publish Its category's slug: tools, training, batch, evaluation, data, apps, or one of your organisation's (Categories).
tags, icon How a gallery finds and shows it (at most 12 tags).

inputs#

At most 40.

Field Type Default Description
name string required Lower-case letters, digits and _.
type string required string, text, number, bool, choice, secret, deployment, drive, function, model, agent, flow, pool.
title, description string What the install form shows.
default any none Its value when not given (a secret's: a Credential's name).
required bool false It must be given, when it applies.
choices list A choice's: {value, title, description}.
when condition always Asked only when it holds.
min, max number A number's bounds.
format string A string or text's: url, urls (one per line), name.
key string value A secret's key in its Credential, unless the install names one.

A secret input's value is {credential, key}: read it as {{ inputs.<name>.credential }} and {{ inputs.<name>.key }}, for example in a function's credentials:

credentials:
  - credential: "{{ inputs.tavily_key.credential }}"
    env: {"{{ inputs.tavily_key.key }}": TAVILY_API_KEY}

resources#

Made in this order — each after what it needs — and uninstalled in the reverse. At most 30.

Field Type Description
id string Its id in the template (expressions name it: resources.<id>.name).
kind string run, schedule, replica-group, endpoint, drive, credential, function, model, deployment, agent, flow.
name string Its name in the workspace: an expression, usually "{{ install }}" or "{{ install }}-<something>".
title string What it is for, shown with the installation's parts.
when condition Made only when it holds.
spec object Its specification, exactly as the API takes it: a run's, a function's, a drive's, a replica group's, an endpoint's, a deployment's… Names it references are the workspace's (local). No metadata: the labels are the installation's.
publish object A function's: {aliases: [prod], note} — published as version 1 with these aliases.
needs list Resources of the template (their ids) made — and, when they say wait, done — before this one is made. One left out by its when is not waited for. No circles.
wait string What what needs it waits for: ready (a run running, a replica group's workers healthy, an endpoint with a ready backend, a deployment serving, a model's weights in place, a function published) or succeeded (a run finished successfully; for a run only). None: made is enough.
wait_minutes number How long it may take: 30 for ready, 1440 for succeeded by default, at most 10080 (a week). Past it the install fails and what was made is removed.

Steps that wait#

An install whose parts wait goes on by itself after the request that started it, as the person who installed it: the installation is installing and says the step it is on (Waiting for run ft-train to finish: Running) until it is ready or failed. A run that fails, or a part waited for longer than its wait_minutes, fails the install: what was made is removed again — its runs with them, so read a run's logs while it waits —, and the installation says which step failed and why. A failed installation is installed again under the same name.

resources:
  - {id: prepare, kind: run, name: "{{ install }}-prepare", wait: succeeded, spec: {…}}
  - {id: train, kind: run, name: "{{ install }}-train", needs: [prepare], wait: succeeded, wait_minutes: 4320, spec: {…}}
  - {id: model, kind: model, name: "{{ install }}", needs: [train], spec: {…}}

Every resource made is labelled astralyx.cloud/template, astralyx.cloud/template-version, astralyx.cloud/installation and astralyx.cloud/part (its id). A replica group's labels are its runs' and workers', so an endpoint selects a service of the installation by astralyx.cloud/installation and astralyx.cloud/part, as above.

Expressions#

Expression Is
{{ install }} The installation's name.
{{ inputs.<name> }} An input's value (null when not given and with no default).
{{ inputs.<name>.credential }}, .key A secret input's Credential and key.
{{ resources.<id>.name }} The name a resource gets (null when its when left it out).
{{ template.name }}, {{ template.version }} The template's.
… \| default("text"), … \| default(inputs.other) When the value is empty.
… \| lines A text's non-empty lines, as a list.
… \| text The value as text: a number in an environment variable.
… \| json The value as JSON text.

A string that is one expression and nothing else takes its value as it is: "{{ inputs.replicas }}" is a number, "{{ inputs.sites | lines }}" a list. Inside other text, the value is written as text.

Conditions#

A condition is {<input>: <expected>, …}, every one holding:

Expected Holds when the input
a value (searxng, 3, true) equals it.
a list ([brave, tavily]) equals one of them.
{set: true} / {set: false} is given (not empty) / is empty.

Inside a spec, an object (or a list's item) with $when is kept only when its condition holds ($when itself is removed); {$when: …, $value: x} stands for x; {$first: [a, b]} for the first alternative its own $when keeps; {$literal: "…"} for its text as written, no expression in it filled in (code whose braces are its own):

env:
  SEARCH_BACKEND: "{{ inputs.backend }}"
  SEARXNG_URL:
    $when: {backend: searxng}
    $first:
      - {$when: {searxng_url: {set: true}}, $value: "{{ inputs.searxng_url }}"}
      - "http://{{ resources.searxng-endpoint.name }}:8080"
Field Type Default Description
kind string required tool: a function as a server-side tool of a deployment.
function string required A function of the template (its id), or an expression naming one of the workspace's.
deployment string required A deployment of the template (its id), or an expression ("{{ inputs.attach_to }}").
alias string the function's first published alias, or latest What the tool calls.
name string the function's name, - as _ The tool's name for the model.
approval bool false A person approves each call (Approvals).
when condition always Made only when it holds. A link whose deployment expression is empty is not made.
needs list its function Resources done before it is made, besides its function: [searxng-endpoint] gives the tool once the search service answers.

test#

Field Type Description
function string A function of the template (its id).
alias string What is called (as for a link).
input any The input (expressions allowed).
title string What it shows, in a line.

What is refused#

  • An unknown field anywhere outside spec (a typo is not ignored).
  • An expression naming an input or a resource the template does not have.
  • A literal value that looks like a secret — a long value under a key named like a password, token or API key, or the shape of a well-known key (sk-…, ghp_…, tvly-…): use an input of type secret.
  • More than 1 MiB.