postCard method
Posts a card of agentId into threadId (kind = card, 09 11): the message with
text, then its components (ComponentCreate-like maps with custom_id, type,
definition and optional single_use, required_capability, restricted_to,
expires_at) bound to runId; the components follow as message.updated, as the
server writes the card row before its components (09 11.4). Returns the message ID.
Implementation
String postCard(
String agentId,
String threadId,
String text,
List<JsonMap> components, {
String? runId,
}) {
final created = world.createMessage(agentId, threadId, {
'client_msg_id': world.nextId(),
'content_md': text,
'kind': 'card',
}, origin: 'agent');
final id = created.message['id']! as String;
final stored = <JsonMap>[];
for (var i = 0; i < components.length; i++) {
final c = components[i];
final capability = c['required_capability'] as String?;
stored.add({
'id': world.nextId(),
'custom_id': c['custom_id'],
'type': c['type'],
'definition': c['definition'],
'position': i + 1,
'single_use': c['single_use'] ?? true,
'required_capability': ?capability,
// 09 11.1: `run_starter` is the default with `approve_actions` (SEC-AI-4).
'restricted_to':
c['restricted_to'] ??
(capability == 'approve_actions' ? 'run_starter' : 'any'),
'run_id': ?runId,
'state': 'active',
'expires_at': ?c['expires_at'],
'version': 1,
});
}
world.updateMessageFields(id, {'components': stored}, actor: agentId);
return id;
}