feat(studio): @-syntax file inputs in flows, copyable doc errors, services-row overflow (v0.40.0)
Three concrete fixes against today's user feedback.
- Flows that take binary inputs (extract / extract-summarize /
…) work from the Flows tab. The run-flow input dialog now
accepts the same `@/path/to/file` syntax `fai run --input`
uses on the CLI: any value beginning with `@` is read as
bytes and sent as a binary Payload; plain values still flow
through as text. The dialog hint copy and the example
placeholder reflect the new syntax. File-read failures
surface as a SnackBar before the run dialog opens, so a
typo in the path doesn't reach the hub. Threaded through
`_FlowRunDialog` and `HubService.runSavedFlow`, which both
carry separate `textInputs` and `fileInputs` maps now and
forward to the SDK's mixed-mode runSavedFlow (v0.14.0).
- The Welcome doc-reader's error path uses `FaiErrorBox` so
the actual underlying error is selectable + copy-to-
clipboard via the existing widget. Plus the loader throws
a richer error string that names *both* attempted asset
paths (`<slug>_<lang>.md` and the EN fallback) and the
underlying exception each, so the operator can paste a
diagnostic into a chat without us having to ship a
separate "how to read Flutter asset errors" doc.
- Doctor's empty Services panel had a horizontal RenderFlex
overflow at narrow widths because the long mono-spaced
hint ("add to ~/.fai/config.yaml under services:") and
the leading icon+text both demanded full intrinsic width
in a single Row. Now wraps via a `Wrap` widget so the
hint flows to a second line on narrow viewports and stays
in the same row when there's space.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
eb447c6ec0
commit
63e19974c0
11 changed files with 118 additions and 39 deletions
|
|
@ -1,3 +1,6 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../data/hub.dart';
|
||||
|
|
@ -29,11 +32,44 @@ class _FlowsPageState extends State<FlowsPage> {
|
|||
Future<void> _runFlow(SavedFlow flow) async {
|
||||
final inputs = await _FlowInputDialog.show(context, flow);
|
||||
if (inputs == null) return;
|
||||
// Split the dialog's text-shaped key=value pairs into text
|
||||
// vs file payloads. Values starting with `@` mean "treat
|
||||
// the rest as a path; read the file as bytes" — same
|
||||
// syntax `fai run --input` uses on the CLI. File-read
|
||||
// failures bubble up as the run dialog's error state so
|
||||
// the operator sees a useful message.
|
||||
final textInputs = <String, String>{};
|
||||
final fileInputs = <String, Uint8List>{};
|
||||
String? readError;
|
||||
for (final entry in inputs.entries) {
|
||||
final value = entry.value;
|
||||
if (value.startsWith('@')) {
|
||||
final path = value.substring(1).trim();
|
||||
try {
|
||||
fileInputs[entry.key] = await File(path).readAsBytes();
|
||||
} catch (e) {
|
||||
readError = '${entry.key}: $e';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
textInputs[entry.key] = value;
|
||||
}
|
||||
}
|
||||
if (!mounted) return;
|
||||
if (readError != null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(readError)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (_) => _FlowRunDialog(flow: flow, inputs: inputs),
|
||||
builder: (_) => _FlowRunDialog(
|
||||
flow: flow,
|
||||
textInputs: textInputs,
|
||||
fileInputs: fileInputs,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -248,9 +284,14 @@ class _FlowInputDialogState extends State<_FlowInputDialog> {
|
|||
|
||||
class _FlowRunDialog extends StatefulWidget {
|
||||
final SavedFlow flow;
|
||||
final Map<String, String> inputs;
|
||||
final Map<String, String> textInputs;
|
||||
final Map<String, Uint8List> fileInputs;
|
||||
|
||||
const _FlowRunDialog({required this.flow, required this.inputs});
|
||||
const _FlowRunDialog({
|
||||
required this.flow,
|
||||
required this.textInputs,
|
||||
required this.fileInputs,
|
||||
});
|
||||
|
||||
@override
|
||||
State<_FlowRunDialog> createState() => _FlowRunDialogState();
|
||||
|
|
@ -264,7 +305,8 @@ class _FlowRunDialogState extends State<_FlowRunDialog> {
|
|||
super.initState();
|
||||
_future = HubService.instance.runSavedFlow(
|
||||
name: widget.flow.name,
|
||||
textInputs: widget.inputs,
|
||||
textInputs: widget.textInputs,
|
||||
fileInputs: widget.fileInputs,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue