fix(hitl): keep the diagnosis in the HITL ledger so edited messages retain evidence and rationale
버튼 처리·만료 후 메시지를 편집할 때 빈 진단으로 다시 그려 증거·근거 필드가 "-"로 지워지던 결함을 고친다. ai.hitl_messages에 diagnosis jsonb를 추가해 게시 시점의 진단을 저장하고 편집 시 그대로 재사용한다.
This commit is contained in:
1 parent
c442601ab3
commit
43696d48c8
2 files changed
+12
-13
No files matched your search
@@ -131,7 +131,7 @@ func (b *Bot) Post(ctx context.Context, req PostRequest) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := b.store.InsertHitl(ctx, rag.HitlMessage{Token: req.Token, ChannelID: msg.ChannelID, MessageID: msg.ID, ActionID: req.ActionID, Target: req.Target, RunID: req.RunID, ScenarioID: req.ScenarioID, SessionID: req.SessionID, ExpiresAt: expires}); err != nil {
|
if err := b.store.InsertHitl(ctx, rag.HitlMessage{Token: req.Token, ChannelID: msg.ChannelID, MessageID: msg.ID, ActionID: req.ActionID, Target: req.Target, Diagnosis: req.Diagnosis, RunID: req.RunID, ScenarioID: req.ScenarioID, SessionID: req.SessionID, ExpiresAt: expires}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
b.arm(req.Token, time.Until(expires))
|
b.arm(req.Token, time.Until(expires))
|
||||||
@@ -217,14 +217,9 @@ func (b *Bot) Decide(ctx context.Context, token, decision, by string) (string, e
|
|||||||
return "", fmt.Errorf("unknown decision %s", decision)
|
return "", fmt.Errorf("unknown decision %s", decision)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// edit re-renders the original message with the stored diagnosis, the new status and disabled buttons.
|
||||||
func (b *Bot) edit(m *rag.HitlMessage, status string, color int, result map[string]any) error {
|
func (b *Bot) edit(m *rag.HitlMessage, status string, color int, result map[string]any) error {
|
||||||
ctx := context.Background()
|
em := embedFor(m.Diagnosis, m.ActionID, m.Target, m.RunID, m.ScenarioID, status, color)
|
||||||
d := map[string]any{}
|
|
||||||
if se, err := b.store.GetHitl(ctx, m.Token); err == nil {
|
|
||||||
m = se
|
|
||||||
}
|
|
||||||
em := embedFor(d, m.ActionID, m.Target, m.RunID, m.ScenarioID, status, color)
|
|
||||||
em.Fields = em.Fields[1:] // the diagnosis fields are already in the original message; keep the edit compact
|
|
||||||
if result != nil {
|
if result != nil {
|
||||||
rb, _ := json.Marshal(result)
|
rb, _ := json.Marshal(result)
|
||||||
em.Fields = append(em.Fields, &discordgo.MessageEmbedField{Name: "Result", Value: "```json\n" + truncate(string(rb), 900) + "\n```"})
|
em.Fields = append(em.Fields, &discordgo.MessageEmbedField{Name: "Result", Value: "```json\n" + truncate(string(rb), 900) + "\n```"})
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ CREATE TABLE IF NOT EXISTS ai.hitl_messages (
|
|||||||
message_id text NOT NULL,
|
message_id text NOT NULL,
|
||||||
action_id text NOT NULL,
|
action_id text NOT NULL,
|
||||||
target jsonb NOT NULL DEFAULT '{}'::jsonb,
|
target jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||||
|
diagnosis jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||||
run_id text,
|
run_id text,
|
||||||
scenario_id text,
|
scenario_id text,
|
||||||
session_id text,
|
session_id text,
|
||||||
@@ -302,6 +303,7 @@ type HitlMessage struct {
|
|||||||
MessageID string
|
MessageID string
|
||||||
ActionID string
|
ActionID string
|
||||||
Target map[string]any
|
Target map[string]any
|
||||||
|
Diagnosis map[string]any
|
||||||
RunID *string
|
RunID *string
|
||||||
ScenarioID *string
|
ScenarioID *string
|
||||||
SessionID string
|
SessionID string
|
||||||
@@ -313,20 +315,22 @@ type HitlMessage struct {
|
|||||||
|
|
||||||
func (s *Store) InsertHitl(ctx context.Context, m HitlMessage) error {
|
func (s *Store) InsertHitl(ctx context.Context, m HitlMessage) error {
|
||||||
t, _ := json.Marshal(m.Target)
|
t, _ := json.Marshal(m.Target)
|
||||||
_, err := s.pool.Exec(ctx, `INSERT INTO ai.hitl_messages (token,channel_id,message_id,action_id,target,run_id,scenario_id,session_id,expires_at)
|
d, _ := json.Marshal(m.Diagnosis)
|
||||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)`, m.Token, m.ChannelID, m.MessageID, m.ActionID, t, m.RunID, m.ScenarioID, m.SessionID, m.ExpiresAt)
|
_, err := s.pool.Exec(ctx, `INSERT INTO ai.hitl_messages (token,channel_id,message_id,action_id,target,diagnosis,run_id,scenario_id,session_id,expires_at)
|
||||||
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, m.Token, m.ChannelID, m.MessageID, m.ActionID, t, d, m.RunID, m.ScenarioID, m.SessionID, m.ExpiresAt)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetHitl(ctx context.Context, token string) (*HitlMessage, error) {
|
func (s *Store) GetHitl(ctx context.Context, token string) (*HitlMessage, error) {
|
||||||
var m HitlMessage
|
var m HitlMessage
|
||||||
var t []byte
|
var t, d []byte
|
||||||
err := s.pool.QueryRow(ctx, `SELECT token,channel_id,message_id,action_id,target,run_id,scenario_id,COALESCE(session_id,''),expires_at,decided_at,decision,decided_by FROM ai.hitl_messages WHERE token=$1`, token).
|
err := s.pool.QueryRow(ctx, `SELECT token,channel_id,message_id,action_id,target,diagnosis,run_id,scenario_id,COALESCE(session_id,''),expires_at,decided_at,decision,decided_by FROM ai.hitl_messages WHERE token=$1`, token).
|
||||||
Scan(&m.Token, &m.ChannelID, &m.MessageID, &m.ActionID, &t, &m.RunID, &m.ScenarioID, &m.SessionID, &m.ExpiresAt, &m.DecidedAt, &m.Decision, &m.DecidedBy)
|
Scan(&m.Token, &m.ChannelID, &m.MessageID, &m.ActionID, &t, &d, &m.RunID, &m.ScenarioID, &m.SessionID, &m.ExpiresAt, &m.DecidedAt, &m.Decision, &m.DecidedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = json.Unmarshal(t, &m.Target)
|
_ = json.Unmarshal(t, &m.Target)
|
||||||
|
_ = json.Unmarshal(d, &m.Diagnosis)
|
||||||
return &m, nil
|
return &m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user