Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
115 lines
3.1 KiB
Go
115 lines
3.1 KiB
Go
package agentruntime
|
|
|
|
import (
|
|
"strings"
|
|
|
|
agentsessionstore "github.com/tutti-os/tutti/packages/agent/daemon/activity"
|
|
activityshared "github.com/tutti-os/tutti/packages/agent/daemon/activity/events"
|
|
"github.com/tutti-os/tutti/packages/agent/store-sqlite/canonical"
|
|
)
|
|
|
|
func entityPatchFromSessionEvent(
|
|
source canonical.EventSource,
|
|
event activityshared.Event,
|
|
sessionID string,
|
|
timestamp int64,
|
|
item agentsessionstore.WorkspaceAgentTimelineItem,
|
|
) *agentsessionstore.WorkspaceAgentStatePatch {
|
|
if strings.TrimSpace(item.CallID) == "" && strings.TrimSpace(item.Name) == "" {
|
|
return nil
|
|
}
|
|
entity := agentsessionstore.WorkspaceAgentEntityPatch{
|
|
CallID: strings.TrimSpace(item.CallID),
|
|
TurnID: strings.TrimSpace(item.TurnID),
|
|
CallType: firstNonEmptyString(item.CallType, "tool"),
|
|
Name: strings.TrimSpace(item.Name),
|
|
Status: strings.TrimSpace(item.Status),
|
|
}
|
|
switch event.Type {
|
|
case activityshared.EventCallStarted:
|
|
entity.Input = clonePayload(event.Payload.Input)
|
|
entity.StartedAtUnixMS = timestamp
|
|
case activityshared.EventCallCompleted:
|
|
entity.Output = clonePayload(event.Payload.Output)
|
|
entity.CompletedAtUnixMS = timestamp
|
|
case activityshared.EventCallFailed:
|
|
if len(event.Payload.Output) > 0 {
|
|
entity.Output = clonePayload(event.Payload.Output)
|
|
}
|
|
entity.Error = clonePayload(event.Payload.Error)
|
|
entity.CompletedAtUnixMS = timestamp
|
|
}
|
|
return &agentsessionstore.WorkspaceAgentStatePatch{
|
|
AgentSessionID: strings.TrimSpace(sessionID),
|
|
Provider: firstNonEmptyString(string(event.Provider), source.Provider),
|
|
ProviderSessionID: firstNonEmptyString(event.ProviderSessionID, source.ProviderSessionID),
|
|
CWD: firstNonEmptyString(event.Payload.CWD, source.CWD),
|
|
OccurredAtUnixMS: timestamp,
|
|
Entities: []agentsessionstore.WorkspaceAgentEntityPatch{entity},
|
|
}
|
|
}
|
|
|
|
func payloadWithCallBody(key string, payload map[string]any, metadata map[string]any) map[string]any {
|
|
out := clonePayload(metadata)
|
|
if out == nil {
|
|
out = map[string]any{}
|
|
}
|
|
if len(payload) > 0 {
|
|
out[key] = clonePayload(payload)
|
|
}
|
|
if len(out) == 0 {
|
|
return nil
|
|
}
|
|
return out
|
|
}
|
|
|
|
func payloadValueIsEmpty(value any) bool {
|
|
switch typed := value.(type) {
|
|
case nil:
|
|
return true
|
|
case string:
|
|
return strings.TrimSpace(typed) == ""
|
|
case []any:
|
|
return len(typed) == 0
|
|
case map[string]any:
|
|
return len(typed) == 0
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func clonePayloadValue(value any) any {
|
|
switch typed := value.(type) {
|
|
case map[string]any:
|
|
out := make(map[string]any, len(typed))
|
|
for key, item := range typed {
|
|
out[key] = clonePayloadValue(item)
|
|
}
|
|
return out
|
|
case []any:
|
|
out := make([]any, len(typed))
|
|
for index, item := range typed {
|
|
out[index] = clonePayloadValue(item)
|
|
}
|
|
return out
|
|
default:
|
|
return value
|
|
}
|
|
}
|
|
|
|
func stringFromPayload(payload map[string]any, key string) string {
|
|
if len(payload) == 0 {
|
|
return ""
|
|
}
|
|
return asString(payload[key])
|
|
}
|
|
|
|
func firstNonEmptyString(values ...string) string {
|
|
for _, value := range values {
|
|
if strings.TrimSpace(value) != "" {
|
|
return strings.TrimSpace(value)
|
|
}
|
|
}
|
|
return ""
|
|
}
|