- Introduce ThreadSessionMapper to derive stable OpenClaw session keys from threadId/sessionId, avoiding leaked draft session identifiers - Replace the artifact scope cascading fallback (output-token heuristics, draft variant retries) with a single collect-and-snapshot call followed by export, per anti-fallback rules - Enforce artifact contract by failing runs that report success but miss required final artifact extensions - Update orchestrator and tests to the new methods sequence (collect-and-snapshot before export) - Relax AGENTS.md rule to allow updating tests when the protocol contract itself changes
37 lines
758 B
Go
37 lines
758 B
Go
package acp
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type ThreadSessionMapper struct {
|
|
mu sync.Mutex
|
|
sessions map[string]string
|
|
}
|
|
|
|
func NewThreadSessionMapper() *ThreadSessionMapper {
|
|
return &ThreadSessionMapper{sessions: make(map[string]string)}
|
|
}
|
|
|
|
func (m *ThreadSessionMapper) OpenClawSessionID(threadID string, sessionID string) string {
|
|
key := strings.TrimSpace(threadID)
|
|
if key == "" {
|
|
key = strings.TrimSpace(sessionID)
|
|
}
|
|
if key == "" {
|
|
key = "main"
|
|
}
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
if existing := strings.TrimSpace(m.sessions[key]); existing != "" {
|
|
return existing
|
|
}
|
|
sum := sha256.Sum256([]byte(key))
|
|
session := "xwm-" + hex.EncodeToString(sum[:])[:24]
|
|
m.sessions[key] = session
|
|
return session
|
|
}
|