feat: runSavedFlow accepts file (bytes) inputs (v0.14.0)

Studio's Flows tab couldn't run any sample flow with a
binary input (extract / extract-summarize / …) because
runSavedFlow only knew how to wrap textInputs as text
Payloads. Operators saw the hub return
"step references missing value '\$inputs.document'" because
the document key never made it into the request.

`runSavedFlow` is now mixed-mode:

  Future<SubmitResponse> runSavedFlow({
    required String name,
    Map<String, String> textInputs = const {},
    Map<String, Uint8List> fileInputs = const {},
  })

Both maps default to empty so existing text-only callers
keep working without code changes — the previous required
`textInputs:` parameter is now optional with a default. File
entries get wrapped as `Bytes` Payloads with
`application/octet-stream` MIME — good enough for the
text.extract / text.summarize chain that the bundled flows
exercise. Per-file MIME-type override is a follow-up if any
operator workflow ever needs it.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-05-09 02:07:07 +02:00
parent 45f60ef77b
commit 193f59302a
2 changed files with 24 additions and 6 deletions

View file

@ -4,6 +4,8 @@
// public method maps onto exactly one RPC on Hub or HubAdmin, so // public method maps onto exactly one RPC on Hub or HubAdmin, so
// callers don't have to know which service hosts which call. // callers don't have to know which service hosts which call.
import 'dart:typed_data';
import 'package:grpc/grpc.dart'; import 'package:grpc/grpc.dart';
import 'generated/fai/v1/common.pb.dart' as pb_common; import 'generated/fai/v1/common.pb.dart' as pb_common;
@ -465,18 +467,34 @@ class HubClient {
} }
/// Run a saved flow by name with the supplied named inputs. /// Run a saved flow by name with the supplied named inputs.
/// Each input value is wrapped as a text Payload the most /// Two input shapes are supported in the same call so a
/// common case for human-driven runs from Studio. Callers /// flow that mixes text and binary inputs (e.g. extract
/// that need bytes / file payloads use the lower-level /// taking a `document: bytes`) flows through one RPC:
/// SubmitRequest path. /// * [textInputs] string values wrapped as text Payloads
/// * [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
/// the maps; on collision the bytes-shaped entry wins (the
/// less-common case is more likely to be the operator's
/// intent).
Future<SubmitResponse> runSavedFlow({ Future<SubmitResponse> runSavedFlow({
required String name, required String name,
required Map<String, String> textInputs, Map<String, String> textInputs = const {},
Map<String, Uint8List> fileInputs = const {},
}) async { }) async {
final req = pb.RunSavedFlowRequest()..name = name; final req = pb.RunSavedFlowRequest()..name = name;
for (final entry in textInputs.entries) { for (final entry in textInputs.entries) {
req.inputs[entry.key] = pb_common.Payload()..text = entry.value; req.inputs[entry.key] = pb_common.Payload()..text = entry.value;
} }
for (final entry in fileInputs.entries) {
final bytes = pb_common.Bytes()
..mimeType = 'application/octet-stream'
..data = entry.value;
req.inputs[entry.key] = pb_common.Payload()..bytes = bytes;
}
return _admin.runSavedFlow(req); return _admin.runSavedFlow(req);
} }

View file

@ -1,6 +1,6 @@
name: fai_dart_sdk name: fai_dart_sdk
description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps. description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps.
version: 0.13.0 version: 0.14.0
publish_to: 'none' publish_to: 'none'
repository: https://git.flemming.ws/fai/dart-sdk repository: https://git.flemming.ws/fai/dart-sdk