marona 0.5.0 copy "marona: ^0.5.0" to clipboard
marona: ^0.5.0 copied to clipboard

Unified AI runtime and MCP/Skill gateway for online, hybrid, and offline applications.

marona #

Unified AI runtime and MCP/Skill gateway for Dart and Flutter.

dependencies:
  marona: ^0.5.0

mode controls where execution is allowed, model selects the model for the request, and input contains the user's request. Apps, Skills, discovery, identity, permissions, approvals, service connections, and MCP execution remain inside Marona.

Complete Request #

MARONA_API_KEY authenticates your application with Marona.

import 'dart:io';
import 'package:marona/marona.dart';

Future<void> main() async {
  final identityToken = Platform.environment['MARONA_IDENTITY_TOKEN'];
  final marona = Marona(
    apiKey: Platform.environment['MARONA_API_KEY'],
    mode: 'online',
  );

  try {
    await marona.sync(
      interfaceName: 'mobile_app',
      identityToken: identityToken,
    );

    final response = await marona.client(
      model: 'marona/default',
      input: [
        {'role': 'user', 'content': 'What is my group fund?'},
      ],
      interfaceName: 'mobile_app',
      identityToken: identityToken,
    );
    print(response.text);
  } finally {
    marona.close();
  }
}

Images And Documents #

final response = await marona.client(
  model: 'openai/gpt-4o',
  input: [
    {'role': 'developer', 'content': 'Keep answers clear and concise.'},
    {
      'role': 'user',
      'content': [
        {'type': 'input_text', 'text': 'Compare the image and report.'},
        {'type': 'input_image', 'image_url': 'https://example.com/match.jpg'},
        {
          'type': 'input_file',
          'filename': 'report.pdf',
          'file_data': 'data:application/pdf;base64,...',
          'detail': 'high',
        },
      ],
    },
  ],
  interfaceName: 'mobile_app',
  identityToken: identityToken,
);

Model Routes #

Only the model string changes:

'marona/default'
'openai/gpt-4o'
'anthropic/claude-sonnet-4'
'gemini/gemini-2.5-pro'
'ollama/llama3.2'
'litellm/local-llama'
'office/company-assistant'
'local/gemma-4-e2b'

Pass provider credentials and endpoints in application configuration:

final marona = Marona(
  apiKey: maronaApiKey,
  mode: 'hybrid',
  providerCredentials: {
    'openai': openAiApiKey,
    'litellm': {'apiKey': liteLlmApiKey, 'endpoint': liteLlmBaseUrl},
  },
  providerEndpoints: {'ollama': 'http://127.0.0.1:11434'},
);

Register custom access or a downloaded in-process model:

Future<Map<String, dynamic>> officeNativeAdapter(LocalModelRequest request) async {
  final result = await officeSdk.generate(request);
  return {'choices': [{'message': {'role': 'assistant', 'content': result.text}}]};
}

await marona.models.register(
  name: 'office/company-assistant',
  provider: 'custom',
  endpoint: 'https://models.office.example/v1',
  model: 'company-assistant-v2',
  apiKey: officeModelApiKey,
  adapter: officeNativeAdapter,
);

await marona.models.register(
  name: 'local/gemma-4-e2b',
  executor: gemmaExecutor,
  contextWindow: 2048,
  maxOutputTokens: 128,
);

final response = await marona.client(
  model: 'local/gemma-4-e2b',
  input: [{'role': 'user', 'content': 'Hello offline'}],
  interfaceName: 'mobile_app',
  identityToken: identityToken,
);

Registration configures access. Select the model on client(...) or message(...). models.use(...) is deprecated.

Marona Tools In Any Agent #

final tools = await marona.hub.connect(
  ['sda-books', 'zimsec'],
  skills: ['create-group-fund'],
  adapter: 'tools',
);

final result = await marona.tools.execute(
  selectedTool,
  arguments: toolArguments,
  identityToken: identityToken,
  conversationId: 'conversation-1',
  model: 'openai/gpt-4o',
);

When a Skill returns status: 'planned', call it again only after the user approves, with {'request': 'Yes', 'approved': true}.

App tools execute their MCP target. Skill tools execute through Marona's governed runtime. Internal Skill steps and Skill-managed raw capabilities are not exported.

Publish A Skill #

final request = step(
  id: 'understand-request',
  type: 'reasoning',
  instruction: 'Extract the group name and currency.',
  inputs: {'message': '{{ context.user_message }}'},
  outputs: {'name': 'string', 'currency': 'string'},
);
final permission = step(
  id: 'confirm-create',
  type: 'approval',
  message: "Create '${request.output('name')}' in ${request.output('currency')}?",
  outputs: {'approved': 'boolean'},
);
final create = step(
  id: 'create-group',
  type: 'app',
  app: 'group-fund',
  capability: 'group-fund.create_group',
  instruction: 'Create the approved group.',
  condition: permission.output('approved'),
  inputs: {
    'name': request.output('name'),
    'currency': request.output('currency'),
  },
  outputs: {'group_id': 'string', 'name': 'string'},
);

final definition = SkillDefinition(
  name: 'create-group-fund',
  description: 'Create a group fund after explicit user approval.',
  governs: ['group-fund.create_group'],
  steps: [request, permission, create],
);

await marona.skills.publish(definition, version: '1.0.0');

Mode Rules #

  • online: network models and online MCP targets are allowed.
  • hybrid: try the selected local/private model, then use Edge fallback.
  • offline: use cached data, a local model, and installed offline-capable targets only.

Changing model never changes App, Skill, permission, approval, or MCP rules.

1
likes
0
points
1.18k
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Unified AI runtime and MCP/Skill gateway for online, hybrid, and offline applications.

Homepage

Topics

#marona #ai #agents #runtime #sdk

License

unknown (license)

Dependencies

http

More

Packages that depend on marona