Files
tutti/packages/agent/store-sqlite/runtime_operation_events.go
agent-radar 2ed3415fb7
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
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

88 lines
3.0 KiB
Go

package storesqlite
import (
"context"
"database/sql"
"errors"
"fmt"
"strings"
)
const runtimeOperationEventSelectSQL = `
SELECT id, operation_id, workspace_id, agent_session_id, kind, payload_json,
created_at_unix_ms, COALESCE(published_at_unix_ms, 0)
FROM workspace_agent_runtime_operation_events
`
func (s *Store) ListPendingRuntimeOperationEvents(ctx context.Context, workspaceID string, limit int) ([]RuntimeOperationEvent, error) {
if s == nil || s.db == nil {
return nil, errors.New("workspace database is not initialized")
}
if limit <= 0 || limit > 1000 {
limit = 100
}
workspaceID = strings.TrimSpace(workspaceID)
query := runtimeOperationEventSelectSQL + ` WHERE published_at_unix_ms IS NULL`
args := make([]any, 0, 2)
if workspaceID != "" {
query += ` AND workspace_id = ?`
args = append(args, workspaceID)
}
query += ` ORDER BY id ASC LIMIT ?`
args = append(args, limit)
rows, err := s.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("list pending runtime operation events: %w", err)
}
defer rows.Close()
result := make([]RuntimeOperationEvent, 0)
for rows.Next() {
event, err := scanRuntimeOperationEvent(rows)
if err != nil {
return nil, err
}
result = append(result, event)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate pending runtime operation events: %w", err)
}
return result, nil
}
func (s *Store) MarkRuntimeOperationEventPublished(ctx context.Context, workspaceID string, eventID int64, publishedAtUnixMS int64) (bool, error) {
if s == nil || s.db == nil {
return false, errors.New("workspace database is not initialized")
}
result, err := s.db.ExecContext(ctx, `
UPDATE workspace_agent_runtime_operation_events SET published_at_unix_ms = ?
WHERE workspace_id = ? AND id = ? AND published_at_unix_ms IS NULL
`, publishedAtUnixMS, strings.TrimSpace(workspaceID), eventID)
if err != nil {
return false, fmt.Errorf("mark runtime operation event published: %w", err)
}
return rowsWereAffected(result, "mark runtime operation event published")
}
func getRuntimeOperationEventTx(ctx context.Context, tx *sql.Tx, operationID string) (RuntimeOperationEvent, bool, error) {
event, err := scanRuntimeOperationEvent(tx.QueryRowContext(ctx, runtimeOperationEventSelectSQL+` WHERE operation_id = ? ORDER BY id DESC LIMIT 1`, operationID))
if errors.Is(err, sql.ErrNoRows) {
return RuntimeOperationEvent{}, false, nil
}
return event, err == nil, err
}
func scanRuntimeOperationEvent(scanner rowScanner) (RuntimeOperationEvent, error) {
var event RuntimeOperationEvent
var payloadJSON string
if err := scanner.Scan(&event.ID, &event.OperationID, &event.WorkspaceID, &event.AgentSessionID,
&event.Kind, &payloadJSON, &event.CreatedAtUnixMS, &event.PublishedAtUnixMS); err != nil {
return RuntimeOperationEvent{}, err
}
payload, err := unmarshalJSONMap(payloadJSON)
if err != nil {
return RuntimeOperationEvent{}, fmt.Errorf("decode runtime operation event payload: %w", err)
}
event.Payload = payload
return event, nil
}