iop/apps/node/internal/adapters/cli/emitter_profile_json.go

282 lines
6.3 KiB
Go

package cli
import (
"encoding/json"
"iop/apps/node/internal/runtime"
)
// --- claude-json emitter ---
type claudeJSONEmitter struct{}
func (claudeJSONEmitter) Name() string { return "claude-json" }
func (e claudeJSONEmitter) Emit(line string) ([]runtime.RuntimeEvent, error) {
var ev struct {
Type string `json:"type"`
Event struct {
Type string `json:"type"`
Delta struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"delta"`
} `json:"event"`
IsError bool `json:"is_error"`
Result string `json:"result"`
}
if err := json.Unmarshal([]byte(line), &ev); err != nil {
return nil, nil
}
switch ev.Type {
case "stream_event":
if ev.Event.Type == "content_block_delta" &&
ev.Event.Delta.Type == "text_delta" &&
ev.Event.Delta.Text != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeDelta,
Delta: ev.Event.Delta.Text,
}}, nil
}
return nil, nil
case "result":
if ev.IsError && ev.Result != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: ev.Result,
}}, nil
}
return nil, nil
}
return nil, nil
}
// --- codex-json emitter ---
type codexJSONEmitter struct{}
func (codexJSONEmitter) Name() string { return "codex-json" }
func (e codexJSONEmitter) Emit(line string) ([]runtime.RuntimeEvent, error) {
var ev struct {
Type string `json:"type"`
Item struct {
Type string `json:"type"`
Text string `json:"text"`
Delta string `json:"delta"`
Message struct {
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content"`
} `json:"message"`
} `json:"item"`
Delta string `json:"delta"`
Text string `json:"text"`
Message string `json:"message"`
Error struct {
Message string `json:"message"`
} `json:"error"`
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content"`
}
if err := json.Unmarshal([]byte(line), &ev); err != nil {
return nil, nil
}
switch ev.Type {
case "item.delta", "item.updated", "response.output_text.delta", "output_text.delta":
if delta := codexDeltaText(ev); delta != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeDelta,
Delta: delta,
}}, nil
}
return nil, nil
case "item.completed":
if ev.Item.Type == "agent_message" && ev.Item.Text != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeDelta,
Delta: ev.Item.Text,
}}, nil
}
if delta := codexDeltaText(ev); delta != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeDelta,
Delta: delta,
}}, nil
}
return nil, nil
case "error":
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: ev.Message,
}}, nil
case "turn.failed":
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: ev.Error.Message,
}}, nil
}
return nil, nil
}
func codexDeltaText(ev struct {
Type string `json:"type"`
Item struct {
Type string `json:"type"`
Text string `json:"text"`
Delta string `json:"delta"`
Message struct {
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content"`
} `json:"message"`
} `json:"item"`
Delta string `json:"delta"`
Text string `json:"text"`
Message string `json:"message"`
Error struct {
Message string `json:"message"`
} `json:"error"`
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content"`
}) string {
if ev.Item.Delta != "" {
return ev.Item.Delta
}
if ev.Delta != "" {
return ev.Delta
}
if ev.Text != "" {
return ev.Text
}
for _, part := range ev.Item.Message.Content {
if part.Type == "output_text" && part.Text != "" {
return part.Text
}
}
for _, part := range ev.Content {
if part.Type == "output_text" && part.Text != "" {
return part.Text
}
}
return ""
}
// --- opencode-json emitter ---
type opencodeJSONEmitter struct{}
func (opencodeJSONEmitter) Name() string { return "opencode-json" }
func (e opencodeJSONEmitter) Emit(line string) ([]runtime.RuntimeEvent, error) {
var ev struct {
Type string `json:"type"`
Error struct {
Name string `json:"name"`
Data struct {
Message string `json:"message"`
} `json:"data"`
} `json:"error"`
Part struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"part"`
}
if err := json.Unmarshal([]byte(line), &ev); err != nil {
return nil, nil
}
switch ev.Type {
case "text":
if ev.Part.Type == "text" && ev.Part.Text != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeDelta,
Delta: ev.Part.Text,
}}, nil
}
return nil, nil
case "error":
msg := ev.Error.Data.Message
if msg == "" {
msg = ev.Error.Name
}
if msg != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: msg,
}}, nil
}
return nil, nil
}
return nil, nil
}
// --- cline-json emitter ---
type clineJSONEmitter struct{}
func (clineJSONEmitter) Name() string { return "cline-json" }
func (e clineJSONEmitter) Emit(line string) ([]runtime.RuntimeEvent, error) {
var ev struct {
Type string `json:"type"`
Say string `json:"say"`
Ask string `json:"ask"`
Text string `json:"text"`
Message string `json:"message"`
Status string `json:"status"`
Error string `json:"error"`
}
if err := json.Unmarshal([]byte(line), &ev); err != nil {
return nil, nil
}
switch {
case ev.Type == "say" && ev.Say == "text" && ev.Text != "":
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeDelta,
Delta: ev.Text,
}}, nil
case ev.Type == "say" && ev.Say == "error":
msg := ev.Text
if msg == "" {
msg = ev.Message
}
if msg != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: msg,
}}, nil
}
return nil, nil
case ev.Type == "completion" && ev.Status == "error":
msg := ev.Error
if msg == "" {
msg = ev.Message
}
if msg == "" {
msg = "cline task failed"
}
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: msg,
}}, nil
case ev.Type == "ask" && ev.Ask == "api_req_failed":
msg := ev.Text
if msg == "" {
msg = ev.Message
}
if msg != "" {
return []runtime.RuntimeEvent{{
Type: runtime.EventTypeError,
Error: msg,
}}, nil
}
return nil, nil
}
return nil, nil
}