309 lines
8.8 KiB
C++
309 lines
8.8 KiB
C++
#include "session_manager.h"
|
|
#include "libollie.h"
|
|
|
|
#include <QDebug>
|
|
#include <QMetaObject>
|
|
|
|
// Global pointer to the singleton — used by C callbacks to route events.
|
|
static SessionManager *g_instance = nullptr;
|
|
|
|
// --- C callback handlers (called from Go goroutines, must be thread-safe) ---
|
|
|
|
static void onStateChange(const char *session_id, const char *state)
|
|
{
|
|
if (!g_instance) return;
|
|
QString sid = QString::fromUtf8(session_id);
|
|
QString st = QString::fromUtf8(state);
|
|
// Marshal to the Qt event loop thread
|
|
QMetaObject::invokeMethod(g_instance, [sid, st]() {
|
|
emit g_instance->StateChanged(sid, st);
|
|
}, Qt::QueuedConnection);
|
|
}
|
|
|
|
static void onChatUpdate(const char *session_id, int64_t offset, const char *text, int len)
|
|
{
|
|
if (!g_instance) return;
|
|
QString sid = QString::fromUtf8(session_id);
|
|
QString txt = QString::fromUtf8(text, len);
|
|
qlonglong off = static_cast<qlonglong>(offset);
|
|
QMetaObject::invokeMethod(g_instance, [sid, off, txt]() {
|
|
emit g_instance->ChatUpdated(sid, off, txt);
|
|
}, Qt::QueuedConnection);
|
|
}
|
|
|
|
// --- SessionManager implementation ---
|
|
|
|
SessionManager::SessionManager(QObject *parent)
|
|
: QObject(parent)
|
|
{
|
|
g_instance = this;
|
|
ollie_init(nullptr);
|
|
installCallbacks();
|
|
qDebug() << "SessionManager: initialized ollie core";
|
|
}
|
|
|
|
SessionManager::~SessionManager()
|
|
{
|
|
ollie_shutdown();
|
|
g_instance = nullptr;
|
|
qDebug() << "SessionManager: shut down ollie core";
|
|
}
|
|
|
|
void SessionManager::installCallbacks()
|
|
{
|
|
ollie_on_state_change(onStateChange);
|
|
ollie_on_chat_update(onChatUpdate);
|
|
}
|
|
|
|
// --- Session lifecycle ---
|
|
|
|
QString SessionManager::CreateSession(const QString &cwd, const QString &backend,
|
|
const QString &model, const QString &agent)
|
|
{
|
|
QByteArray cwdUtf8 = cwd.toUtf8();
|
|
QByteArray backendUtf8 = backend.toUtf8();
|
|
QByteArray modelUtf8 = model.toUtf8();
|
|
QByteArray agentUtf8 = agent.toUtf8();
|
|
|
|
char *outID = nullptr;
|
|
int rc = ollie_create_session(
|
|
const_cast<char*>(cwdUtf8.constData()),
|
|
const_cast<char*>(backendUtf8.constData()),
|
|
const_cast<char*>(modelUtf8.constData()),
|
|
const_cast<char*>(agentUtf8.constData()),
|
|
&outID);
|
|
if (rc != 0 || !outID) {
|
|
qWarning() << "CreateSession failed, rc=" << rc;
|
|
return QString();
|
|
}
|
|
|
|
QString sessionID = QString::fromUtf8(outID);
|
|
ollie_free(outID);
|
|
|
|
emit SessionCreated(sessionID);
|
|
return sessionID;
|
|
}
|
|
|
|
QStringList SessionManager::ListSessions()
|
|
{
|
|
char *buf = nullptr;
|
|
ollie_list_sessions(&buf);
|
|
QStringList result;
|
|
|
|
if (buf) {
|
|
QString raw = QString::fromUtf8(buf);
|
|
ollie_free(buf);
|
|
result = raw.split('\n', Qt::SkipEmptyParts);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool SessionManager::KillSession(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
int rc = ollie_kill_session(const_cast<char*>(idUtf8.constData()));
|
|
if (rc == 0) {
|
|
emit SessionKilled(session_id);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SessionManager::RenameSession(const QString &session_id, const QString &new_name)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
QByteArray nameUtf8 = new_name.toUtf8();
|
|
int rc = ollie_rename_session(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
const_cast<char*>(nameUtf8.constData()));
|
|
return rc == 0;
|
|
}
|
|
|
|
// --- Interaction ---
|
|
|
|
bool SessionManager::Submit(const QString &session_id, const QString &prompt)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
QByteArray promptUtf8 = prompt.toUtf8();
|
|
int rc = ollie_submit(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
const_cast<char*>(promptUtf8.constData()));
|
|
return rc == 0;
|
|
}
|
|
|
|
bool SessionManager::Interrupt(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
int rc = ollie_interrupt(const_cast<char*>(idUtf8.constData()));
|
|
return rc == 0;
|
|
}
|
|
|
|
// --- State queries ---
|
|
|
|
QString SessionManager::GetState(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int rc = ollie_get_state(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (rc != 0 || !out) return QString();
|
|
QString state = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return state;
|
|
}
|
|
|
|
QString SessionManager::GetChat(const QString &session_id, qlonglong offset, qlonglong &new_offset)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int64_t newOff = 0;
|
|
int rc = ollie_get_chat(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
static_cast<int64_t>(offset), &out, &newOff);
|
|
if (rc != 0 || !out) {
|
|
new_offset = offset;
|
|
return QString();
|
|
}
|
|
QString text = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
new_offset = static_cast<qlonglong>(newOff);
|
|
return text;
|
|
}
|
|
|
|
QString SessionManager::GetUsage(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int rc = ollie_get_usage(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (rc != 0 || !out) return QString();
|
|
QString usage = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return usage;
|
|
}
|
|
|
|
QString SessionManager::GetCost(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int rc = ollie_get_cost(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (rc != 0 || !out) return QString();
|
|
QString cost = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return cost;
|
|
}
|
|
|
|
// --- Config ---
|
|
|
|
QString SessionManager::GetConfig(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int rc = ollie_get_config(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (rc != 0 || !out) return QString();
|
|
QString config = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return config;
|
|
}
|
|
|
|
bool SessionManager::SetConfig(const QString &session_id, const QString &key, const QString &value)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
QByteArray keyUtf8 = key.toUtf8();
|
|
QByteArray valueUtf8 = value.toUtf8();
|
|
int rc = ollie_set_config(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
const_cast<char*>(keyUtf8.constData()),
|
|
const_cast<char*>(valueUtf8.constData()));
|
|
return rc == 0;
|
|
}
|
|
|
|
// --- Context ---
|
|
|
|
QString SessionManager::GetContext(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int rc = ollie_get_context(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (rc != 0 || !out) return QString();
|
|
QString context = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return context;
|
|
}
|
|
|
|
// --- Backends/models/agents ---
|
|
|
|
QStringList SessionManager::ListBackends()
|
|
{
|
|
char *out = nullptr;
|
|
ollie_list_backends(&out);
|
|
if (!out) return {};
|
|
QString raw = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return raw.split('\n', Qt::SkipEmptyParts);
|
|
}
|
|
|
|
QStringList SessionManager::ListModels(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
int rc = ollie_list_models(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (rc != 0 || !out) return {};
|
|
QString raw = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return raw.split('\n', Qt::SkipEmptyParts);
|
|
}
|
|
|
|
QStringList SessionManager::ListAgents()
|
|
{
|
|
char *out = nullptr;
|
|
ollie_list_agents(&out);
|
|
if (!out) return {};
|
|
QString raw = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return raw.split('\n', Qt::SkipEmptyParts);
|
|
}
|
|
|
|
// --- Peers ---
|
|
|
|
bool SessionManager::PeerAdd(const QString &session_id, const QString &peer_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
QByteArray peerUtf8 = peer_id.toUtf8();
|
|
int rc = ollie_peer_add(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
const_cast<char*>(peerUtf8.constData()));
|
|
return rc == 0;
|
|
}
|
|
|
|
bool SessionManager::PeerRemove(const QString &session_id, const QString &peer_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
QByteArray peerUtf8 = peer_id.toUtf8();
|
|
int rc = ollie_peer_remove(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
const_cast<char*>(peerUtf8.constData()));
|
|
return rc == 0;
|
|
}
|
|
|
|
QStringList SessionManager::PeerList(const QString &session_id)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
char *out = nullptr;
|
|
ollie_peer_list(const_cast<char*>(idUtf8.constData()), &out);
|
|
if (!out) return {};
|
|
QString raw = QString::fromUtf8(out);
|
|
ollie_free(out);
|
|
return raw.split('\n', Qt::SkipEmptyParts);
|
|
}
|
|
|
|
bool SessionManager::PeerSubmit(const QString &session_id, const QString &peer_id, const QString &prompt)
|
|
{
|
|
QByteArray idUtf8 = session_id.toUtf8();
|
|
QByteArray peerUtf8 = peer_id.toUtf8();
|
|
QByteArray promptUtf8 = prompt.toUtf8();
|
|
int rc = ollie_peer_submit(
|
|
const_cast<char*>(idUtf8.constData()),
|
|
const_cast<char*>(peerUtf8.constData()),
|
|
const_cast<char*>(promptUtf8.constData()));
|
|
return rc == 0;
|
|
}
|