( line extractedMemoryLine, turn memcontract.TurnRecord, workspaceRoot string, submittedAt time.Time, )
| 806 | } |
| 807 | |
| 808 | func candidateFromExtractedLine( |
| 809 | line extractedMemoryLine, |
| 810 | turn memcontract.TurnRecord, |
| 811 | workspaceRoot string, |
| 812 | submittedAt time.Time, |
| 813 | ) (memcontract.Candidate, error) { |
| 814 | memoryType := memcontract.Type(strings.TrimSpace(line.Type)).Normalize() |
| 815 | if err := memoryType.Validate(); err != nil { |
| 816 | return memcontract.Candidate{}, err |
| 817 | } |
| 818 | scope := memcontract.Scope(strings.TrimSpace(line.Scope)).Normalize() |
| 819 | if scope == "" { |
| 820 | defaultScope, err := memcontract.DefaultScopeForType(memoryType) |
| 821 | if err != nil { |
| 822 | return memcontract.Candidate{}, err |
| 823 | } |
| 824 | scope = defaultScope |
| 825 | } |
| 826 | if err := scope.Validate(); err != nil { |
| 827 | return memcontract.Candidate{}, err |
| 828 | } |
| 829 | content := strings.TrimSpace(line.Content) |
| 830 | if content == "" { |
| 831 | return memcontract.Candidate{}, errors.New("content is required") |
| 832 | } |
| 833 | agentTier := memcontract.AgentTier(strings.TrimSpace(line.AgentTier)).Normalize() |
| 834 | if scope == memcontract.ScopeAgent && agentTier == "" { |
| 835 | agentTier = memcontract.AgentTierWorkspace |
| 836 | } |
| 837 | agentName := "" |
| 838 | if scope == memcontract.ScopeAgent { |
| 839 | agentName = strings.TrimSpace(turn.AgentID) |
| 840 | } |
| 841 | metadata := map[string]string{ |
| 842 | "evidence": line.Evidence, |
| 843 | } |
| 844 | if workspaceRoot != "" { |
| 845 | metadata["workspace_root"] = workspaceRoot |
| 846 | } |
| 847 | return memcontract.Candidate{ |
| 848 | WorkspaceID: strings.TrimSpace(turn.WorkspaceID), |
| 849 | Scope: scope, |
| 850 | AgentName: agentName, |
| 851 | AgentTier: agentTier, |
| 852 | Origin: memcontract.OriginExtractor, |
| 853 | Content: content, |
| 854 | Frontmatter: memcontract.Header{ |
| 855 | Name: memoryCandidateName(line, content), |
| 856 | Description: strings.TrimSpace(line.Evidence), |
| 857 | Type: memoryType, |
| 858 | Scope: scope, |
| 859 | AgentName: agentName, |
| 860 | AgentTier: agentTier, |
| 861 | Provenance: &memcontract.Provenance{ |
| 862 | SourceSessionIDs: []string{turn.SessionID}, |
| 863 | SourceActor: memcontract.OriginExtractor, |
| 864 | Confidence: "candidate", |
| 865 | CreatedAt: submittedAt.UTC(), |
no test coverage detected