Repository navigation
Expand file tree
/
Copy pathevents.go
More file actions
97 lines (92 loc) · 2.78 KB
/
Copy pathevents.go
File metadata and controls
97 lines (92 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package mcode
import (
"bytes"
"encoding/json"
"fmt"
"net/url"
"github.com/MiniMax-AI/OpenAgentCore/internal/agentdaemon/proto"
)
func decodeComponent(value string) (string, error) { return url.PathUnescape(value) }
func (s *Session) handle(frame rpcFrame) error {
if len(frame.ID) > 0 {
// Harnesses run unattended, so no client method other than the
// permission answer is offered. Pinned mcode 0.4.12 maps the ACP
// cancelled outcome to deny: the tool call is blocked and the Turn
// continues.
if frame.Method == "session/request_permission" {
return s.write(rpcFrame{JSONRPC: "2.0", ID: frame.ID, Result: json.RawMessage(`{"outcome":{"outcome":"cancelled"}}`)})
}
return s.write(rpcFrame{JSONRPC: "2.0", ID: frame.ID, Error: &rpcError{Code: -32601, Message: "ACP method not supported by OpenAgentCore"}})
}
if frame.Method != "session/update" || !s.active {
return nil
}
var event sessionUpdate
decoder := json.NewDecoder(bytes.NewReader(frame.Params))
decoder.UseNumber()
if err := decoder.Decode(&event); err != nil {
return fmt.Errorf("mcode: invalid session update")
}
if event.SessionID != s.sessionID {
return nil
}
s.mu.Lock()
s.steeringReady = true
s.mu.Unlock()
switch event.Update.Kind {
case "agent_message_chunk":
if event.Update.Content.Type != "text" {
return fmt.Errorf("mcode: unsupported response content")
}
text := event.Update.Content.Text
s.content.WriteString(text)
s.sequence++
s.emit(proto.TypeDelta, proto.DeltaPayload{Delta: text, Sequence: s.sequence})
case "agent_thought_chunk":
s.sequence++
s.emit(proto.TypeThinking, proto.ThinkingPayload{Text: event.Update.Content.Text, Sequence: s.sequence})
case "tool_call", "tool_call_update":
return s.emitTool(event.Update.toolUpdate)
}
return nil
}
func (s *Session) emitTool(update toolUpdate) error {
if update.ID == "" || s.completedTools[update.ID] {
return nil
}
previous := s.tools[update.ID]
if update.Name == "" {
update.Name = previous.Name
}
if update.Name == "" {
update.Name = update.Title
}
if update.RawInput == nil {
update.RawInput = previous.RawInput
}
update.mcp = previous.mcp
if update.mcp != nil && update.Name != previous.Name {
return fmt.Errorf("mcode: native MCP call identity changed")
}
if update.mcp == nil {
var err error
update.mcp, err = s.environmentMCPIdentity(update.Name)
if err != nil {
return err
}
}
if previous.mcp == nil && workspaceToolObservation(previous, "before") == nil {
if err := s.emitToolStage(update, "before"); err != nil {
return err
}
}
s.tools[update.ID] = update
if update.Status == "completed" || update.Status == "failed" {
if err := s.emitToolStage(update, "after"); err != nil {
return err
}
delete(s.tools, update.ID)
s.completedTools[update.ID] = true
}
return nil
}