mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-08-31 00:50:02 +08:00
fix(tests): update resource alias syntax from 'res:' to 'res://' in tests and registry
Refactor tests and registry to use the new 'res://' syntax for resource aliases, ensuring consistency across the codebase. This change addresses alias handling in various test cases, including stream processing and registry encoding, to prevent data loss and improve resource reference management.
This commit is contained in:
@@ -53,7 +53,7 @@ func (m *mockChat) ChatStream(
|
||||
func TestStreamLLMResourceAliasesRoundTrip(t *testing.T) {
|
||||
const ref = "resource://AbCdEfGhIjKlMnOpQrStUv"
|
||||
model := &mockChat{responses: []mockResponse{{chunks: []types.StreamResponse{
|
||||
{ResponseType: types.ResponseTypeAnswer, Content: "", Done: true},
|
||||
}}}}
|
||||
engine := newTestEngine(t, model)
|
||||
@@ -66,7 +66,7 @@ func TestStreamLLMResourceAliasesRoundTrip(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "", result.Content)
|
||||
require.Len(t, model.calls, 1)
|
||||
require.Equal(t, "source=res:0001", model.calls[0][0].Content)
|
||||
require.Equal(t, "source=res://0001", model.calls[0][0].Content)
|
||||
}
|
||||
|
||||
func (m *mockChat) Chat(_ context.Context, _ []chat.Message, _ *chat.ChatOptions) (*types.ChatResponse, error) {
|
||||
|
||||
@@ -80,19 +80,19 @@ func (s *stubModelService) GetChatModel(context.Context, string) (chat.Chat, err
|
||||
|
||||
// TestStreamFlushesHeldAliasOnCancel verifies that when the request is cancelled
|
||||
// mid-stream, the decoder's held-back alias suffix is flushed (emitted) rather
|
||||
// than silently dropped. Without the ctx.Done() flush, "res:0" would be lost.
|
||||
// than silently dropped. Without the ctx.Done() flush, "res://0" would be lost.
|
||||
func TestStreamFlushesHeldAliasOnCancel(t *testing.T) {
|
||||
const ref = "resource://AbCdEfGhIjKlMnOpQrStUv"
|
||||
bus := &syncEventBus{}
|
||||
model := &openStreamChat{chunks: []types.StreamResponse{
|
||||
// Ends with a partial alias prefix ("res:0"), so the stream decoder
|
||||
// Ends with a partial alias prefix ("res://0"), so the stream decoder
|
||||
// holds it back waiting for the rest that never arrives before cancel.
|
||||
{ResponseType: types.ResponseTypeAnswer, Content: "hello res:0"},
|
||||
{ResponseType: types.ResponseTypeAnswer, Content: "hello res://0"},
|
||||
}}
|
||||
|
||||
chatManage := &types.ChatManage{}
|
||||
chatManage.SessionID = "sess-cancel"
|
||||
chatManage.UserContent = ref // seeds the registry so res:0001 becomes a known alias
|
||||
chatManage.UserContent = ref // seeds the registry so res://0001 becomes a known alias
|
||||
chatManage.EventBus = bus
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -111,10 +111,10 @@ func TestStreamFlushesHeldAliasOnCancel(t *testing.T) {
|
||||
|
||||
cancel()
|
||||
|
||||
// After cancel, the held "res:0" suffix must be flushed as a final-answer chunk.
|
||||
// After cancel, the held "res://0" suffix must be flushed as a final-answer chunk.
|
||||
require.Eventually(t, func() bool {
|
||||
for _, c := range bus.finalAnswerContents() {
|
||||
if c == "res:0" {
|
||||
if c == "res://0" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ var storedRefRE = regexp.MustCompile(
|
||||
// aliasShapeRE matches the alias syntax produced by EncodeText. It is used only
|
||||
// to spot alias-shaped tokens the model emitted that the registry cannot map
|
||||
// back — either a hallucinated reference or a coincidental collision.
|
||||
var aliasShapeRE = regexp.MustCompile(`res:\d{4,}`)
|
||||
var aliasShapeRE = regexp.MustCompile(`res://\d{4,}`)
|
||||
|
||||
// Registry assigns low-entropy, request-local aliases to stable resource
|
||||
// handles. It is safe to reuse across all rounds of one Agent execution.
|
||||
@@ -55,7 +55,10 @@ func (r *Registry) EncodeText(value string) string {
|
||||
if alias, ok := r.refToAlias[ref]; ok {
|
||||
return alias
|
||||
}
|
||||
alias := fmt.Sprintf("res:%04d", len(r.aliasToRef)+1)
|
||||
// A URL-shaped alias (scheme://digits) keeps the token low-entropy while
|
||||
// looking enough like a link that the model reuses it verbatim inside
|
||||
// Markdown image/link syntax instead of reasoning about or rewriting it.
|
||||
alias := fmt.Sprintf("res://%04d", len(r.aliasToRef)+1)
|
||||
r.refToAlias[ref] = alias
|
||||
r.aliasToRef[alias] = ref
|
||||
return alias
|
||||
|
||||
@@ -11,7 +11,7 @@ func TestRegistryRoundTripAndDeduplicate(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
ref := "resource://AbCdEfGhIjKlMnOpQrStUv"
|
||||
encoded := r.EncodeText(" and " + ref)
|
||||
require.Equal(t, " and res:0001", encoded)
|
||||
require.Equal(t, " and res://0001", encoded)
|
||||
require.Equal(t, " and "+ref, r.DecodeText(encoded))
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestRegistryAliasesLegacyPhysicalReferencesDuringRollout(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
ref := "storage://c0d93536-702c-4977-aa5e-fe670073c3cb/local://10000/exports/image.png"
|
||||
encoded := r.EncodeText("")
|
||||
require.Equal(t, "", encoded)
|
||||
require.Equal(t, "", encoded)
|
||||
require.Equal(t, "", r.DecodeText(encoded))
|
||||
}
|
||||
|
||||
@@ -29,15 +29,15 @@ func TestRegistryEncodesMessageCopies(t *testing.T) {
|
||||
original := []chat.Message{{Role: "tool", Content: ref}}
|
||||
encoded := r.EncodeMessages(original)
|
||||
require.Equal(t, ref, original[0].Content)
|
||||
require.Equal(t, "res:0001", encoded[0].Content)
|
||||
require.Equal(t, "res://0001", encoded[0].Content)
|
||||
}
|
||||
|
||||
func TestStreamDecoderRestoresSplitAlias(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
ref := "resource://AbCdEfGhIjKlMnOpQrStUv"
|
||||
require.Equal(t, "res:0001", r.EncodeText(ref))
|
||||
require.Equal(t, "res://0001", r.EncodeText(ref))
|
||||
d := NewStreamDecoder(r)
|
||||
require.Equal(t, "before ", d.Feed("before res:0"))
|
||||
require.Equal(t, "before ", d.Feed("before res://0"))
|
||||
require.Equal(t, ref+" afte", d.Feed("001 after"))
|
||||
require.Equal(t, "r", d.Flush())
|
||||
}
|
||||
@@ -45,16 +45,16 @@ func TestStreamDecoderRestoresSplitAlias(t *testing.T) {
|
||||
func TestOrphanAliasesReportsUnresolvableTokens(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
ref := "resource://AbCdEfGhIjKlMnOpQrStUv"
|
||||
require.Equal(t, "res:0001", r.EncodeText(ref))
|
||||
require.Equal(t, "res://0001", r.EncodeText(ref))
|
||||
|
||||
// Known alias resolves and leaves no orphan once decoded.
|
||||
require.Nil(t, r.OrphanAliases(r.DecodeText("see res:0001")))
|
||||
require.Nil(t, r.OrphanAliases(r.DecodeText("see res://0001")))
|
||||
|
||||
// A reference the registry never assigned is reported (deduplicated).
|
||||
require.Equal(t, []string{"res:0099"}, r.OrphanAliases("look at res:0099 and res:0099"))
|
||||
require.Equal(t, []string{"res://0099"}, r.OrphanAliases("look at res://0099 and res://0099"))
|
||||
}
|
||||
|
||||
func TestOrphanAliasesNilRegistry(t *testing.T) {
|
||||
var r *Registry
|
||||
require.Equal(t, []string{"res:0001"}, r.OrphanAliases("res:0001"))
|
||||
require.Equal(t, []string{"res://0001"}, r.OrphanAliases("res://0001"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user