v0.9.7: a turn that cannot hang, a session list that reads nothing twice, and PDFs
- consent: on_permission / on_ask_user wait at most two / five minutes, and in
the background (a phone off screen, a window that is gone) the answer is
refused at once with a reason -- a dialog nobody can see blocked the worker
for good, which is what "the app hangs while the agent works" looked like.
- finishTurn() no longer joins the thread it is called from; the event loop
reaps the Turn instead.
- AndroidTools: the hop to the GUI thread pings first and gives up after 3 s
instead of waiting forever on a busy GUI thread.
- the session list stopped reading every transcript: cst_agent_store_info()
counts newlines in 64 KiB blocks (first_user only within the first 256 KiB),
and AgentCore::sessions() reuses a row while (mtime, size) is unchanged.
- session_search gets a budget (max_bytes 32 MB, max_seconds 5 s), skips lines
over 64 KiB, and says when the budget stopped the walk.
- the header shows the phase ("shell: make -j8"), so a long turn no longer
looks like a stuck one.
- md_to_pdf: the front end's own Qt tool (owner app:qt, every platform):
markdown or a workspace .md/.html becomes an A4 PDF with 15 mm margins,
paginated by hand, written into the workspace and delivered as a file card.
No PrintSupport, so the phone gets it too.
- --uitest runs md_to_pdf through the registry with Chinese text and checks the
bytes are a PDF; app/CMakeLists.txt no longer drops src/web_md.c from the
standalone engine build, which the window needs to render markdown.
Version 0.9.7.
This commit is contained in:
@@ -416,6 +416,53 @@ int runUiTest(AgentCore &core, const QString &size) {
|
||||
QStringLiteral("and the line is where the card is"));
|
||||
}
|
||||
|
||||
/* --- md_to_pdf: the front end's own document writer ------------------- */
|
||||
{
|
||||
const cst_tool_def_t *def = cst_tool_find("md_to_pdf");
|
||||
check(def != nullptr && def->owner != nullptr &&
|
||||
strncmp(def->owner, "app:qt", 6) == 0,
|
||||
QStringLiteral("md_to_pdf is registered by the front end"));
|
||||
if (def && def->run_ex) {
|
||||
/* Run it the way the agent's turn would: through the registry, with a
|
||||
* call and the engine's context. */
|
||||
const QByteArray ws = core.workspace().toUtf8();
|
||||
cst_tool_ctx_t ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.workspace_root = ws.constData();
|
||||
ctx.agent = core.agent();
|
||||
ctl_tool_call_t call;
|
||||
memset(&call, 0, sizeof(call));
|
||||
snprintf(call.id, sizeof(call.id), "pdf1");
|
||||
snprintf(call.name, sizeof(call.name), "md_to_pdf");
|
||||
static const char *kMd =
|
||||
"# 设备信息报告\n\n这是一段**中文**正文,用来确认字体和分页。\n\n"
|
||||
"- 项目一\n- 项目二\n\n```\ncode block\n```\n";
|
||||
static const char *kOut = "selftest.pdf";
|
||||
snprintf(call.args[0].key, sizeof(call.args[0].key), "markdown");
|
||||
call.args[0].value = const_cast<char *>(kMd);
|
||||
call.args[0].value_len = strlen(kMd);
|
||||
snprintf(call.args[1].key, sizeof(call.args[1].key), "out");
|
||||
call.args[1].value = const_cast<char *>(kOut);
|
||||
call.args[1].value_len = strlen(kOut);
|
||||
call.nargs = 2;
|
||||
cst_tool_result_t res;
|
||||
memset(&res, 0, sizeof(res));
|
||||
const int rc = cst_tool_run(&ctx, &call, &res);
|
||||
check(res.exit_code == 0,
|
||||
QStringLiteral("md_to_pdf writes the document (%1)")
|
||||
.arg(QString::fromUtf8(res.out ? res.out : "")));
|
||||
check(rc == 0 && res.nattach == 1,
|
||||
QStringLiteral("and hands it over as a file for the user"));
|
||||
QFile f(core.workspace() + QStringLiteral("/selftest.pdf"));
|
||||
const bool opened = f.open(QIODevice::ReadOnly);
|
||||
const QByteArray head = opened ? f.read(5) : QByteArray();
|
||||
check(head == QByteArrayLiteral("%PDF-"),
|
||||
QStringLiteral("the bytes are a PDF (%1)")
|
||||
.arg(QString::fromLatin1(head)));
|
||||
cst_tool_result_free(&res);
|
||||
}
|
||||
}
|
||||
|
||||
/* new sessions: the engine moves, the view empties, the store grows */
|
||||
const int before = core.sessions().size();
|
||||
clickMouse(win, QStringLiteral("newSessionButton"));
|
||||
|
||||
Reference in New Issue
Block a user