init
This commit is contained in:
76
tools/write_scene.go
Normal file
76
tools/write_scene.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/voocel/agentcore/schema"
|
||||
"github.com/voocel/ainovel-cli/domain"
|
||||
"github.com/voocel/ainovel-cli/state"
|
||||
)
|
||||
|
||||
// WriteSceneTool 写入单个场景草稿。
|
||||
type WriteSceneTool struct {
|
||||
store *state.Store
|
||||
}
|
||||
|
||||
func NewWriteSceneTool(store *state.Store) *WriteSceneTool {
|
||||
return &WriteSceneTool{store: store}
|
||||
}
|
||||
|
||||
func (t *WriteSceneTool) Name() string { return "write_scene" }
|
||||
func (t *WriteSceneTool) Description() string {
|
||||
return "写入单个场景草稿。严格按场景级写作,每次只写一个场景。必须先调用 plan_chapter"
|
||||
}
|
||||
func (t *WriteSceneTool) Label() string { return "写入场景" }
|
||||
|
||||
func (t *WriteSceneTool) Schema() map[string]any {
|
||||
return schema.Object(
|
||||
schema.Property("chapter", schema.Int("章节号")).Required(),
|
||||
schema.Property("scene", schema.Int("场景编号,从 1 开始")).Required(),
|
||||
schema.Property("content", schema.String("场景正文")).Required(),
|
||||
)
|
||||
}
|
||||
|
||||
func (t *WriteSceneTool) Execute(_ context.Context, args json.RawMessage) (json.RawMessage, error) {
|
||||
var a struct {
|
||||
Chapter int `json:"chapter"`
|
||||
Scene int `json:"scene"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
if err := json.Unmarshal(args, &a); err != nil {
|
||||
return nil, fmt.Errorf("invalid args: %w", err)
|
||||
}
|
||||
if a.Chapter <= 0 || a.Scene <= 0 {
|
||||
return nil, fmt.Errorf("chapter and scene must be > 0")
|
||||
}
|
||||
if a.Content == "" {
|
||||
return nil, fmt.Errorf("content must not be empty")
|
||||
}
|
||||
|
||||
wordCount := utf8.RuneCountInString(a.Content)
|
||||
draft := domain.SceneDraft{
|
||||
Chapter: a.Chapter,
|
||||
Scene: a.Scene,
|
||||
Content: a.Content,
|
||||
WordCount: wordCount,
|
||||
}
|
||||
|
||||
if err := t.store.SaveSceneDraft(draft); err != nil {
|
||||
return nil, fmt.Errorf("save scene draft: %w", err)
|
||||
}
|
||||
|
||||
// 场景级 checkpoint
|
||||
if err := t.store.MarkSceneComplete(a.Chapter, a.Scene); err != nil {
|
||||
return nil, fmt.Errorf("mark scene complete: %w", err)
|
||||
}
|
||||
|
||||
return json.Marshal(map[string]any{
|
||||
"written": true,
|
||||
"chapter": a.Chapter,
|
||||
"scene": a.Scene,
|
||||
"word_count": wordCount,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user