mirror of
https://github.com/alibaba/open-code-review.git
synced 2026-07-16 20:59:06 +00:00
feat: 修复一些问题
This commit is contained in:
parent
a896ba5aca
commit
e2d6a54d55
4 changed files with 50 additions and 42 deletions
BIN
dist/opencodereview
vendored
BIN
dist/opencodereview
vendored
Binary file not shown.
|
|
@ -433,15 +433,13 @@ func (a *Agent) resolveSystemRule(path string) string {
|
|||
|
||||
// executePlanPhase runs the plan task for a single file, sending template messages
|
||||
// with resolved placeholders and collecting the LLM response as plan guidance.
|
||||
func (a *Agent) executePlanPhase(_ context.Context, newPath, rawDiff, changeFiles, rule string) (string, error) {
|
||||
func (a *Agent) executePlanPhase(ctx context.Context, newPath, rawDiff, changeFiles, rule string) (string, error) {
|
||||
pt := a.args.Template.PlanTask
|
||||
messages := make([]llm.Message, 0, len(pt.Messages))
|
||||
for _, m := range pt.Messages {
|
||||
content := m.Content
|
||||
content = strings.ReplaceAll(content, "{{current_system_date_time}}", a.currentDate)
|
||||
content = strings.ReplaceAll(content, "{{current_file_path}}", newPath)
|
||||
content = strings.ReplaceAll(content, "{{current_file_path}}", newPath)
|
||||
content = strings.ReplaceAll(content, "{{current_file_path}}", newPath)
|
||||
content = strings.ReplaceAll(content, "{{system_rule}}", rule)
|
||||
content = strings.ReplaceAll(content, "{{change_files}}", changeFiles)
|
||||
content = strings.ReplaceAll(content, "{{diff}}", rawDiff)
|
||||
|
|
@ -453,7 +451,7 @@ func (a *Agent) executePlanPhase(_ context.Context, newPath, rawDiff, changeFile
|
|||
rec := fs.AppendTaskRecord(session.PlanTask, messages)
|
||||
startTime := time.Now()
|
||||
|
||||
resp, err := a.args.LLMClient.GeneralRequest(messages, a.args.Model, nil)
|
||||
resp, err := a.args.LLMClient.GeneralRequestWithCtx(ctx, messages, a.args.Model, nil)
|
||||
if err != nil {
|
||||
rec.SetError(err, time.Since(startTime))
|
||||
return "", fmt.Errorf("plan request: %w", err)
|
||||
|
|
@ -772,39 +770,8 @@ func (a *Agent) compressAndRecord(msgs []llm.Message, filePath string) []llm.Mes
|
|||
return msgs[:2]
|
||||
}
|
||||
|
||||
compressed := msgs[:2]
|
||||
// Append summary to the original user prompt
|
||||
userMsg := compressed[1]
|
||||
currentText := userMsg.ExtractText()
|
||||
compressed[1] = llm.NewTextMessage(userMsg.Role, currentText+"\n\n"+summary)
|
||||
return compressed
|
||||
}
|
||||
|
||||
// compressMessages runs the memory compression task and replaces old messages with a summary.
|
||||
func compressMessages(msgs []llm.Message, compTask template.LlmConversation, client *llm.Client, model string) []llm.Message {
|
||||
if len(compTask.Messages) == 0 || len(msgs) <= 2 {
|
||||
return msgs[:min(len(msgs), 2)]
|
||||
}
|
||||
|
||||
contextXML := buildMessageXML(msgs[2:])
|
||||
compressionMsgs := make([]llm.Message, 0, len(compTask.Messages))
|
||||
for _, m := range compTask.Messages {
|
||||
content := strings.ReplaceAll(m.Content, "{{context}}", contextXML)
|
||||
compressionMsgs = append(compressionMsgs, llm.NewTextMessage(m.Role, content))
|
||||
}
|
||||
|
||||
resp, err := client.GeneralRequest(compressionMsgs, model, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("[ocr] Memory compression failed: %v\n", err)
|
||||
return msgs[:2]
|
||||
}
|
||||
|
||||
summary := resp.Content()
|
||||
if summary == "" {
|
||||
return msgs[:2]
|
||||
}
|
||||
|
||||
compressed := msgs[:2]
|
||||
compressed := make([]llm.Message, 2)
|
||||
copy(compressed, msgs[:2])
|
||||
// Append summary to the original user prompt
|
||||
userMsg := compressed[1]
|
||||
currentText := userMsg.ExtractText()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package llm
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -203,14 +204,19 @@ type ChatRequest struct {
|
|||
|
||||
// Completions sends a chat completion request and returns the parsed response.
|
||||
func (c *Client) Completions(req ChatRequest) (*ChatResponse, error) {
|
||||
return c.CompletionsWithCtx(context.Background(), req)
|
||||
}
|
||||
|
||||
// CompletionsWithCtx sends a chat completion request with context support for cancellation and timeout.
|
||||
func (c *Client) CompletionsWithCtx(ctx context.Context, req ChatRequest) (*ChatResponse, error) {
|
||||
model := req.Model
|
||||
if model == "" {
|
||||
model = c.cfg.Model
|
||||
}
|
||||
|
||||
var result *ChatResponse
|
||||
err := c.withRetry(func() error {
|
||||
resp, err := c.doRequest(model, req)
|
||||
err := c.withRetryCtx(ctx, func() error {
|
||||
resp, err := c.doRequestCtx(ctx, model, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -222,7 +228,12 @@ func (c *Client) Completions(req ChatRequest) (*ChatResponse, error) {
|
|||
|
||||
// GeneralRequest sends a simple chat request without or with optional tool calls (for plan phase, compression, etc.).
|
||||
func (c *Client) GeneralRequest(messages []Message, model string, tools []ToolDef) (*ChatResponse, error) {
|
||||
return c.Completions(ChatRequest{
|
||||
return c.GeneralRequestWithCtx(context.Background(), messages, model, tools)
|
||||
}
|
||||
|
||||
// GeneralRequestWithCtx sends a simple chat request with context support.
|
||||
func (c *Client) GeneralRequestWithCtx(ctx context.Context, messages []Message, model string, tools []ToolDef) (*ChatResponse, error) {
|
||||
return c.CompletionsWithCtx(ctx, ChatRequest{
|
||||
Model: model,
|
||||
Messages: messages,
|
||||
Tools: tools,
|
||||
|
|
@ -369,8 +380,18 @@ func stripThinkTags(s string) string {
|
|||
}
|
||||
|
||||
func (c *Client) withRetry(fn func() error) error {
|
||||
return c.withRetryCtx(context.Background(), fn)
|
||||
}
|
||||
|
||||
func (c *Client) withRetryCtx(ctx context.Context, fn func() error) error {
|
||||
var lastErr error
|
||||
for attempt := 0; attempt <= maxRetries; attempt++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("context cancelled: %w", ctx.Err())
|
||||
default:
|
||||
}
|
||||
|
||||
lastErr = fn()
|
||||
if lastErr == nil {
|
||||
return nil
|
||||
|
|
@ -445,12 +466,17 @@ func min(a, b int) int {
|
|||
|
||||
// doRequest builds and sends a non-streaming completion request, returning the parsed response.
|
||||
func (c *Client) doRequest(model string, req ChatRequest) (*ChatResponse, error) {
|
||||
return c.doRequestCtx(context.Background(), model, req)
|
||||
}
|
||||
|
||||
// doRequestCtx builds and sends a non-streaming completion request with context support.
|
||||
func (c *Client) doRequestCtx(ctx context.Context, model string, req ChatRequest) (*ChatResponse, error) {
|
||||
if model == "" {
|
||||
model = c.cfg.Model
|
||||
}
|
||||
req.Model = model
|
||||
payload, _ := json.Marshal(req)
|
||||
httpReq, err := http.NewRequest(http.MethodPost, c.cfg.URL, bytes.NewReader(payload))
|
||||
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.cfg.URL, bytes.NewReader(payload))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create request: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,12 +206,27 @@ func (fs *FileSession) AppendTaskRecord(taskType TaskType, messages []llm.Messag
|
|||
rec := &TaskRecord{
|
||||
Type: taskType,
|
||||
RequestNo: len(fs.TaskRecords[taskType]) + 1,
|
||||
RequestMessages: messages,
|
||||
RequestMessages: copyMessages(messages),
|
||||
}
|
||||
fs.TaskRecords[taskType] = append(fs.TaskRecords[taskType], rec)
|
||||
return rec
|
||||
}
|
||||
|
||||
// copyMessages returns a deep copy of a messages slice so that future mutations
|
||||
// don't corrupt stored records.
|
||||
func copyMessages(msgs []llm.Message) []llm.Message {
|
||||
cp := make([]llm.Message, len(msgs))
|
||||
for i, m := range msgs {
|
||||
cp[i] = llm.Message{
|
||||
Role: m.Role,
|
||||
Content: m.Content,
|
||||
ToolCallID: m.ToolCallID,
|
||||
ToolCalls: append([]llm.ToolCall(nil), m.ToolCalls...),
|
||||
}
|
||||
}
|
||||
return cp
|
||||
}
|
||||
|
||||
// SetResponse records the LLM response in the most recent TaskRecord of the given type.
|
||||
// It computes estimated token usage locally using tiktoken, independent of any API format.
|
||||
func (tr *TaskRecord) SetResponse(resp *llm.ChatResponse, duration time.Duration) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue