chore: docker, config, delivery sinks, dialogue, and agent docs

- Dockerfile: multi-stage build with CGO_ENABLED=0, embedder model copy,
  non-root user, healthcheck, and /data volume.
- docker-compose.yml: mavend + mavweb services with shared volume, health
  checks, and restart policy.
- .gitignore: ignore models/llm/*.gguf, deploy/telegram.env, tmp artifacts.
- deploy/mavend.json: add LLM, phraser, voice sections (embedder, model
  paths, wake sensitivity). Add telegram token env-var expansion.
- deploy/telegram.env.example: template for telegram bot token.
- internal/config/config.go: add LLM config struct, voice config struct
  (embedder, llama, wake sensitivity), telegram token loading.
- telegramsink: add chat intent delivery support alongside existing types.
- voicesink: skip empty payloads in delivery.
- dialogue/session: add chat intent to anaphora resolution, test coverage.
- AGENTS.md: update with LLM embedder, LFM model download/configure steps,
  new UI conventions.
- REARCH.md: architecture research document.
- cmd/mavend/main.go: wire LLM config, phraser, embedder, telegram config,
  WebAuthn, IPC event/routine handlers, and reactive notes.
This commit is contained in:
kami
2026-07-10 15:49:27 +04:00
parent 7a95097cc7
commit da60c14399
13 changed files with 313 additions and 45 deletions
@@ -51,21 +51,21 @@ const DefaultTimeout = 10 * time.Second
type Config struct {
// BotToken — the telegram bot token from BotFather. required. sent in the
// URL path (the only place telegram accepts it), not in the body.
BotToken string
BotToken string `json:"bot_token"`
// ChatID — destination chat. may be a numeric user/group id (sent as a
// JSON number) or @channelusername (sent as a JSON string). required.
ChatID string
ChatID string `json:"chat_id"`
// BaseURL — telegram API base. empty = DefaultBaseURL. override to point
// at a self-hosted API bridge if the proxy path isn't used.
BaseURL string
BaseURL string `json:"base_url,omitempty"`
// Proxy — URL of an HTTP/HTTPS/SOCKS5 relay used to reach the telegram
// API (region-restricted direct egress). empty = direct (won't work from
// the homesrv without a relay; kept configurable for tests + future
// topology change).
Proxy string
Proxy string `json:"proxy,omitempty"`
// Timeout — per-request; 0 = DefaultTimeout. a dead relay can't hang the
// tick loop.
+2 -1
View File
@@ -37,6 +37,7 @@ import (
"github.com/kami/maven/internal/audio"
"github.com/kami/maven/internal/delivery"
"github.com/kami/maven/internal/tts"
"github.com/kami/maven/internal/ttsnorm"
"github.com/kami/maven/internal/voice"
)
@@ -75,7 +76,7 @@ func (s *Sink) Send(ctx context.Context, send delivery.Sendable) error {
// in the phraser behind routing).
text = send.Summary
}
out, err := s.tts.Synthesize(ctx, text)
out, err := s.tts.Synthesize(ctx, ttsnorm.Speakable(text))
if err != nil {
return fmt.Errorf("voicesink: synthesize: %w", err)
}