WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package chatpipeline
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Tencent/WeKnora/internal/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPrepareMessagesWithModelContextUsesChunkCentricContext(t *testing.T) {
|
||||
rendered := `<context id="1">first content</context><context id="2">second content</context>`
|
||||
manage := &types.ChatManage{
|
||||
PipelineRequest: types.PipelineRequest{
|
||||
Query: "question",
|
||||
SummaryConfig: types.SummaryConfig{
|
||||
Prompt: "system",
|
||||
},
|
||||
},
|
||||
PipelineState: types.PipelineState{
|
||||
RenderedContexts: rendered,
|
||||
UserContent: "References:\n" + rendered + "\nQuestion: question",
|
||||
MergeResult: []*types.SearchResult{
|
||||
{ID: "chunk-1", KnowledgeID: "doc-1", KnowledgeBaseID: "kb-1", KnowledgeTitle: "Doc", ChunkIndex: 1, Content: "first content"},
|
||||
{ID: "chunk-2", KnowledgeID: "doc-1", KnowledgeBaseID: "kb-1", KnowledgeTitle: "Doc", ChunkIndex: 2, Content: "second content"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
messages, refs := prepareMessagesWithModelContext(context.Background(), manage)
|
||||
require.Len(t, messages, 2)
|
||||
require.Contains(t, messages[0].Content, "Source handling protocol")
|
||||
require.Contains(t, messages[1].Content, `<document id="d1" kb="b1" title="Doc">`)
|
||||
require.Contains(t, messages[1].Content, `<chunk id="c1" index="1" view="full">`)
|
||||
require.Contains(t, messages[1].Content, `<chunk id="c2" index="2" view="full">`)
|
||||
require.False(t, strings.Contains(messages[1].Content, "chunk-1"))
|
||||
require.Equal(t,
|
||||
`<kb doc="Doc" chunk_id="chunk-1" kb_id="kb-1" />`,
|
||||
refs.DecodeOutputText(`<ref id="c1"/>`),
|
||||
)
|
||||
}
|
||||
|
||||
func TestPrepareMessagesWithModelContextReplacesSystemPromptContextAndHistoryCitations(t *testing.T) {
|
||||
rendered := `<context id="1">first content</context>`
|
||||
manage := &types.ChatManage{
|
||||
PipelineRequest: types.PipelineRequest{
|
||||
Query: "question",
|
||||
SummaryConfig: types.SummaryConfig{
|
||||
Prompt: `System references: {{contexts}}`,
|
||||
},
|
||||
},
|
||||
PipelineState: types.PipelineState{
|
||||
RenderedContexts: rendered,
|
||||
UserContent: "Question: question",
|
||||
History: []*types.History{{
|
||||
Query: "previous",
|
||||
Answer: `Previous <kb doc="Old" chunk_id="old-chunk" kb_id="old-kb" />`,
|
||||
}},
|
||||
MergeResult: []*types.SearchResult{{
|
||||
ID: "current-chunk", KnowledgeID: "current-doc", KnowledgeBaseID: "current-kb", KnowledgeTitle: "Current", Content: "first content",
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
messages, refs := prepareMessagesWithModelContext(context.Background(), manage)
|
||||
messages = refs.EncodeMessages(messages)
|
||||
require.NotContains(t, messages[0].Content, rendered)
|
||||
require.Contains(t, messages[0].Content, `<chunk id="c1"`)
|
||||
require.Contains(t, messages[2].Content, `<ref id="c2"/>`)
|
||||
require.NotContains(t, messages[2].Content, "old-chunk")
|
||||
}
|
||||
|
||||
func TestPrepareMessagesWithModelContextKeepsWebSeparateFromChunks(t *testing.T) {
|
||||
manage := &types.ChatManage{
|
||||
PipelineRequest: types.PipelineRequest{Query: "question", SummaryConfig: types.SummaryConfig{Prompt: "system"}},
|
||||
PipelineState: types.PipelineState{
|
||||
UserContent: "question",
|
||||
MergeResult: []*types.SearchResult{{
|
||||
ID: "https://example.com/page",
|
||||
KnowledgeTitle: "Example",
|
||||
Content: "web content",
|
||||
ChunkType: string(types.ChunkTypeWebSearch),
|
||||
KnowledgeSource: "web_search",
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
messages, refs := prepareMessagesWithModelContext(context.Background(), manage)
|
||||
require.Contains(t, messages[1].Content, `<retrieval type="web" mode="search">`)
|
||||
require.Contains(t, messages[1].Content, `<page id="w1" title="Example">`)
|
||||
require.NotContains(t, messages[1].Content, `<chunk id="c1"`)
|
||||
require.Equal(t,
|
||||
`<web url="https://example.com/page" title="Example" />`,
|
||||
refs.DecodeOutputText(`<ref id="w1"/>`),
|
||||
)
|
||||
}
|
||||
|
||||
func TestPrepareMessagesWithModelContextCompactsHistoryWithoutCurrentRetrieval(t *testing.T) {
|
||||
manage := &types.ChatManage{
|
||||
PipelineRequest: types.PipelineRequest{Query: "follow-up", SummaryConfig: types.SummaryConfig{Prompt: "system"}},
|
||||
PipelineState: types.PipelineState{
|
||||
UserContent: "follow-up",
|
||||
History: []*types.History{{
|
||||
Query: "previous",
|
||||
Answer: `Previous <web url="https://example.com/old" title="Old" />`,
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
messages, refs := prepareMessagesWithModelContext(context.Background(), manage)
|
||||
messages = refs.EncodeMessages(messages)
|
||||
require.Contains(t, messages[0].Content, "Source handling protocol")
|
||||
require.Contains(t, messages[2].Content, `<ref id="w1"/>`)
|
||||
require.NotContains(t, messages[2].Content, "https://example.com/old")
|
||||
}
|
||||
|
||||
func TestPrepareMessagesWithModelContextSuppressesCitationsWhenDisabled(t *testing.T) {
|
||||
disabled := false
|
||||
manage := &types.ChatManage{
|
||||
PipelineRequest: types.PipelineRequest{
|
||||
Query: "question",
|
||||
CitationEnabled: &disabled,
|
||||
SummaryConfig: types.SummaryConfig{Prompt: "custom system prompt"},
|
||||
},
|
||||
PipelineState: types.PipelineState{
|
||||
UserContent: "question",
|
||||
MergeResult: []*types.SearchResult{{
|
||||
ID: "chunk-1", KnowledgeID: "doc-1", KnowledgeBaseID: "kb-1", KnowledgeTitle: "Doc", Content: "evidence",
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
messages, refs := prepareMessagesWithModelContext(context.Background(), manage)
|
||||
require.Contains(t, messages[0].Content, "Source citations are disabled")
|
||||
require.Contains(t, messages[1].Content, `<chunk id="c1"`)
|
||||
require.NotContains(t, messages[1].Content, "chunk-1")
|
||||
require.Equal(t, "answer ", refs.DecodeOutputText(`answer <ref id="c1"/>`))
|
||||
}
|
||||
Reference in New Issue
Block a user