Restore missing required asset/flow packages from the pinned nigig revision; retain upstream script isolation, X11 hover, and widget-core fixes. Validated makepad-widgets data feature with Rust 1.97.1.
114 lines
4.8 KiB
Rust
114 lines
4.8 KiB
Rust
//! What the serving box does with the generation session's ACTUAL system
|
|
//! text. Ignored by default; it needs a live fleet box.
|
|
//!
|
|
//! ```text
|
|
//! MAKEPAD_FLEET_BASE=http://10.0.0.165:8123 \
|
|
//! cargo test -p makepad-asset-chat --test live_fleet_probe -- --ignored --nocapture
|
|
//! ```
|
|
//!
|
|
//! It answers one question a model's self-report cannot: given the tool
|
|
//! table we render, does the box emit `image.generate` for "make me a
|
|
//! picture of a unicorn"?
|
|
|
|
use makepad_asset_chat::provider::{ChatProvider, ProviderEvent, TurnInput};
|
|
use makepad_asset_chat::qwen::{FleetQwenChatProvider, HttpFleetTransport};
|
|
use makepad_asset_chat::toolcall;
|
|
use makepad_asset_chat::tools;
|
|
use makepad_asset_chat::wire::{ChatMessage, ChatRole};
|
|
use std::time::{Duration, Instant};
|
|
|
|
fn run(label: &str, capabilities: &str) -> String {
|
|
run_with_history(label, capabilities, Vec::new())
|
|
}
|
|
|
|
fn run_with_history(
|
|
label: &str,
|
|
capabilities: &str,
|
|
history: Vec<ChatMessage>,
|
|
) -> String {
|
|
let base = std::env::var("MAKEPAD_FLEET_BASE").expect("MAKEPAD_FLEET_BASE");
|
|
let mut provider = FleetQwenChatProvider::new(HttpFleetTransport, vec![base]);
|
|
let system = toolcall::render_system(&tools::definitions(), capabilities);
|
|
let mut messages = history;
|
|
messages.push(ChatMessage::new(ChatRole::User, "make me a picture of a unicorn"));
|
|
let input = TurnInput {
|
|
system,
|
|
messages,
|
|
tools_enabled: true,
|
|
dynamic_context: String::new(),
|
|
};
|
|
provider.begin_turn(&input).expect("begin turn");
|
|
let deadline = Instant::now() + Duration::from_secs(180);
|
|
let mut text = String::new();
|
|
while Instant::now() < deadline {
|
|
for ev in provider.poll() {
|
|
match ev {
|
|
ProviderEvent::Delta(t) => text.push_str(&t),
|
|
ProviderEvent::Done { text: t } => {
|
|
let out = if t.is_empty() { text.clone() } else { t };
|
|
println!("=== {label} ===\n{out}\n");
|
|
return out;
|
|
}
|
|
ProviderEvent::Error(e) => panic!("{label}: provider error {e}"),
|
|
_ => {}
|
|
}
|
|
}
|
|
std::thread::sleep(Duration::from_millis(50));
|
|
}
|
|
panic!("{label}: timed out; partial={text}");
|
|
}
|
|
|
|
#[test]
|
|
#[ignore = "needs a live fleet box (MAKEPAD_FLEET_BASE)"]
|
|
fn the_box_calls_image_generate_from_our_tool_table() {
|
|
let out = run("bare table", "");
|
|
assert!(
|
|
out.contains("image.generate"),
|
|
"the box ignored the advertised tool table"
|
|
);
|
|
}
|
|
|
|
/// The failure the user hit: a worker-less server, a few turns of ordinary
|
|
/// chat first, and the model answers "I don't have an image-generation tool
|
|
/// available in this session" instead of calling the tool that is sitting in
|
|
/// its own list. The capability doc's wall of UNAVAILABLE is what did it —
|
|
/// so the generation profile now says, before that list, that the generate
|
|
/// tools are a different path and are live.
|
|
#[test]
|
|
#[ignore = "needs a live fleet box (MAKEPAD_FLEET_BASE)"]
|
|
fn an_offline_operation_worker_does_not_silence_the_generate_tools() {
|
|
// The real assembled context of a `gen` session on a server whose
|
|
// operation worker is down.
|
|
let dynamic = format!(
|
|
"LIVE STORE right now (kind count): mesh 4004, image 271, audio 245\n\n{}{}",
|
|
"The *.generate tools (image, video, audio, speech, music, mesh, world, \
|
|
character) run on the CONNECTED APP's fleet and are AVAILABLE in this \
|
|
session. The registered operations below are a separate, optional path \
|
|
for deriving from an existing asset; their worker status never applies \
|
|
to the generate tools.\n",
|
|
"Registered operations (for operation.create):\n\
|
|
- mesh.from_image.v1 [UNAVAILABLE: the worker is currently offline]: image to mesh\n\
|
|
- depth.from_image.v1 [UNAVAILABLE: the worker is currently offline]: image to depth\n\
|
|
Operations are created in namespace 'gen'. Inputs must be exact revisions \
|
|
bound to this session.\n",
|
|
);
|
|
let caps = makepad_asset_chat::context::assemble(
|
|
makepad_asset_chat::context::ClientProfile::Gen,
|
|
&dynamic,
|
|
);
|
|
// The same warm-up the user's window had before it refused.
|
|
let history = vec![
|
|
ChatMessage::new(ChatRole::User, "hi qwen"),
|
|
ChatMessage::new(ChatRole::Assistant, "Hi! I'm Qwen. How can I help you today?"),
|
|
ChatMessage::new(ChatRole::User, "test"),
|
|
ChatMessage::new(
|
|
ChatRole::Assistant,
|
|
"All good — I'm here and responsive. What can I do for you?",
|
|
),
|
|
];
|
|
let out = run_with_history("worker offline, warmed-up chat", &caps, history);
|
|
assert!(
|
|
out.contains("image.generate"),
|
|
"an offline operation worker talked the model out of generating"
|
|
);
|
|
}
|