Ressources partagées
Une ressource est une donnée métier qui appartient à votre agent et que plusieurs jobs utilisent : des contacts, des prompts, des produits, des modèles. Quand vous déclarez une ressource, Studio peut la lister, la modifier et l'importer, et vos formulaires peuvent proposer ses éléments comme choix. Vous n'écrivez aucune interface utilisateur.

Quand en ajouter une
- Les mêmes données sont utilisées par plus d'un job.
- Les opérateurs doivent voir ou corriger les données sans l'aide d'un développeur.
- Un formulaire doit permettre à l'opérateur de choisir un élément existant.
Des données qui n'appartiennent qu'à un seul job ne sont pas une ressource. Placez-les dans les cases du job, ou sur l'écran Configure.
1. Déclarer la ressource
registration = build_v2_agent_registration(
agent_slug="my-agent",
display_name="My Agent",
a2ui_catalog_version="my-agent-ui.1",
surfaces=["job.start"],
actions=[
"job.start", "job.sync", "job.stop",
# Une liste ne modifie pas l'état : dites-le, et Studio laisse les lecteurs la consulter.
V2ActionDefinition(id="resource.contacts.list", mutating=False, scope="workspace"),
],
resources=[
{
"id": "contacts",
"label": "Contacts",
"scope": "workspace",
"auto_surface": True,
"operations": ["list", "create", "update", "delete", "import"],
"display": {
"title_field": "email",
"columns": ["first_name", "last_name", "email", "city"],
"search_fields": ["first_name", "last_name", "email", "city"],
},
"fields": [
{"id": "first_name", "label": "First name", "type": "string", "required": True},
{"id": "last_name", "label": "Last name", "type": "string"},
{"id": "email", "label": "Email", "type": "email"},
{"id": "city", "label": "City", "type": "string"},
],
}
],
)
| Clé | Signification |
|---|---|
id | Le nom de la ressource dans les identifiants d'action et dans les formulaires. |
scope | Qui partage les données : workspace (toutes les missions), mission ou job. |
operations | Ce que Studio peut faire : list, get, create, update, delete, import. |
auto_surface | Studio construit le tableau et les formulaires à partir de display et de fields. |
display | Le champ de titre, les colonnes du tableau et les champs de recherche. |
fields | Les champs du formulaire, avec les définitions de champs habituelles. |
requires_context | Le contexte dont un appel a besoin. La valeur par défaut est ["workspace.id"]. |
mounted_views | Remplace une vue générée, comme edit ou import, par une surface de votre agent : {"view": "import", "surface": "..."}. |
Le SDK dérive une action pour chaque opération, nommée resource.<id>.<operation>, ainsi que la surface mission.agent.resource.<id>.
2. Traiter les opérations
Enregistrez un seul gestionnaire pour les actions dérivées, et renvoyez un effet pour chaque opération.
CONTACT_ACTIONS = [f"resource.contacts.{op}" for op in ("list", "create", "update", "delete", "import")]
def handle_contacts(request: V2ActionRequest) -> dict:
workspace_id = request.workspace_authorization.workspace_id # vérifié par le SDK
store = contacts_of(workspace_id)
data = request.input
operation = request.action.rsplit(".", 1)[1]
if operation == "list":
items = store.all()
effect = {"type": "resource.listed", "count": len(items), "items": items}
elif operation == "create":
effect = {"type": "resource.created", "item": store.create(data)}
elif operation == "update":
item = store.update(data.get("id"), data)
if item is None:
return error("Contact not found")
effect = {"type": "resource.updated", "item": item}
elif operation == "delete":
if not store.delete(data.get("id")):
return error("Contact not found")
effect = {"type": "resource.deleted", "item": {"id": data.get("id")}}
else: # import
created = store.create_many(data.get("records") or [])
effect = {"type": "resource.imported", "count": len(created), "items": store.all(), "errors": []}
return {"status": "ok", "effects": [{"resource": "contacts", **effect}]}
def error(message: str) -> dict:
return {"status": "error", "effects": [{"type": "resource.action.failed", "resource": "contacts", "message": message}]}
for action in CONTACT_ACTIONS:
sv_server.register_v2_action(action, handle_contacts, agent_slug=agent.slug)
Chaque élément a besoin d'un id de type chaîne. Créez l'id côté agent et ignorez un id fourni avec une création.
3. Utiliser la ressource dans un formulaire
Un champ resource_ref permet à l'opérateur de choisir un élément. Studio charge les choix avec l'action list.
{
"id": "contact_id",
"label": "Contact",
"type": "resource_ref",
"required": True,
"options_source": {"type": "resource", "resource": "contacts", "value_field": "id", "label_field": "email"},
}
Votre action reçoit l'id de l'élément choisi. Chargez l'élément depuis votre stockage ; ne vous fiez pas aux autres valeurs du formulaire.
Séparer les données de chaque espace de travail
Le même contrôleur peut servir plusieurs espaces de travail. Un gestionnaire de ressource ne doit jamais renvoyer les données d'un autre espace de travail.
- Prenez l'espace de travail dans
request.workspace_authorization. Le SDK l'a vérifié à partir d'un jeton signé par Studio. - N'utilisez pas un identifiant ou un slug d'espace de travail venant de
request.input. Un appelant peut y écrire n'importe quelle valeur. - Pour une portée
mission, filtrez aussi surrequest.mission_id. request.mission, quand Studio l'envoie, contient les champsid,nameetmetadatade la mission. Studio envoie les métadonnées courantes à chaque requête. Ne les mettez pas en cache. Utilisez-les pour délimiter les résultats, jamais comme frontière d'accès. Voir le guide du SDK.
Liste de contrôle
- La ressource est dans
resources, avec uniquement les opérations que le gestionnaire prend en charge. - L'action
listest déclarée avecmutating=False. - Chaque opération filtre sur l'espace de travail vérifié.
- Chaque opération valide ses données d'entrée et renvoie son effet.
- Les formulaires utilisent
resource_refavecoptions_source, pas un champ de texte libre.
Référence
- Hello World :
agent_data_resource.pyet les actions de contact dansagent_v2.py. - Une liste de lignes qu'un opérateur modifie à l'intérieur d'un seul job : le composant
ResourceListdu Configurateur de job. - Écrans de modification ou d'import personnalisés, et contrat complet des ressources : le guide du SDK.