osvi_chat 0.1.0
osvi_chat: ^0.1.0 copied to clipboard
Embed an Osvi AI chat agent in a Flutter app: a headless chat client and drop-in chat widgets.
example/lib/main.dart
// Run with your agent id (and, for a local stack, the API base url):
//
// flutter run --dart-define=OSVI_AGENT_ID=agent_xxx
// flutter run --dart-define=OSVI_AGENT_ID=agent_xxx --dart-define=OSVI_BASE_URL=http://10.0.2.2:3000
//
// Server mode (signed-in users): set OSVI_TOKEN_URL to a backend endpoint that returns
// {sessionId, token, wsUrl, expiresAt}; osvi-chat-sdk/e2e/support/token-server.mjs is one for local testing.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:osvi_chat/osvi_chat.dart';
const agentId = String.fromEnvironment('OSVI_AGENT_ID');
const baseUrl = String.fromEnvironment('OSVI_BASE_URL');
const tokenUrl = String.fromEnvironment('OSVI_TOKEN_URL');
void main() => runApp(const ExampleApp());
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Osvi chat example',
theme: ThemeData(colorSchemeSeed: const Color(0xFF4F46E5)),
darkTheme: ThemeData(colorSchemeSeed: const Color(0xFF4F46E5), brightness: Brightness.dark),
home: const HomePage(),
);
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
OsviChatClient? _client;
@override
void initState() {
super.initState();
if (agentId.isNotEmpty) _connect();
}
Future<void> _connect() async {
final client = await OsviChatClient.create(
agentId: agentId,
baseUrl: baseUrl.isEmpty ? null : baseUrl,
auth: tokenUrl.isEmpty ? const ChatAuth.anonymous() : ChatAuth.server(getToken: _token),
);
if (mounted) setState(() => _client = client);
}
static Future<ServerToken> _token({bool newSession = false}) async {
final response = await http.get(Uri.parse(tokenUrl));
if (response.statusCode != 200) throw Exception('token server failed');
return ServerToken.fromJson(jsonDecode(response.body) as Map<String, Object?>);
}
@override
void dispose() {
_client?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final client = _client;
return Scaffold(
appBar: AppBar(title: const Text('Osvi chat example')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Text(
agentId.isEmpty
? 'Run with --dart-define=OSVI_AGENT_ID=<your agent id>'
: client == null
? 'Connecting…'
: 'Tap the chat button to talk to the agent.',
textAlign: TextAlign.center,
),
),
),
floatingActionButton: client == null ? null : OsviChatLauncher(client: client, subtitle: 'Typically replies instantly'),
);
}
}