Commit graph naco-api/internal/config
Author SHA1 Message Date
b27108467e
fix: harden main entrypoint — graceful shutdown, context handling, readyz binding
- Add Server.Shutdown() method delegating to X402Server
- Wire main-server graceful shutdown with 15s bounded timeout
- Derive long-lived clients (bluesky, ollama) from backgroundCtx instead of
  signal context to prevent poisoned sessions on SIGTERM during startup
- Remove empty errgroup goroutine that only logged on cancellation
- Bind readyz sidecar to configurable READYZ_ADDRESS (default 127.0.0.1)
  instead of 0.0.0.0
- Validate port strings (ReadyzPort, MetricsPort, ListenPort) at config load
- Fix ready-check Ollama probe: use defer for body drain, guard nil resp
2026-09-09 15:07:27 +00:00
3b443eff36
refactor: harden HTTP clients with timeouts, per-relay ctx, rate-limit handling 2026-09-08 01:11:13 +00:00
60d18beda2
Switch CI and defaults back to CDP facilitator (auth fixed)
Some checks failed
test-endpoints.yaml / Switch CI and defaults back to CDP facilitator (auth fixed) (push) Failing after 0s
CI/CD Go Verification / build_and_test (push) Successful in 1m10s
- test-endpoints.yaml: X402_FACILITATOR_URL -> https://api.cdp.coinbase.com/platform/v2/x402 (2 locations)
- start-test-server.sh: X402_FACILITATOR_URL -> https://api.cdp.coinbase.com/platform/v2/x402
- config.go default: https://api.cdp.coinbase.com/platform/v2/x402
- x402.go fallback: https://api.cdp.coinbase.com/platform/v2/x402
- CDP auth now matches official SDK (fixes 401 Unauthorized)
2026-09-04 23:42:22 +00:00
6f6b952e46
fix: handle single-line PEM with \n and make MATRIX optional
Some checks failed
CI/CD Go Verification / build_and_test (push) Successful in 1m0s
Test Every Endpoint on Base Sepolia / test_endpoints (push) Failing after 1m22s
- config: MATRIX_WEBHOOK_URL / MATRIX_SERVER_ID via os.Getenv (optional),
  keep hostname fallback for MatrixServerID, avoid Fatal when webhook
  not configured (test-endpoints omits it, webhook.go nil-safe)
- auth: NewCDPAuth converts literal \n to real newlines before
  pem.Decode, so Forgejo single-line secret
  -----BEGIN EC PRIVATE KEY-----\n... works while malformed
  still returns error and CI fails via log.Fatal (as required)
2026-09-04 00:46:26 +00:00
6477d5845f test: remove tautological stdlib-roundabout tests
Aggressive deletion of tests that only replay stdlib or copy impl:
- config/config_test.go: getEnvBool/splitComma/Load defaults (strings.* wrappers)
- utils/styleProfiles_test.go: ParseEmbedding type-switch
- store/migrate_test.go: extractUpSQL marker parsing
- clustering/kmeans_test.go: IdenticalVectors/SingleItem/DifferentSeeds (trivial)
- ollama/client_test.go: PromptStructure/UsesProvidedModels (setter replay)
2026-09-03 17:00:24 +00:00
0dcb74675e fix(analytics,x402): fix coverage gaps, engagement drivers, and Twitter cost passing
Analytics review fixes:
- Store Twitter analytics coverage as discrete intervals instead of a single
  contiguous window so disjoint fetch ranges no longer mask inner gaps as
  covered (fetch per uncovered range, add gap regression tests)
- Compute real AvgEngagement/Correlation in getEngagementDrivers instead of
  all-zero placeholders
- Make parseAnalyticsTimeRange surface invalid timestamps, cap merged analytics
  posts at limit, and normalize sentiment by timestamped posts only
- gofmt: fix misalignment in config.go and types.go
- Include Twitter in the default aggregate analytics scope; its API costs are
  passed to the caller through paid tool pricing

x402 cost passing:
- computeTwitterStyleProfileCost now charges base cost ($0.10) + user lookup
  ($0.01) + $0.005 per Twitter post, guaranteeing the charge always clears the
  underlying API cost (never break-even or loss)
- Return a $-prefixed dollar string for the settlement override, fixing the
  previously off-by-factor-100 raw-atomic-unit amount
- Raise getStyleProfile base registration to $0.36 to authorize the max Twitter
  charge
- Add tests for the cost formula, profitable floor, and dollar formatting
2026-09-02 22:44:02 +00:00
4e027ca857 config: add per-tool analytics cache TTL settings
Wire configurable cache TTLs for each analytics tool from environment
variables, and provide a helper for parsing duration env vars.
2026-09-02 23:49:38 +02:00
695e137915 config: single source of truth for model names via config/models.env
- config/models.env: EMBEDDING_MODEL and STYLE_MODEL defaults
- config.go: loads models.env by finding project root (go.mod), removes hardcoded defaults
- test-endpoints.yaml: sources config/models.env to set env vars for CI
- Works from any working directory (server, tests, CI)
2026-09-02 01:41:00 +02:00
4f56def00e config: switch STYLE_MODEL to qwen3:4b-instruct-2507-q4_K_M
- Instruction-tuned variant for reliable prompt following
- Q4_K_M quantization for CPU latency optimization
- Updated test workflow to pull correct model
2026-09-02 01:06:46 +02:00
ad67171f37 config: move Ollama model defaults to config package
- config.go: set EMBEDDING_MODEL=qwen3-embedding:0.6b, STYLE_MODEL=qwen3:4b as defaults
- ollama/client.go: remove hardcoded fallback logic, use passed values directly
- Single source of truth for model defaults in config package
2026-09-02 00:09:06 +02:00
d3845671b4 ollama: fix EmbedTexts signature, add model config, use clustering package
- ollama/client.go: EmbedTexts accepts []clustering.Item, returns [][]float64
- backends.go: ollamaBackend interface uses clustering.Item
- utils/styleProfiles.go: remove duplicate KMeans, normalize, cosineSimilarity
- clustering/: new package with Item, Result types and KMeans
- config.go: add EmbeddingModel, StyleModel env vars
- main.go: pass model config to ollama.New()
- go.mod: add github.com/ethereum/go-ethereum for test client
2026-09-01 23:40:21 +02:00
e54d17736b Complete Matrix webhook integration and interface{}→any migration
- Add MATRIX_WEBHOOK_URL and MATRIX_SERVER_ID config fields (optional, defaults to hostname)
- Create internal/server/webhook.go: WebhookSender with exponential backoff retry (5 attempts),
  first/last attempt logging, non-blocking goroutine integration
- Wire webhook into OnAfterSettle callback in server.go (goroutine, fire-and-forget)
- Migrate all persistent interface{} to any (Go 1.25.4 convention):
  db.go: ...any in DBTX interface
  models.go: Embedding any
  FindSimilarUsers.sql.go: QueryEmbedding any, Embedding any
  UpsertStyleProfiles.sql.go: Embedding any
- Migrate server.go map[string]interface{} to map[string]any in webhook payload
- Add TestStoreSaveTransaction integration test (skipped without TEST_DATABASE_URL)
- Add TestSettleHook unit test for param mapping
2026-08-31 01:02:55 +02:00
3c024d668e Add observability, post caching, dedup, Bluesky refresh, Twitter backoff, MCP tests
- Per-tool Prometheus-style metrics via /metrics and error logging on failures
- In-memory TTL post cache for getPost/getLatestPosts/getPostsInTime/getFeed
- searchActors dedupes cross-platform duplicates by normalized handle
- Bluesky client refreshes session on auth/expired-token errors (retry once)
- Twitter client backs off on HTTP 429 honoring Retry-After
- MCP tests with fake platform backends (dispatch, caching, dedup, partial/full failure)

Co-Authored-By: Claude (AI assistant) <noreply@anthropic.com>
2026-08-29 02:46:17 +02:00
8cfb1291aa ops: migrator, enrichment backpressure, ollama fallback, readiness
- Add dependency-free in-process schema migrator (internal/store/migrate.go) that applies
  sql/schema/*.sql in order, tracking versions in schema_migrations. Gated by MIGRATE_ON_START
  and MIGRATIONS_DIR (default sql/schema).
- Fix migration ordering: 002 now creates the 'vector' extension before defining the
  user_style_profiles table (previously the extension was only created later in 003).
- Bound concurrent background enrichment with a 4-slot semaphore so bursts of live
  getStyleProfile calls cannot overwhelm Ollama.
- buildStyleProfile degrades gracefully when Ollama is down: stores a zero embedding and a
  keyword-based fallback summary instead of failing the whole request.
- Add a /readyz side server (READYZ_PORT, default 9090) that checks DB connectivity and
  Ollama availability.

Co-Authored-By: Claude (AI assistant) <noreply@anthropic.com>
2026-08-29 02:09:50 +02:00
e31a4313f4 test: add unit tests for pure helpers and HTTP clients
Add runnable unit tests (no external services required):

- internal/utils: FormatVector/ParseEmbedding (all type branches + round-trip),
  AverageVector, TopWords (min-length + stopword filtering + ranking)
- internal/config: getEnvBool, splitComma, Load defaults/override
- internal/server: determinePlatform (did/npub/@-handle/64-hex/dotted) and
  platformFromString
- internal/twitter: mocked Twitter API v2 (empty-token error, fetch+parse,
  max_results clamping, non-200 error)
- internal/activitypub: mocked Mastodon API (constructor validation,
  GetLatestNPosts, GetPost, non-200 error)

Not covered (require live services / heavy mocking): store sqlc queries +
pgvector migrations (need Postgres), nostr client (needs a relay), ollama
client (wraps the ollama/go API over HTTP), and server orchestration
(requestStyleProfile, enrichCrossPlatform, fetchProfilePosts, getSimilarProfiles
need a DB + platform clients).

Co-Authored-By: Claude (AI assistant) <noreply@anthropic.com>
2026-08-29 01:33:42 +02:00
bc168e1bca add: background cross-platform enrichment on profile request
- refactor requestStyleProfile into a shared requestStyleProfileForced core (resolve -> cache
  check -> build) so a specific platform can be targeted regardless of identifier format
- on a live getStyleProfile request, fire-and-forget enrichCrossPlatform: bounded fan-out
  (<=3 goroutines) tries the same identifier on every other platform, logs/skips mismatches,
  and still obeys the 1-week update gate; uses a detached context (context.WithoutCancel +
  5m timeout) so it outlives the request
- trigger only on live tool calls (not the prewarmer) and gated by ENRICH_CROSS_PLATFORM
  (default true)
- add platformFromString helper
2026-08-29 01:26:08 +02:00
e5168e33f3 add: multi-platform getStyleProfile with slow, discovery-based prewarmer
- Nostr client (fiatjaf.com/nostr) fetching kind:1 notes from relays
- Twitter client using raw Twitter API v2 (no external X library), optional (no token = lazy error)
- getStyleProfile dispatches by platform; a profile is updated only when a request is
  made and the cached profile is older than a week (served from cache otherwise)
- shared requestStyleProfile path used by both the tool and the prewarmer
- StartPrewarm discovers interesting authors (from a feed URI or seed list) and
  pre-fetches at most one profile per minute; fresh profiles are never re-embedded
2026-08-29 01:07:47 +02:00
dbf0e2591b add: supported network config option
update: align testClient with x402-v2
2026-08-03 12:40:04 +00:00
fed1a8d294 feat: add activitypub 2026-07-18 22:42:44 +00:00
2b4980edab Major changes 2025-12-19 00:05:45 +00:00
b87910d1c4 Major changes 2025-12-02 19:33:03 +00:00
5b409678ad First release build 2025-12-02 19:32:47 +00:00
af58fdeeab initial commit 2025-10-25 01:06:02 +00:00