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
88 lines
3.0 KiB
Go
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
|
|
}
|