postCard method

String postCard(
  1. String agentId,
  2. String threadId,
  3. String text,
  4. List<JsonMap> components, {
  5. String? runId,
})

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;
}