Files
wehub-resource-sync f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

999 lines
28 KiB
Go

package postgres
import (
"context"
"crypto/sha256"
"database/sql"
"encoding/json"
"fmt"
"strings"
"go.kenn.io/agentsview/internal/db"
)
const pushComparisonBatchSize = 900
type pushMessageAggregate struct {
Count int
Sum int64
Max int64
Min int64
SysFP string
}
type pushToolCallAggregate struct {
Count int
Sum int64
}
type pushMessageComparison struct {
MessageAggregates map[string]pushMessageAggregate
MessageContentHash map[string]string
MessageRoleTime map[string]string
MessageFlags map[string]string
MessageSystemOrdinals map[string]string
MessageTokenFingerprint map[string]string
ToolCallAggregates map[string]pushToolCallAggregate
ToolCallFingerprint map[string]string
ToolResultFingerprint map[string]string
UsageEventFingerprint map[string]string
}
type pushLocalMessageFingerprint struct {
Sum int64
Max int64
Min int64
ContentHashFP string
RoleTimeFP string
FlagsFP string
SystemFP string
ToolCallCount int
ToolCallSum int64
ToolCallFP string
ToolResultFP string
TokenFP string
UsageEventFP string
}
func localSessionDependencyPushFingerprint(
ctx context.Context,
local *db.DB,
sessionID string,
usageEventFingerprint string,
usageKnown bool,
) (string, error) {
msgFP, err := localPushMessageFingerprint(
local, sessionID, usageEventFingerprint, usageKnown,
)
if err != nil {
return "", err
}
findings, err := local.SessionSecretFindings(ctx, sessionID)
if err != nil {
return "", fmt.Errorf("reading local secret findings: %w", err)
}
pins, err := local.ListPinnedMessages(ctx, sessionID, "")
if err != nil {
return "", fmt.Errorf("reading local pinned messages: %w", err)
}
return hashLocalDependencyPayload(msgFP, findings, pins)
}
// hashLocalDependencyPayload is the shared final step of the per-session
// and batched dependency fingerprints. The JSON encoding is the persisted
// fingerprint format: any change re-pushes every session on the next push.
func hashLocalDependencyPayload(
msgFP pushLocalMessageFingerprint,
findings []db.SecretFinding,
pins []db.PinnedMessage,
) (string, error) {
payload := struct {
Messages pushLocalMessageFingerprint
SecretFindings []db.SecretFinding
Pins []db.PinnedMessage
}{
Messages: msgFP,
SecretFindings: findings,
Pins: pins,
}
data, err := json.Marshal(payload)
if err != nil {
return "", fmt.Errorf("encoding local dependency fingerprint: %w", err)
}
sum := sha256.Sum256(data)
return fmt.Sprintf("%x", sum), nil
}
// localPushDependencyState holds one chunk's worth of prefetched local
// fingerprint inputs. The push loop fingerprints every candidate session on
// every push; reading these per session (a dozen point queries each) took
// minutes on a full push, so the loop prefetches them in batched queries.
// Values must match the per-session methods byte for byte — see the
// batched twins in internal/db for the identity contract.
type localPushDependencyState struct {
contentAgg map[string]db.MessageContentAggregate
contentHashFP map[string]string
roleTimeFP map[string]string
flagsFP map[string]string
systemFP map[string]string
tokenFP map[string]string
toolCallCount map[string]int
toolCallSum map[string]int64
toolCallFP map[string]string
toolResultFP map[string]string
secretFindings map[string][]db.SecretFinding
pins map[string][]db.PinnedMessage
}
func readLocalPushDependencyState(
ctx context.Context, local *db.DB, sessionIDs []string,
) (*localPushDependencyState, error) {
st := &localPushDependencyState{}
var err error
if st.contentAgg, err = local.MessageContentFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf("computing local content fingerprints: %w", err)
}
if st.contentHashFP, err = local.MessageContentHashFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf("computing local content hash fingerprints: %w", err)
}
if st.roleTimeFP, err = local.MessageRoleTimeFingerprintsWithTimestampNormalizer(
sessionIDs, pgPushTimestampFingerprintText,
); err != nil {
return nil, fmt.Errorf("computing local role/time fingerprints: %w", err)
}
if st.flagsFP, err = local.MessageFlagsFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf(
"computing local message flags fingerprints: %w", err,
)
}
if st.systemFP, err = local.SystemMessageFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf(
"computing local system message fingerprints: %w", err,
)
}
if st.tokenFP, err = local.MessageTokenFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf("computing local token fingerprints: %w", err)
}
if st.toolCallCount, err = local.ToolCallCounts(sessionIDs); err != nil {
return nil, fmt.Errorf("counting local tool_calls: %w", err)
}
if st.toolCallSum, err = local.ToolCallContentFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf(
"computing local tool_call content fingerprints: %w", err,
)
}
if st.toolCallFP, err = local.ToolCallFingerprints(sessionIDs); err != nil {
return nil, fmt.Errorf("computing local tool_call fingerprints: %w", err)
}
if st.toolResultFP, err = local.ToolResultEventFingerprintsWithTimestampNormalizer(
sessionIDs, pgPushTimestampFingerprintText,
); err != nil {
return nil, fmt.Errorf(
"computing local tool_result_event fingerprints: %w", err,
)
}
if st.secretFindings, err = local.SessionSecretFindingsBySession(
ctx, sessionIDs,
); err != nil {
return nil, fmt.Errorf("reading local secret findings: %w", err)
}
if st.pins, err = local.PinnedMessagesBySession(ctx, sessionIDs); err != nil {
return nil, fmt.Errorf("reading local pinned messages: %w", err)
}
return st, nil
}
// dependencyFingerprint assembles the same fingerprint as
// localSessionDependencyPushFingerprint from the prefetched maps. local is
// only queried on the usageKnown=false fallback, which the push loop never
// takes (it prefetches usage fingerprints for every candidate).
func (st *localPushDependencyState) dependencyFingerprint(
local *db.DB,
sessionID string,
usageEventFingerprint string,
usageKnown bool,
) (string, error) {
agg := st.contentAgg[sessionID]
msgFP := pushLocalMessageFingerprint{
Sum: agg.Sum,
Max: agg.Max,
Min: agg.Min,
ContentHashFP: st.contentHashFP[sessionID],
RoleTimeFP: st.roleTimeFP[sessionID],
FlagsFP: st.flagsFP[sessionID],
SystemFP: st.systemFP[sessionID],
ToolCallCount: st.toolCallCount[sessionID],
ToolCallSum: st.toolCallSum[sessionID],
ToolCallFP: st.toolCallFP[sessionID],
ToolResultFP: st.toolResultFP[sessionID],
TokenFP: st.tokenFP[sessionID],
}
if usageKnown {
msgFP.UsageEventFP = usageEventFingerprint
} else {
var err error
msgFP.UsageEventFP, err = local.UsageEventFingerprint(sessionID)
if err != nil {
return "", fmt.Errorf(
"computing local usage event fingerprint: %w", err,
)
}
}
return hashLocalDependencyPayload(
msgFP, st.secretFindings[sessionID], st.pins[sessionID],
)
}
func localPushMessageFingerprint(
local *db.DB,
sessionID string,
usageEventFingerprint string,
usageKnown bool,
) (pushLocalMessageFingerprint, error) {
fp := pushLocalMessageFingerprint{}
var err error
fp.Sum, fp.Max, fp.Min, err = local.MessageContentFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local content fingerprint: %w", err)
}
fp.ContentHashFP, err = local.MessageContentHashFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local content hash fingerprint: %w", err)
}
fp.RoleTimeFP, err = localMessageRoleTimePGFingerprint(local, sessionID)
if err != nil {
return fp, fmt.Errorf("computing local role/time fingerprint: %w", err)
}
fp.FlagsFP, err = local.MessageFlagsFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local message flags fingerprint: %w", err)
}
fp.SystemFP, err = local.SystemMessageFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local system message fingerprint: %w", err)
}
fp.ToolCallCount, err = local.ToolCallCount(sessionID)
if err != nil {
return fp, fmt.Errorf("counting local tool_calls: %w", err)
}
fp.ToolCallSum, err = local.ToolCallContentFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local tool_call content fingerprint: %w", err)
}
fp.ToolCallFP, err = local.ToolCallFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local tool_call fingerprint: %w", err)
}
fp.ToolResultFP, err = localToolResultEventPGFingerprint(local, sessionID)
if err != nil {
return fp, fmt.Errorf("computing local tool_result_event fingerprint: %w", err)
}
fp.TokenFP, err = local.MessageTokenFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local token fingerprint: %w", err)
}
if usageKnown {
fp.UsageEventFP = usageEventFingerprint
return fp, nil
}
fp.UsageEventFP, err = local.UsageEventFingerprint(sessionID)
if err != nil {
return fp, fmt.Errorf("computing local usage event fingerprint: %w", err)
}
return fp, nil
}
func comparisonAggregates(
sessionID string,
comparisons *pushMessageComparison,
) (pushMessageAggregate, pushToolCallAggregate, bool) {
if comparisons == nil {
return pushMessageAggregate{}, pushToolCallAggregate{}, false
}
return comparisons.MessageAggregates[sessionID],
comparisons.ToolCallAggregates[sessionID],
true
}
func readPushSessionMessageComparisons(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
) (*pushMessageComparison, error) {
comparisons := &pushMessageComparison{
MessageAggregates: make(map[string]pushMessageAggregate, len(sessionIDs)),
MessageContentHash: make(map[string]string, len(sessionIDs)),
MessageRoleTime: make(map[string]string, len(sessionIDs)),
MessageFlags: make(map[string]string, len(sessionIDs)),
MessageSystemOrdinals: make(map[string]string, len(sessionIDs)),
MessageTokenFingerprint: make(map[string]string, len(sessionIDs)),
ToolCallAggregates: make(map[string]pushToolCallAggregate, len(sessionIDs)),
ToolCallFingerprint: make(map[string]string, len(sessionIDs)),
ToolResultFingerprint: make(map[string]string, len(sessionIDs)),
UsageEventFingerprint: make(map[string]string, len(sessionIDs)),
}
for i := 0; i < len(sessionIDs); i += pushComparisonBatchSize {
end := min(i+pushComparisonBatchSize, len(sessionIDs))
chunk := sessionIDs[i:end]
if err := loadPushMessageAggregates(ctx, tx, chunk, comparisons.MessageAggregates); err != nil {
return nil, err
}
if err := loadPushMessageContentHashFingerprints(
ctx, tx, chunk, comparisons.MessageContentHash,
); err != nil {
return nil, err
}
if err := loadPushMessageRoleTimeFingerprints(
ctx, tx, chunk, comparisons.MessageRoleTime,
); err != nil {
return nil, err
}
if err := loadPushMessageFlagFingerprints(
ctx, tx, chunk, comparisons.MessageFlags,
); err != nil {
return nil, err
}
if err := loadPushMessageSystemOrdinals(
ctx, tx, chunk, comparisons.MessageSystemOrdinals,
); err != nil {
return nil, err
}
if err := loadPushMessageTokenFingerprints(
ctx, tx, chunk, comparisons.MessageTokenFingerprint,
); err != nil {
return nil, err
}
if err := loadPushToolCallAggregates(
ctx, tx, chunk, comparisons.ToolCallAggregates,
); err != nil {
return nil, err
}
if err := loadPushToolCallFingerprints(
ctx, tx, chunk, comparisons.ToolCallFingerprint,
); err != nil {
return nil, err
}
if err := loadPushToolResultEventFingerprints(
ctx, tx, chunk, comparisons.ToolResultFingerprint,
); err != nil {
return nil, err
}
if err := loadPushUsageEventFingerprints(
ctx, tx, chunk, comparisons.UsageEventFingerprint,
); err != nil {
return nil, err
}
}
return comparisons, nil
}
func loadPushMessageAggregates(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]pushMessageAggregate,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, COUNT(*), COALESCE(SUM(content_length), 0),
COALESCE(MAX(content_length), 0), COALESCE(MIN(content_length), 0),
COALESCE(STRING_AGG(ordinal::text, ',' ORDER BY ordinal)
FILTER (WHERE is_system), '')
FROM messages
WHERE session_id = ANY($1)
GROUP BY session_id
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var sessionID string
var count int64
var agg pushMessageAggregate
if err := rows.Scan(
&sessionID, &count, &agg.Sum, &agg.Max, &agg.Min, &agg.SysFP,
); err != nil {
return err
}
agg.Count = int(count)
out[sessionID] = agg
}
return rows.Err()
}
func loadPushMessageContentHashFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, ordinal, COALESCE(content, ''),
content_length
FROM messages
WHERE session_id = ANY($1)
ORDER BY session_id, ordinal ASC
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var ordinal, contentLength int
var content string
if err := rows.Scan(&sessionID, &ordinal, &content, &contentLength); err != nil {
return err
}
sum := sha256.Sum256([]byte(db.SanitizeUTF8(content)))
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
fmt.Fprintf(b, "%d|%d|%x;", ordinal, contentLength, sum)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func loadPushMessageRoleTimeFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, ordinal, role, timestamp
FROM messages
WHERE session_id = ANY($1)
ORDER BY session_id, ordinal ASC
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var ordinal int
var role string
var timestamp sql.NullTime
if err := rows.Scan(&sessionID, &ordinal, &role, &timestamp); err != nil {
return err
}
timestampText := ""
if timestamp.Valid {
timestampText = pgPushTimestampFingerprintText(
FormatISO8601(timestamp.Time),
)
}
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
fmt.Fprintf(
b, "%d|%d:%s|%d:%s;",
ordinal, len(role), role, len(timestampText), timestampText,
)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func loadPushMessageFlagFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, ordinal, is_system, has_thinking, has_tool_use,
COALESCE(thinking_text, '')
FROM messages
WHERE session_id = ANY($1)
ORDER BY session_id, ordinal ASC
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var ordinal int
var isSystem, hasThinking, hasToolUse bool
var thinkingText string
if err := rows.Scan(
&sessionID, &ordinal, &isSystem, &hasThinking, &hasToolUse,
&thinkingText,
); err != nil {
return err
}
sum := sha256.Sum256([]byte(db.SanitizeUTF8(thinkingText)))
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
fmt.Fprintf(
b, "%d|%t|%t|%t|%x;", ordinal, isSystem, hasThinking,
hasToolUse, sum,
)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func loadPushMessageSystemOrdinals(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id,
COALESCE(
STRING_AGG(ordinal::text, ',' ORDER BY ordinal)
FILTER (WHERE is_system),
''
)
FROM messages
WHERE session_id = ANY($1)
GROUP BY session_id
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var sessionID string
var systemOrdinals string
if err := rows.Scan(&sessionID, &systemOrdinals); err != nil {
return err
}
out[sessionID] = systemOrdinals
}
return rows.Err()
}
func loadPushMessageTokenFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, ordinal, model, token_usage, context_tokens,
output_tokens, has_context_tokens, has_output_tokens,
claude_message_id, claude_request_id,
source_type, source_subtype, source_uuid,
source_parent_uuid, is_sidechain, is_compact_boundary
FROM messages
WHERE session_id = ANY($1)
ORDER BY session_id, ordinal ASC
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var ordinal, contextTokens, outputTokens int
var model, tokenUsage string
var hasContextTokens, hasOutputTokens bool
var claudeMsgID, claudeReqID string
var srcType, srcSubtype, srcUUID, srcParentUUID string
var isSidechain, isCompactBoundary bool
if err := rows.Scan(
&sessionID, &ordinal, &model, &tokenUsage, &contextTokens,
&outputTokens, &hasContextTokens, &hasOutputTokens,
&claudeMsgID, &claudeReqID,
&srcType, &srcSubtype, &srcUUID, &srcParentUUID,
&isSidechain, &isCompactBoundary,
); err != nil {
return err
}
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
fmt.Fprintf(
b,
"%d|%d:%s|%d:%s|%d|%d|%t|%t|%s|%s|"+
"%d:%s|%d:%s|%d:%s|%d:%s|%t|%t;",
ordinal,
len(model), model,
len(tokenUsage), tokenUsage,
contextTokens, outputTokens,
hasContextTokens, hasOutputTokens,
claudeMsgID, claudeReqID,
len(srcType), srcType,
len(srcSubtype), srcSubtype,
len(srcUUID), srcUUID,
len(srcParentUUID), srcParentUUID,
isSidechain, isCompactBoundary,
)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func loadPushToolCallAggregates(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]pushToolCallAggregate,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id,
COUNT(*), COALESCE(SUM(result_content_length), 0)
FROM tool_calls
WHERE session_id = ANY($1)
GROUP BY session_id
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var sessionID string
var agg pushToolCallAggregate
var count int64
if err := rows.Scan(&sessionID, &count, &agg.Sum); err != nil {
return err
}
agg.Count = int(count)
out[sessionID] = agg
}
return rows.Err()
}
func loadPushToolCallFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, message_ordinal, call_index, tool_name, category,
tool_use_id, COALESCE(input_json, ''),
COALESCE(skill_name, ''), COALESCE(subagent_session_id, ''),
COALESCE(result_content_length, 0),
COALESCE(result_content, ''),
COALESCE(file_path, '')
FROM tool_calls
WHERE session_id = ANY($1)
ORDER BY session_id, message_ordinal ASC, call_index ASC
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var messageOrdinal, callIndex, resultContentLength int
var toolName, category, toolUseID, inputJSON string
var skillName, subagentSessionID, resultContent, filePath string
if err := rows.Scan(
&sessionID, &messageOrdinal, &callIndex, &toolName,
&category, &toolUseID, &inputJSON,
&skillName, &subagentSessionID, &resultContentLength,
&resultContent, &filePath,
); err != nil {
return err
}
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
fmt.Fprintf(
b,
"%d|%d|%d:%s|%d:%s|%d:%s|%d:%s|%d:%s|%d:%s|%d|%d:%s|%d:%s;",
messageOrdinal, callIndex,
len(toolName), toolName,
len(category), category,
len(toolUseID), toolUseID,
len(inputJSON), inputJSON,
len(skillName), skillName,
len(subagentSessionID), subagentSessionID,
resultContentLength,
len(resultContent), resultContent,
len(filePath), filePath,
)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func loadPushUsageEventFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, message_ordinal, source, model,
input_tokens, output_tokens,
cache_creation_input_tokens, cache_read_input_tokens,
reasoning_tokens, cost_usd, cost_status, cost_source,
occurred_at, dedup_key
FROM usage_events
WHERE session_id = ANY($1)
ORDER BY session_id, occurred_at NULLS FIRST, id
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var ordinal sql.NullInt64
var source, model, costStatus, costSource string
var inputTokens, outputTokens int
var cacheCreationInputTokens, cacheReadInputTokens int
var reasoningTokens int
var cost sql.NullFloat64
var occurredAt sql.NullTime
var dedupKey sql.NullString
if err := rows.Scan(
&sessionID, &ordinal, &source, &model,
&inputTokens, &outputTokens,
&cacheCreationInputTokens, &cacheReadInputTokens,
&reasoningTokens, &cost, &costStatus, &costSource,
&occurredAt, &dedupKey,
); err != nil {
return err
}
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
occurred := ""
if occurredAt.Valid {
occurred = FormatISO8601(occurredAt.Time)
}
fmt.Fprintf(
b,
"%t|%d|%d:%s|%d:%s|%d|%d|%d|%d|%d|%t|%g|%d:%s|%d:%s|%d:%s|%d:%s;",
ordinal.Valid,
ordinal.Int64,
len(source), source,
len(model), model,
inputTokens,
outputTokens,
cacheCreationInputTokens,
cacheReadInputTokens,
reasoningTokens,
cost.Valid,
cost.Float64,
len(costStatus), costStatus,
len(costSource), costSource,
len(occurred), occurred,
len(dedupKey.String), dedupKey.String,
)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func loadPushToolResultEventFingerprints(
ctx context.Context,
tx *sql.Tx,
sessionIDs []string,
out map[string]string,
) error {
rows, err := tx.QueryContext(ctx, `
SELECT session_id, tool_call_message_ordinal, call_index, event_index,
COALESCE(tool_use_id, ''), COALESCE(agent_id, ''),
COALESCE(subagent_session_id, ''), source, status,
content, content_length, timestamp
FROM tool_result_events
WHERE session_id = ANY($1)
ORDER BY session_id, tool_call_message_ordinal ASC, call_index ASC, event_index ASC
`, sessionIDs)
if err != nil {
return err
}
defer rows.Close()
builders := make(map[string]*strings.Builder, len(sessionIDs))
for rows.Next() {
var sessionID string
var messageOrdinal, callIndex, eventIndex, contentLength int
var toolUseID, agentID, subagentSessionID string
var source, status, content string
var timestamp sql.NullTime
if err := rows.Scan(
&sessionID, &messageOrdinal, &callIndex, &eventIndex,
&toolUseID, &agentID, &subagentSessionID,
&source, &status, &content, &contentLength, &timestamp,
); err != nil {
return err
}
b := builders[sessionID]
if b == nil {
b = &strings.Builder{}
builders[sessionID] = b
}
timestampText := ""
if timestamp.Valid {
timestampText = FormatISO8601(timestamp.Time)
}
toolUseID = db.SanitizeUTF8(toolUseID)
agentID = db.SanitizeUTF8(agentID)
subagentSessionID = db.SanitizeUTF8(subagentSessionID)
source = db.SanitizeUTF8(source)
status = db.SanitizeUTF8(status)
content = db.SanitizeUTF8(content)
contentSum := sha256.Sum256([]byte(content))
fmt.Fprintf(
b,
"%d|%d|%d|%d:%s|%d:%s|%d:%s|%d:%s|%d:%s|%d|%x|%d:%s;",
messageOrdinal, callIndex, eventIndex,
len(toolUseID), toolUseID,
len(agentID), agentID,
len(subagentSessionID), subagentSessionID,
len(source), source,
len(status), status,
contentLength,
contentSum,
len(timestampText), timestampText,
)
}
if err := rows.Err(); err != nil {
return err
}
for sessionID, b := range builders {
out[sessionID] = b.String()
}
return nil
}
func localToolResultEventPGFingerprint(
local *db.DB, sessionID string,
) (string, error) {
return local.ToolResultEventFingerprintWithTimestampNormalizer(
sessionID,
pgPushTimestampFingerprintText,
)
}
func pgToolResultEventFingerprint(
ctx context.Context, tx *sql.Tx, sessionID string,
) (string, error) {
rows, err := tx.QueryContext(ctx,
`SELECT tool_call_message_ordinal, call_index, event_index,
COALESCE(tool_use_id, ''), COALESCE(agent_id, ''),
COALESCE(subagent_session_id, ''), source, status,
content, content_length, timestamp
FROM tool_result_events
WHERE session_id = $1
ORDER BY tool_call_message_ordinal ASC, call_index ASC, event_index ASC`,
sessionID,
)
if err != nil {
return "", err
}
defer rows.Close()
var b strings.Builder
for rows.Next() {
var messageOrdinal, callIndex, eventIndex, contentLength int
var toolUseID, agentID, subagentSessionID string
var source, status, content string
var timestamp sql.NullTime
if err := rows.Scan(
&messageOrdinal, &callIndex, &eventIndex,
&toolUseID, &agentID, &subagentSessionID,
&source, &status, &content, &contentLength, &timestamp,
); err != nil {
return "", err
}
timestampText := ""
if timestamp.Valid {
timestampText = FormatISO8601(timestamp.Time)
}
toolUseID = db.SanitizeUTF8(toolUseID)
agentID = db.SanitizeUTF8(agentID)
subagentSessionID = db.SanitizeUTF8(subagentSessionID)
source = db.SanitizeUTF8(source)
status = db.SanitizeUTF8(status)
content = db.SanitizeUTF8(content)
contentSum := sha256.Sum256([]byte(content))
fmt.Fprintf(&b,
"%d|%d|%d|%d:%s|%d:%s|%d:%s|%d:%s|%d:%s|%d|%x|%d:%s;",
messageOrdinal, callIndex, eventIndex,
len(toolUseID), toolUseID,
len(agentID), agentID,
len(subagentSessionID), subagentSessionID,
len(source), source,
len(status), status,
contentLength,
contentSum,
len(timestampText), timestampText,
)
}
return b.String(), rows.Err()
}
func shouldSkipSessionMessages(
sessionID string,
localCount int,
localFP pushLocalMessageFingerprint,
full bool,
comparisons *pushMessageComparison,
) bool {
if full || localCount == 0 || comparisons == nil {
return false
}
pgAgg := comparisons.MessageAggregates[sessionID]
if pgAgg.Count != localCount || pgAgg.Count == 0 {
return false
}
return localFP.Sum == pgAgg.Sum &&
localFP.Max == pgAgg.Max &&
localFP.Min == pgAgg.Min &&
localFP.ContentHashFP == comparisons.MessageContentHash[sessionID] &&
localFP.RoleTimeFP == comparisons.MessageRoleTime[sessionID] &&
localFP.FlagsFP == comparisons.MessageFlags[sessionID] &&
localFP.SystemFP == comparisons.MessageSystemOrdinals[sessionID] &&
localFP.ToolCallCount == comparisons.ToolCallAggregates[sessionID].Count &&
localFP.ToolCallSum == comparisons.ToolCallAggregates[sessionID].Sum &&
localFP.ToolCallFP == comparisons.ToolCallFingerprint[sessionID] &&
localFP.ToolResultFP == comparisons.ToolResultFingerprint[sessionID] &&
localFP.TokenFP == comparisons.MessageTokenFingerprint[sessionID] &&
localFP.UsageEventFP == comparisons.UsageEventFingerprint[sessionID]
}