fix(acp): unify protocol compatibility, enhance authentication, and fix conversation history
This commit is contained in:
parent
f30c8d4816
commit
00ef2ceeed
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"xworkmate-bridge/internal/shared"
|
||||
"xworkmate-bridge/internal/service"
|
||||
)
|
||||
|
||||
@ -17,13 +18,24 @@ func NewTokenAuthHandler(service *service.StaticTokenAuthService) *TokenAuthHand
|
||||
|
||||
func (h *TokenAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if h.service == nil {
|
||||
http.Error(w, "service unavailable", http.StatusServiceUnavailable)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
_ = json.NewEncoder(w).Encode(shared.ErrorEnvelope(nil, -32000, "auth service unavailable"))
|
||||
return
|
||||
}
|
||||
token := r.Header.Get("Authorization")
|
||||
if !h.service.ValidateAuthorizationHeader(token) {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
// Return JSON error instead of plain text to satisfy Flutter's expectation
|
||||
_ = json.NewEncoder(w).Encode(shared.ErrorEnvelope(nil, -32001, "unauthorized"))
|
||||
return
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"ok": true})
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"ok": true,
|
||||
"type": "res",
|
||||
"payload": map[string]any{"authenticated": true},
|
||||
})
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
|
||||
type RPCRequest struct {
|
||||
JSONRPC string `json:"jsonrpc,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
ID any `json:"id,omitempty"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Params map[string]any `json:"params,omitempty"`
|
||||
@ -49,17 +50,25 @@ func ResultEnvelope(id any, result map[string]any) map[string]any {
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": result,
|
||||
// Backward compatibility with legacy GatewayRuntime
|
||||
"type": "res",
|
||||
"ok": true,
|
||||
"payload": result,
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorEnvelope(id any, code int, message string) map[string]any {
|
||||
errPayload := map[string]any{
|
||||
"code": code,
|
||||
"message": message,
|
||||
}
|
||||
return map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"error": map[string]any{
|
||||
"code": code,
|
||||
"message": message,
|
||||
},
|
||||
"error": errPayload,
|
||||
// Backward compatibility with legacy GatewayRuntime
|
||||
"type": "res",
|
||||
"ok": false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,41 +77,32 @@ func NotificationEnvelope(method string, params map[string]any) map[string]any {
|
||||
"jsonrpc": "2.0",
|
||||
"method": method,
|
||||
"params": params,
|
||||
// Backward compatibility with legacy GatewayRuntime
|
||||
"type": "event",
|
||||
"event": method,
|
||||
"payload": params,
|
||||
}
|
||||
}
|
||||
|
||||
func ErrorResponse(id any, code int, message string) map[string]any {
|
||||
return map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"error": map[string]any{
|
||||
"code": code,
|
||||
"message": message,
|
||||
},
|
||||
}
|
||||
return ErrorEnvelope(id, code, message)
|
||||
}
|
||||
|
||||
func ToolTextResult(id any, content string) map[string]any {
|
||||
return map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": map[string]any{
|
||||
"content": []map[string]any{
|
||||
{"type": "text", "text": content},
|
||||
},
|
||||
result := map[string]any{
|
||||
"content": []map[string]any{
|
||||
{"type": "text", "text": content},
|
||||
},
|
||||
}
|
||||
return ResultEnvelope(id, result)
|
||||
}
|
||||
|
||||
func ToolErrorResult(id any, err error) map[string]any {
|
||||
return map[string]any{
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"result": map[string]any{
|
||||
"content": []map[string]any{
|
||||
{"type": "text", "text": fmt.Sprintf("Error: %v", err)},
|
||||
},
|
||||
"isError": true,
|
||||
result := map[string]any{
|
||||
"content": []map[string]any{
|
||||
{"type": "text", "text": fmt.Sprintf("Error: %v", err)},
|
||||
},
|
||||
"isError": true,
|
||||
}
|
||||
return ResultEnvelope(id, result)
|
||||
}
|
||||
|
||||
@ -178,15 +178,35 @@ func AugmentPromptWithAttachments(prompt string, params map[string]any) string {
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func ComposeHistoryPrompt(history []string) string {
|
||||
if len(history) == 0 {
|
||||
return ""
|
||||
}
|
||||
func ComposeHistoryPrompt(history any) string {
|
||||
var builder strings.Builder
|
||||
for index, turn := range history {
|
||||
_, _ = fmt.Fprintf(&builder, "## User Turn %d\n", index+1)
|
||||
builder.WriteString(turn)
|
||||
builder.WriteString("\n\n")
|
||||
switch h := history.(type) {
|
||||
case []string:
|
||||
if len(h) == 0 {
|
||||
return ""
|
||||
}
|
||||
for index, turn := range h {
|
||||
_, _ = fmt.Fprintf(&builder, "## Turn %d\n", index+1)
|
||||
builder.WriteString(turn)
|
||||
builder.WriteString("\n\n")
|
||||
}
|
||||
case []map[string]string:
|
||||
if len(h) == 0 {
|
||||
return ""
|
||||
}
|
||||
turn := 1
|
||||
for _, msg := range h {
|
||||
role := msg["role"]
|
||||
content := msg["content"]
|
||||
if role == "user" {
|
||||
_, _ = fmt.Fprintf(&builder, "## User Turn %d\n", turn)
|
||||
turn++
|
||||
} else {
|
||||
builder.WriteString("## Assistant Response\n")
|
||||
}
|
||||
builder.WriteString(content)
|
||||
builder.WriteString("\n\n")
|
||||
}
|
||||
}
|
||||
return strings.TrimSpace(builder.String())
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user