feat(agent): 云端 Agent - 增加上下文预算、任务事实与终态恢复保障
This commit is contained in:
@@ -4,10 +4,18 @@ import "time"
|
||||
|
||||
// CloudAgentExecution checkpoints orchestration independently of billed tasks.
|
||||
type CloudAgentExecution struct {
|
||||
ID string `gorm:"primaryKey;size:80"`
|
||||
UserID string `gorm:"index;size:36"`
|
||||
Status string `gorm:"index;size:32"`
|
||||
Revision int64
|
||||
ID string `gorm:"primaryKey;size:80"`
|
||||
UserID string `gorm:"index;size:36"`
|
||||
Status string `gorm:"index;size:32"`
|
||||
Revision int64
|
||||
CheckpointVersion int `gorm:"not null;default:0"`
|
||||
ConversationID string `gorm:"index;size:80"`
|
||||
ParentID string `gorm:"index;size:80"`
|
||||
Title string `gorm:"size:240"`
|
||||
EventCount int
|
||||
MessageCount int
|
||||
Journal []CloudAgentEventRecord `gorm:"foreignKey:RunID;references:ID" json:"-"`
|
||||
Transcript []CloudAgentMessageRecord `gorm:"foreignKey:RunID;references:ID" json:"-"`
|
||||
// Control fields remain writable even when the transcript cannot be decoded or saved.
|
||||
CanvasID string `gorm:"size:80"`
|
||||
ActiveTaskID string `gorm:"size:80"`
|
||||
@@ -19,6 +27,25 @@ type CloudAgentExecution struct {
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// Journal rows are append-only and commit in the same transaction as the run.
|
||||
type CloudAgentEventRecord struct {
|
||||
RunID string `gorm:"primaryKey;size:80"`
|
||||
Sequence int `gorm:"primaryKey;autoIncrement:false"`
|
||||
UserID string `gorm:"index;size:36"`
|
||||
EventJSON string `gorm:"type:text;not null"`
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// Transcript bodies do not share the bounded execution checkpoint. Canonical
|
||||
// messages may be compacted; the append-only journal retains execution receipts.
|
||||
type CloudAgentMessageRecord struct {
|
||||
RunID string `gorm:"primaryKey;size:80"`
|
||||
Kind string `gorm:"primaryKey;size:24"`
|
||||
Sequence int `gorm:"primaryKey;autoIncrement:false"`
|
||||
UserID string `gorm:"index;size:36"`
|
||||
MessageJSON string `gorm:"type:text;not null"`
|
||||
}
|
||||
|
||||
// CloudAgentCanvasMutation records one atomic canvas change made by an Agent.
|
||||
// BeforeJSON is intentionally bounded by the application layer; mutations that
|
||||
// cannot retain a safe snapshot are marked not_undoable instead of truncating it.
|
||||
|
||||
13
backend/internal/model/cloud_agent_resource_lease.go
Normal file
13
backend/internal/model/cloud_agent_resource_lease.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// CloudAgentResourceLease pins immutable inputs while a prepared action waits
|
||||
// for approval. Submitted tasks subsequently own their resource references.
|
||||
type CloudAgentResourceLease struct {
|
||||
UserID string `gorm:"primaryKey;size:36"`
|
||||
RunID string `gorm:"index;size:80"`
|
||||
OwnerID string `gorm:"primaryKey;size:160"`
|
||||
ResourceID string `gorm:"primaryKey;size:36;index"`
|
||||
ExpiresAt time.Time `gorm:"index"`
|
||||
}
|
||||
@@ -54,7 +54,9 @@ type BillingOrder struct {
|
||||
Quantity int64 `json:"quantity"`
|
||||
AmountMicrocredits int64 `json:"amountMicrocredits"`
|
||||
ReservedAmountMicrocredits int64 `json:"reservedAmountMicrocredits"`
|
||||
// ChargeLimitMicrocredits 非零时限制最终用户扣费;Agent 的 Token 报价用它把预授权金额固化为本轮硬上限。
|
||||
// ChargeLimitSet distinguishes an authorized zero price from an uncapped order.
|
||||
// All Agent prices remain capped across route changes and settlement.
|
||||
ChargeLimitSet bool `json:"chargeLimitSet,omitempty" gorm:"not null;default:false"`
|
||||
ChargeLimitMicrocredits int64 `json:"chargeLimitMicrocredits,omitempty"`
|
||||
ActualAmountMicrocredits int64 `json:"actualAmountMicrocredits"`
|
||||
RefundedAmountMicrocredits int64 `json:"refundedAmountMicrocredits"`
|
||||
|
||||
@@ -3,24 +3,33 @@ package model
|
||||
import "time"
|
||||
|
||||
type Task struct {
|
||||
CreationSubmissionID *string `json:"creationSubmissionId,omitempty" gorm:"size:36;uniqueIndex"`
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
UserID string `json:"userId" gorm:"index;size:36;index:idx_tasks_user_created,priority:1;index:idx_tasks_user_project_created,priority:1"`
|
||||
TraceID string `json:"-" gorm:"index;size:96"`
|
||||
RequestID string `json:"-" gorm:"index;size:96"`
|
||||
ProjectID string `json:"projectId" gorm:"index;size:80;index:idx_tasks_user_project_created,priority:2"`
|
||||
Type string `json:"type" gorm:"index;size:64"`
|
||||
Status TaskStatus `json:"status" gorm:"index;size:24;index:idx_tasks_status_created,priority:1;index:idx_tasks_claim,priority:1;index:idx_tasks_provider_cancel,priority:1"`
|
||||
Stage string `json:"stage" gorm:"size:80"`
|
||||
Progress int `json:"progress"`
|
||||
Prompt string `json:"prompt"`
|
||||
Operation string `json:"operation" gorm:"size:64"`
|
||||
Provider string `json:"provider" gorm:"size:64"`
|
||||
Model string `json:"model" gorm:"size:120"`
|
||||
LogicalModelID string `json:"logicalModelId,omitempty" gorm:"size:36;index"`
|
||||
LogicalModelRevisionID string `json:"logicalModelRevisionId,omitempty" gorm:"size:36;index"`
|
||||
RouteID string `json:"routeId,omitempty" gorm:"size:36;index"`
|
||||
ChannelModelID string `json:"channelModelId,omitempty" gorm:"size:36;index"`
|
||||
AgentRunID string `json:"agentRunId,omitempty" gorm:"size:36;index"`
|
||||
GenerationID string `json:"generationId,omitempty" gorm:"size:36;index"`
|
||||
ApprovalID string `json:"approvalId,omitempty" gorm:"size:160"`
|
||||
AuthorizedChargeMicrocredits int64 `json:"authorizedChargeMicrocredits,omitempty"`
|
||||
ExecutionDiagnosticJSON string `json:"-" gorm:"type:text"`
|
||||
Diagnostic *TaskExecutionDiagnostic `json:"diagnostic,omitempty" gorm:"-"`
|
||||
CancellationSource string `json:"cancellationSource,omitempty" gorm:"size:40"`
|
||||
CancellationActorID string `json:"cancellationActorId,omitempty" gorm:"size:36"`
|
||||
CancellationRequestedAt *time.Time `json:"cancellationRequestedAt,omitempty"`
|
||||
CreationSubmissionID *string `json:"creationSubmissionId,omitempty" gorm:"size:36;uniqueIndex"`
|
||||
ID string `json:"id" gorm:"primaryKey;size:36"`
|
||||
UserID string `json:"userId" gorm:"index;size:36;index:idx_tasks_user_created,priority:1;index:idx_tasks_user_project_created,priority:1"`
|
||||
TraceID string `json:"-" gorm:"index;size:96"`
|
||||
RequestID string `json:"-" gorm:"index;size:96"`
|
||||
ProjectID string `json:"projectId" gorm:"index;size:80;index:idx_tasks_user_project_created,priority:2"`
|
||||
Type string `json:"type" gorm:"index;size:64"`
|
||||
Status TaskStatus `json:"status" gorm:"index;size:24;index:idx_tasks_status_created,priority:1;index:idx_tasks_claim,priority:1;index:idx_tasks_provider_cancel,priority:1"`
|
||||
Stage string `json:"stage" gorm:"size:80"`
|
||||
Progress int `json:"progress"`
|
||||
Prompt string `json:"prompt"`
|
||||
Operation string `json:"operation" gorm:"size:64"`
|
||||
Provider string `json:"provider" gorm:"size:64"`
|
||||
Model string `json:"model" gorm:"size:120"`
|
||||
LogicalModelID string `json:"logicalModelId,omitempty" gorm:"size:36;index"`
|
||||
LogicalModelRevisionID string `json:"logicalModelRevisionId,omitempty" gorm:"size:36;index"`
|
||||
RouteID string `json:"routeId,omitempty" gorm:"size:36;index"`
|
||||
ChannelModelID string `json:"channelModelId,omitempty" gorm:"size:36;index"`
|
||||
// RouteRun 只在用户主动重试时递增;worker 租约恢复不应创建新的路由选择世代。
|
||||
RouteRun int `json:"-" gorm:"index"`
|
||||
BillingOrderID string `json:"billingOrderId,omitempty" gorm:"index;size:36"`
|
||||
|
||||
34
backend/internal/model/task_execution.go
Normal file
34
backend/internal/model/task_execution.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
TaskCancellationUserRequest = "user_request"
|
||||
TaskCancellationParentCancelled = "parent_cancelled"
|
||||
TaskCancellationParentFailed = "parent_failed"
|
||||
TaskCancellationWorkerContext = "worker_context"
|
||||
)
|
||||
|
||||
// TaskExecutionDiagnostic records execution facts independently of the node's
|
||||
// presentation state. SafeMessage is suitable for users and model context.
|
||||
type TaskExecutionDiagnostic struct {
|
||||
Code string `json:"code"`
|
||||
Phase string `json:"phase"`
|
||||
FieldPath string `json:"fieldPath,omitempty"`
|
||||
TaskSubmitted bool `json:"taskSubmitted"`
|
||||
SubmissionOutcome string `json:"submissionOutcome"`
|
||||
RetryClass string `json:"retryClass"`
|
||||
SafeMessage string `json:"safeMessage"`
|
||||
DiagnosticID string `json:"diagnosticId"`
|
||||
WritebackOutcome string `json:"writebackOutcome,omitempty"`
|
||||
WritebackReason string `json:"writebackReason,omitempty"`
|
||||
WritebackNodeID string `json:"writebackNodeId,omitempty"`
|
||||
WritebackMessage string `json:"writebackMessage,omitempty"`
|
||||
}
|
||||
|
||||
type TaskCancellationIntent struct {
|
||||
Source string
|
||||
ActorID string
|
||||
RequestedAt time.Time
|
||||
Diagnostic TaskExecutionDiagnostic
|
||||
}
|
||||
Reference in New Issue
Block a user