4bbce5f083
- Extract assist runtime (prompt building, response parsing, finalize) from the worker into kol_assist_runtime so the sync streaming path and the async task path share the same logic. - Add POST /kol/manage/assist/stream as a Server-Sent Events endpoint emitting start/delta/completed/error events, and wire it to a streamAssist helper on kolManageApi that reports ApiClientError with the server's error envelope. - Stream generated content live in KolPromptEditor and KolGenerateView, switching KolPromptEditArea to a boolean aiBusy flag and refining the generator page layout. - Add KolAssistStreamEvent to shared types. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package app
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestFinalizeKolAssistResultRepairsDuplicateVariableIDs(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
result, err := FinalizeKolAssistResult(
|
|
AssistRequest{Mode: kolAssistModeGenerate},
|
|
&KolAssistResult{
|
|
Content: "围绕 {{城市}} 和 {{目标词}} 输出内容",
|
|
Schema: KolSchemaJSON{
|
|
Variables: []KolVariableDefinition{
|
|
{ID: "var_dup", Key: "城市", Label: "城市", Type: KolVariableTypeInput, Required: true},
|
|
{ID: "var_dup", Key: "目标词", Label: "目标词", Type: KolVariableTypeInput, Required: true},
|
|
},
|
|
},
|
|
},
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, result.Schema.Variables, 2)
|
|
require.NotEqual(t, result.Schema.Variables[0].ID, result.Schema.Variables[1].ID)
|
|
require.Equal(t, "城市", result.Schema.Variables[0].Key)
|
|
require.Equal(t, "目标词", result.Schema.Variables[1].Key)
|
|
}
|
|
|
|
func TestFinalizeKolAssistResultOptimizePreservesExistingSchemaByKey(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
originalMaxLength := 80
|
|
|
|
result, err := FinalizeKolAssistResult(
|
|
AssistRequest{
|
|
Mode: kolAssistModeOptimize,
|
|
Schema: &KolSchemaJSON{
|
|
Variables: []KolVariableDefinition{
|
|
{ID: "var_city", Key: "城市", Label: "城市", Type: KolVariableTypeInput, Required: true, MaxLength: intPtr(originalMaxLength)},
|
|
},
|
|
},
|
|
},
|
|
&KolAssistResult{
|
|
Content: "围绕 {{城市}} 优化提示词",
|
|
Schema: KolSchemaJSON{
|
|
Variables: []KolVariableDefinition{
|
|
{ID: "var_dup", Key: "城市", Label: "城市", Type: KolVariableTypeTextarea, Required: false},
|
|
},
|
|
},
|
|
},
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.Len(t, result.Schema.Variables, 1)
|
|
require.Equal(t, "var_city", result.Schema.Variables[0].ID)
|
|
require.Equal(t, KolVariableTypeInput, result.Schema.Variables[0].Type)
|
|
require.NotNil(t, result.Schema.Variables[0].MaxLength)
|
|
require.Equal(t, originalMaxLength, *result.Schema.Variables[0].MaxLength)
|
|
}
|
|
|
|
func TestParseKolAssistResponseSupportsStringVariables(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
result, err := ParseKolAssistResponse(`{"content":"围绕 {{城市}} 写内容","schema":{"variables":["城市"]}}`)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "围绕 {{城市}} 写内容", result.Content)
|
|
require.Len(t, result.Schema.Variables, 1)
|
|
require.Equal(t, "城市", result.Schema.Variables[0].Key)
|
|
}
|
|
|
|
func TestExtractKolAssistContentFromPartialJSON(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
content := extractKolAssistContentFromPartialJSON("{\"content\":\"第一段\\n第二")
|
|
|
|
require.Equal(t, "第一段\n第二", content)
|
|
}
|