run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<void> run() async {
final args = argResults!;
final providerArg = args['provider'] as String?;
final provider = providerArg == null
? null
: ai.AiProviderKind.tryParse(providerArg);
if (providerArg != null && provider == null) {
throw CliError('invalid --provider: $providerArg');
}
final modeArg = args['mode'] as String?;
final mode = modeArg == null ? null : ai.AgentMode.tryParse(modeArg);
if (modeArg != null && mode == null) {
throw CliError('invalid --mode: $modeArg');
}
int? maxSteps;
final maxStepsArg = args['max-steps'] as String?;
if (maxStepsArg != null) {
maxSteps = int.tryParse(maxStepsArg.trim());
if (maxSteps == null || maxSteps <= 0) {
throw CliError(
'invalid --max-steps: $maxStepsArg (expected a positive integer)',
);
}
}
var key = args['key'] as String?;
if (key == '-') {
key = _readSecret('API key: ');
if (key.isEmpty) throw CliError('no key entered');
}
// null = not provided; '' = clear back to the default; else the value.
String? clearable(String name) {
final raw = (args[name] as String?)?.trim();
if (raw == null) return null;
final v = raw.toLowerCase();
return (raw.isEmpty || v == 'off' || v == 'none' || v == 'default')
? ''
: raw;
}
final model = clearable('model');
final plannerModel = clearable('planner-model');
final executorModel = clearable('executor-model');
final explainerModel = clearable('explainer-model');
final baseUrl = clearable('base-url');
final language = clearable('language');
bool blank(String? s) => s == null || s.isEmpty;
if (provider == null &&
model == null &&
plannerModel == null &&
executorModel == null &&
explainerModel == null &&
blank(key) &&
mode == null &&
language == null &&
baseUrl == null &&
maxSteps == null) {
throw CliError(
'nothing to set — pass at least one of --provider/--model/'
'--planner-model/--executor-model/--explainer-model/--key/--mode/'
'--language/--base-url/--max-steps. Pass "default" to clear a value. '
'See: omnyserver ai config --help',
);
}
final path = omnyServerAiConfigPath(args['path'] as String?);
ai.AiConfigIo.write(
provider: provider,
model: model,
plannerModel: plannerModel,
executorModel: executorModel,
explainerModel: explainerModel,
apiKey: blank(key) ? null : key,
mode: mode,
language: language,
baseUrl: baseUrl,
maxSteps: maxSteps,
path: path,
);
void report(String label, String? value) {
if (value == null) return;
stdout.writeln(
' $label: ${value.isEmpty ? '(cleared — uses default)' : value}',
);
}
stdout.writeln('Wrote $path');
if (provider != null) stdout.writeln(' provider: ${provider.wireName}');
report('model', model);
report('plannerModel', plannerModel);
report('executorModel', executorModel);
report('explainerModel', explainerModel);
if (!blank(key)) stdout.writeln(' key: ${_maskKey(key!)}');
if (mode != null) stdout.writeln(' mode: ${mode.wireName}');
report('language', language);
report('baseUrl', baseUrl);
if (maxSteps != null) stdout.writeln(' maxSteps: $maxSteps');
stdout.writeln('Start the Hub with --shell to serve it to web clients.');
}