agent-exec transport 2f80ef82aa46c436ab31ad04be4314d5/5a44c92c20c8

This commit is contained in:
agent-exec-transport
2026-10-19 09:24:56 +00:00
parent c7b37e888a
commit c65ba8eb6d
72 changed files with 8655 additions and 239 deletions
+126
View File
@@ -0,0 +1,126 @@
package runmgr
import (
"fmt"
"agent-system-backend/internal/runtime"
core "agent-system-core"
)
type materialIntakeState string
const (
materialNone materialIntakeState = "none"
materialQueued materialIntakeState = "queued"
materialRunning materialIntakeState = "running"
materialReusedRunning materialIntakeState = "reused_running"
materialCompleted materialIntakeState = "completed"
materialFailed materialIntakeState = "failed"
materialUnknown materialIntakeState = "unknown"
)
type materialIntakeDecision struct {
Note string
State materialIntakeState
CardID core.ID
}
func (d materialIntakeDecision) needsAcknowledgement(userText string) bool {
return d.State == materialRunning || d.State == materialReusedRunning || d.State == materialQueued ||
d.State == materialFailed || d.State == materialUnknown ||
(d.State == materialCompleted && userText == "")
}
// materialDecisionForNote reads server-owned task state after intake or reuse;
// an absent card is unknown rather than proof that work has started.
func (m *Manager) materialDecisionForNote(rc *runCtx, key, note string) materialIntakeDecision {
decision := materialIntakeDecision{Note: note, State: materialUnknown}
if m.cards == nil {
return decision
}
cards, err := m.cards.List(rc.run.Owner, rc.run.ConversationID)
if err != nil {
return decision
}
var current *core.ActivityCard
for i := range cards {
card := &cards[i]
if card.Kind != core.CardKindProgress || card.ProjectID != rc.run.ProjectID ||
card.Task == nil || card.Task.InputRevision != key {
continue
}
if current == nil || card.CreatedAt.After(current.CreatedAt) ||
(card.CreatedAt.Equal(current.CreatedAt) && current.Task.Terminal() && !card.Task.Terminal()) {
current = card
}
}
if current != nil {
decision.CardID = current.ID
if current.Task.ExecutionState == "completed" {
if m.taskSourcesAvailable(rc.run.Owner, rc.run.ProjectID, current.Task) {
decision.State = materialCompleted
decision.Note = materialDoneNote
} else {
decision.State = materialUnknown
}
} else if current.Task.ExecutionState == "queued" {
decision.State = materialQueued
} else if current.Task.Terminal() {
decision.State = materialFailed
decision.Note = ""
} else {
decision.State = materialRunning
}
}
return decision
}
type materialAckRunner struct {
decision materialIntakeDecision
attachmentCount int
hasUserFocus bool
}
func (materialAckRunner) Name() string { return "material-acknowledgement" }
func (r materialAckRunner) Execute(rc runtime.RunCtx) error {
if err := rc.Context().Err(); err != nil {
return err
}
text := r.reply()
if err := rc.Emit(core.EvRunPhase, core.RunPhasePayload{Phase: core.PhaseResponding}); err != nil {
return err
}
if err := rc.Emit(core.EvMessageDelta, core.MessageDeltaPayload{Index: 0, Text: text}); err != nil {
return err
}
return rc.SetAssistantParts([]core.Part{{Type: core.PartText, Text: text}})
}
func (r materialAckRunner) reply() string {
lead := ""
if r.decision.State == materialCompleted {
lead = "这批材料已整理完成,可在“材料整理”卡查看结果。"
} else if r.decision.State == materialQueued {
lead = fmt.Sprintf("已收到 %d 份材料,整理任务正在排队。", r.attachmentCount)
} else if r.decision.State == materialReusedRunning {
lead = "这批材料仍在整理,已有任务会继续更新“材料整理”卡。"
} else if r.decision.State == materialFailed {
if r.decision.CardID == "" {
lead = "材料已收到,但后台整理未能启动;请稍后重新提出请求。"
} else {
lead = "后台整理未能完成;请查看“材料整理”卡中的已保存成果和未完成范围。"
}
} else if r.decision.State == materialUnknown {
if r.decision.CardID == "" {
return "材料已收到,但暂时无法确认整理状态;当前没有可核对的工作卡,请稍后刷新会话或重新提出请求。数字、分期和归属判断待确认。"
}
lead = "材料已收到,但暂时无法确认整理状态;请查看工作卡。"
} else {
lead = fmt.Sprintf("已收到 %d 份材料,正在整理。", r.attachmentCount)
}
if r.hasUserFocus {
lead += "你提出的工作重点已带入整理任务。"
}
return lead + "材料中的数字、分期和归属判断在核对依据前均标为待确认;有依据的发现会显示在“材料整理”卡。"
}