mirror of
https://github.com/lukaszraczylo/claude-mnemonic.git
synced 2026-10-18 06:09:15 +00:00
Release dec 2025 (#15)
* Resolves issue #13 - Switched model to bge-small-en-v1.5 - Added lazy re-embedding - Added model version tracking per vector - Added conversion of vectors to the new model * Add lfs support to the workflow. * Implements importance scoring with decay + voting #6 * Resolves issue #5 by marking observations as superseeded and scheduled for deletion * Implement pattern detection #7 * Improve injections and observations accuracy - Session start: Recent observations for project context (recency-based) - User prompt: Semantically relevant observations (similarity-based with threshold) * Added two stage retrieval with bi and cross encoder #8 * Implement query expansion and reformulation #9 * Knowledge graph and relationships ( resolves #4 ) - File Overlap Detection: Detects relationships when observations modify/read the same files - Concept Overlap Detection: Detects relationships based on shared semantic concepts - Type Progression Detection: Infers relationships from natural observation type progressions (e.g., discovery → bugfix = "fixes") - Temporal Proximity Detection: Detects relationships between observations in the same session within 5 minutes - Narrative Mention Detection: Detects explicit relationship language in narratives (e.g., "fixes", "depends on", "supersedes") * Add visualisation of the relations to the dashboard. * fixup! Add visualisation of the relations to the dashboard. * Update documentation with new settings and screenshots.
This commit is contained in:
@@ -139,6 +139,16 @@ type Observation struct {
|
||||
CreatedAt string `db:"created_at" json:"created_at"`
|
||||
CreatedAtEpoch int64 `db:"created_at_epoch" json:"created_at_epoch"`
|
||||
IsStale bool `db:"-" json:"is_stale,omitempty"`
|
||||
|
||||
// Importance scoring fields
|
||||
ImportanceScore float64 `db:"importance_score" json:"importance_score"`
|
||||
UserFeedback int `db:"user_feedback" json:"user_feedback"`
|
||||
RetrievalCount int `db:"retrieval_count" json:"retrieval_count"`
|
||||
LastRetrievedAt sql.NullInt64 `db:"last_retrieved_at_epoch" json:"last_retrieved_at_epoch,omitempty"`
|
||||
ScoreUpdatedAt sql.NullInt64 `db:"score_updated_at_epoch" json:"score_updated_at_epoch,omitempty"`
|
||||
|
||||
// Conflict detection fields
|
||||
IsSuperseded bool `db:"is_superseded" json:"is_superseded,omitempty"`
|
||||
}
|
||||
|
||||
// ParsedObservation represents an observation parsed from SDK response XML.
|
||||
@@ -205,6 +215,16 @@ type ObservationJSON struct {
|
||||
CreatedAt string `json:"created_at"`
|
||||
CreatedAtEpoch int64 `json:"created_at_epoch"`
|
||||
IsStale bool `json:"is_stale,omitempty"`
|
||||
|
||||
// Importance scoring fields
|
||||
ImportanceScore float64 `json:"importance_score"`
|
||||
UserFeedback int `json:"user_feedback"`
|
||||
RetrievalCount int `json:"retrieval_count"`
|
||||
LastRetrievedAt int64 `json:"last_retrieved_at_epoch,omitempty"`
|
||||
ScoreUpdatedAt int64 `json:"score_updated_at_epoch,omitempty"`
|
||||
|
||||
// Conflict detection fields
|
||||
IsSuperseded bool `json:"is_superseded,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler for Observation.
|
||||
@@ -225,6 +245,12 @@ func (o *Observation) MarshalJSON() ([]byte, error) {
|
||||
CreatedAt: o.CreatedAt,
|
||||
CreatedAtEpoch: o.CreatedAtEpoch,
|
||||
IsStale: o.IsStale,
|
||||
// Importance scoring fields
|
||||
ImportanceScore: o.ImportanceScore,
|
||||
UserFeedback: o.UserFeedback,
|
||||
RetrievalCount: o.RetrievalCount,
|
||||
// Conflict detection fields
|
||||
IsSuperseded: o.IsSuperseded,
|
||||
}
|
||||
if o.Title.Valid {
|
||||
j.Title = o.Title.String
|
||||
@@ -238,6 +264,12 @@ func (o *Observation) MarshalJSON() ([]byte, error) {
|
||||
if o.PromptNumber.Valid {
|
||||
j.PromptNumber = o.PromptNumber.Int64
|
||||
}
|
||||
if o.LastRetrievedAt.Valid {
|
||||
j.LastRetrievedAt = o.LastRetrievedAt.Int64
|
||||
}
|
||||
if o.ScoreUpdatedAt.Valid {
|
||||
j.ScoreUpdatedAt = o.ScoreUpdatedAt.Int64
|
||||
}
|
||||
return json.Marshal(j)
|
||||
}
|
||||
|
||||
@@ -268,9 +300,28 @@ func NewObservation(sdkSessionID, project string, parsed *ParsedObservation, pro
|
||||
DiscoveryTokens: discoveryTokens,
|
||||
CreatedAt: now.Format(time.RFC3339),
|
||||
CreatedAtEpoch: now.UnixMilli(),
|
||||
// Importance scoring: new observations start with score 1.0
|
||||
ImportanceScore: 1.0,
|
||||
UserFeedback: 0,
|
||||
RetrievalCount: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// ToMap converts the observation to a map for JSON response building.
|
||||
// This allows adding extra fields like similarity scores.
|
||||
func (o *Observation) ToMap() map[string]interface{} {
|
||||
// Marshal to JSON then unmarshal to map (uses MarshalJSON for proper conversion)
|
||||
data, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return map[string]interface{}{"id": o.ID, "error": err.Error()}
|
||||
}
|
||||
var result map[string]interface{}
|
||||
if err := json.Unmarshal(data, &result); err != nil {
|
||||
return map[string]interface{}{"id": o.ID, "error": err.Error()}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CheckStaleness checks if an observation is stale based on current file mtimes.
|
||||
// Returns true if any tracked file has been modified since the observation was created.
|
||||
func (o *Observation) CheckStaleness(currentMtimes map[string]int64) bool {
|
||||
|
||||
Reference in New Issue
Block a user