Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## Unreleased

- Coze 集成补齐开发者文档全量能力:`AsyncCozeClient.upload_file` 走 `/v1/files/upload`
(multipart);新增 `file_object`/`image_object`/`text_object` 与 `object_string` 消息编码,
支持在 `additional_messages` 中携带文件/图片。
- `CozeAgentNode`/`CozeChatModel` 流式输出 `reasoning_content`(思考信息,打
`additional_kwargs={"reasoning": True}` 标记)并收集 `follow_up` 用户问题建议,写入最终
`AIMessage.additional_kwargs`(`reasoning_content`/`follow_ups`)与 `response_metadata`。
`CozeAgentNode(suggestions_key=...)` 可选把建议写入 state(默认 `None`,不破坏严格 schema)。
- 修复:`conversation.message.delta`/`.completed` 流式路径此前未按 `data.type` 过滤,
`verbose`(多智能体 jump 信息)、`function_call`、`knowledge_recall` 等非正文消息会被
错误拼接进可见回答;新增 `_is_answer_delta` 只放行 `type in (None, "answer")`。
- 新增会话/消息管理端点:`conversation_retrieve`、`conversation_message_create`、
`conversation_message_list`(游标分页)、`conversation_message_retrieve`;新增
`file_retrieve`(查询上传文件状态)与 `bot_retrieve`(bot 元信息)。
- `conversation.chat.completed` 的 `usage`(`token_count`/`input_count`/`output_count`)
现在会写入最终 `AIMessage.usage`,流式与轮询路径均覆盖。

## 2.0.0

- 完成 MVP P0/P1 硬化:强类型 state/output/工具参数校验、结构化输出修复、工具权限/审批/
Expand Down
40 changes: 40 additions & 0 deletions docs/integrations-coze.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,46 @@ conversation_id 写入用户声明的 `coze_conversations` 状态键。SSE delta
`astream(..., stream_mode="messages"|"events")` 已可消费,Chainlit 可直接逐 token 调用
`stream_token()`。requires_action 可交给本地工具或通过 `hitl=True` 触发耐久审批 interrupt。

## 完整能力(对齐 Coze 开发者文档)

- **流式返回**:SSE `conversation.message.delta` 的 `content` 逐 token 通过 messages 模式输出。
- **思考信息流式输出**:delta 中的 `reasoning_content` 单独形成 `AIMessageChunk`,并在
`additional_kwargs={"reasoning": True}` 上打标,Chainlit 侧据此渲染独立的“思考中”Step;
完整思维链也汇总到最终 `AIMessage.additional_kwargs["reasoning_content"]`。
- **用户问题建议(follow-up)**:`conversation.message.completed` 中 `type == "follow_up"`
的消息被收集为建议问题,写入最终 `AIMessage.additional_kwargs["follow_ups"]` 与
`response_metadata["follow_ups"]`;若 `CozeAgentNode(suggestions_key=...)` 指定了状态键
(且图 state schema 已声明),也会写入该键。非流式轮询路径从 `chat/message/list` 的
`type == "follow_up"` 条目提取,逻辑一致。
- **文件上传**:`AsyncCozeClient.upload_file(content, filename=..., content_type=...)` 调用
`/v1/files/upload`(multipart),返回含 `id` 的文件元数据。用 `file_object(file_id)` /
`image_object(file_id)` / `text_object(text)` 构造 `object_string` 项,放入
`HumanMessage(additional_kwargs={"objects": [...]})`;`_message_to_coze` 会自动切换为
`content_type="object_string"`,并在缺省时把消息正文补成首个 text 项。`file_retrieve(file_id)`
可查询上传文件的处理状态/元数据。
- **Token 用量**:`conversation.chat.completed`(流式)与轮询终态 `chat` 对象的 `usage`
字段(`token_count`/`input_count`/`output_count`)会写入最终 `AIMessage.usage`。

`suggestions_key` 默认 `None`:只有显式指定且 state schema 声明该键时才写入,避免破坏严格
schema 的图。

### 消息 type 过滤(重要)

Coze `conversation.message.delta` / `.completed` 把 `answer`、`function_call`、
`tool_output`、`verbose`(如多智能体 jump 信息)、`knowledge_recall`、`follow_up` 等不同
语义的消息复用同一个事件名,仅靠 `event:` 无法区分。集成内部用 `_is_answer_delta(data)`
(即 `data["type"] in (None, "answer")`)过滤出真正要展示给用户的正文,避免 verbose/
function_call/knowledge_recall 内容混入可见回答;`follow_up` 单独按 `_extract_follow_up`
收集。自定义消费 `chat_stream()`/`workflow_stream()` 原始事件时也应做同样的 `type` 判断。

### 会话与消息管理

除 `create_conversation` 外,还提供 `conversation_retrieve`、
`conversation_message_create`(直接向会话追加消息,不触发 chat 运行)、
`conversation_message_list`(`before_id`/`after_id`/`limit` 游标分页,返回
`items`/`first_id`/`last_id`/`has_more`)、`conversation_message_retrieve`。
`bot_retrieve(bot_id)` 对应 `/v1/bot/get_online_info`,用于读取 bot 元信息。

`CozeWorkflowNode` 遇到工作流 interrupt 时返回 `coze_workflow_question`。恢复值必须回显
`event_id`、`interrupt_type` 和 `resume_data`,例如:

Expand Down
13 changes: 12 additions & 1 deletion src/lingxigraph/integrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@


def __getattr__(name: str) -> Any:
if name in {"AsyncCozeClient", "CozeAgentNode", "CozeChatModel", "CozeWorkflowNode"}:
if name in {
"AsyncCozeClient",
"CozeAgentNode",
"CozeChatModel",
"CozeWorkflowNode",
"file_object",
"image_object",
"text_object",
}:
from . import coze

return getattr(coze, name)
Expand All @@ -23,4 +31,7 @@ def __getattr__(name: str) -> Any:
"CozeChatModel",
"CozeWorkflowNode",
"OpenAICompatChatModel",
"file_object",
"image_object",
"text_object",
]
Loading
Loading