feat: Enhance AI Agent and Channel Management
- 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.
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
// 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)
|
||||
}
|
||||
Reference in New Issue
Block a user