34051a4631
- Updated labels in the AI Agents dashboard for clarity, changing "流程状态" to "Playbook 状态" and "未发布流程" to "未发布 Playbook". - Introduced AI Agent rollout percentage management in channel editing, allowing users to set and rollback rollout percentages. - Added new API endpoints for rolling back AI Agent rollout and fetching agent run metrics. - Implemented new UI components for displaying agent run details, including status, duration, and input/output tokens. - Enhanced type definitions for AdminChannel and AIAgent to include rollout percentages and runtime modes. - Updated navigation to include a section for agent runs. - Added new translations for agent run features in both English and Chinese.
87 lines
3.0 KiB
Go
87 lines
3.0 KiB
Go
// Package einoexperiment contains an isolated Eino ReAct verification path.
|
|
// It must not be registered in the production Agent Engine registry.
|
|
package einoexperiment
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"agent-desk/internal/models"
|
|
|
|
einoopenai "github.com/cloudwego/eino-ext/components/model/openai"
|
|
"github.com/cloudwego/eino/components/model"
|
|
"github.com/cloudwego/eino/components/tool"
|
|
"github.com/cloudwego/eino/compose"
|
|
"github.com/cloudwego/eino/flow/agent/react"
|
|
"github.com/cloudwego/eino/schema"
|
|
)
|
|
|
|
// ReActConfig keeps the experiment dependency-injected. The caller owns model
|
|
// construction, connection reuse, and all production configuration decisions.
|
|
type ReActConfig struct {
|
|
Model model.ToolCallingChatModel
|
|
Tools []tool.BaseTool
|
|
MaxSteps int
|
|
}
|
|
|
|
// NewOpenAICompatibleModel adapts an existing AgentDesk AI configuration to
|
|
// Eino's OpenAI-compatible chat model. It is intentionally not wired into any
|
|
// production Engine; the experiment owns the adoption decision.
|
|
func NewOpenAICompatibleModel(ctx context.Context, config models.AIConfig) (model.ToolCallingChatModel, error) {
|
|
if strings.TrimSpace(config.APIKey) == "" || strings.TrimSpace(config.BaseURL) == "" || strings.TrimSpace(config.ModelName) == "" {
|
|
return nil, fmt.Errorf("ai config base URL, API key, and model name are required")
|
|
}
|
|
modelConfig := &einoopenai.ChatModelConfig{
|
|
APIKey: strings.TrimSpace(config.APIKey),
|
|
BaseURL: strings.TrimSpace(config.BaseURL),
|
|
Model: strings.TrimSpace(config.ModelName),
|
|
}
|
|
if config.TimeoutMS > 0 {
|
|
modelConfig.Timeout = time.Duration(config.TimeoutMS) * time.Millisecond
|
|
}
|
|
if config.MaxOutputTokens > 0 {
|
|
maxTokens := config.MaxOutputTokens
|
|
modelConfig.MaxCompletionTokens = &maxTokens
|
|
}
|
|
return einoopenai.NewChatModel(ctx, modelConfig)
|
|
}
|
|
|
|
// NewReAct creates an Eino ReAct agent without registering it with AgentDesk's
|
|
// runtime. It is deliberately suitable only for technical verification.
|
|
func NewReAct(ctx context.Context, config ReActConfig) (*react.Agent, error) {
|
|
if config.Model == nil {
|
|
return nil, fmt.Errorf("eino experiment model is required")
|
|
}
|
|
maxSteps := config.MaxSteps
|
|
if maxSteps <= 0 {
|
|
maxSteps = 5
|
|
}
|
|
return react.NewAgent(ctx, &react.AgentConfig{
|
|
ToolCallingModel: config.Model,
|
|
ToolsConfig: compose.ToolsNodeConfig{Tools: config.Tools},
|
|
MaxStep: maxSteps,
|
|
})
|
|
}
|
|
|
|
// Run performs one non-streaming experiment. Context cancellation is passed
|
|
// directly to Eino and the injected model/tools.
|
|
func Run(ctx context.Context, config ReActConfig, input []*schema.Message) (*schema.Message, error) {
|
|
agent, err := NewReAct(ctx, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return agent.Generate(ctx, input)
|
|
}
|
|
|
|
// Stream performs one streaming experiment. The caller must close the returned
|
|
// reader after consuming it.
|
|
func Stream(ctx context.Context, config ReActConfig, input []*schema.Message) (*schema.StreamReader[*schema.Message], error) {
|
|
agent, err := NewReAct(ctx, config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return agent.Stream(ctx, input)
|
|
}
|