diff --git a/lib/src/channel_factory_io.dart b/lib/src/channel_factory_io.dart deleted file mode 100644 index 4b593da..0000000 --- a/lib/src/channel_factory_io.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Native channel factory — plain gRPC over HTTP/2. -// Selected on every non-web target (macOS, Linux, Windows, iOS, -// Android) via the conditional import in hub_client.dart. - -import 'package:grpc/grpc.dart'; -import 'package:grpc/grpc_connection_interface.dart'; - -import 'hub_client.dart' show HubEndpoint; - -ClientChannelBase createChannel(HubEndpoint endpoint) { - return ClientChannel( - endpoint.host, - port: endpoint.port, - options: ChannelOptions( - credentials: endpoint.secure - ? const ChannelCredentials.secure() - : const ChannelCredentials.insecure(), - idleTimeout: const Duration(minutes: 5), - ), - ); -} diff --git a/lib/src/channel_factory_web.dart b/lib/src/channel_factory_web.dart deleted file mode 100644 index 565f4be..0000000 --- a/lib/src/channel_factory_web.dart +++ /dev/null @@ -1,17 +0,0 @@ -// Web channel factory — gRPC-Web over HTTP/1.1. -// Selected on dart:html targets (Flutter web, Dart-for-web) via -// the conditional import in hub_client.dart. The hub must be -// running with `tonic-web` enabled — see fai_platform docs -// architecture/protocol-surfaces.md. - -import 'package:grpc/grpc_connection_interface.dart'; -import 'package:grpc/grpc_web.dart'; - -import 'hub_client.dart' show HubEndpoint; - -ClientChannelBase createChannel(HubEndpoint endpoint) { - final scheme = endpoint.secure ? 'https' : 'http'; - return GrpcWebClientChannel.xhr( - Uri.parse('$scheme://${endpoint.host}:${endpoint.port}'), - ); -} diff --git a/lib/src/generated/fai/v1/hub.pb.dart b/lib/src/generated/fai/v1/hub.pb.dart index 7104862..3341919 100644 --- a/lib/src/generated/fai/v1/hub.pb.dart +++ b/lib/src/generated/fai/v1/hub.pb.dart @@ -336,7 +336,6 @@ class CapabilityEntry extends $pb.GeneratedMessage { $core.String? version, $core.String? moduleName, $core.String? moduleVersion, - $core.String? kind, }) { final $result = create(); if (capability != null) { @@ -351,9 +350,6 @@ class CapabilityEntry extends $pb.GeneratedMessage { if (moduleVersion != null) { $result.moduleVersion = moduleVersion; } - if (kind != null) { - $result.kind = kind; - } return $result; } CapabilityEntry._() : super(); @@ -365,7 +361,6 @@ class CapabilityEntry extends $pb.GeneratedMessage { ..aOS(2, _omitFieldNames ? '' : 'version') ..aOS(3, _omitFieldNames ? '' : 'moduleName') ..aOS(4, _omitFieldNames ? '' : 'moduleVersion') - ..aOS(5, _omitFieldNames ? '' : 'kind') ..hasRequiredFields = false ; @@ -423,24 +418,6 @@ class CapabilityEntry extends $pb.GeneratedMessage { $core.bool hasModuleVersion() => $_has(3); @$pb.TagNumber(4) void clearModuleVersion() => $_clearField(4); - - /// Where this capability comes from. Studio gates install - /// affordances on this — only "wasm" caps have a bundle to - /// install. Empty string is treated as "wasm" for - /// backwards-compat with older hubs. - /// "wasm" — declared by an installed WASM module - /// "builtin" — implemented in the hub itself - /// (e.g. system.approval) - /// "federated" — discovered from an external MCP/n8n server; - /// not installable via the module-store path - @$pb.TagNumber(5) - $core.String get kind => $_getSZ(4); - @$pb.TagNumber(5) - set kind($core.String v) { $_setString(4, v); } - @$pb.TagNumber(5) - $core.bool hasKind() => $_has(4); - @$pb.TagNumber(5) - void clearKind() => $_clearField(5); } class ModuleInfoRequest extends $pb.GeneratedMessage { @@ -494,7 +471,6 @@ class ModuleInfoResponse extends $pb.GeneratedMessage { $core.Iterable<$4.CapabilityRef>? provides, $core.Iterable<$core.String>? permissions, $core.String? directory, - $core.Iterable<$core.String>? acceptsMime, }) { final $result = create(); if (name != null) { @@ -512,9 +488,6 @@ class ModuleInfoResponse extends $pb.GeneratedMessage { if (directory != null) { $result.directory = directory; } - if (acceptsMime != null) { - $result.acceptsMime.addAll(acceptsMime); - } return $result; } ModuleInfoResponse._() : super(); @@ -527,7 +500,6 @@ class ModuleInfoResponse extends $pb.GeneratedMessage { ..pc<$4.CapabilityRef>(3, _omitFieldNames ? '' : 'provides', $pb.PbFieldType.PM, subBuilder: $4.CapabilityRef.create) ..pPS(4, _omitFieldNames ? '' : 'permissions') ..aOS(5, _omitFieldNames ? '' : 'directory') - ..pPS(6, _omitFieldNames ? '' : 'acceptsMime') ..hasRequiredFields = false ; @@ -580,14 +552,6 @@ class ModuleInfoResponse extends $pb.GeneratedMessage { $core.bool hasDirectory() => $_has(4); @$pb.TagNumber(5) void clearDirectory() => $_clearField(5); - - /// MIME allow-list for bytes-shaped inputs, copied verbatim - /// from `module.yaml`'s `accepts_mime:` field. Empty means - /// "no declared restriction". Studio uses this to pre-filter - /// the OS file-picker so operators don't pick a file the - /// module would reject. - @$pb.TagNumber(6) - $pb.PbList<$core.String> get acceptsMime => $_getList(5); } class CheckPermissionRequest extends $pb.GeneratedMessage { @@ -2091,416 +2055,6 @@ class FetchModuleDocsResponse extends $pb.GeneratedMessage { void clearSourceUrl() => $_clearField(3); } -class GetInstalledModuleDocsRequest extends $pb.GeneratedMessage { - factory GetInstalledModuleDocsRequest({ - $core.String? name, - $core.String? locale, - }) { - final $result = create(); - if (name != null) { - $result.name = name; - } - if (locale != null) { - $result.locale = locale; - } - return $result; - } - GetInstalledModuleDocsRequest._() : super(); - factory GetInstalledModuleDocsRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GetInstalledModuleDocsRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'GetInstalledModuleDocsRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'name') - ..aOS(2, _omitFieldNames ? '' : 'locale') - ..hasRequiredFields = false - ; - - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - GetInstalledModuleDocsRequest clone() => GetInstalledModuleDocsRequest()..mergeFromMessage(this); - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - GetInstalledModuleDocsRequest copyWith(void Function(GetInstalledModuleDocsRequest) updates) => super.copyWith((message) => updates(message as GetInstalledModuleDocsRequest)) as GetInstalledModuleDocsRequest; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static GetInstalledModuleDocsRequest create() => GetInstalledModuleDocsRequest._(); - GetInstalledModuleDocsRequest createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GetInstalledModuleDocsRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GetInstalledModuleDocsRequest? _defaultInstance; - - /// Capability id (e.g. `text.extract`) or module-manifest name - /// (e.g. `text-extract`). The hub maps capability → module via - /// the registry; falls back to treating the name as a - /// directory name. - @$pb.TagNumber(1) - $core.String get name => $_getSZ(0); - @$pb.TagNumber(1) - set name($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasName() => $_has(0); - @$pb.TagNumber(1) - void clearName() => $_clearField(1); - - /// Preferred locale code (e.g. "de", "en"). When set and not - /// "en", `MODULE..md` is tried first; otherwise the - /// generic `MODULE.md` is used. Empty string = no preference. - @$pb.TagNumber(2) - $core.String get locale => $_getSZ(1); - @$pb.TagNumber(2) - set locale($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasLocale() => $_has(1); - @$pb.TagNumber(2) - void clearLocale() => $_clearField(2); -} - -class GetInstalledModuleDocsResponse extends $pb.GeneratedMessage { - factory GetInstalledModuleDocsResponse({ - $core.String? text, - $core.String? sourcePath, - $core.bool? notInstalled, - }) { - final $result = create(); - if (text != null) { - $result.text = text; - } - if (sourcePath != null) { - $result.sourcePath = sourcePath; - } - if (notInstalled != null) { - $result.notInstalled = notInstalled; - } - return $result; - } - GetInstalledModuleDocsResponse._() : super(); - factory GetInstalledModuleDocsResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory GetInstalledModuleDocsResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'GetInstalledModuleDocsResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'text') - ..aOS(2, _omitFieldNames ? '' : 'sourcePath') - ..aOB(3, _omitFieldNames ? '' : 'notInstalled') - ..hasRequiredFields = false - ; - - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - GetInstalledModuleDocsResponse clone() => GetInstalledModuleDocsResponse()..mergeFromMessage(this); - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - GetInstalledModuleDocsResponse copyWith(void Function(GetInstalledModuleDocsResponse) updates) => super.copyWith((message) => updates(message as GetInstalledModuleDocsResponse)) as GetInstalledModuleDocsResponse; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static GetInstalledModuleDocsResponse create() => GetInstalledModuleDocsResponse._(); - GetInstalledModuleDocsResponse createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static GetInstalledModuleDocsResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static GetInstalledModuleDocsResponse? _defaultInstance; - - /// Markdown body. Empty when the module is installed but ships - /// no inline docs — Studio uses this to hide its docs button. - @$pb.TagNumber(1) - $core.String get text => $_getSZ(0); - @$pb.TagNumber(1) - set text($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasText() => $_has(0); - @$pb.TagNumber(1) - void clearText() => $_clearField(1); - - /// Absolute path on the hub host that the body was read from, - /// for "loaded from /path/MODULE.md" hints in Studio. Empty - /// when text is empty. - @$pb.TagNumber(2) - $core.String get sourcePath => $_getSZ(1); - @$pb.TagNumber(2) - set sourcePath($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasSourcePath() => $_has(1); - @$pb.TagNumber(2) - void clearSourcePath() => $_clearField(2); - - /// True when the module wasn't installed at all. Distinct from - /// "installed but no inline docs" so Studio can show different - /// affordances ("install first" vs "no inline docs available"). - @$pb.TagNumber(3) - $core.bool get notInstalled => $_getBF(2); - @$pb.TagNumber(3) - set notInstalled($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasNotInstalled() => $_has(2); - @$pb.TagNumber(3) - void clearNotInstalled() => $_clearField(3); -} - -class InvokePluginThemeRequest extends $pb.GeneratedMessage { - factory InvokePluginThemeRequest({ - $core.String? capability, - $core.String? brightness, - }) { - final $result = create(); - if (capability != null) { - $result.capability = capability; - } - if (brightness != null) { - $result.brightness = brightness; - } - return $result; - } - InvokePluginThemeRequest._() : super(); - factory InvokePluginThemeRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InvokePluginThemeRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'InvokePluginThemeRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'capability') - ..aOS(2, _omitFieldNames ? '' : 'brightness') - ..hasRequiredFields = false - ; - - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginThemeRequest clone() => InvokePluginThemeRequest()..mergeFromMessage(this); - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginThemeRequest copyWith(void Function(InvokePluginThemeRequest) updates) => super.copyWith((message) => updates(message as InvokePluginThemeRequest)) as InvokePluginThemeRequest; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static InvokePluginThemeRequest create() => InvokePluginThemeRequest._(); - InvokePluginThemeRequest createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static InvokePluginThemeRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static InvokePluginThemeRequest? _defaultInstance; - - /// Capability name the operator asked for, e.g. - /// `studio.theme.solarized`. The hub maps this to the - /// installed plugin directory. - @$pb.TagNumber(1) - $core.String get capability => $_getSZ(0); - @$pb.TagNumber(1) - set capability($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasCapability() => $_has(0); - @$pb.TagNumber(1) - void clearCapability() => $_clearField(1); - - /// "light" or "dark" — the plugin returns a ColorScheme - /// for this brightness. Plugins that don't recognise the - /// value return PluginError::declined and the hub - /// surfaces that as a friendly error. - @$pb.TagNumber(2) - $core.String get brightness => $_getSZ(1); - @$pb.TagNumber(2) - set brightness($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasBrightness() => $_has(1); - @$pb.TagNumber(2) - void clearBrightness() => $_clearField(2); -} - -class InvokePluginTranslateRequest extends $pb.GeneratedMessage { - factory InvokePluginTranslateRequest({ - $core.String? capability, - $core.String? text, - $core.String? fromLocale, - $core.String? toLocale, - }) { - final $result = create(); - if (capability != null) { - $result.capability = capability; - } - if (text != null) { - $result.text = text; - } - if (fromLocale != null) { - $result.fromLocale = fromLocale; - } - if (toLocale != null) { - $result.toLocale = toLocale; - } - return $result; - } - InvokePluginTranslateRequest._() : super(); - factory InvokePluginTranslateRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InvokePluginTranslateRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'InvokePluginTranslateRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'capability') - ..aOS(2, _omitFieldNames ? '' : 'text') - ..aOS(3, _omitFieldNames ? '' : 'fromLocale') - ..aOS(4, _omitFieldNames ? '' : 'toLocale') - ..hasRequiredFields = false - ; - - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginTranslateRequest clone() => InvokePluginTranslateRequest()..mergeFromMessage(this); - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginTranslateRequest copyWith(void Function(InvokePluginTranslateRequest) updates) => super.copyWith((message) => updates(message as InvokePluginTranslateRequest)) as InvokePluginTranslateRequest; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static InvokePluginTranslateRequest create() => InvokePluginTranslateRequest._(); - InvokePluginTranslateRequest createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static InvokePluginTranslateRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static InvokePluginTranslateRequest? _defaultInstance; - - /// Capability name (e.g. `studio.translate.ollama`). - @$pb.TagNumber(1) - $core.String get capability => $_getSZ(0); - @$pb.TagNumber(1) - set capability($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasCapability() => $_has(0); - @$pb.TagNumber(1) - void clearCapability() => $_clearField(1); - - /// Text to translate. UTF-8, arbitrary length the plugin - /// tolerates. - @$pb.TagNumber(2) - $core.String get text => $_getSZ(1); - @$pb.TagNumber(2) - set text($core.String v) { $_setString(1, v); } - @$pb.TagNumber(2) - $core.bool hasText() => $_has(1); - @$pb.TagNumber(2) - void clearText() => $_clearField(2); - - /// BCP-47 source locale. Empty = let the plugin auto-detect. - @$pb.TagNumber(3) - $core.String get fromLocale => $_getSZ(2); - @$pb.TagNumber(3) - set fromLocale($core.String v) { $_setString(2, v); } - @$pb.TagNumber(3) - $core.bool hasFromLocale() => $_has(2); - @$pb.TagNumber(3) - void clearFromLocale() => $_clearField(3); - - /// BCP-47 target locale. Required; the host always knows it. - @$pb.TagNumber(4) - $core.String get toLocale => $_getSZ(3); - @$pb.TagNumber(4) - set toLocale($core.String v) { $_setString(3, v); } - @$pb.TagNumber(4) - $core.bool hasToLocale() => $_has(3); - @$pb.TagNumber(4) - void clearToLocale() => $_clearField(4); -} - -class InvokePluginTranslateResponse extends $pb.GeneratedMessage { - factory InvokePluginTranslateResponse({ - $core.String? translated, - }) { - final $result = create(); - if (translated != null) { - $result.translated = translated; - } - return $result; - } - InvokePluginTranslateResponse._() : super(); - factory InvokePluginTranslateResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InvokePluginTranslateResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'InvokePluginTranslateResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'translated') - ..hasRequiredFields = false - ; - - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginTranslateResponse clone() => InvokePluginTranslateResponse()..mergeFromMessage(this); - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginTranslateResponse copyWith(void Function(InvokePluginTranslateResponse) updates) => super.copyWith((message) => updates(message as InvokePluginTranslateResponse)) as InvokePluginTranslateResponse; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static InvokePluginTranslateResponse create() => InvokePluginTranslateResponse._(); - InvokePluginTranslateResponse createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static InvokePluginTranslateResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static InvokePluginTranslateResponse? _defaultInstance; - - /// Translated text. Returns verbatim what the plugin - /// emits — no normalisation by the hub. - @$pb.TagNumber(1) - $core.String get translated => $_getSZ(0); - @$pb.TagNumber(1) - set translated($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasTranslated() => $_has(0); - @$pb.TagNumber(1) - void clearTranslated() => $_clearField(1); -} - -class InvokePluginThemeResponse extends $pb.GeneratedMessage { - factory InvokePluginThemeResponse({ - $core.String? brightness, - $core.Iterable<$core.int>? tokens, - }) { - final $result = create(); - if (brightness != null) { - $result.brightness = brightness; - } - if (tokens != null) { - $result.tokens.addAll(tokens); - } - return $result; - } - InvokePluginThemeResponse._() : super(); - factory InvokePluginThemeResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InvokePluginThemeResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'InvokePluginThemeResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'brightness') - ..p<$core.int>(2, _omitFieldNames ? '' : 'tokens', $pb.PbFieldType.KU3) - ..hasRequiredFields = false - ; - - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginThemeResponse clone() => InvokePluginThemeResponse()..mergeFromMessage(this); - @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') - InvokePluginThemeResponse copyWith(void Function(InvokePluginThemeResponse) updates) => super.copyWith((message) => updates(message as InvokePluginThemeResponse)) as InvokePluginThemeResponse; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static InvokePluginThemeResponse create() => InvokePluginThemeResponse._(); - InvokePluginThemeResponse createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static InvokePluginThemeResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static InvokePluginThemeResponse? _defaultInstance; - - /// Echo of the brightness input. Plugins are expected to - /// round-trip it; if they don't the client treats that as - /// a contract violation. - @$pb.TagNumber(1) - $core.String get brightness => $_getSZ(0); - @$pb.TagNumber(1) - set brightness($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasBrightness() => $_has(0); - @$pb.TagNumber(1) - void clearBrightness() => $_clearField(1); - - /// 14 ARGB tokens in Material 3 order: - /// primary, on_primary, secondary, on_secondary, - /// tertiary, on_tertiary, error, on_error, - /// surface, on_surface, surface_variant, - /// on_surface_variant, outline, outline_variant. - /// Studio merges any missing slot (well-behaved plugins - /// send all 14) with its built-in fallback before - /// applying the scheme. - @$pb.TagNumber(2) - $pb.PbList<$core.int> get tokens => $_getList(1); -} - class ListApprovalsRequest extends $pb.GeneratedMessage { factory ListApprovalsRequest({ $core.Iterable<$core.String>? statuses, diff --git a/lib/src/generated/fai/v1/hub.pbgrpc.dart b/lib/src/generated/fai/v1/hub.pbgrpc.dart index 659fe01..b643be5 100644 --- a/lib/src/generated/fai/v1/hub.pbgrpc.dart +++ b/lib/src/generated/fai/v1/hub.pbgrpc.dart @@ -175,18 +175,6 @@ class HubAdminClient extends $grpc.Client { '/fai.v1.HubAdmin/FetchModuleDocs', ($0.FetchModuleDocsRequest value) => value.writeToBuffer(), ($core.List<$core.int> value) => $0.FetchModuleDocsResponse.fromBuffer(value)); - static final _$getInstalledModuleDocs = $grpc.ClientMethod<$0.GetInstalledModuleDocsRequest, $0.GetInstalledModuleDocsResponse>( - '/fai.v1.HubAdmin/GetInstalledModuleDocs', - ($0.GetInstalledModuleDocsRequest value) => value.writeToBuffer(), - ($core.List<$core.int> value) => $0.GetInstalledModuleDocsResponse.fromBuffer(value)); - static final _$invokePluginTheme = $grpc.ClientMethod<$0.InvokePluginThemeRequest, $0.InvokePluginThemeResponse>( - '/fai.v1.HubAdmin/InvokePluginTheme', - ($0.InvokePluginThemeRequest value) => value.writeToBuffer(), - ($core.List<$core.int> value) => $0.InvokePluginThemeResponse.fromBuffer(value)); - static final _$invokePluginTranslate = $grpc.ClientMethod<$0.InvokePluginTranslateRequest, $0.InvokePluginTranslateResponse>( - '/fai.v1.HubAdmin/InvokePluginTranslate', - ($0.InvokePluginTranslateRequest value) => value.writeToBuffer(), - ($core.List<$core.int> value) => $0.InvokePluginTranslateResponse.fromBuffer(value)); static final _$listApprovals = $grpc.ClientMethod<$0.ListApprovalsRequest, $0.ApprovalList>( '/fai.v1.HubAdmin/ListApprovals', ($0.ListApprovalsRequest value) => value.writeToBuffer(), @@ -368,37 +356,6 @@ class HubAdminClient extends $grpc.Client { return $createUnaryCall(_$fetchModuleDocs, request, options: options); } - /// Read the inline-docs (MODULE.md / MODULE..md) of an - /// installed module from disk. No network fetch, no provider- - /// specific URL probing — the docs ship in the .fai bundle and - /// live next to module.wasm on disk after install. Returns an - /// empty body when the module is installed but ships no inline - /// docs; Studio uses that to hide the docs button entirely. - $grpc.ResponseFuture<$0.GetInstalledModuleDocsResponse> getInstalledModuleDocs($0.GetInstalledModuleDocsRequest request, {$grpc.CallOptions? options}) { - return $createUnaryCall(_$getInstalledModuleDocs, request, options: options); - } - - /// Invoke an installed Studio plugin's `theme` hook. Returns - /// the plugin's proposed Material 3 ColorScheme for the - /// brightness the caller asked for ("light" or "dark"). The - /// first end-to-end RPC of the Studio-plugin subsystem; the - /// `translate` and `output-view` hooks get their own RPCs as - /// the matching Studio surfaces ship. - $grpc.ResponseFuture<$0.InvokePluginThemeResponse> invokePluginTheme($0.InvokePluginThemeRequest request, {$grpc.CallOptions? options}) { - return $createUnaryCall(_$invokePluginTheme, request, options: options); - } - - /// Invoke an installed Studio plugin's `translate` hook. - /// The first user surface that consumes this is Studio's - /// FaiEnBadge — when an operator has a translate plugin - /// installed, server-supplied English text (MCP tool - /// descriptions, n8n endpoint names) gets translated - /// on-the-fly into the active locale instead of carrying - /// the honest-but-rough [EN] badge. - $grpc.ResponseFuture<$0.InvokePluginTranslateResponse> invokePluginTranslate($0.InvokePluginTranslateRequest request, {$grpc.CallOptions? options}) { - return $createUnaryCall(_$invokePluginTranslate, request, options: options); - } - /// List system.approval@^0 entries, optionally filtered by status. $grpc.ResponseFuture<$0.ApprovalList> listApprovals($0.ListApprovalsRequest request, {$grpc.CallOptions? options}) { return $createUnaryCall(_$listApprovals, request, options: options); @@ -682,27 +639,6 @@ abstract class HubAdminServiceBase extends $grpc.Service { false, ($core.List<$core.int> value) => $0.FetchModuleDocsRequest.fromBuffer(value), ($0.FetchModuleDocsResponse value) => value.writeToBuffer())); - $addMethod($grpc.ServiceMethod<$0.GetInstalledModuleDocsRequest, $0.GetInstalledModuleDocsResponse>( - 'GetInstalledModuleDocs', - getInstalledModuleDocs_Pre, - false, - false, - ($core.List<$core.int> value) => $0.GetInstalledModuleDocsRequest.fromBuffer(value), - ($0.GetInstalledModuleDocsResponse value) => value.writeToBuffer())); - $addMethod($grpc.ServiceMethod<$0.InvokePluginThemeRequest, $0.InvokePluginThemeResponse>( - 'InvokePluginTheme', - invokePluginTheme_Pre, - false, - false, - ($core.List<$core.int> value) => $0.InvokePluginThemeRequest.fromBuffer(value), - ($0.InvokePluginThemeResponse value) => value.writeToBuffer())); - $addMethod($grpc.ServiceMethod<$0.InvokePluginTranslateRequest, $0.InvokePluginTranslateResponse>( - 'InvokePluginTranslate', - invokePluginTranslate_Pre, - false, - false, - ($core.List<$core.int> value) => $0.InvokePluginTranslateRequest.fromBuffer(value), - ($0.InvokePluginTranslateResponse value) => value.writeToBuffer())); $addMethod($grpc.ServiceMethod<$0.ListApprovalsRequest, $0.ApprovalList>( 'ListApprovals', listApprovals_Pre, @@ -939,18 +875,6 @@ abstract class HubAdminServiceBase extends $grpc.Service { return fetchModuleDocs($call, await $request); } - $async.Future<$0.GetInstalledModuleDocsResponse> getInstalledModuleDocs_Pre($grpc.ServiceCall $call, $async.Future<$0.GetInstalledModuleDocsRequest> $request) async { - return getInstalledModuleDocs($call, await $request); - } - - $async.Future<$0.InvokePluginThemeResponse> invokePluginTheme_Pre($grpc.ServiceCall $call, $async.Future<$0.InvokePluginThemeRequest> $request) async { - return invokePluginTheme($call, await $request); - } - - $async.Future<$0.InvokePluginTranslateResponse> invokePluginTranslate_Pre($grpc.ServiceCall $call, $async.Future<$0.InvokePluginTranslateRequest> $request) async { - return invokePluginTranslate($call, await $request); - } - $async.Future<$0.ApprovalList> listApprovals_Pre($grpc.ServiceCall $call, $async.Future<$0.ListApprovalsRequest> $request) async { return listApprovals($call, await $request); } @@ -1068,9 +992,6 @@ abstract class HubAdminServiceBase extends $grpc.Service { $async.Future<$0.InstallModuleResponse> installModule($grpc.ServiceCall call, $0.InstallModuleRequest request); $async.Future<$0.UninstallModuleResponse> uninstallModule($grpc.ServiceCall call, $0.UninstallModuleRequest request); $async.Future<$0.FetchModuleDocsResponse> fetchModuleDocs($grpc.ServiceCall call, $0.FetchModuleDocsRequest request); - $async.Future<$0.GetInstalledModuleDocsResponse> getInstalledModuleDocs($grpc.ServiceCall call, $0.GetInstalledModuleDocsRequest request); - $async.Future<$0.InvokePluginThemeResponse> invokePluginTheme($grpc.ServiceCall call, $0.InvokePluginThemeRequest request); - $async.Future<$0.InvokePluginTranslateResponse> invokePluginTranslate($grpc.ServiceCall call, $0.InvokePluginTranslateRequest request); $async.Future<$0.ApprovalList> listApprovals($grpc.ServiceCall call, $0.ListApprovalsRequest request); $async.Future<$0.DecideApprovalResponse> decideApproval($grpc.ServiceCall call, $0.DecideApprovalRequest request); $async.Future<$0.VerifyEventChainResponse> verifyEventChain($grpc.ServiceCall call, $1.Empty request); diff --git a/lib/src/generated/fai/v1/hub.pbjson.dart b/lib/src/generated/fai/v1/hub.pbjson.dart index 476fb4d..48b8631 100644 --- a/lib/src/generated/fai/v1/hub.pbjson.dart +++ b/lib/src/generated/fai/v1/hub.pbjson.dart @@ -143,7 +143,6 @@ const CapabilityEntry$json = { {'1': 'version', '3': 2, '4': 1, '5': 9, '10': 'version'}, {'1': 'module_name', '3': 3, '4': 1, '5': 9, '10': 'moduleName'}, {'1': 'module_version', '3': 4, '4': 1, '5': 9, '10': 'moduleVersion'}, - {'1': 'kind', '3': 5, '4': 1, '5': 9, '10': 'kind'}, ], }; @@ -151,8 +150,7 @@ const CapabilityEntry$json = { final $typed_data.Uint8List capabilityEntryDescriptor = $convert.base64Decode( 'Cg9DYXBhYmlsaXR5RW50cnkSHgoKY2FwYWJpbGl0eRgBIAEoCVIKY2FwYWJpbGl0eRIYCgd2ZX' 'JzaW9uGAIgASgJUgd2ZXJzaW9uEh8KC21vZHVsZV9uYW1lGAMgASgJUgptb2R1bGVOYW1lEiUK' - 'Dm1vZHVsZV92ZXJzaW9uGAQgASgJUg1tb2R1bGVWZXJzaW9uEhIKBGtpbmQYBSABKAlSBGtpbm' - 'Q='); + 'Dm1vZHVsZV92ZXJzaW9uGAQgASgJUg1tb2R1bGVWZXJzaW9u'); @$core.Deprecated('Use moduleInfoRequestDescriptor instead') const ModuleInfoRequest$json = { @@ -175,7 +173,6 @@ const ModuleInfoResponse$json = { {'1': 'provides', '3': 3, '4': 3, '5': 11, '6': '.fai.v1.CapabilityRef', '10': 'provides'}, {'1': 'permissions', '3': 4, '4': 3, '5': 9, '10': 'permissions'}, {'1': 'directory', '3': 5, '4': 1, '5': 9, '10': 'directory'}, - {'1': 'accepts_mime', '3': 6, '4': 3, '5': 9, '10': 'acceptsMime'}, ], }; @@ -184,7 +181,7 @@ final $typed_data.Uint8List moduleInfoResponseDescriptor = $convert.base64Decode 'ChJNb2R1bGVJbmZvUmVzcG9uc2USEgoEbmFtZRgBIAEoCVIEbmFtZRIYCgd2ZXJzaW9uGAIgAS' 'gJUgd2ZXJzaW9uEjEKCHByb3ZpZGVzGAMgAygLMhUuZmFpLnYxLkNhcGFiaWxpdHlSZWZSCHBy' 'b3ZpZGVzEiAKC3Blcm1pc3Npb25zGAQgAygJUgtwZXJtaXNzaW9ucxIcCglkaXJlY3RvcnkYBS' - 'ABKAlSCWRpcmVjdG9yeRIhCgxhY2NlcHRzX21pbWUYBiADKAlSC2FjY2VwdHNNaW1l'); + 'ABKAlSCWRpcmVjdG9yeQ=='); @$core.Deprecated('Use checkPermissionRequestDescriptor instead') const CheckPermissionRequest$json = { @@ -535,94 +532,6 @@ final $typed_data.Uint8List fetchModuleDocsResponseDescriptor = $convert.base64D 'ChdGZXRjaE1vZHVsZURvY3NSZXNwb25zZRIdCgplcnJvcl9raW5kGAEgASgJUgllcnJvcktpbm' 'QSEgoEdGV4dBgCIAEoCVIEdGV4dBIdCgpzb3VyY2VfdXJsGAMgASgJUglzb3VyY2VVcmw='); -@$core.Deprecated('Use getInstalledModuleDocsRequestDescriptor instead') -const GetInstalledModuleDocsRequest$json = { - '1': 'GetInstalledModuleDocsRequest', - '2': [ - {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, - {'1': 'locale', '3': 2, '4': 1, '5': 9, '10': 'locale'}, - ], -}; - -/// Descriptor for `GetInstalledModuleDocsRequest`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List getInstalledModuleDocsRequestDescriptor = $convert.base64Decode( - 'Ch1HZXRJbnN0YWxsZWRNb2R1bGVEb2NzUmVxdWVzdBISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm' - 'xvY2FsZRgCIAEoCVIGbG9jYWxl'); - -@$core.Deprecated('Use getInstalledModuleDocsResponseDescriptor instead') -const GetInstalledModuleDocsResponse$json = { - '1': 'GetInstalledModuleDocsResponse', - '2': [ - {'1': 'text', '3': 1, '4': 1, '5': 9, '10': 'text'}, - {'1': 'source_path', '3': 2, '4': 1, '5': 9, '10': 'sourcePath'}, - {'1': 'not_installed', '3': 3, '4': 1, '5': 8, '10': 'notInstalled'}, - ], -}; - -/// Descriptor for `GetInstalledModuleDocsResponse`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List getInstalledModuleDocsResponseDescriptor = $convert.base64Decode( - 'Ch5HZXRJbnN0YWxsZWRNb2R1bGVEb2NzUmVzcG9uc2USEgoEdGV4dBgBIAEoCVIEdGV4dBIfCg' - 'tzb3VyY2VfcGF0aBgCIAEoCVIKc291cmNlUGF0aBIjCg1ub3RfaW5zdGFsbGVkGAMgASgIUgxu' - 'b3RJbnN0YWxsZWQ='); - -@$core.Deprecated('Use invokePluginThemeRequestDescriptor instead') -const InvokePluginThemeRequest$json = { - '1': 'InvokePluginThemeRequest', - '2': [ - {'1': 'capability', '3': 1, '4': 1, '5': 9, '10': 'capability'}, - {'1': 'brightness', '3': 2, '4': 1, '5': 9, '10': 'brightness'}, - ], -}; - -/// Descriptor for `InvokePluginThemeRequest`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List invokePluginThemeRequestDescriptor = $convert.base64Decode( - 'ChhJbnZva2VQbHVnaW5UaGVtZVJlcXVlc3QSHgoKY2FwYWJpbGl0eRgBIAEoCVIKY2FwYWJpbG' - 'l0eRIeCgpicmlnaHRuZXNzGAIgASgJUgpicmlnaHRuZXNz'); - -@$core.Deprecated('Use invokePluginTranslateRequestDescriptor instead') -const InvokePluginTranslateRequest$json = { - '1': 'InvokePluginTranslateRequest', - '2': [ - {'1': 'capability', '3': 1, '4': 1, '5': 9, '10': 'capability'}, - {'1': 'text', '3': 2, '4': 1, '5': 9, '10': 'text'}, - {'1': 'from_locale', '3': 3, '4': 1, '5': 9, '10': 'fromLocale'}, - {'1': 'to_locale', '3': 4, '4': 1, '5': 9, '10': 'toLocale'}, - ], -}; - -/// Descriptor for `InvokePluginTranslateRequest`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List invokePluginTranslateRequestDescriptor = $convert.base64Decode( - 'ChxJbnZva2VQbHVnaW5UcmFuc2xhdGVSZXF1ZXN0Eh4KCmNhcGFiaWxpdHkYASABKAlSCmNhcG' - 'FiaWxpdHkSEgoEdGV4dBgCIAEoCVIEdGV4dBIfCgtmcm9tX2xvY2FsZRgDIAEoCVIKZnJvbUxv' - 'Y2FsZRIbCgl0b19sb2NhbGUYBCABKAlSCHRvTG9jYWxl'); - -@$core.Deprecated('Use invokePluginTranslateResponseDescriptor instead') -const InvokePluginTranslateResponse$json = { - '1': 'InvokePluginTranslateResponse', - '2': [ - {'1': 'translated', '3': 1, '4': 1, '5': 9, '10': 'translated'}, - ], -}; - -/// Descriptor for `InvokePluginTranslateResponse`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List invokePluginTranslateResponseDescriptor = $convert.base64Decode( - 'Ch1JbnZva2VQbHVnaW5UcmFuc2xhdGVSZXNwb25zZRIeCgp0cmFuc2xhdGVkGAEgASgJUgp0cm' - 'Fuc2xhdGVk'); - -@$core.Deprecated('Use invokePluginThemeResponseDescriptor instead') -const InvokePluginThemeResponse$json = { - '1': 'InvokePluginThemeResponse', - '2': [ - {'1': 'brightness', '3': 1, '4': 1, '5': 9, '10': 'brightness'}, - {'1': 'tokens', '3': 2, '4': 3, '5': 13, '10': 'tokens'}, - ], -}; - -/// Descriptor for `InvokePluginThemeResponse`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List invokePluginThemeResponseDescriptor = $convert.base64Decode( - 'ChlJbnZva2VQbHVnaW5UaGVtZVJlc3BvbnNlEh4KCmJyaWdodG5lc3MYASABKAlSCmJyaWdodG' - '5lc3MSFgoGdG9rZW5zGAIgAygNUgZ0b2tlbnM='); - @$core.Deprecated('Use listApprovalsRequestDescriptor instead') const ListApprovalsRequest$json = { '1': 'ListApprovalsRequest', diff --git a/lib/src/hub_client.dart b/lib/src/hub_client.dart index 7b4fb02..82d84a7 100644 --- a/lib/src/hub_client.dart +++ b/lib/src/hub_client.dart @@ -6,10 +6,8 @@ import 'dart:typed_data'; -import 'package:grpc/grpc_connection_interface.dart'; +import 'package:grpc/grpc.dart'; -import 'channel_factory_io.dart' - if (dart.library.html) 'channel_factory_web.dart' as channel_factory; import 'generated/fai/v1/common.pb.dart' as pb_common; import 'generated/fai/v1/hub.pb.dart' as pb; import 'generated/fai/v1/hub.pbgrpc.dart' as grpc_hub; @@ -61,9 +59,6 @@ typedef ClearEventLogResponse = pb.ClearEventLogResponse; typedef DaemonPathsResponse = pb.DaemonPathsResponse; typedef UninstallModuleResponse = pb.UninstallModuleResponse; typedef FetchModuleDocsResponse = pb.FetchModuleDocsResponse; -typedef GetInstalledModuleDocsResponse = pb.GetInstalledModuleDocsResponse; -typedef InvokePluginThemeResponse = pb.InvokePluginThemeResponse; -typedef InvokePluginTranslateResponse = pb.InvokePluginTranslateResponse; typedef ListMcpClientsResponse = pb.ListMcpClientsResponse; typedef McpClientStatus = pb.McpClientStatus; typedef McpClientConfigEntry = pb.McpClientConfigEntry; @@ -80,15 +75,9 @@ typedef SubmitResponse = pb.SubmitResponse; /// Typed client for the F∆I Hub gRPC surface. Construct once, /// reuse for the process lifetime, call [close] on shutdown. -/// -/// The channel type is picked at compile time: -/// * native targets → plain HTTP/2 gRPC via [ClientChannel]. -/// * web targets → HTTP/1.1 gRPC-Web via [GrpcWebClientChannel]. -/// Requires the hub to be running with the -/// `tonic-web` layer enabled. class HubClient { final HubEndpoint endpoint; - final ClientChannelBase _channel; + final ClientChannel _channel; final grpc_hub.HubClient _hub; final grpc_hub.HubAdminClient _admin; @@ -97,7 +86,17 @@ class HubClient { _admin = grpc_hub.HubAdminClient(_channel); factory HubClient({HubEndpoint endpoint = const HubEndpoint()}) { - return HubClient._(endpoint, channel_factory.createChannel(endpoint)); + final channel = ClientChannel( + endpoint.host, + port: endpoint.port, + options: ChannelOptions( + credentials: endpoint.secure + ? const ChannelCredentials.secure() + : const ChannelCredentials.insecure(), + idleTimeout: const Duration(minutes: 5), + ), + ); + return HubClient._(endpoint, channel); } /// Liveness probe. Returns true when the hub responds with @@ -241,10 +240,6 @@ class HubClient { /// when set, so Studio doesn't have to handle credentials. /// Errors come back inside [FetchModuleDocsResponse.errorKind] /// (not as exceptions) so the UI can render fallbacks. - /// - /// Deprecated: prefer [getInstalledModuleDocs], which reads - /// `MODULE.md`/`MODULE..md` shipped inside the bundle. - @Deprecated('Use getInstalledModuleDocs (reads from bundle, no network)') Future fetchModuleDocs( String name, { String locale = '', @@ -254,80 +249,6 @@ class HubClient { ); } - /// Read the installed module's `MODULE.md` (or `MODULE..md`) - /// from disk under `~/.fai/modules//`. No network. Works in - /// air-gapped installs. The response distinguishes three states via - /// [GetInstalledModuleDocsResponse.notInstalled] and an empty - /// [GetInstalledModuleDocsResponse.text]: - /// - /// - text non-empty → docs found, render them - /// - text empty + notInstalled=false → installed but bundle had - /// no inline docs - /// - text empty + notInstalled=true → module is not installed - Future getInstalledModuleDocs( - String name, { - String locale = '', - }) { - return _admin.getInstalledModuleDocs( - pb.GetInstalledModuleDocsRequest(name: name, locale: locale), - ); - } - - /// Invoke an installed Studio plugin's `theme` hook and - /// receive a Material 3 ColorScheme for the brightness - /// ("light" or "dark") the caller asked for. - /// - /// [capability] is the full Studio-plugin capability name - /// (e.g. "studio.theme.solarized"). [brightness] must be - /// "light" or "dark"; other values surface as - /// `INVALID_ARGUMENT` from the hub. A plugin that doesn't - /// recognise the brightness returns Declined, which the - /// hub maps to `FAILED_PRECONDITION` — Studio's - /// friendly-error mapper renders it with a recovery hint. - /// - /// The first end-to-end RPC of the Studio-plugin - /// subsystem; `translate` and `output-view` hooks get - /// their own methods once the matching Studio surfaces - /// ship. - Future invokePluginTheme({ - required String capability, - required String brightness, - }) { - return _admin.invokePluginTheme( - pb.InvokePluginThemeRequest( - capability: capability, - brightness: brightness, - ), - ); - } - - /// Invoke an installed Studio plugin's `translate` hook and - /// receive translated text. [fromLocale] may be empty - /// (auto-detect); [toLocale] must be a BCP-47 code (the - /// host always knows the target). - /// - /// Errors surface as gRPC exceptions: - /// * NOT_FOUND — plugin not installed. - /// * FAILED_PRECONDITION — plugin returned Declined or - /// Misconfigured (e.g. unreachable - /// LLM endpoint). - /// * INTERNAL — generic catch-all. - Future invokePluginTranslate({ - required String capability, - required String text, - required String toLocale, - String fromLocale = '', - }) { - return _admin.invokePluginTranslate( - pb.InvokePluginTranslateRequest( - capability: capability, - text: text, - fromLocale: fromLocale, - toLocale: toLocale, - ), - ); - } - /// List every configured MCP server with the last-discovery /// snapshot. Drives Studio's MCP-clients editor. Future listMcpClients() { @@ -568,33 +489,27 @@ class HubClient { /// flow that mixes text and binary inputs (e.g. extract /// taking a `document: bytes`) flows through one RPC: /// * [textInputs] — string values wrapped as text Payloads - /// * [fileInputs] — raw bytes wrapped as bytes Payloads. - /// MIME type defaults to - /// `application/octet-stream`; clients that - /// know the real type pass it via - /// [fileMimeTypes] (same key). Modules - /// typically gate on MIME — e.g. - /// `text.extract` rejects octet-stream — so - /// accurate types matter. - /// All maps default to empty so existing text-only callers + /// * [fileInputs] — raw bytes wrapped as bytes Payloads, + /// with `application/octet-stream` MIME + /// type. Caller can override the MIME by + /// passing a [bytePayloads] entry instead. + /// Both maps default to empty so existing text-only callers /// are backward-compatible. Keys must not collide between - /// [textInputs] and [fileInputs]; on collision the bytes-shaped - /// entry wins (the less-common case is more likely to be the - /// operator's intent). + /// the maps; on collision the bytes-shaped entry wins (the + /// less-common case is more likely to be the operator's + /// intent). Future runSavedFlow({ required String name, Map textInputs = const {}, Map fileInputs = const {}, - Map fileMimeTypes = const {}, }) async { final req = pb.RunSavedFlowRequest()..name = name; for (final entry in textInputs.entries) { req.inputs[entry.key] = pb_common.Payload()..text = entry.value; } for (final entry in fileInputs.entries) { - final mime = fileMimeTypes[entry.key] ?? 'application/octet-stream'; final bytes = pb_common.Bytes() - ..mimeType = mime + ..mimeType = 'application/octet-stream' ..data = entry.value; req.inputs[entry.key] = pb_common.Payload()..bytes = bytes; }