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

Use Marona to build AI apps for any AI interface, edge device, or intelligent agent. Build once and deploy online, offline, or in hybrid environments through a unified runtime.

marona #

Official Dart client for Marona-compatible AI runtimes and Hub integrations.

Use Marona to build AI apps for any AI interface, edge device, or intelligent agent. Build once and deploy online, offline, or in hybrid environments through a unified runtime.

Install #

dependencies:
  marona: ^0.4.1

Then run:

dart pub get

Complete Example #

This example shows the normal Flutter/Dart flow:

  1. Create a Marona client.
  2. Sync Hub metadata into local storage.
  3. Connect approved Hub apps by app ID.
  4. Send a user message through the runtime.
  5. Close the client.

The optional developer role controls app behavior.

import 'dart:io';

import 'package:marona/marona.dart';

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

  try {
    final identityToken = Platform.environment['MARONA_IDENTITY_TOKEN']; // Optional

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

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

    final response = await marona.client(
      input: [
        {
          'role': 'developer',
          'content': 'Keep answers clear and concise.',
        },
        {
          'role': 'user',
          'content': [
            {
              'type': 'input_text',
              'text': 'What teams are playing in this image?',
            },
            {
              'type': 'input_image',
              'image_url':
                  'https://api.nga.gov/iiif/a2e6da57-3cd1-4235-b20e-95dcaefed6c8/full/!800,800/0/default.jpg',
            },
            {
              'type': 'input_file',
              'filename': 'document.pdf',
              'file_data': 'data:application/pdf;base64,...',
              'detail': 'high',
            },
          ],
        },
      ],
      interfaceName: 'mobile_app',
      identityToken: identityToken,
      tools: tools,
    );

    print(response.text);
  } finally {
    marona.close();
  }
}

Run it:

export MARONA_API_KEY="mrn_live_..."
dart run bin/app.dart

Pair A User #

Use pairing when an interface needs to become the same user across web, mobile, WhatsApp, wearables, or another client surface.

final pairing = await marona.startPairing(
  interfaceName: 'mobile_app',
  deviceName: 'Customer phone',
);

print(pairing.displayCode);
print(pairing.whatsappUrl);

final status = await marona.pairingStatus(pairing.pairingId);
print(status.status);

After the user confirms pairing, store the returned identity token and pass it to marona.client(...).

Online, Offline, And Hybrid Modes #

Choose one runtime mode for the client:

  • online: use online runtime and online app routes.
  • offline: use only local cache, local/private models, and installed offline-capable app targets.
  • hybrid: try local/private execution first, then use online runtime when allowed.

Apps also declare one availability mode:

  • online: online only.
  • offline: offline only.
  • hybrid: online and offline capable.

Hybrid is a single mode. Do not declare online + offline + hybrid; declare hybrid.

Hybrid Or Offline With A Local/Private Model #

Marona uses one provider-neutral runtime flow. Registering a model changes the inference provider; App/Skill discovery, MCP execution, context, permissions, and hybrid fallback remain unchanged.

final marona = Marona(
  apiKey: Platform.environment['MARONA_API_KEY'],
  mode: 'hybrid',
);

await marona.sync(interfaceName: 'desktop');

await marona.models.register(
  name: 'office-model',
  endpoint: 'http://localhost:9379',
);
marona.models.use('office-model');

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

final response = await marona.client(
  input: [
    {
      'role': 'user',
      'content': [
        {
          'type': 'input_text',
          'text': 'Summarize the chapter about faith.',
        },
      ],
    },
  ],
  interfaceName: 'desktop',
  tools: tools,
);

print(response.text);

Downloaded models do not require an endpoint. Flutter apps register their in-process adapter with marona.models.registerLocalExecutor(...); that adapter receives the same normalized messages and runtime tools as an endpoint model.

In offline mode, only installed offline/hybrid Apps and Skills whose required Apps are available are discoverable. Skill-managed capabilities are not exposed as raw App tools.

The model selects the best matching Skill from the synced catalog. Marona, not the model provider, executes its ordered step() values, persists approval gates, and invokes each exact MCP capability. Hybrid uses the same executor when the local route succeeds and falls back to Edge when the local model cannot produce a valid route.

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');

sync() synchronizes Apps and Skills. Users continue through client(...); there is no separate Skill run API. governs declares raw capabilities that must only run through that workflow. Every workflow entry uses step(); its type selects reasoning, approval, or App execution. There are no raw step maps or type-specific step builders.

In offline mode, Marona never calls public cloud runtime. If a model or an offline-capable app target is missing, the client returns a clear offline error.

Synced conversation context and connected tool schemas are supplied to the configured model on every turn. The current user prompt remains the active task, and the model decides whether to answer directly or call an available tool.

Interface Names #

interfaceName identifies the client surface making the request. Standard values:

  • api
  • web
  • mobile_app
  • desktop
  • whatsapp

Future devices can use custom lowercase slugs such as smart_glasses, vehicle_console, or kiosk.

  • Dart client: marona, import package:marona/marona.dart
  • Python client: marona, import marona
  • TypeScript client: marona, import Marona from "marona"
  • Developer SDK for building apps: marona-sdk
1
likes
0
points
1.18k
downloads

Documentation

Documentation

Publisher

unverified uploader

Weekly Downloads

Use Marona to build AI apps for any AI interface, edge device, or intelligent agent. Build once and deploy online, offline, or in hybrid environments through a unified runtime.

Homepage

Topics

#marona #ai #agents #runtime #sdk

License

unknown (license)

Dependencies

http

More

Packages that depend on marona