fix: Init 前 AcquireRoundtableRoom

与 Java 对齐,避免新版 Gateway「会商会话标识缺失」。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
gozerosandCursor committed 2026-11-05 11:24:29 +08:00
1 parent 5dd5049298
commit 6ef395a7f5
2 files changed
+68 -1

No files matched your search

+62 -1
View File
@@ -86,8 +86,40 @@ type InitMultiAgentOpts struct {
RoomSessionID string
}
// AcquireRoundtableRoom 占用一步会商房间。新版 Gateway 的 init 只续租不新建,
// 缺 roomSessionId / 未 acquire 时会报「会商会话标识缺失」。
func (c *Client) AcquireRoundtableRoom(draftID, taskID, roomSessionID string) error {
draftID = strings.TrimSpace(draftID)
roomSessionID = strings.TrimSpace(roomSessionID)
if draftID == "" || roomSessionID == "" {
return fmt.Errorf("缺少会商标识(draftId/roomSessionId),无法占用研讨房间")
}
body := map[string]interface{}{
"draftId": draftID,
"roomSessionId": roomSessionID,
}
if t := strings.TrimSpace(taskID); t != "" {
body["taskId"] = t
}
raw, err := c.postJSON("/api/roundtable-rooms/acquire", body)
if err != nil {
return err
}
var resp map[string]interface{}
_ = json.Unmarshal(raw, &resp)
if ok, has := resp["ok"].(bool); has && !ok {
msg := fmt.Sprint(resp["message"])
if msg == "" || msg == "<nil>" {
msg = "占用会商房间失败"
}
return fmt.Errorf("%s", msg)
}
logging.L.Infow("DeerFlow 房间已占用", "draftId", draftID, "roomSessionId", roomSessionID)
return nil
}
// InitMultiAgent 建多席线程,返回 agentName → threadId。
// draft_id 在内网较新 Gateway 上是「会商标识」,缺了会 4xx。
// draft_id 在内网较新 Gateway 上是「会商标识」,缺了会 4xx。调用前须 AcquireRoundtableRoom。
func (c *Client) InitMultiAgent(agentNames []string, mainAgent, model string, opts InitMultiAgentOpts) (map[string]string, error) {
body := map[string]interface{}{
"agent_names": agentNames,
@@ -366,6 +398,35 @@ func (c *Client) readSSE(
return scanner.Err()
}
func (c *Client) postJSON(path string, body map[string]interface{}) ([]byte, error) {
token, err := c.auth.BearerToken()
if err != nil {
return nil, err
}
raw, err := json.Marshal(body)
if err != nil {
return nil, err
}
req, err := http.NewRequest(http.MethodPost, c.cfg.DeerFlowBaseURL+path, bytes.NewReader(raw))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
if resp.StatusCode >= 400 {
return nil, fmt.Errorf("DeerFlow %s HTTP %d: %s", path, resp.StatusCode, string(out))
}
return out, nil
}
func isFinalStatusFrame(v map[string]interface{}) bool {
if v == nil {
return false
+6
View File
@@ -88,6 +88,12 @@ func (r *LiveChainRunner) Run(job *domain.AnalysisJob) {
if dfTaskID == "" {
dfTaskID = job.TaskID
}
putProgress(job, 3, "正在占用会商房间…")
r.flush(job)
if err := r.DF.AcquireRoundtableRoom(job.DraftID, dfTaskID, roomSessionID); err != nil {
r.fail(job, err.Error())
return
}
tids, err := r.DF.InitMultiAgent(agentNames, r.Coord, job.Model, deerflow.InitMultiAgentOpts{
DraftID: job.DraftID,
TaskID: dfTaskID,