Merge branch 'sipeed:main' into main

This commit is contained in:
anthrodjear 2026-05-06 05:19:55 +03:00 committed by GitHub
commit 9870f46180
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 150 additions and 4 deletions

View file

@ -285,6 +285,12 @@ func inferMediaType(filename, contentType string) string {
ct := strings.ToLower(contentType)
fn := strings.ToLower(filename)
// SVG is an image MIME type, but raster-only delivery endpoints such as
// Telegram SendPhoto reject it. Treat it as a file/document instead.
if strings.HasPrefix(ct, "image/svg") || filepath.Ext(fn) == ".svg" {
return "file"
}
if strings.HasPrefix(ct, "image/") {
return "image"
}
@ -298,7 +304,7 @@ func inferMediaType(filename, contentType string) string {
// Fallback: infer from extension
ext := filepath.Ext(fn)
switch ext {
case ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg":
case ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp":
return "image"
case ".mp3", ".wav", ".ogg", ".m4a", ".flac", ".aac", ".wma", ".opus":
return "audio"

View file

@ -0,0 +1,76 @@
package agent
import "testing"
func TestInferMediaType(t *testing.T) {
tests := []struct {
name string
filename string
contentType string
want string
}{
{
name: "png content type",
filename: "diagram",
contentType: "image/png",
want: "image",
},
{
name: "jpeg extension fallback",
filename: "photo.JPG",
contentType: "",
want: "image",
},
{
name: "svg content type is file",
filename: "diagram",
contentType: "image/svg+xml",
want: "file",
},
{
name: "svg content type with parameters is file",
filename: "diagram",
contentType: "image/svg+xml; charset=utf-8",
want: "file",
},
{
name: "svg extension fallback is file",
filename: "diagram.SVG",
contentType: "",
want: "file",
},
{
name: "audio content type",
filename: "voice",
contentType: "audio/ogg",
want: "audio",
},
{
name: "ogg application content type",
filename: "voice.ogg",
contentType: "application/ogg",
want: "audio",
},
{
name: "video extension fallback",
filename: "clip.MP4",
contentType: "",
want: "video",
},
{
name: "unknown type",
filename: "archive.bin",
contentType: "application/octet-stream",
want: "file",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := inferMediaType(tt.filename, tt.contentType)
if got != tt.want {
t.Fatalf("inferMediaType(%q, %q) = %q, want %q", tt.filename, tt.contentType, got, tt.want)
}
})
}
}

View file

@ -602,8 +602,8 @@ func (e *CompactionEngine) generateLeafSummary(
}
}
// Check if level 1 succeeded
if content != "" && tokenizer.EstimateMessageTokens(providers.Message{Content: content}) < inputTokens {
// Level 1 only succeeds if it actually reaches the requested target size.
if content != "" && tokenizer.EstimateMessageTokens(providers.Message{Content: content}) <= targetTokens {
return content, nil
}
@ -627,7 +627,7 @@ func (e *CompactionEngine) generateLeafSummary(
return "", err
}
}
if content != "" && tokenizer.EstimateMessageTokens(providers.Message{Content: content}) < inputTokens {
if content != "" && tokenizer.EstimateMessageTokens(providers.Message{Content: content}) <= aggressiveTarget {
return content, nil
}

View file

@ -3,6 +3,7 @@ package seahorse
import (
"context"
"fmt"
"strings"
"sync"
"sync/atomic"
"testing"
@ -697,6 +698,69 @@ func TestGenerateLeafSummaryEscalationToAggressive(t *testing.T) {
}
}
func TestGenerateLeafSummaryEscalatesWhenLevel1MissesTarget(t *testing.T) {
var calls []string
normalContent := strings.Repeat("n", 1000) // ~404 tokens: below input, above target
aggressiveContent := strings.Repeat("a", 450) // ~184 tokens: within aggressive target
escalateComplete := func(ctx context.Context, prompt string, opts CompleteOptions) (string, error) {
if contains(prompt, "Aggressive summary policy") {
calls = append(calls, "aggressive")
return aggressiveContent, nil
}
calls = append(calls, "normal")
return normalContent, nil
}
s := openTestStore(t)
ce, _ := newTestCompactionEngineWithStore(s, escalateComplete)
msgs := []Message{
{Role: "user", Content: "hello world", TokenCount: 500},
{Role: "assistant", Content: "response", TokenCount: 500},
}
content, err := ce.generateLeafSummary(context.Background(), msgs, "")
if err != nil {
t.Fatalf("generateLeafSummary: %v", err)
}
if content != aggressiveContent {
t.Fatalf("expected aggressive summary after level 1 missed target")
}
if len(calls) != 2 || calls[0] != "normal" || calls[1] != "aggressive" {
t.Fatalf("expected normal then aggressive calls, got %v", calls)
}
}
func TestGenerateLeafSummaryAcceptsContentAtTargetBoundary(t *testing.T) {
exactTargetContent := strings.Repeat("x", 488) // (488 + 12) * 2 / 5 = 200 tokens
var aggressiveCalled bool
complete := func(ctx context.Context, prompt string, opts CompleteOptions) (string, error) {
if contains(prompt, "Aggressive summary policy") {
aggressiveCalled = true
}
return exactTargetContent, nil
}
s := openTestStore(t)
ce, _ := newTestCompactionEngineWithStore(s, complete)
msgs := []Message{
{Role: "user", Content: "hello world", TokenCount: 286},
{Role: "assistant", Content: "response", TokenCount: 286},
}
content, err := ce.generateLeafSummary(context.Background(), msgs, "")
if err != nil {
t.Fatalf("generateLeafSummary: %v", err)
}
if content != exactTargetContent {
t.Fatalf("expected level 1 summary at target boundary to be accepted")
}
if aggressiveCalled {
t.Fatal("did not expect aggressive retry when level 1 hit target exactly")
}
}
func TestGenerateLeafSummaryEscalationToTruncation(t *testing.T) {
// Both normal and aggressive return empty, should escalate to level 3 truncation
emptyComplete := func(ctx context.Context, prompt string, opts CompleteOptions) (string, error) {