Skip to content

Telegram: image input support#35

Merged
vaayne merged 9 commits intomainfrom
feat/telegram-image-input
Mar 8, 2026
Merged

Telegram: image input support#35
vaayne merged 9 commits intomainfrom
feat/telegram-image-input

Conversation

@vaayne
Copy link
Owner

@vaayne vaayne commented Mar 8, 2026

Summary

  • Add ImageContent support to all 3 AI providers (Anthropic, OpenAI completions, OpenAI responses)
  • Change Runner.Chat and Pool.Chat to accept multimodal messages (string or []ContentBlock)
  • Add tele.OnPhoto handler in Telegram — downloads photo, base64 encodes, sends as multimodal message
  • Add ImageEvent plumbing through the stream for sending images back to Telegram
  • Persist multimodal user messages in session history via RPCEvent.Content field

Test plan

  • All existing tests pass (go test -race ./...)
  • Manually tested: send photo to Telegram bot, model describes the image
  • Image output to Telegram (tracked in Telegram: send image output back to users #34 — requires tool interface changes)

Closes #29

vaayne added 5 commits March 8, 2026 22:53
Handle ImageContent blocks in user messages for Anthropic (base64 image
block), OpenAI completions (image_url content part), and OpenAI responses
(input_image with data URI). Text-only messages still use the efficient
plain string path.

Part of #29
Change Runner.Chat and Pool.Chat to accept `any` message (string or
[]ContentBlock). Add RPCEvent.Content field for persisting image blocks
in session history. Add UserMessageToRPCEvent and MessageText helpers.
Update convertHistory to reconstruct multimodal user messages.

Part of #29
Add tele.OnPhoto handler that downloads the photo, base64-encodes it,
detects MIME type, and sends it as a multimodal message (ImageContent +
optional TextContent caption) through the agent pipeline. Refactor
handleText into a shared handleMessage flow.

Part of #29
Add ImageEvent to runner.Event for carrying base64 images through the
stream. Collect images during streaming and send them as tele.Photo
after the text response. Plumbs through streamDraft and streamEditEvents.

Part of #29
Add image support section to telegram.md, update README feature list,
and note multimodal message support in architecture.md.

Part of #29
@github-actions
Copy link

github-actions bot commented Mar 8, 2026

📊 Coverage Report

Total coverage: 54.9%

Per-package breakdown
github.com/vaayne/anna/agent/engine/continue.go:12:          60.0%
github.com/vaayne/anna/agent/engine/engine.go:123:           85.1%
github.com/vaayne/anna/agent/engine/engine.go:213:           88.9%
github.com/vaayne/anna/agent/engine/engine.go:228:           100.0%
github.com/vaayne/anna/agent/engine/engine.go:22:            91.7%
github.com/vaayne/anna/agent/engine/engine.go:44:            94.6%
github.com/vaayne/anna/agent/engine/events.go:13:            0.0%
github.com/vaayne/anna/agent/engine/events.go:20:            0.0%
github.com/vaayne/anna/agent/engine/events.go:28:            0.0%
github.com/vaayne/anna/agent/engine/events.go:35:            0.0%
github.com/vaayne/anna/agent/engine/events.go:42:            0.0%
github.com/vaayne/anna/agent/engine/events.go:49:            0.0%
github.com/vaayne/anna/agent/engine/events.go:56:            0.0%
github.com/vaayne/anna/agent/engine/events.go:63:            0.0%
github.com/vaayne/anna/agent/engine/events.go:68:            0.0%
github.com/vaayne/anna/agent/engine/events.go:75:            0.0%
github.com/vaayne/anna/agent/engine/tool_execution.go:17:    90.9%
github.com/vaayne/anna/agent/pool.go:108:                    100.0%
github.com/vaayne/anna/agent/pool.go:121:                    80.0%
github.com/vaayne/anna/agent/pool.go:133:                    56.5%
github.com/vaayne/anna/agent/pool.go:175:                    100.0%
github.com/vaayne/anna/agent/pool.go:183:                    100.0%
github.com/vaayne/anna/agent/pool.go:195:                    75.0%
github.com/vaayne/anna/agent/pool.go:205:                    70.0%
github.com/vaayne/anna/agent/pool.go:223:                    53.3%
github.com/vaayne/anna/agent/pool.go:248:                    72.2%
github.com/vaayne/anna/agent/pool.go:319:                    87.2%
github.com/vaayne/anna/agent/pool.go:35:                     100.0%
github.com/vaayne/anna/agent/pool.go:394:                    80.0%
github.com/vaayne/anna/agent/pool.go:414:                    28.6%
github.com/vaayne/anna/agent/pool.go:428:                    46.2%
github.com/vaayne/anna/agent/pool.go:42:                     0.0%
github.com/vaayne/anna/agent/pool.go:451:                    66.7%
github.com/vaayne/anna/agent/pool.go:49:                     100.0%
github.com/vaayne/anna/agent/pool.go:56:                     100.0%
github.com/vaayne/anna/agent/pool.go:576:                    0.0%
github.com/vaayne/anna/agent/pool.go:584:                    100.0%
github.com/vaayne/anna/agent/pool.go:591:                    90.9%
github.com/vaayne/anna/agent/pool.go:611:                    83.3%
github.com/vaayne/anna/agent/pool.go:629:                    77.1%
github.com/vaayne/anna/agent/pool.go:63:                     100.0%
github.com/vaayne/anna/agent/pool.go:710:                    75.0%
github.com/vaayne/anna/agent/pool.go:720:                    75.0%
github.com/vaayne/anna/agent/pool.go:730:                    75.0%
github.com/vaayne/anna/agent/pool.go:745:                    89.5%
github.com/vaayne/anna/agent/pool.go:78:                     100.0%
github.com/vaayne/anna/agent/pool.go:85:                     100.0%
github.com/vaayne/anna/agent/pool.go:99:                     100.0%
github.com/vaayne/anna/agent/runner/gorunner.go:130:         100.0%
github.com/vaayne/anna/agent/runner/gorunner.go:133:         100.0%
github.com/vaayne/anna/agent/runner/gorunner.go:140:         100.0%
github.com/vaayne/anna/agent/runner/gorunner.go:143:         100.0%
github.com/vaayne/anna/agent/runner/gorunner.go:156:         94.4%
github.com/vaayne/anna/agent/runner/gorunner.go:205:         90.5%
github.com/vaayne/anna/agent/runner/gorunner.go:247:         33.3%
github.com/vaayne/anna/agent/runner/gorunner.go:274:         84.6%
github.com/vaayne/anna/agent/runner/gorunner.go:298:         97.6%
github.com/vaayne/anna/agent/runner/gorunner.go:52:          89.5%
github.com/vaayne/anna/agent/runner/gorunner.go:95:          100.0%
github.com/vaayne/anna/agent/runner/prompt.go:118:           85.7%
github.com/vaayne/anna/agent/runner/prompt.go:133:           95.0%
github.com/vaayne/anna/agent/runner/prompt.go:173:           100.0%
github.com/vaayne/anna/agent/runner/prompt.go:191:           100.0%
github.com/vaayne/anna/agent/runner/prompt.go:52:            91.4%
github.com/vaayne/anna/agent/runner/runner.go:101:           100.0%
github.com/vaayne/anna/agent/runner/runner.go:133:           86.7%
github.com/vaayne/anna/agent/runner/runner.go:163:           75.0%
github.com/vaayne/anna/agent/runner/runner.go:175:           100.0%
github.com/vaayne/anna/agent/runner/runner.go:184:           0.0%
github.com/vaayne/anna/agent/runner/runner.go:192:           100.0%
github.com/vaayne/anna/agent/runner/runner.go:203:           83.3%
github.com/vaayne/anna/agent/runner/skill.go:100:            85.7%
github.com/vaayne/anna/agent/runner/skill.go:142:            85.7%
github.com/vaayne/anna/agent/runner/skill.go:178:            91.7%
github.com/vaayne/anna/agent/runner/skill.go:204:            100.0%
github.com/vaayne/anna/agent/runner/skill.go:236:            91.7%
github.com/vaayne/anna/agent/runner/skill.go:256:            100.0%
github.com/vaayne/anna/agent/runner/skill.go:40:             100.0%
github.com/vaayne/anna/agent/runner/skill.go:45:             95.5%
github.com/vaayne/anna/agent/runner/skill.go:91:             100.0%
github.com/vaayne/anna/agent/runner/stream_proxy.go:17:      80.0%
github.com/vaayne/anna/agent/runner/stream_proxy.go:27:      35.3%
github.com/vaayne/anna/agent/runner/stream_proxy.go:57:      40.0%
github.com/vaayne/anna/agent/session.go:21:                  0.0%
github.com/vaayne/anna/agent/store/index.go:102:             83.3%
github.com/vaayne/anna/agent/store/index.go:113:             90.0%
github.com/vaayne/anna/agent/store/index.go:132:             100.0%
github.com/vaayne/anna/agent/store/index.go:136:             100.0%
github.com/vaayne/anna/agent/store/index.go:144:             100.0%
github.com/vaayne/anna/agent/store/index.go:22:              100.0%
github.com/vaayne/anna/agent/store/index.go:30:              100.0%
github.com/vaayne/anna/agent/store/index.go:40:              82.6%
github.com/vaayne/anna/agent/store/index.go:74:              75.0%
github.com/vaayne/anna/agent/store/store.go:144:             66.7%
github.com/vaayne/anna/agent/store/store.go:156:             100.0%
github.com/vaayne/anna/agent/store/store.go:165:             91.7%
github.com/vaayne/anna/agent/store/store.go:188:             100.0%
github.com/vaayne/anna/agent/store/store.go:194:             80.0%
github.com/vaayne/anna/agent/store/store.go:219:             70.0%
github.com/vaayne/anna/agent/store/store.go:254:             86.1%
github.com/vaayne/anna/agent/store/store.go:320:             100.0%
github.com/vaayne/anna/agent/store/store.go:329:             73.3%
github.com/vaayne/anna/agent/store/store.go:358:             85.7%
github.com/vaayne/anna/agent/store/store.go:395:             85.5%
github.com/vaayne/anna/agent/store/store.go:492:             94.6%
github.com/vaayne/anna/agent/store/store.go:586:             78.8%
github.com/vaayne/anna/agent/store/store.go:658:             71.4%
github.com/vaayne/anna/agent/store/store.go:684:             89.3%
github.com/vaayne/anna/agent/store/store.go:738:             87.5%
github.com/vaayne/anna/agent/store/store.go:761:             75.0%
github.com/vaayne/anna/agent/store/store.go:773:             88.2%
github.com/vaayne/anna/agent/tool/bash.go:17:                100.0%
github.com/vaayne/anna/agent/tool/bash.go:34:                81.0%
github.com/vaayne/anna/agent/tool/edit.go:15:                100.0%
github.com/vaayne/anna/agent/tool/edit.go:40:                85.0%
github.com/vaayne/anna/agent/tool/read.go:111:               76.2%
github.com/vaayne/anna/agent/tool/read.go:147:               71.4%
github.com/vaayne/anna/agent/tool/read.go:159:               71.4%
github.com/vaayne/anna/agent/tool/read.go:16:                100.0%
github.com/vaayne/anna/agent/tool/read.go:41:                96.6%
github.com/vaayne/anna/agent/tool/read.go:94:                100.0%
github.com/vaayne/anna/agent/tool/tool.go:22:                100.0%
github.com/vaayne/anna/agent/tool/tool.go:33:                100.0%
github.com/vaayne/anna/agent/tool/tool.go:38:                100.0%
github.com/vaayne/anna/agent/tool/tool.go:47:                100.0%
github.com/vaayne/anna/agent/tool/truncate.go:101:           100.0%
github.com/vaayne/anna/agent/tool/truncate.go:118:           66.7%
github.com/vaayne/anna/agent/tool/truncate.go:131:           100.0%
github.com/vaayne/anna/agent/tool/truncate.go:21:            100.0%
github.com/vaayne/anna/agent/tool/truncate.go:30:            100.0%
github.com/vaayne/anna/agent/tool/truncate.go:41:            100.0%
github.com/vaayne/anna/agent/tool/truncate.go:51:            100.0%
github.com/vaayne/anna/agent/tool/truncate.go:57:            100.0%
github.com/vaayne/anna/agent/tool/truncate.go:64:            92.9%
github.com/vaayne/anna/agent/tool/truncate.go:88:            100.0%
github.com/vaayne/anna/agent/tool/webfetch.go:109:           66.7%
github.com/vaayne/anna/agent/tool/webfetch.go:118:           68.0%
github.com/vaayne/anna/agent/tool/webfetch.go:164:           66.7%
github.com/vaayne/anna/agent/tool/webfetch.go:175:           40.0%
github.com/vaayne/anna/agent/tool/webfetch.go:188:           81.8%
github.com/vaayne/anna/agent/tool/webfetch.go:206:           0.0%
github.com/vaayne/anna/agent/tool/webfetch.go:214:           0.0%
github.com/vaayne/anna/agent/tool/webfetch.go:237:           0.0%
github.com/vaayne/anna/agent/tool/webfetch.go:263:           90.0%
github.com/vaayne/anna/agent/tool/webfetch.go:282:           75.0%
github.com/vaayne/anna/agent/tool/webfetch.go:40:            100.0%
github.com/vaayne/anna/agent/tool/webfetch.go:46:            100.0%
github.com/vaayne/anna/agent/tool/webfetch.go:69:            77.3%
github.com/vaayne/anna/agent/tool/write.go:15:               100.0%
github.com/vaayne/anna/agent/tool/write.go:36:               80.0%
github.com/vaayne/anna/ai/providers/anthropic/client.go:25:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/client.go:37:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/client.go:40:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/client.go:57:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/client.go:62:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/client.go:82:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/convert_messages.go:10: 0.0%
github.com/vaayne/anna/ai/providers/anthropic/convert_messages.go:25: 0.0%
github.com/vaayne/anna/ai/providers/anthropic/convert_messages.go:45: 0.0%
github.com/vaayne/anna/ai/providers/anthropic/convert_messages.go:60: 0.0%
github.com/vaayne/anna/ai/providers/anthropic/options.go:36: 0.0%
github.com/vaayne/anna/ai/providers/anthropic/options.go:9:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/stream.go:10:  0.0%
github.com/vaayne/anna/ai/providers/anthropic/stream.go:22:  76.0%
github.com/vaayne/anna/ai/providers/anthropic/stream.go:78:  40.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:106: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:111: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:131: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:28: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:43: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:60: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:80: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:85: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/client.go:88: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/convert_messages.go:13: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/convert_messages.go:34: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/convert_messages.go:68: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/options.go:10: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/options.go:38: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/stream.go:10: 0.0%
github.com/vaayne/anna/ai/providers/openai-response/stream.go:22: 100.0%
github.com/vaayne/anna/ai/providers/openai-response/stream.go:75: 40.0%
github.com/vaayne/anna/ai/providers/openai/client.go:25:     0.0%
github.com/vaayne/anna/ai/providers/openai/client.go:37:     0.0%
github.com/vaayne/anna/ai/providers/openai/client.go:40:     0.0%
github.com/vaayne/anna/ai/providers/openai/client.go:58:     0.0%
github.com/vaayne/anna/ai/providers/openai/client.go:63:     0.0%
github.com/vaayne/anna/ai/providers/openai/client.go:83:     0.0%
github.com/vaayne/anna/ai/providers/openai/convert_messages.go:13: 0.0%
github.com/vaayne/anna/ai/providers/openai/convert_messages.go:33: 0.0%
github.com/vaayne/anna/ai/providers/openai/convert_messages.go:66: 0.0%
github.com/vaayne/anna/ai/providers/openai/options.go:10:    0.0%
github.com/vaayne/anna/ai/providers/openai/options.go:32:    0.0%
github.com/vaayne/anna/ai/providers/openai/stream.go:10:     0.0%
github.com/vaayne/anna/ai/providers/openai/stream.go:23:     100.0%
github.com/vaayne/anna/ai/providers/openai/stream.go:58:     60.0%
github.com/vaayne/anna/ai/providers/register_builtins.go:11: 0.0%
github.com/vaayne/anna/ai/registry/register.go:11:           0.0%
github.com/vaayne/anna/ai/registry/registry.go:16:           0.0%
github.com/vaayne/anna/ai/registry/registry.go:21:           0.0%
github.com/vaayne/anna/ai/registry/registry.go:28:           0.0%
github.com/vaayne/anna/ai/stream/event_stream.go:25:         100.0%
github.com/vaayne/anna/ai/stream/event_stream.go:30:         100.0%
github.com/vaayne/anna/ai/stream/event_stream.go:35:         100.0%
github.com/vaayne/anna/ai/stream/event_stream.go:40:         100.0%
github.com/vaayne/anna/ai/stream/event_stream.go:50:         0.0%
github.com/vaayne/anna/ai/stream/event_stream.go:58:         100.0%
github.com/vaayne/anna/ai/stream/stream.go:31:               75.0%
github.com/vaayne/anna/ai/stream/stream.go:40:               0.0%
github.com/vaayne/anna/ai/stream/stream.go:49:               50.0%
github.com/vaayne/anna/ai/transform/transform_messages.go:10: 93.8%
github.com/vaayne/anna/ai/transform/transform_messages.go:46: 85.7%
github.com/vaayne/anna/ai/types/events.go:103:               0.0%
github.com/vaayne/anna/ai/types/events.go:111:               0.0%
github.com/vaayne/anna/ai/types/events.go:119:               0.0%
github.com/vaayne/anna/ai/types/events.go:124:               0.0%
github.com/vaayne/anna/ai/types/events.go:16:                0.0%
github.com/vaayne/anna/ai/types/events.go:24:                0.0%
github.com/vaayne/anna/ai/types/events.go:33:                0.0%
github.com/vaayne/anna/ai/types/events.go:42:                0.0%
github.com/vaayne/anna/ai/types/events.go:50:                0.0%
github.com/vaayne/anna/ai/types/events.go:59:                0.0%
github.com/vaayne/anna/ai/types/events.go:68:                0.0%
github.com/vaayne/anna/ai/types/events.go:76:                0.0%
github.com/vaayne/anna/ai/types/events.go:87:                0.0%
github.com/vaayne/anna/ai/types/events.go:96:                0.0%
github.com/vaayne/anna/ai/types/message.go:101:              100.0%
github.com/vaayne/anna/ai/types/message.go:111:              100.0%
github.com/vaayne/anna/ai/types/message.go:26:               0.0%
github.com/vaayne/anna/ai/types/message.go:35:               0.0%
github.com/vaayne/anna/ai/types/message.go:43:               0.0%
github.com/vaayne/anna/ai/types/message.go:46:               0.0%
github.com/vaayne/anna/ai/types/message.go:58:               0.0%
github.com/vaayne/anna/ai/types/message.go:72:               0.0%
github.com/vaayne/anna/ai/types/message.go:86:               0.0%
github.com/vaayne/anna/ai/types/message.go:98:               0.0%
github.com/vaayne/anna/channel/cli/chat.go:128:              75.0%
github.com/vaayne/anna/channel/cli/chat.go:138:              18.8%
github.com/vaayne/anna/channel/cli/chat.go:168:              0.0%
github.com/vaayne/anna/channel/cli/chat.go:172:              38.5%
github.com/vaayne/anna/channel/cli/chat.go:359:              20.0%
github.com/vaayne/anna/channel/cli/chat.go:383:              77.3%
github.com/vaayne/anna/channel/cli/chat.go:432:              47.9%
github.com/vaayne/anna/channel/cli/chat.go:497:              72.7%
github.com/vaayne/anna/channel/cli/chat.go:522:              66.7%
github.com/vaayne/anna/channel/cli/chat.go:534:              100.0%
github.com/vaayne/anna/channel/cli/chat.go:541:              100.0%
github.com/vaayne/anna/channel/cli/chat.go:544:              0.0%
github.com/vaayne/anna/channel/cli/chat.go:553:              0.0%
github.com/vaayne/anna/channel/cli/chat.go:564:              0.0%
github.com/vaayne/anna/channel/cli/chat.go:651:              0.0%
github.com/vaayne/anna/channel/cli/chat.go:660:              0.0%
github.com/vaayne/anna/channel/cli/chat.go:90:               84.6%
github.com/vaayne/anna/channel/cli/cli.go:28:                0.0%
github.com/vaayne/anna/channel/cli/cli.go:51:                0.0%
github.com/vaayne/anna/channel/cli/command.go:21:            0.0%
github.com/vaayne/anna/channel/cli/command.go:35:            0.0%
github.com/vaayne/anna/channel/cli/model.go:17:              0.0%
github.com/vaayne/anna/channel/cli/model.go:25:              0.0%
github.com/vaayne/anna/channel/cli/model.go:41:              0.0%
github.com/vaayne/anna/channel/notifier.go:43:               100.0%
github.com/vaayne/anna/channel/notifier.go:48:               100.0%
github.com/vaayne/anna/channel/notifier.go:56:               100.0%
github.com/vaayne/anna/channel/notifier.go:94:               100.0%
github.com/vaayne/anna/channel/notify_tool.go:16:            0.0%
github.com/vaayne/anna/channel/notify_tool.go:43:            0.0%
github.com/vaayne/anna/channel/notify_tool.go:51:            0.0%
github.com/vaayne/anna/channel/telegram/handler.go:143:      0.0%
github.com/vaayne/anna/channel/telegram/handler.go:152:      0.0%
github.com/vaayne/anna/channel/telegram/handler.go:192:      0.0%
github.com/vaayne/anna/channel/telegram/handler.go:26:       100.0%
github.com/vaayne/anna/channel/telegram/handler.go:35:       0.0%
github.com/vaayne/anna/channel/telegram/handler.go:39:       0.0%
github.com/vaayne/anna/channel/telegram/model.go:126:        0.0%
github.com/vaayne/anna/channel/telegram/model.go:30:         0.0%
github.com/vaayne/anna/channel/telegram/model.go:39:         0.0%
github.com/vaayne/anna/channel/telegram/model.go:55:         0.0%
github.com/vaayne/anna/channel/telegram/model.go:62:         0.0%
github.com/vaayne/anna/channel/telegram/render.go:22:        0.0%
github.com/vaayne/anna/channel/telegram/render.go:32:        0.0%
github.com/vaayne/anna/channel/telegram/render.go:48:        0.0%
github.com/vaayne/anna/channel/telegram/render.go:67:        85.7%
github.com/vaayne/anna/channel/telegram/render.go:81:        100.0%
github.com/vaayne/anna/channel/telegram/stream.go:109:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:137:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:145:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:152:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:214:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:234:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:242:       100.0%
github.com/vaayne/anna/channel/telegram/stream.go:251:       75.0%
github.com/vaayne/anna/channel/telegram/stream.go:269:       0.0%
github.com/vaayne/anna/channel/telegram/stream.go:290:       0.0%
github.com/vaayne/anna/channel/telegram/stream.go:347:       0.0%
github.com/vaayne/anna/channel/telegram/stream.go:417:       85.7%
github.com/vaayne/anna/channel/telegram/stream.go:446:       0.0%
github.com/vaayne/anna/channel/telegram/stream.go:457:       0.0%
github.com/vaayne/anna/channel/telegram/stream.go:59:        100.0%
github.com/vaayne/anna/channel/telegram/stream.go:76:        100.0%
github.com/vaayne/anna/channel/telegram/stream.go:96:        83.3%
github.com/vaayne/anna/channel/telegram/telegram.go:109:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:112:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:149:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:152:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:176:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:188:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:194:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:207:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:225:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:234:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:240:     0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:24:      0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:52:      0.0%
github.com/vaayne/anna/channel/telegram/telegram.go:89:      0.0%
github.com/vaayne/anna/config.go:107:                        100.0%
github.com/vaayne/anna/config.go:112:                        100.0%
github.com/vaayne/anna/config.go:117:                        100.0%
github.com/vaayne/anna/config.go:122:                        100.0%
github.com/vaayne/anna/config.go:127:                        87.5%
github.com/vaayne/anna/config.go:197:                        100.0%
github.com/vaayne/anna/config.go:214:                        100.0%
github.com/vaayne/anna/config.go:218:                        100.0%
github.com/vaayne/anna/config.go:222:                        100.0%
github.com/vaayne/anna/config.go:226:                        100.0%
github.com/vaayne/anna/config.go:230:                        100.0%
github.com/vaayne/anna/config.go:236:                        100.0%
github.com/vaayne/anna/config.go:242:                        100.0%
github.com/vaayne/anna/config.go:262:                        90.0%
github.com/vaayne/anna/config.go:284:                        66.7%
github.com/vaayne/anna/config.go:315:                        84.6%
github.com/vaayne/anna/config.go:339:                        62.5%
github.com/vaayne/anna/config.go:46:                         100.0%
github.com/vaayne/anna/config.go:95:                         83.3%
github.com/vaayne/anna/cron/cron.go:176:                     69.6%
github.com/vaayne/anna/cron/cron.go:215:                     100.0%
github.com/vaayne/anna/cron/cron.go:226:                     88.9%
github.com/vaayne/anna/cron/cron.go:270:                     88.9%
github.com/vaayne/anna/cron/cron.go:287:                     100.0%
github.com/vaayne/anna/cron/cron.go:292:                     77.8%
github.com/vaayne/anna/cron/cron.go:309:                     75.0%
github.com/vaayne/anna/cron/cron.go:40:                      75.0%
github.com/vaayne/anna/cron/cron.go:55:                      100.0%
github.com/vaayne/anna/cron/cron.go:62:                      87.5%
github.com/vaayne/anna/cron/cron.go:90:                      100.0%
github.com/vaayne/anna/cron/cron.go:96:                      85.7%
github.com/vaayne/anna/cron/job.go:36:                       100.0%
github.com/vaayne/anna/cron/tool.go:108:                     100.0%
github.com/vaayne/anna/cron/tool.go:118:                     83.3%
github.com/vaayne/anna/cron/tool.go:62:                      100.0%
github.com/vaayne/anna/cron/tool.go:67:                      100.0%
github.com/vaayne/anna/cron/tool.go:76:                      100.0%
github.com/vaayne/anna/cron/tool.go:90:                      91.7%
github.com/vaayne/anna/main.go:124:                          73.8%
github.com/vaayne/anna/main.go:210:                          100.0%
github.com/vaayne/anna/main.go:235:                          9.1%
github.com/vaayne/anna/main.go:252:                          0.0%
github.com/vaayne/anna/main.go:267:                          20.8%
github.com/vaayne/anna/main.go:27:                           0.0%
github.com/vaayne/anna/main.go:318:                          0.0%
github.com/vaayne/anna/main.go:40:                           100.0%
github.com/vaayne/anna/main.go:53:                           5.0%
github.com/vaayne/anna/main.go:93:                           80.0%
github.com/vaayne/anna/memory/memory.go:109:                 69.2%
github.com/vaayne/anna/memory/memory.go:133:                 83.9%
github.com/vaayne/anna/memory/memory.go:183:                 100.0%
github.com/vaayne/anna/memory/memory.go:36:                  100.0%
github.com/vaayne/anna/memory/memory.go:45:                  100.0%
github.com/vaayne/anna/memory/memory.go:55:                  53.3%
github.com/vaayne/anna/memory/memory.go:78:                  0.0%
github.com/vaayne/anna/memory/memory.go:84:                  0.0%
github.com/vaayne/anna/memory/memory.go:90:                  72.7%
github.com/vaayne/anna/memory/tool.go:129:                   0.0%
github.com/vaayne/anna/memory/tool.go:59:                    0.0%
github.com/vaayne/anna/memory/tool.go:64:                    0.0%
github.com/vaayne/anna/memory/tool.go:73:                    0.0%
github.com/vaayne/anna/memory/tool.go:87:                    0.0%
github.com/vaayne/anna/memory/tool.go:98:                    0.0%
github.com/vaayne/anna/models.go:115:                        0.0%
github.com/vaayne/anna/models.go:158:                        0.0%
github.com/vaayne/anna/models.go:171:                        100.0%
github.com/vaayne/anna/models.go:186:                        100.0%
github.com/vaayne/anna/models.go:194:                        0.0%
github.com/vaayne/anna/models.go:205:                        9.1%
github.com/vaayne/anna/models.go:233:                        16.7%
github.com/vaayne/anna/models.go:248:                        7.1%
github.com/vaayne/anna/models.go:277:                        5.6%
github.com/vaayne/anna/models.go:314:                        0.0%
github.com/vaayne/anna/models.go:34:                         0.0%
github.com/vaayne/anna/models.go:39:                         0.0%
github.com/vaayne/anna/models.go:52:                         0.0%
github.com/vaayne/anna/models.go:65:                         0.0%
github.com/vaayne/anna/skills/install.go:133:                80.0%
github.com/vaayne/anna/skills/install.go:151:                0.0%
github.com/vaayne/anna/skills/install.go:189:                88.2%
github.com/vaayne/anna/skills/install.go:20:                 0.0%
github.com/vaayne/anna/skills/install.go:217:                75.0%
github.com/vaayne/anna/skills/install.go:250:                73.3%
github.com/vaayne/anna/skills/install.go:48:                 81.0%
github.com/vaayne/anna/skills/install.go:86:                 100.0%
github.com/vaayne/anna/skills/list.go:17:                    87.5%
github.com/vaayne/anna/skills/remove.go:14:                  66.7%
github.com/vaayne/anna/skills/remove.go:34:                  100.0%
github.com/vaayne/anna/skills/search.go:30:                  0.0%
github.com/vaayne/anna/skills/search.go:34:                  81.8%
github.com/vaayne/anna/skills/search.go:71:                  93.8%
github.com/vaayne/anna/skills/tool.go:55:                    100.0%
github.com/vaayne/anna/skills/tool.go:60:                    100.0%
github.com/vaayne/anna/skills/tool.go:69:                    85.7%
github.com/vaayne/anna/skills_cmd.go:108:                    25.0%
github.com/vaayne/anna/skills_cmd.go:127:                    0.0%
github.com/vaayne/anna/skills_cmd.go:166:                    0.0%
github.com/vaayne/anna/skills_cmd.go:17:                     50.0%
github.com/vaayne/anna/skills_cmd.go:196:                    8.3%
github.com/vaayne/anna/skills_cmd.go:34:                     5.3%
github.com/vaayne/anna/skills_cmd.go:77:                     7.1%

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aa8050e737

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


// Store user message so stateless runners can reconstruct the conversation.
userEvt := runner.RPCEvent{Type: "user_message", Summary: message}
userEvt := runner.UserMessageToRPCEvent(message)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist multimodal user content to session store

This now creates user events via UserMessageToRPCEvent(message), but the storage pipeline still writes user messages from evt.Summary only (agent/store/store.go rpcEventToEntry) and reads them back as summary text (entryToRPCEvents), so RPCEvent.Content (image blocks) is dropped on disk round-trips. In practice, photo inputs disappear after restart/cold load and auto-compaction token estimates undercount image-heavy sessions because the base64 payload never reaches the persisted log.

Useful? React with 👍 / 👎.

vaayne added 2 commits March 9, 2026 00:01
- Add MessageContent type alias for type-safe message passing
- Extract shared HasImage/FlattenText helpers to ai/types
- Cap photo download at 20MB via io.LimitReader
- Reorder multimodal content blocks to text-first for better model results
- Log JSON marshal errors in UserMessageToRPCEvent
- Fix MessageText to join all text blocks instead of returning only the first
- Add comprehensive tests for multimodal message handling and round-tripping
The store layer was only writing evt.Summary (text) for user messages,
dropping the Content field that carries base64 image blocks. After a
restart or cold load, photo inputs disappeared from session history.

- Add piImageContent type for Pi-format image serialization
- Write multimodal content blocks (text + image) when evt.Content is set
- Restore RPCEvent.Content on load when image blocks are detected
- Remove unused extractUserText (replaced by extractUserContent)
- Add round-trip tests for multimodal and text-only user messages
@vaayne
Copy link
Owner Author

vaayne commented Mar 8, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6aaf2759a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +130 to +132
b.bot.Handle(tele.OnPhoto, b.guard(func(c tele.Context) error {
return b.handlePhoto(c)
}))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor caption mentions for photo messages

Registering tele.OnPhoto behind b.guard means group photo updates now go through shouldRespondInGroup, but isMentionedOrReplied only checks c.Message().Text (not Caption). In group_mode=mention, a non-reply photo with @botname in the caption will be silently ignored, so the new image-input path does not work in the default group configuration unless users reply to a bot message. Please make mention detection include captions (or bypass this filter for photo captions) so photo handling is consistent with text mention semantics.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0e66a5c. isMentionedOrReplied now checks Caption in addition to Text, and handlePhoto strips the bot mention from captions in groups (consistent with handleText).

vaayne added 2 commits March 9, 2026 00:13
…dge cases

- Export ContentBlockJSON and add BlockKindText/BlockKindImage constants
- Merge double iteration in extractUserContent into single pass
- Add DataURI() method on ImageContent, deduplicate across providers
- Inline trivial flattenToolResult wrappers in both OpenAI providers
- Use FlattenText in ToolResultToRPCEvent for consistency
- Fix truncate() to respect UTF-8 rune boundaries
- Fix io.LimitReader silent truncation for oversized photos
In group_mode=mention, isMentionedOrReplied only checked Message.Text,
so photos with @botName in the caption were silently ignored. Now also
checks Caption and strips the mention from captions before processing.

Closes review comment on PR #35.
@vaayne vaayne merged commit b6da39d into main Mar 8, 2026
6 checks passed
@vaayne vaayne deleted the feat/telegram-image-input branch March 8, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Telegram channel: image input support

1 participant