Fixes onnx version mismatch, vectordb not liking it and dashboard

Fixes summaries not being generated and timeline showing all observations
despite of project filter being applied.
This commit is contained in:
2025-12-16 18:27:55 +00:00
parent 2730727e8b
commit 4440fd0afb
11 changed files with 137 additions and 18 deletions
+19 -2
View File
@@ -75,13 +75,16 @@ func parseTranscript(path string) (lastUser, lastAssistant string) {
continue
}
if msg.Type == "message" {
// Transcript entries have type: "user" or "assistant" (not "message")
// Check if this is a user/assistant message with content
if msg.Type == "user" || msg.Type == "assistant" {
text := extractTextContent(msg.Message.Content)
if text == "" {
continue
}
switch msg.Message.Role {
// Use the outer type field for role (message.role may differ)
switch msg.Type {
case "user":
lastUser = text
case "assistant":
@@ -98,6 +101,9 @@ func main() {
}
func handleStop(ctx *hooks.HookContext, input *Input) (string, error) {
// Debug: dump raw input
fmt.Fprintf(os.Stderr, "[stop] Raw input: %s\n", string(ctx.RawInput))
// Find session
result, err := hooks.GET(ctx.Port, fmt.Sprintf("/api/sessions?claudeSessionId=%s", ctx.SessionID))
if err != nil || result == nil {
@@ -116,6 +122,17 @@ func handleStop(ctx *hooks.HookContext, input *Input) (string, error) {
lastUser, lastAssistant = parseTranscript(input.TranscriptPath)
}
// Debug: log what we extracted
fmt.Fprintf(os.Stderr, "[stop] Transcript path: %s\n", input.TranscriptPath)
fmt.Fprintf(os.Stderr, "[stop] Last user message length: %d\n", len(lastUser))
fmt.Fprintf(os.Stderr, "[stop] Last assistant message length: %d\n", len(lastAssistant))
if len(lastAssistant) > 0 {
preview := lastAssistant
if len(preview) > 300 {
preview = preview[:300] + "..."
}
fmt.Fprintf(os.Stderr, "[stop] Last assistant preview: %s\n", preview)
}
fmt.Fprintf(os.Stderr, "[stop] Requesting summary for session %d (transcript: %v)\n", int64(sessionID), input.TranscriptPath != "")
// Request summary with message context from transcript
+23
View File
@@ -175,6 +175,29 @@ func (s *ObservationStore) GetRecentObservations(ctx context.Context, project st
return scanObservationRows(rows)
}
// GetObservationsByProjectStrict retrieves observations strictly for a specific project.
// Unlike GetRecentObservations, this does NOT include global observations from other projects.
// Use this for dashboard filtering where the user expects to see only that project's data.
func (s *ObservationStore) GetObservationsByProjectStrict(ctx context.Context, project string, limit int) ([]*models.Observation, error) {
const query = `
SELECT id, sdk_session_id, project, COALESCE(scope, 'project') as scope, type, title, subtitle, facts, narrative,
concepts, files_read, files_modified, file_mtimes, prompt_number, discovery_tokens,
created_at, created_at_epoch
FROM observations
WHERE project = ?
ORDER BY created_at_epoch DESC
LIMIT ?
`
rows, err := s.store.QueryContext(ctx, query, project, limit)
if err != nil {
return nil, err
}
defer rows.Close()
return scanObservationRows(rows)
}
// GetObservationCount returns the count of observations for a project (including global).
func (s *ObservationStore) GetObservationCount(ctx context.Context, project string) (int, error) {
const query = `
@@ -0,0 +1 @@
1.23.2
@@ -0,0 +1 @@
1.23.2
@@ -0,0 +1 @@
1.23.2
@@ -0,0 +1 @@
1.23.2
+2 -2
View File
@@ -478,8 +478,8 @@ func (s *Service) handleGetObservations(w http.ResponseWriter, r *http.Request)
// Fall back to SQLite if vector search not used
if !usedVector {
if project != "" {
// Filter by project - includes project-scoped and global observations
observations, err = s.observationStore.GetRecentObservations(r.Context(), project, limit)
// Strict project filtering for dashboard - only observations from this project
observations, err = s.observationStore.GetObservationsByProjectStrict(r.Context(), project, limit)
} else {
// All projects
observations, err = s.observationStore.GetAllRecentObservations(r.Context(), limit)
+16
View File
@@ -234,11 +234,19 @@ func (p *Processor) ProcessObservation(ctx context.Context, sdkSessionID, projec
// ProcessSummary processes a session summary request.
func (p *Processor) ProcessSummary(ctx context.Context, sessionDBID int64, sdkSessionID, project, userPrompt, lastUserMsg, lastAssistantMsg string) error {
// Debug: log what we received
log.Debug().
Int64("sessionId", sessionDBID).
Int("lastAssistantMsgLen", len(lastAssistantMsg)).
Str("lastAssistantMsgPreview", truncateForLog(lastAssistantMsg, 200)).
Msg("ProcessSummary called")
// Skip summary generation if there's no meaningful assistant response
// This prevents generic "initial session setup" summaries
if !hasMeaningfulContent(lastAssistantMsg) {
log.Info().
Int64("sessionId", sessionDBID).
Int("msgLen", len(lastAssistantMsg)).
Msg("Skipping summary - no meaningful assistant response")
return nil
}
@@ -727,6 +735,14 @@ func hasMeaningfulContent(assistantMsg string) bool {
return matchCount >= 2
}
// truncateForLog truncates a string for logging purposes.
func truncateForLog(s string, maxLen int) string {
if len(s) <= maxLen {
return s
}
return s[:maxLen] + "..."
}
const systemPrompt = `You are a memory extraction agent for Claude Code sessions. Your job is to analyze tool executions and extract meaningful observations that would be useful for future sessions.
GUIDELINES:
+70 -11
View File
@@ -1,13 +1,22 @@
#!/bin/bash
# Download ONNX Runtime libraries for embedding
# Usage: ./download-onnx-libs.sh [platform]
# Usage: ./download-onnx-libs.sh [platform] [--force]
# Platform: darwin-arm64, linux-amd64, windows-amd64, or "all" (default)
# Use --force to re-download even if libraries exist
set -e
ONNX_VERSION="1.23.2"
ASSETS_DIR="internal/embedding/assets/lib"
PLATFORM="${1:-all}"
FORCE_DOWNLOAD=false
# Check for --force flag
for arg in "$@"; do
if [ "$arg" = "--force" ]; then
FORCE_DOWNLOAD=true
fi
done
# Auto-detect platform if not specified
if [ "$PLATFORM" = "auto" ]; then
@@ -31,12 +40,38 @@ fi
TEMP_DIR=$(mktemp -d)
trap "rm -rf ${TEMP_DIR}" EXIT
# Get the installed version for a platform
get_installed_version() {
local plat="$1"
local version_file="${ASSETS_DIR}/${plat}/.version"
if [ -f "$version_file" ]; then
cat "$version_file"
else
echo ""
fi
}
# Write version file after successful download
write_version_file() {
local plat="$1"
echo "${ONNX_VERSION}" > "${ASSETS_DIR}/${plat}/.version"
}
# Check if version matches
version_matches() {
local plat="$1"
local installed_version
installed_version=$(get_installed_version "$plat")
[ "$installed_version" = "$ONNX_VERSION" ]
}
download_darwin_arm64() {
echo "Downloading darwin-arm64..."
mkdir -p "${ASSETS_DIR}/darwin-arm64"
curl -fsSL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNX_VERSION}/onnxruntime-osx-arm64-${ONNX_VERSION}.tgz" -o "${TEMP_DIR}/darwin-arm64.tgz"
tar -xzf "${TEMP_DIR}/darwin-arm64.tgz" -C "${TEMP_DIR}"
cp "${TEMP_DIR}/onnxruntime-osx-arm64-${ONNX_VERSION}/lib/libonnxruntime.${ONNX_VERSION}.dylib" "${ASSETS_DIR}/darwin-arm64/libonnxruntime.dylib"
write_version_file "darwin-arm64"
}
download_linux_amd64() {
@@ -46,6 +81,7 @@ download_linux_amd64() {
tar -xzf "${TEMP_DIR}/linux-amd64.tgz" -C "${TEMP_DIR}"
cp "${TEMP_DIR}/onnxruntime-linux-x64-${ONNX_VERSION}/lib/libonnxruntime.so.${ONNX_VERSION}" "${ASSETS_DIR}/linux-amd64/libonnxruntime.so"
cp "${TEMP_DIR}/onnxruntime-linux-x64-${ONNX_VERSION}/lib/libonnxruntime_providers_shared.so" "${ASSETS_DIR}/linux-amd64/libonnxruntime_providers_shared.so" 2>/dev/null || true
write_version_file "linux-amd64"
}
download_linux_arm64() {
@@ -55,6 +91,7 @@ download_linux_arm64() {
tar -xzf "${TEMP_DIR}/linux-arm64.tgz" -C "${TEMP_DIR}"
cp "${TEMP_DIR}/onnxruntime-linux-aarch64-${ONNX_VERSION}/lib/libonnxruntime.so.${ONNX_VERSION}" "${ASSETS_DIR}/linux-arm64/libonnxruntime.so"
cp "${TEMP_DIR}/onnxruntime-linux-aarch64-${ONNX_VERSION}/lib/libonnxruntime_providers_shared.so" "${ASSETS_DIR}/linux-arm64/libonnxruntime_providers_shared.so" 2>/dev/null || true
write_version_file "linux-arm64"
}
download_windows_amd64() {
@@ -66,6 +103,7 @@ download_windows_amd64() {
echo "Downloaded file size: $(wc -c < "${TEMP_DIR}/windows-amd64.zip") bytes"
unzip -q "${TEMP_DIR}/windows-amd64.zip" -d "${TEMP_DIR}"
cp "${TEMP_DIR}/onnxruntime-win-x64-${ONNX_VERSION}/lib/onnxruntime.dll" "${ASSETS_DIR}/windows-amd64/onnxruntime.dll"
write_version_file "windows-amd64"
}
# Check if library already exists for a platform
@@ -79,19 +117,40 @@ lib_exists() {
esac
}
# Download only if not present
# Download only if not present or version mismatch
download_if_needed() {
local plat="$1"
if lib_exists "$plat"; then
echo "Library for ${plat} already exists, skipping download"
return 0
local need_download=false
local reason=""
if [ "$FORCE_DOWNLOAD" = true ]; then
need_download=true
reason="forced"
elif ! lib_exists "$plat"; then
need_download=true
reason="not found"
elif ! version_matches "$plat"; then
local installed_version
installed_version=$(get_installed_version "$plat")
need_download=true
reason="version mismatch (installed: ${installed_version:-unknown}, required: ${ONNX_VERSION})"
fi
if [ "$need_download" = true ]; then
if [ -n "$reason" ] && [ "$reason" != "not found" ]; then
echo "Re-downloading ${plat}: ${reason}"
fi
# Remove old library before downloading
rm -rf "${ASSETS_DIR}/${plat}"
case "$plat" in
darwin-arm64) download_darwin_arm64 ;;
linux-amd64) download_linux_amd64 ;;
linux-arm64) download_linux_arm64 ;;
windows-amd64) download_windows_amd64 ;;
esac
else
echo "Library for ${plat} already exists (v${ONNX_VERSION}), skipping download"
fi
case "$plat" in
darwin-arm64) download_darwin_arm64 ;;
linux-amd64) download_linux_amd64 ;;
linux-arm64) download_linux_arm64 ;;
windows-amd64) download_windows_amd64 ;;
esac
}
echo "ONNX Runtime v${ONNX_VERSION} - Platform: ${PLATFORM}"
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "claude-mnemonic-dashboard",
"version": "v0.6.5-23-g21bcbfa",
"version": "v0.6.5-25-g372942e-dirty",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "claude-mnemonic-dashboard",
"version": "v0.6.5-23-g21bcbfa",
"version": "v0.6.5-25-g372942e-dirty",
"dependencies": {
"vue": "^3.5.13"
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claude-mnemonic-dashboard",
"version": "v0.6.5-23-g21bcbfa",
"version": "v0.6.5-25-g372942e-dirty",
"private": true,
"type": "module",
"scripts": {