forked from WHC/Hermit
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:
@@ -9,6 +9,7 @@
|
||||
#define CST_APP_AGENTCORE_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
@@ -204,6 +205,11 @@ class AgentCore : public QObject {
|
||||
void permissionRequested(const QString &tool, const QString &detail,
|
||||
const QString &preview);
|
||||
void questionAsked(const QString &question, const QString &options);
|
||||
/* The worker asked and nobody answered in time (or the app was in the
|
||||
* background, where the dialog cannot be seen): the turn went on with a
|
||||
* refusal, and the window puts its dialog away again. */
|
||||
void permissionExpired(const QString &tool);
|
||||
void questionExpired();
|
||||
void turnFinished(int rc, const QString &err);
|
||||
void runningChanged();
|
||||
void workspaceChanged();
|
||||
@@ -218,6 +224,10 @@ class AgentCore : public QObject {
|
||||
void syncConfig();
|
||||
/* Re-read what a session switch changed (id, todo) and say so. */
|
||||
void afterSessionChange();
|
||||
/* True when the app is not on screen: a phone in the background (Qt
|
||||
* suspends it), or a window that is not there at all. A dialog opened now
|
||||
* would be invisible, so consent is refused instead of waited for. */
|
||||
bool backgrounded() const;
|
||||
|
||||
/* Hook trampolines (C, run on the worker thread). */
|
||||
static void hookStatus(const char *msg, void *ud);
|
||||
@@ -255,6 +265,15 @@ class AgentCore : public QObject {
|
||||
bool m_permPending = false;
|
||||
QString m_question;
|
||||
QString m_todo;
|
||||
/* The session list rebuilt only when a transcript moved: filling one row
|
||||
* walks the whole file, and the sidebar asks for the list on every store
|
||||
* change. Keyed by id, dropped when the id is gone. */
|
||||
struct SessionCache {
|
||||
qint64 mtime = 0;
|
||||
qint64 size = 0;
|
||||
QVariantMap row;
|
||||
};
|
||||
mutable QHash<QString, SessionCache> m_sessionCache;
|
||||
/* Names of the files this window attached, in the engine's pending order:
|
||||
* the engine's own description says what it is, not where it came from. */
|
||||
QStringList m_attachNames;
|
||||
|
||||
Reference in New Issue
Block a user