wiring the poller into both boot paths (V-637)
It reaches the daemon through ipc.CoreAPI and nothing else, so a telegram turn takes the path POST /api/chat already takes: Chat returns the reply and the trace id it collected off the context (V-630), and CorrectTurn writes the label. Nothing in internal/delivery learns what a handler is. Wired on the unlocked start and on the passkey unlock, like the mail intake, so telegram behaves the same either way. A sink that will not build is logged rather than fatal here, because wireDispatcher already failed the boot on the same config.
This commit is contained in:
@@ -364,6 +364,9 @@ func run(args []string) error {
|
|||||||
if !locked {
|
if !locked {
|
||||||
wireMailIntake(srv, st, phr, cfg, evBus)
|
wireMailIntake(srv, st, phr, cfg, evBus)
|
||||||
wireModelSwap(srv, phr, cfg)
|
wireModelSwap(srv, phr, cfg)
|
||||||
|
// Inbound telegram (V-637). Dark unless the telegram block says intake,
|
||||||
|
// and it reads one chat.
|
||||||
|
wireTelegramIntake(ctx, &wg, coreAPI, cfg)
|
||||||
// Vision + the media blob store (Vikunja #252). Both stay dark without a
|
// Vision + the media blob store (Vikunja #252). Both stay dark without a
|
||||||
// media block; MethodDescribeImage answers ErrUnknownMethod then.
|
// media block; MethodDescribeImage answers ErrUnknownMethod then.
|
||||||
keeper := wireVision(ctx, &wg, srv, st, embedderOf(voiceW), cfg)
|
keeper := wireVision(ctx, &wg, srv, st, embedderOf(voiceW), cfg)
|
||||||
@@ -511,6 +514,9 @@ func run(args []string) error {
|
|||||||
srv.Check = (&auth.Gate{Enrollment: auth.NewFloorEnrollment(), Session: passkeySess}).Check
|
srv.Check = (&auth.Gate{Enrollment: auth.NewFloorEnrollment(), Session: passkeySess}).Check
|
||||||
wireMailIntake(srv, st, phr, cfg, evBus)
|
wireMailIntake(srv, st, phr, cfg, evBus)
|
||||||
wireModelSwap(srv, phr, cfg)
|
wireModelSwap(srv, phr, cfg)
|
||||||
|
// Same on the unlock path, with the API that has just replaced the
|
||||||
|
// locked placeholder (V-637).
|
||||||
|
wireTelegramIntake(ctx, &wg, newAPI, cfg)
|
||||||
keeper := wireVision(ctx, &wg, srv, st, embedderOf(voiceW), cfg)
|
keeper := wireVision(ctx, &wg, srv, st, embedderOf(voiceW), cfg)
|
||||||
wireCapture(ctx, &wg, srv, keeper, st, voiceW, phr, cfg)
|
wireCapture(ctx, &wg, srv, keeper, st, voiceW, phr, cfg)
|
||||||
// Voice identification (Vikunja #255). Enrolment plumbing only until a
|
// Voice identification (Vikunja #255). Enrolment plumbing only until a
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// mavend/telegramintake.go — wiring the inbound telegram poller (V-637).
|
||||||
|
//
|
||||||
|
// The poller reaches the daemon through ipc.CoreAPI and nothing else, so a
|
||||||
|
// telegram turn takes exactly the path the web's POST /api/chat takes: Chat
|
||||||
|
// returns the reply and the persisted trace id, and CorrectTurn writes the
|
||||||
|
// label. Nothing in internal/delivery knows what a handler is.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/kami/maven/internal/config"
|
||||||
|
"github.com/kami/maven/internal/delivery/telegramsink"
|
||||||
|
"github.com/kami/maven/internal/ipc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// wireTelegramIntake starts the poller, or returns having done nothing. It is
|
||||||
|
// nil-safe in every argument, because it is called from both boot paths — the
|
||||||
|
// unlocked start and the passkey unlock — and telegram must behave the same on
|
||||||
|
// either.
|
||||||
|
//
|
||||||
|
// A sink that will not build is logged rather than fatal here. The push half
|
||||||
|
// already failed the boot in wireDispatcher for the same config, so a second
|
||||||
|
// hard failure would only lose that message.
|
||||||
|
func wireTelegramIntake(ctx context.Context, wg *sync.WaitGroup, api ipc.CoreAPI, cfg *config.Config) {
|
||||||
|
if cfg == nil || cfg.Telegram == nil || !cfg.Telegram.Intake || api == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sink, err := telegramsink.New(*cfg.Telegram)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("telegram intake: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
poller, err := telegramsink.NewPoller(sink, chatTurnFn(api), api.CorrectTurn)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("telegram intake: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
poller.Run(ctx)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// chatTurnFn adapts ipc.Chat to the poller's Turn. The trace id comes back on
|
||||||
|
// the reply because the daemon's Chat collects it off the context (V-630), so
|
||||||
|
// the chat can offer the same correction the web does without a second op.
|
||||||
|
func chatTurnFn(api ipc.CoreAPI) telegramsink.Turn {
|
||||||
|
return func(ctx context.Context, conversation, text string) (string, int64, error) {
|
||||||
|
reply, err := api.Chat(ctx, conversation, text)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
return reply.Reply, reply.TraceID, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user