Visindigo::Agent::Dialog Class
class Visindigo::Agent::Dialog一次完整的对话及其执行入口. 详情...
| 头文件: | #include <Agent/Dialog.h> |
| 自以下版本: | Visindigo 0.17.0 |
公开成员函数
(自 Visindigo 0.17.0 引入) | Dialog() |
(自 Visindigo 0.17.0 引入) virtual | ~Dialog() |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | addFunction(Visindigo::Agent::Function *function) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | addMCP(const Visindigo::Agent::MCP &server) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | addPrompt(const Visindigo::Agent::Prompt &prompt) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | addSkill(const Visindigo::Agent::Skill &skill) |
(自 Visindigo 0.17.0 引入) void | appendDelta(const QString &delta) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | appendMessage(const Visindigo::Agent::Message &message) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | appendMessage(Visindigo::Agent::Message::Role role, const QString &content) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | appendPrompt(const QString &name, const QMap<QString, QString> &variables = {}) |
(自 Visindigo 0.17.0 引入) void | beginAssistantMessage() |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | clearMessages() |
(自 Visindigo 0.17.0 引入) bool | copyTo(Visindigo::Agent::Dialog *target) const |
(自 Visindigo 0.17.0 引入) void | endAssistantMessage() |
(自 Visindigo 0.17.0 引入) qint32 | findLastAssistantMessage() const |
(自 Visindigo 0.17.0 引入) bool | fromJson(const Visindigo::Utility::JsonConfig &json) |
(自 Visindigo 0.17.0 引入) QString | getBranchFromID() const |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Model::Capabilities | getCapabilityRequirement() const |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Function * | getFunction(const QString &id) const |
(自 Visindigo 0.17.0 引入) QStringList | getFunctionIds() const |
(自 Visindigo 0.17.0 引入) QString | getId() const |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Message | getLastMessage() const |
(自 Visindigo 0.17.0 引入) QList<Visindigo::Agent::MCP> | getMCPs() const |
(自 Visindigo 0.17.0 引入) qint32 | getMessageCount() const |
(自 Visindigo 0.17.0 引入) QList<Visindigo::Agent::Message> | getMessages() const |
(自 Visindigo 0.17.0 引入) QString | getModelId() const |
(自 Visindigo 0.17.0 引入) QList<Visindigo::Agent::Prompt> | getPrompts() const |
(自 Visindigo 0.17.0 引入) QString | getProviderId() const |
(自 Visindigo 0.17.0 引入) QString | getReasoningContent() const |
(自 Visindigo 0.17.0 引入) QList<Visindigo::Agent::Skill> | getSkills() const |
(自 Visindigo 0.17.0 引入) QString | getStreamingContent() const |
(自 Visindigo 0.17.0 引入) bool | isStreaming() const |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | removeFunction(const QString &id) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | removeMCP(const QString &name) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | removePrompt(const QString &name) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | removeSkill(const QString &name) |
(自 Visindigo 0.17.0 引入) void | run() |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | setBranchFromID(const QString &id) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | setCapabilityRequirement(Visindigo::Agent::Model::Capabilities required) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | setModelId(const QString &id) |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | setProviderId(const QString &id) |
(自 Visindigo 0.17.0 引入) Visindigo::Utility::JsonConfig | toJson() const |
(自 Visindigo 0.17.0 引入) Visindigo::Agent::Dialog & | truncateTo(qint32 messageCount) |
信号
(自 Visindigo 0.17.0 引入) void | messageAppended(qint32 index) |
(自 Visindigo 0.17.0 引入) void | runFailed(const QString &message) |
(自 Visindigo 0.17.0 引入) void | streamBegan() |
(自 Visindigo 0.17.0 引入) void | streamDelta(const QString &delta) |
(自 Visindigo 0.17.0 引入) void | streamEnded(const QString &fullContent) |
(自 Visindigo 0.17.0 引入) void | streamReasoning(const QString &delta) |
详细说明
Dialog 持有消息列表、这次对话可用的 Skill / MCP / Function / Prompt, 以及要用哪个 Provider 的哪个模型。run() 会把当前消息发出去,把流式 返回的内容通过信号吐出,并在模型请求调用工具时自动执行工具、把结果 回灌后继续请求,直到模型给出最终答复。
每个 Dialog 在构造时获得一个 UUID,之后不再改变——它同时是 Center 里的 索引键和会话记录里的标识。setBranchFromID() 记录"本条对话是从哪条 分出来的",重新生成回答时新对话会指向被它取代的那条,于是分支关系自然而 然地留在数据里,不需要额外维护一棵树。
run() 上的配置优先级是:本 Dialog 上挂的 Skill / MCP / Function / Prompt 覆盖 Center 上的同名全局配置。这让人可以给某次特殊对话临时挂一个技能, 而不必先去全局配置里删掉同名项。
Note: Dialog 的所有权属于 Center。请通过 Center::removeDialog() 销毁, 直接 delete 会让 Center 的表里留下一个悬空指针。
成员函数文档
[since Visindigo 0.17.0] Dialog::Dialog()
构造一个空对话,并立即分配一个新的 UUID。
这个function 从 Visindigo 0.17.0 开始支持。
[virtual noexcept, since Visindigo 0.17.0] Dialog::~Dialog()
中止仍在进行的请求,并释放本对话独占的函数对象。
Warning: 这里不会把自己从 Center 的表中摘除。销毁对话请调用 Center::removeDialog()。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::addFunction(Visindigo::Agent::Function *function)
给本对话挂一个函数,所有权随之转移给本对话。
同一个 id 重复添加会替换旧项,旧对象被释放。传入 nullptr 什么也不做。
function 要挂载的函数对象,所有权随之转移给本对话。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::addMCP(const Visindigo::Agent::MCP &server)
给本对话挂一个工具服务器配置,同名会覆盖 Center 上的全局同名项。
server 要挂载的工具服务器配置。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::addPrompt(const Visindigo::Agent::Prompt &prompt)
给本对话挂一个提示模板,同名会覆盖 Center 上的全局同名项。
prompt 要挂载的提示模板。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::addSkill(const Visindigo::Agent::Skill &skill)
给本对话挂一个技能。同名技能会覆盖 Center 上的全局同名项。
skill 要挂载的技能。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] void Dialog::appendDelta(const QString &delta)
追加一段流式增量,并发出 streamDelta()。
Note: 增量是模型输出的碎片,可能从多字节字符或 Markdown 语法的中途切开, 因此不要对单个增量做解析,只能对累积结果做。
delta 本次新增的正文片段。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::appendMessage(const Visindigo::Agent::Message &message)
追加一条消息,并发出 messageAppended()。
message 要追加的消息。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::appendMessage(Visindigo::Agent::Message::Role role, const QString &content)
以角色与内容追加一条消息的便捷重载。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::appendPrompt(const QString &name, const QMap<QString, QString> &variables = {})
查找模板、渲染并追加为一条消息。模板名不存在时什么也不做。
查找顺序是先本对话后 Center,与 run() 的覆盖规则一致。
name 模板名称。 variables 模板变量表。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] void Dialog::beginAssistantMessage()
开始接收一条助手消息:清空流式缓冲并发出 streamBegan()。
流式接收由 run() 自行驱动,手工调用它只适用于自己实现了传输、 想复用本对话渲染逻辑的场景。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::clearMessages()
清空全部消息,但保留技能、工具与模型配置。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] bool Dialog::copyTo(Visindigo::Agent::Dialog *target) const
把消息与配置复制到另一条对话。
复制的内容包括消息列表、Skill / MCP / Prompt、Provider 与模型选择、 能力要求。目标对话保留自己的 id,这样可以先看一份草稿再决定是否让它 取代原对话。
Note: 函数对象不会被复制。Function 是带有独占所有权的接口,无法深拷贝, 共享指针又会在两边析构时重复释放;需要跨对话复用的工具请注册到 Center 上, 那里本来就是通过 id 解析的。目标对话自己原有的函数保持不变。
target 复制目标对话。
return 复制是否成功;目标为空或就是自身时返回 false。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] void Dialog::endAssistantMessage()
结束流式接收:把缓冲内容作为一条助手消息追加到对话末尾,发出 messageAppended() 与 streamEnded()。
缓冲为空时不追加消息,但仍会发出 streamEnded(),以便界面上把"正在 生成"的状态收回去。
思考内容会被一并写进这条消息(见 Message::setReasoning()),因此历史 记录里每一轮都能看到当时是怎么想的,而不只是最后说了什么。这一步必须在 清空缓冲之前完成:思考原本只活在缓冲区里,一旦漏掉,界面上那一段就会 随着流式状态一起消失,留下的答复看不出为什么是那个结论。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] qint32 Dialog::findLastAssistantMessage() const
返回最后一条助手消息的下标;没有助手消息时返回 -1。
下标可以直接交给 truncateTo():保留到这个下标为止,就恰好丢掉了那次 回答以及之后的所有内容,这正是"重新生成"需要的前置状态。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] bool Dialog::fromJson(const Visindigo::Utility::JsonConfig &json)
从 JSON 对象恢复。
存档里的 id 会被恢复,这是 Dialog 的 id 唯一的赋值入口。没有 id 字段时 保留当前(新生成的)id。
Warning: 函数对象不在存档里,恢复后需要重新用 addFunction() 挂上; 否则模型请求调用工具时会收到"未知工具"的答复。
json 已解析的 JSON 对象。
return 是否恢复了存档里的 id。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QString Dialog::getBranchFromID() const
返回分叉来源的 id;不是由其他对话派生而来时返回空串。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Model::Capabilities Dialog::getCapabilityRequirement() const
返回挑选模型时的最低能力要求。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Function *Dialog::getFunction(const QString &id) const
按 id 查找函数,先查本对话再查 Center。找不到时返回 nullptr。
id 函数 id。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QStringList Dialog::getFunctionIds() const
返回本对话独占的函数 id,不含 Center 上的全局函数。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QString Dialog::getId() const
返回对话的唯一标识。它在构造时生成,之后不再变化。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Message Dialog::getLastMessage() const
返回最后一条消息;没有任何消息时返回空消息。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QList<Visindigo::Agent::MCP> Dialog::getMCPs() const
返回本对话挂载的工具服务器配置。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] qint32 Dialog::getMessageCount() const
返回消息条数。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QList<Visindigo::Agent::Message> Dialog::getMessages() const
返回全部消息,按时间顺序。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QString Dialog::getModelId() const
返回指定的模型 id;未指定时返回空串。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QList<Visindigo::Agent::Prompt> Dialog::getPrompts() const
返回本对话挂载的提示模板。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QString Dialog::getProviderId() const
返回指定的 Provider id;未指定时返回空串。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QString Dialog::getReasoningContent() const
返回最近一次生成中模型给出的思考内容,供界面在生成过程中实时展示。
推理模型的思考过程从 streamDelta() 之外的通道到达,它不属于回答, 因此不会在下一轮被重新发回服务端。生成结束后,这段内容会被写进对应的 助手消息(见 Message::getReasoning()),历史记录里仍能查到; 本函数只反映“当前这一次”的缓冲,在每次 beginAssistantMessage() 时清空。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QList<Visindigo::Agent::Skill> Dialog::getSkills() const
返回本对话挂载的技能,不含 Center 上的全局技能。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] QString Dialog::getStreamingContent() const
返回当前已接收但尚未收尾的流式内容。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] bool Dialog::isStreaming() const
判断本对话是否正在接收流式响应。
return 正在接收流式响应时返回 true。
这个function 从 Visindigo 0.17.0 开始支持。
[signal, since Visindigo 0.17.0] void Dialog::messageAppended(qint32 index)
新增了一条消息。index 是它在 getMessages() 中的下标。
Note: 只报下标不报内容,是为了让监听方自己去取:同一条消息在发出信号之后 仍可能被继续改写,传一份副本出去反而会造成"界面上的和实际存的不一样"。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::removeFunction(const QString &id)
移除并释放本对话上的函数。移除之后,Center 上的全局同名函数会重新生效。
id 函数 id。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::removeMCP(const QString &name)
移除本对话上的同名工具服务器配置。
name 工具服务器名称。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::removePrompt(const QString &name)
移除本对话上的同名提示模板。
name 模板名称。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::removeSkill(const QString &name)
移除本对话上的同名技能。移除之后,Center 上的全局同名技能会重新生效。
name 技能名称。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] void Dialog::run()
执行本对话。
流程是:解析 Provider 与模型、拼装请求体(系统提示来自技能,消息来自 消息列表,工具声明来自函数表),随后发起流式请求。响应中的文本增量通过 streamDelta() 实时吐出;如果模型要求调用工具,则依次执行、把结果作为 Message::Role::Tool 消息追加,然后自动再发一轮,直到模型给出不含工具 调用的最终答复。
结果是异步的,本函数在请求发出后就返回。流程结束会发出 streamEnded(), 失败则发出 runFailed()。
Note: 同一时刻只允许一次执行。正在执行时再次调用会直接发出 runFailed(), 而不会排队——把两次生成叠在一起只会让会话记录变成一堆无法解释的片段。
这个function 从 Visindigo 0.17.0 开始支持。
[signal, since Visindigo 0.17.0] void Dialog::runFailed(const QString &message)
执行失败。message 是可以直接展示给用户的原因描述。
Note: 失败之后不会再有 streamEnded,因此界面上必须两个信号都接,否则 "正在生成"的状态会一直挂着消不掉。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::setBranchFromID(const QString &id)
记录本对话从哪条对话分出来。全新对话留空。
它表达的是"这条对话取代了哪一条",因此重新生成回答时,新对话指向被它 取代的那条,分支关系就自然形成了,不需要额外的树结构。
id 被本条对话取代的对话 id;全新对话传空串。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::setCapabilityRequirement(Visindigo::Agent::Model::Capabilities required)
设置挑选模型时的最低能力要求,默认要求文本能力。
当一次对话需要图片输入时把它设为文本与图片的按位或,模型挑选就会自动 跳过不支持图片的端点,而不是把图片发过去等一个 400 回来。
required 最低能力要求,多个能力按位或。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::setModelId(const QString &id)
指定本次对话使用的模型。留空或指定的模型不可用时,由 Provider 按能力 要求自行挑选。
id 模型 id;留空表示由 Provider 挑选。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::setProviderId(const QString &id)
指定本次对话使用的 Provider。留空时使用 Center::getDefaultProvider()。
id Provider 的 id;留空表示使用 Center 的默认 Provider。
这个function 从 Visindigo 0.17.0 开始支持。
[signal, since Visindigo 0.17.0] void Dialog::streamBegan()
开始一轮生成。这一轮的增量从此刻开始到达。
这个function 从 Visindigo 0.17.0 开始支持。
[signal, since Visindigo 0.17.0] void Dialog::streamDelta(const QString &delta)
回答正文的增量。
delta 本次新增的正文片段。
这个function 从 Visindigo 0.17.0 开始支持。
[signal, since Visindigo 0.17.0] void Dialog::streamEnded(const QString &fullContent)
这一轮生成结束。fullContent 是完整的回答正文。
出现工具调用时,一轮结束后会立刻开始下一轮,因此一次 run() 可能触发 多次 streamBegan 与 streamEnded。
这个function 从 Visindigo 0.17.0 开始支持。
[signal, since Visindigo 0.17.0] void Dialog::streamReasoning(const QString &delta)
思考内容的增量。仅推理模型会发出。
Note: 它与 streamDelta 是两条独立的通道:思考不属于回答,不会进入下一轮 请求,但会随 Message::setReasoning() 存进对应的助手消息。
delta 本次新增的思考片段。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Utility::JsonConfig Dialog::toJson() const
序列化为 JSON 对象,包含 id、分叉来源、模型选择、能力要求、消息列表, 以及本对话挂载的技能、工具服务器与模板。
Note: 函数对象无法序列化:它们承载的是可执行代码而不是数据。
这个function 从 Visindigo 0.17.0 开始支持。
[since Visindigo 0.17.0] Visindigo::Agent::Dialog &Dialog::truncateTo(qint32 messageCount)
只保留前 messageCount 条消息,删除其余部分。
messageCount 大于当前条数时什么也不做;为 0 时清空全部消息。
这个function 从 Visindigo 0.17.0 开始支持。