Properly report that the computation was timedout to the model (#3369)

Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
AT 2025-01-07 14:02:18 -05:00 committed by GitHub
parent ce6558ec94
commit 22f6a7f1bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 18 additions and 9 deletions

View File

@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
- Fix the timeout error in code interpreter ([#3369](https://github.com/nomic-ai/gpt4all/pull/3369))
## [3.6.1] - 2024-12-20 ## [3.6.1] - 2024-12-20
### Fixed ### Fixed

View File

@ -26,7 +26,7 @@ QString CodeInterpreter::run(const QList<ToolParam> &params, qint64 timeout)
workerThread.start(); workerThread.start();
bool timedOut = !workerThread.wait(timeout); bool timedOut = !workerThread.wait(timeout);
if (timedOut) { if (timedOut) {
worker.interrupt(); // thread safe worker.interrupt(timeout); // thread safe
m_error = ToolEnums::Error::TimeoutError; m_error = ToolEnums::Error::TimeoutError;
} }
workerThread.quit(); workerThread.quit();
@ -96,14 +96,17 @@ void CodeInterpreterWorker::request(const QString &code)
m_engine.globalObject().setProperty("console", consoleObject); m_engine.globalObject().setProperty("console", consoleObject);
const QJSValue result = m_engine.evaluate(code); const QJSValue result = m_engine.evaluate(code);
QString resultString = result.isUndefined() ? QString() : result.toString();
// NOTE: We purposely do not set the m_error or m_errorString for the code interpreter since QString resultString;
// we *want* the model to see the response has an error so it can hopefully correct itself. The
// error member variables are intended for tools that have error conditions that cannot be corrected. if (m_engine.isInterrupted()) {
// For instance, a tool depending upon the network might set these error variables if the network resultString = QString("Error: code execution was timed out as it exceeded %1 ms. Code must be written to ensure execution does not timeout.").arg(m_timeout);
// is not available. } else if (result.isError()) {
if (result.isError()) { // NOTE: We purposely do not set the m_error or m_errorString for the code interpreter since
// we *want* the model to see the response has an error so it can hopefully correct itself. The
// error member variables are intended for tools that have error conditions that cannot be corrected.
// For instance, a tool depending upon the network might set these error variables if the network
// is not available.
const QStringList lines = code.split('\n'); const QStringList lines = code.split('\n');
const int line = result.property("lineNumber").toInt(); const int line = result.property("lineNumber").toInt();
const int index = line - 1; const int index = line - 1;
@ -114,6 +117,8 @@ void CodeInterpreterWorker::request(const QString &code)
.arg(lineContent); .arg(lineContent);
m_error = ToolEnums::Error::UnknownError; m_error = ToolEnums::Error::UnknownError;
m_errorString = resultString; m_errorString = resultString;
} else {
resultString = result.isUndefined() ? QString() : result.toString();
} }
if (resultString.isEmpty()) if (resultString.isEmpty())

View File

@ -42,7 +42,7 @@ public:
QString response() const { return m_response; } QString response() const { return m_response; }
void request(const QString &code); void request(const QString &code);
void interrupt() { m_engine.setInterrupted(true); } void interrupt(qint64 timeout) { m_timeout = timeout; m_engine.setInterrupted(true); }
ToolEnums::Error error() const { return m_error; } ToolEnums::Error error() const { return m_error; }
QString errorString() const { return m_errorString; } QString errorString() const { return m_errorString; }
@ -50,6 +50,7 @@ Q_SIGNALS:
void finished(); void finished();
private: private:
qint64 m_timeout = 0;
QJSEngine m_engine; QJSEngine m_engine;
QString m_response; QString m_response;
ToolEnums::Error m_error = ToolEnums::Error::NoError; ToolEnums::Error m_error = ToolEnums::Error::NoError;