diff --git a/lib/src/generated/fai/v1/hub.pb.dart b/lib/src/generated/fai/v1/hub.pb.dart index fd84c73..7104862 100644 --- a/lib/src/generated/fai/v1/hub.pb.dart +++ b/lib/src/generated/fai/v1/hub.pb.dart @@ -2301,6 +2301,143 @@ class InvokePluginThemeRequest extends $pb.GeneratedMessage { 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, diff --git a/lib/src/generated/fai/v1/hub.pbgrpc.dart b/lib/src/generated/fai/v1/hub.pbgrpc.dart index e518459..659fe01 100644 --- a/lib/src/generated/fai/v1/hub.pbgrpc.dart +++ b/lib/src/generated/fai/v1/hub.pbgrpc.dart @@ -183,6 +183,10 @@ class HubAdminClient extends $grpc.Client { '/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(), @@ -384,6 +388,17 @@ class HubAdminClient extends $grpc.Client { 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); @@ -681,6 +696,13 @@ abstract class HubAdminServiceBase extends $grpc.Service { 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, @@ -925,6 +947,10 @@ abstract class HubAdminServiceBase extends $grpc.Service { 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); } @@ -1044,6 +1070,7 @@ abstract class HubAdminServiceBase extends $grpc.Service { $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 571bbfd..476fb4d 100644 --- a/lib/src/generated/fai/v1/hub.pbjson.dart +++ b/lib/src/generated/fai/v1/hub.pbjson.dart @@ -579,6 +579,36 @@ final $typed_data.Uint8List invokePluginThemeRequestDescriptor = $convert.base64 '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', diff --git a/lib/src/hub_client.dart b/lib/src/hub_client.dart index 36ef62e..5765b8e 100644 --- a/lib/src/hub_client.dart +++ b/lib/src/hub_client.dart @@ -61,6 +61,7 @@ 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; @@ -302,6 +303,33 @@ class HubClient { ); } + /// 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() {