Function bodies 401 total
LastPushed method · go · L35-L37 (3 LOC)connectors/rp/postinvest_push_store.go
func (s *MemPushStore) LastPushed() *PushedRecord {
return s.last
}Fetch method · go · L14-L16 (3 LOC)connectors/rp/preinvest_fetcher.go
func (f *StubFetcher) Fetch(launchID int) (*Envelope, error) {
return f.Env, nil
}NewStubFetcher function · go · L19-L21 (3 LOC)connectors/rp/preinvest_fetcher.go
func NewStubFetcher(env *Envelope) *StubFetcher {
return &StubFetcher{Env: env}
}FetchAndSave function · go · L4-L10 (7 LOC)connectors/rp/preinvest_preinvest.go
func FetchAndSave(f EnvelopeFetcher, s EnvelopeStore, launchID int) error {
env, err := f.Fetch(launchID)
if err != nil {
return err
}
return s.Save(launchID, env)
}NewMemEnvelopeStore function · go · L15-L17 (3 LOC)connectors/rp/preinvest_store.go
func NewMemEnvelopeStore() *MemEnvelopeStore {
return &MemEnvelopeStore{envelopes: make(map[int]*Envelope)}
}Save method · go · L20-L23 (4 LOC)connectors/rp/preinvest_store.go
func (s *MemEnvelopeStore) Save(launchID int, envelope *Envelope) error {
s.envelopes[launchID] = envelope
return nil
}Get method · go · L26-L28 (3 LOC)connectors/rp/preinvest_store.go
func (s *MemEnvelopeStore) Get(launchID int) (*Envelope, error) {
return s.envelopes[launchID], nil
}All rows scored by the Repobility analyzer (https://repobility.com)
Project method · go · L12-L14 (3 LOC)connectors/rp/project.go
func (c *Client) Project(name string) *ProjectScope {
return &ProjectScope{client: c, projectName: name}
}Launches method · go · L17-L19 (3 LOC)connectors/rp/project.go
func (p *ProjectScope) Launches() *LaunchScope {
return &LaunchScope{project: p}
}Items method · go · L22-L24 (3 LOC)connectors/rp/project.go
func (p *ProjectScope) Items() *ItemScope {
return &ItemScope{project: p}
}logger method · go · L26-L28 (3 LOC)connectors/rp/project.go
func (p *ProjectScope) logger() *slog.Logger {
return p.client.logger.With("project", p.projectName)
}NewPusher function · go · L24-L29 (6 LOC)connectors/rp/pusher.go
func NewPusher(client *Client, project, submittedBy, appName string) *Pusher {
if appName == "" {
appName = "Origami"
}
return &Pusher{client: client, project: project, submittedBy: submittedBy, appName: appName}
}Push method · go · L33-L71 (39 LOC)connectors/rp/pusher.go
func (p *Pusher) Push(artifactPath string, store PushStore, jiraTicketID, jiraLink string) error {
data, err := os.ReadFile(artifactPath)
if err != nil {
return err
}
var a pushArtifact
if err := json.Unmarshal(data, &a); err != nil {
return err
}
ctx := context.Background()
items := p.client.Project(p.project).Items()
comment := p.buildComment(a.RCAMessage, a.EvidenceRefs)
defs := make([]IssueDefinition, 0, len(a.CaseIDs))
for _, caseID := range a.CaseIDs {
itemID, _ := strconv.Atoi(caseID)
defs = append(defs, IssueDefinition{
TestItemID: itemID,
Issue: Issue{
IssueType: a.DefectType,
Comment: comment,
},
})
}
if err := items.UpdateDefectBulk(ctx, defs); err != nil {
return fmt.Errorf("update defects: %w", err)
}
return store.RecordPushed(PushedRecord{
RunID: a.RunID,
CaseIDs: a.CaseIDs,
DefectType: a.DefectType,
JiraTicketID: jiraTicketID,
JiraLink: jiraLink,
})
}PushVerdict method · go · L74-L103 (30 LOC)connectors/rp/pusher.go
func (p *Pusher) PushVerdict(verdict rcatype.RCAVerdict, store PushStore) error {
ctx := context.Background()
items := p.client.Project(p.project).Items()
comment := p.buildComment(verdict.RCAMessage, verdict.EvidenceRefs)
defs := make([]IssueDefinition, 0, len(verdict.CaseIDs))
for _, caseID := range verdict.CaseIDs {
itemID, _ := strconv.Atoi(caseID)
defs = append(defs, IssueDefinition{
TestItemID: itemID,
Issue: Issue{
IssueType: verdict.DefectType,
Comment: comment,
},
})
}
if err := items.UpdateDefectBulk(ctx, defs); err != nil {
return fmt.Errorf("update defects: %w", err)
}
return store.RecordPushed(PushedRecord{
RunID: verdict.RunID,
CaseIDs: verdict.CaseIDs,
DefectType: verdict.DefectType,
JiraTicketID: verdict.JiraTicketID,
JiraLink: verdict.JiraLink,
})
}buildComment method · go · L105-L125 (21 LOC)connectors/rp/pusher.go
func (p *Pusher) buildComment(rcaMessage string, evidenceRefs []string) string {
var parts []string
if rcaMessage != "" {
parts = append(parts, rcaMessage)
}
commitLinks := filterCommitLinks(evidenceRefs)
if len(commitLinks) > 0 {
parts = append(parts, "**Suspected commit(s):**\n"+strings.Join(commitLinks, "\n"))
}
attribution := "Analysis was submitted"
if p.submittedBy != "" {
attribution += " by " + p.submittedBy
}
attribution += " (via " + p.appName + ")"
parts = append(parts, attribution)
return strings.Join(parts, "\n\n---\n")
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
filterCommitLinks function · go · L127-L135 (9 LOC)connectors/rp/pusher.go
func filterCommitLinks(refs []string) []string {
var links []string
for _, ref := range refs {
if isCommitLink(ref) {
links = append(links, ref)
}
}
return links
}NewSourceReader function · go · L21-L31 (11 LOC)connectors/rp/source.go
func NewSourceReader(baseURL, apiKeyPath, project string) (rcatype.SourceReader, error) {
key, err := ReadAPIKey(apiKeyPath)
if err != nil {
return nil, err
}
client, err := New(baseURL, key, WithTimeout(30*time.Second))
if err != nil {
return nil, err
}
return &SourceReaderRP{client: client, project: project}, nil
}FetchEnvelope method · go · L33-L44 (12 LOC)connectors/rp/source.go
func (a *SourceReaderRP) FetchEnvelope(runID string) (*rcatype.Envelope, error) {
launchID, err := strconv.Atoi(runID)
if err != nil {
return nil, fmt.Errorf("invalid runID %q: %w", runID, err)
}
f := NewFetcher(a.client, a.project)
rpEnv, err := f.Fetch(launchID)
if err != nil {
return nil, err
}
return envelopeToRCAType(rpEnv), nil
}EnvelopeFetcher method · go · L46-L48 (3 LOC)connectors/rp/source.go
func (a *SourceReaderRP) EnvelopeFetcher() rcatype.EnvelopeFetcher {
return &envelopeFetcherBridge{client: a.client, project: a.project}
}CurrentUser method · go · L50-L57 (8 LOC)connectors/rp/source.go
func (a *SourceReaderRP) CurrentUser() string {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if u, err := a.client.GetCurrentUser(ctx); err == nil && u.UserID != "" {
return u.UserID
}
return ""
}Fetch method · go · L64-L75 (12 LOC)connectors/rp/source.go
func (b *envelopeFetcherBridge) Fetch(runID string) (*rcatype.Envelope, error) {
launchID, err := strconv.Atoi(runID)
if err != nil {
return nil, fmt.Errorf("invalid runID %q: %w", runID, err)
}
f := NewFetcher(b.client, b.project)
rpEnv, err := f.Fetch(launchID)
if err != nil {
return nil, err
}
return envelopeToRCAType(rpEnv), nil
}NewDefectWriter function · go · L84-L94 (11 LOC)connectors/rp/source.go
func NewDefectWriter(baseURL, apiKeyPath, project, submittedBy string) (rcatype.DefectWriter, error) {
key, err := ReadAPIKey(apiKeyPath)
if err != nil {
return nil, err
}
client, err := New(baseURL, key, WithTimeout(30*time.Second))
if err != nil {
return nil, err
}
return &DefectWriterRP{pusher: NewPusher(client, project, submittedBy, "")}, nil
}Push method · go · L96-L106 (11 LOC)connectors/rp/source.go
func (p *DefectWriterRP) Push(verdict rcatype.RCAVerdict) (*rcatype.PushedRecord, error) {
st := NewMemPushStore()
if err := p.pusher.PushVerdict(verdict, st); err != nil {
return nil, err
}
rec := st.LastPushed()
if rec == nil {
return nil, nil
}
return &rcatype.PushedRecord{RunID: rec.RunID, DefectType: rec.DefectType}, nil
}Repobility (the analyzer behind this table) · https://repobility.com
envelopeToRCAType function · go · L109-L172 (64 LOC)connectors/rp/source.go
func envelopeToRCAType(e *Envelope) *rcatype.Envelope {
if e == nil {
return nil
}
tags := map[string]string{}
if e.LaunchUUID != "" {
tags["rp.launch_uuid"] = e.LaunchUUID
}
env := &rcatype.Envelope{
RunID: e.RunID,
Name: e.Name,
}
if len(tags) > 0 {
env.Tags = tags
}
for _, f := range e.FailureList {
ftags := map[string]string{}
if f.UUID != "" {
ftags["rp.uuid"] = f.UUID
}
if f.Type != "" {
ftags["rp.type"] = f.Type
}
if f.Path != "" {
ftags["rp.path"] = f.Path
}
if f.CodeRef != "" {
ftags["rp.code_ref"] = f.CodeRef
}
if f.ParentID != 0 {
ftags["rp.parent_id"] = strconv.Itoa(f.ParentID)
}
if f.IssueType != "" {
ftags["rp.issue_type"] = f.IssueType
}
if f.AutoAnalyzed {
ftags["rp.auto_analyzed"] = "true"
}
item := rcatype.FailureItem{
ID: strconv.Itoa(f.ID),
Name: f.Name,
Status: f.Status,
Description: f.Description,
ErrorMessage: f.Description,
LogSnippet: MarshalJSON method · go · L24-L27 (4 LOC)connectors/rp/types.go
func (e EpochMillis) MarshalJSON() ([]byte, error) {
ms := time.Time(e).UnixMilli()
return json.Marshal(ms)
}UnmarshalJSON method · go · L30-L41 (12 LOC)connectors/rp/types.go
func (e *EpochMillis) UnmarshalJSON(data []byte) error {
var value int64
if err := json.Unmarshal(data, &value); err != nil {
return fmt.Errorf("unmarshal epoch millis: %w", err)
}
if value >= maxMillisTimestamp {
*e = EpochMillis(time.UnixMicro(value))
} else {
*e = EpochMillis(time.UnixMilli(value))
}
return nil
}Transform method · go · L18-L43 (26 LOC)correlate_heuristic.go
func (t *correlateHeuristic) Transform(_ context.Context, tc *engine.TransformerContext) (any, error) {
fp := failureFromContext(tc.WalkerState)
rcas, err := t.ht.st.ListRCAs()
if err != nil || len(rcas) == 0 {
return map[string]any{"is_duplicate": false, "confidence": 0.0}, nil
}
text := strings.ToLower(fp.errorMessage)
if text == "" {
return map[string]any{"is_duplicate": false, "confidence": 0.0}, nil
}
for _, existing := range rcas {
if existing.Description == "" {
continue
}
rcaText := strings.ToLower(existing.Description)
if strings.Contains(rcaText, text) || strings.Contains(text, rcaText) {
return map[string]any{
"is_duplicate": true,
"linked_rca_id": float64(existing.ID),
"confidence": 0.75,
"reasoning": fmt.Sprintf("matched existing RCA #%d: %s", existing.ID, existing.Title),
}, nil
}
}
return map[string]any{"is_duplicate": false, "confidence": 0.0}, nil
}ClassifyVerdict function · go · L50-L61 (12 LOC)evidence_gap.go
func ClassifyVerdict(convergence float64, defectType string, confidentThreshold, inconclusiveThreshold float64) string {
if defectType == "unknown" || defectType == "" {
return VerdictInconclusive
}
if convergence >= confidentThreshold {
return VerdictConfident
}
if convergence < inconclusiveThreshold {
return VerdictInconclusive
}
return VerdictLowConfidence
}NewMapExtractor function · go · L15-L17 (3 LOC)extractor.go
func NewMapExtractor(name string) *MapExtractor {
return &MapExtractor{name: name}
}Extract method · go · L21-L36 (16 LOC)extractor.go
func (e *MapExtractor) Extract(_ context.Context, input any) (any, error) {
var data []byte
switch v := input.(type) {
case json.RawMessage:
data = v
case []byte:
data = v
default:
return nil, fmt.Errorf("MapExtractor %q: expected json.RawMessage or []byte, got %T", e.name, input)
}
var result map[string]any
if err := json.Unmarshal(data, &result); err != nil {
return nil, fmt.Errorf("MapExtractor %q: %w", e.name, err)
}
return result, nil
}WrapNodeArtifact function · go · L11-L19 (9 LOC)framework_adapters.go
func WrapNodeArtifact(nodeName string, artifact any) circuit.Artifact {
if artifact == nil {
return nil
}
return &bridgeArtifact{
raw: artifact,
typeName: nodeName,
}
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
NewHeuristicTransformer function · go · L31-L38 (8 LOC)heuristic.go
func NewHeuristicTransformer(st store.Store, repos []string, heuristicsData []byte) *heuristicTransformer {
eval, err := toolkit.NewMatchEvaluator(heuristicsData)
if err != nil {
panic(fmt.Sprintf("load heuristics.yaml: %v", err))
}
conv := loadConvergenceConfig(heuristicsData)
return &heuristicTransformer{st: st, repos: repos, eval: eval, conv: conv}
}failureFromContext function · go · L46-L65 (20 LOC)heuristic.go
func failureFromContext(ws *circuit.WalkerState) failureInfo {
if ws == nil {
return failureInfo{}
}
if fp, ok := ws.Context[KeyParamsFailure].(*FailureParams); ok {
return failureInfo{
name: fp.TestName,
errorMessage: fp.ErrorMessage,
logSnippet: fp.LogSnippet,
}
}
if cd, ok := ws.Context[KeyCaseData].(*store.Case); ok {
return failureInfo{
name: cd.Name,
errorMessage: cd.ErrorMessage,
logSnippet: cd.LogSnippet,
}
}
return failureInfo{}
}textFromFailure method · go · L67-L69 (3 LOC)heuristic.go
func (t *heuristicTransformer) textFromFailure(fp failureInfo) string {
return strings.ToLower(fp.name + " " + fp.errorMessage + " " + fp.logSnippet)
}classifyDefect method · go · L72-L78 (7 LOC)heuristic.go
func (t *heuristicTransformer) classifyDefect(text string) (category, hypothesis string, skip bool) {
result, _, err := t.eval.Evaluate("defect_classification", text)
if err != nil {
return "product", "pb001", false
}
return parseClassification(result)
}parseClassification function · go · L80-L95 (16 LOC)heuristic.go
func parseClassification(result any) (category, hypothesis string, skip bool) {
m, ok := result.(map[string]any)
if !ok {
return "product", "pb001", false
}
cat, _ := m["category"].(string)
hypo, _ := m["hypothesis"].(string)
sk, _ := m["skip"].(bool)
if cat == "" {
cat = "product"
}
if hypo == "" {
hypo = "pb001"
}
return cat, hypo, sk
}identifyComponent method · go · L98-L104 (7 LOC)heuristic.go
func (t *heuristicTransformer) identifyComponent(text string) string {
rs, err := t.eval.Get("component_identification")
if err != nil {
return "unknown"
}
return rs.EvaluateString(text)
}buildRecall method · go · L106-L126 (21 LOC)heuristic.go
func (t *heuristicTransformer) buildRecall(fp failureInfo) map[string]any {
fingerprint := ComputeFingerprint(fp.name, fp.errorMessage, "")
sym, err := t.st.GetSymptomByFingerprint(fingerprint)
if err != nil || sym == nil {
return map[string]any{
"match": false, "confidence": 0.0,
"reasoning": "no matching symptom in store",
}
}
links, err := t.st.GetRCAsForSymptom(sym.ID)
if err != nil || len(links) == 0 {
return map[string]any{
"match": true, "symptom_id": float64(sym.ID), "confidence": 0.60,
"reasoning": fmt.Sprintf("matched symptom %q (count=%d) but no linked RCA", sym.Name, sym.OccurrenceCount),
}
}
return map[string]any{
"match": true, "prior_rca_id": float64(links[0].RCAID), "symptom_id": float64(sym.ID), "confidence": 0.85,
"reasoning": fmt.Sprintf("recalled symptom %q with RCA #%d", sym.Name, links[0].RCAID),
}
}buildTriage method · go · L128-L152 (25 LOC)heuristic.go
func (t *heuristicTransformer) buildTriage(fp failureInfo) map[string]any {
text := t.textFromFailure(fp)
category, hypothesis, skip := t.classifyDefect(text)
component := t.identifyComponent(text)
var candidateRepos []any
if component != "unknown" {
candidateRepos = []any{component}
} else {
for _, r := range t.repos {
candidateRepos = append(candidateRepos, r)
}
}
cascade := matchCount(text, cascadeKeywords()) > 0
return map[string]any{
"symptom_category": category,
"severity": "medium",
"defect_type_hypothesis": hypothesis,
"candidate_repos": candidateRepos,
"skip_investigation": skip,
"cascade_suspected": cascade,
}
}All rows scored by the Repobility analyzer (https://repobility.com)
buildResolve method · go · L154-L166 (13 LOC)heuristic.go
func (t *heuristicTransformer) buildResolve(fp failureInfo) map[string]any {
text := t.textFromFailure(fp)
component := t.identifyComponent(text)
var repos []any
if component != "unknown" {
repos = append(repos, map[string]any{"name": component, "reason": fmt.Sprintf("keyword-identified component: %s", component)})
} else {
for _, name := range t.repos {
repos = append(repos, map[string]any{"name": name, "reason": "included from workspace (no component identified)"})
}
}
return map[string]any{"selected_repos": repos}
}buildInvestigate method · go · L168-L216 (49 LOC)heuristic.go
func (t *heuristicTransformer) buildInvestigate(fp failureInfo) map[string]any {
text := t.textFromFailure(fp)
component := t.identifyComponent(text)
_, defectType, _ := t.classifyDefect(text)
evidenceRefs := extractEvidenceRefs(fp.errorMessage, component)
rcaParts := []string{}
if fp.errorMessage != "" {
rcaParts = append(rcaParts, fp.errorMessage)
}
if fp.name != "" {
rcaParts = append(rcaParts, fmt.Sprintf("Test: %s", fp.name))
}
if component != "unknown" {
rcaParts = append(rcaParts, fmt.Sprintf("Suspected component: %s", component))
}
rcaMessage := strings.Join(rcaParts, " | ")
if rcaMessage == "" {
rcaMessage = "investigation pending (no error message available)"
}
convergence := t.computeConvergence(text, component)
gapBrief := t.buildGapBrief(fp, text, component, defectType, convergence)
m := map[string]any{
"rca_message": rcaMessage,
"defect_type": defectType,
"component": component,
"convergence_score": convergence,
"ebuildGapBrief method · go · L218-L239 (22 LOC)heuristic.go
func (t *heuristicTransformer) buildGapBrief(fp failureInfo, text, component, defectType string, convergence float64) *GapBrief {
verdict := ClassifyVerdict(convergence, defectType, DefaultGapConfidentThreshold, DefaultGapInconclusiveThreshold)
var gaps []EvidenceGap
if len(fp.errorMessage)+len(fp.logSnippet) < 200 {
gaps = append(gaps, EvidenceGap{Category: GapLogDepth, Description: "Only a short error message is available; no full logs or stack trace", WouldHelp: "Full pod logs from the failure window would show the actual error chain", Source: "CI job console log"})
}
if !jiraIDPattern.MatchString(text) {
gaps = append(gaps, EvidenceGap{Category: GapJiraContext, Description: "No Jira ticket references found in the failure data", WouldHelp: "Linked Jira ticket description would confirm or deny the hypothesis", Source: "Jira / issue tracker"})
}
if component == "unknown" {
gaps = append(gaps, EvidenceGap{Category: GapSourceCode, Description: "Could not identify the affecbuildCorrelate method · go · L241-L265 (25 LOC)heuristic.go
func (t *heuristicTransformer) buildCorrelate(fp failureInfo) map[string]any {
rcas, err := t.st.ListRCAs()
if err != nil || len(rcas) == 0 {
return map[string]any{"is_duplicate": false, "confidence": 0.0}
}
text := strings.ToLower(fp.errorMessage)
if text == "" {
return map[string]any{"is_duplicate": false, "confidence": 0.0}
}
for _, existing := range rcas {
if existing.Description == "" {
continue
}
rcaText := strings.ToLower(existing.Description)
if strings.Contains(rcaText, text) || strings.Contains(text, rcaText) {
return map[string]any{
"is_duplicate": true,
"linked_rca_id": float64(existing.ID),
"confidence": 0.75,
"reasoning": fmt.Sprintf("matched existing RCA #%d: %s", existing.ID, existing.Title),
}
}
}
return map[string]any{"is_duplicate": false, "confidence": 0.0}
}computeConvergence method · go · L267-L285 (19 LOC)heuristic.go
func (t *heuristicTransformer) computeConvergence(text, component string) float64 {
if component == "unknown" {
return 0.70
}
score := 0.70
if matchCount(text, t.conv.JiraKW) > 0 {
score += 0.10
}
matches := matchCount(text, t.conv.DescriptiveKW)
if matches >= 2 {
score += 0.10
} else if matches == 1 {
score += 0.05
}
if score > 0.95 {
score = 0.95
}
return score
}matchCount function · go · L287-L295 (9 LOC)heuristic.go
func matchCount(text string, keywords []string) int {
count := 0
for _, kw := range keywords {
if strings.Contains(text, kw) {
count++
}
}
return count
}extractEvidenceRefs function · go · L299-L316 (18 LOC)heuristic.go
func extractEvidenceRefs(errorMessage string, component string) []string {
var refs []string
seen := make(map[string]bool)
if component != "" && component != "unknown" {
ref := component + ":relevant_source_file"
refs = append(refs, ref)
seen[ref] = true
}
matches := jiraIDPattern.FindAllString(errorMessage, -1)
for _, m := range matches {
upper := strings.ToUpper(m)
if !seen[upper] {
refs = append(refs, upper)
seen[upper] = true
}
}
return refs
}cascadeKeywords function · go · L320-L322 (3 LOC)heuristic.go
func cascadeKeywords() []string {
return []string{"aftereach", "beforeeach", "setup failure", "suite setup"}
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
loadConvergenceConfig function · go · L329-L335 (7 LOC)heuristic.go
func loadConvergenceConfig(yamlData []byte) convergenceConfig {
var w heuristicsConvergenceWrapper
if err := yaml.Unmarshal(yamlData, &w); err != nil {
return convergenceConfig{}
}
return w.Convergence
}RunHITLStep function · go · L32-L60 (29 LOC)hitl.go
func RunHITLStep(ctx context.Context, cfg HITLConfig) (*HITLResult, error) {
th := DefaultThresholds()
walkerID := fmt.Sprintf("case-%d", cfg.CaseData.ID)
cp, err := engine.NewJSONCheckpointer(cfg.CaseDir)
if err != nil {
return nil, fmt.Errorf("create checkpointer: %w", err)
}
hitlComp := HITLComponent()
storeComp := &engine.Component{
Namespace: "store",
Name: "rca-store-hooks",
Hooks: StoreHooks(cfg.Store, cfg.CaseData),
}
runner, err := BuildRunner(nil, th, hitlComp, storeComp)
if err != nil {
return nil, fmt.Errorf("build runner: %w", err)
}
walker, startNode, err := prepareWalker(cp, walkerID, cfg)
if err != nil {
return nil, err
}
wrapped := engine.WrapWithCheckpointer(walker, cp)
walkErr := runner.Walk(ctx, wrapped, startNode)
return buildResult(walker, walkErr)
}ResumeHITLStep function · go · L64-L98 (35 LOC)hitl.go
func ResumeHITLStep(ctx context.Context, cfg HITLConfig, artifactData []byte) (*HITLResult, error) {
th := DefaultThresholds()
walkerID := fmt.Sprintf("case-%d", cfg.CaseData.ID)
cp, err := engine.NewJSONCheckpointer(cfg.CaseDir)
if err != nil {
return nil, fmt.Errorf("create checkpointer: %w", err)
}
hitlComp := HITLComponent()
storeComp := &engine.Component{
Namespace: "store",
Name: "rca-store-hooks",
Hooks: StoreHooks(cfg.Store, cfg.CaseData),
}
runner, err := BuildRunner(nil, th, hitlComp, storeComp)
if err != nil {
return nil, fmt.Errorf("build runner: %w", err)
}
walker, startNode, err := prepareWalker(cp, walkerID, cfg)
if err != nil {
return nil, err
}
var artifact any
if err := json.Unmarshal(artifactData, &artifact); err != nil {
return nil, fmt.Errorf("parse artifact: %w", err)
}
walker.State().Context["resume_input"] = artifact
wrapped := engine.WrapWithCheckpointer(walker, cp)
walkErr := runner.Walk(ctx, wrapped, startNode)