mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-14 08:58:27 +08:00
feat(api): implement GET /api/v1/agents/prompts endpoint in Go (#15748)
### Description
This PR ports the `GET /api/v1/agents/prompts` endpoint from the Python
backend to the Go backend.
### Changes Made
- **Handler**: Added `GetPrompts` method to `internal/handler/agent.go`.
- **Router**: Registered the `agents.GET("/prompts")` route in
`internal/router/router.go`.
- **Logic**: Leveraged the existing `service.LoadPrompt` utility to read
`analyze_task_system`, `analyze_task_user`, `next_step`, `reflect`, and
`citation_prompt` templates directly from the `rag/prompts` directory.
- **Unit Test**: Added `TestGetPrompts_Success` to
`internal/handler/agent_test.go` to mock the HTTP context and validate
the JSON response structure.
### Motivation
This is part of the ongoing effort to port the Agent API surface to Go.
Since this specific endpoint only serves static prompt templates and
does not require the complex DAG/Canvas execution engine, it can be
seamlessly and safely handled by the Go backend.
### Testing
- [x] Added automated unit test `TestGetPrompts_Success` (verified
passing).
- [x] Tested locally via `curl` against the Go server (port 9380) and
Python server (port 9384).
- [x] Verified that the Go JSON response structure and loaded prompt
text are logically 100% identical to the Python implementation.
This commit is contained in:
@@ -570,3 +570,55 @@ func (h *AgentHandler) UpdateAgentTags(c *gin.Context) {
|
||||
"message": "success",
|
||||
})
|
||||
}
|
||||
|
||||
// GetPrompts returns the default prompts used by the agent.
|
||||
// @Summary Get Agent Prompts
|
||||
// @Description Returns the default prompts used by the agent, such as task analysis, plan generation, reflection, and citation guidelines.
|
||||
// @Tags agents
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/agents/prompts [get]
|
||||
func (h *AgentHandler) GetPrompts(c *gin.Context) {
|
||||
if _, errorCode, errorMessage := GetUser(c); errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
taskAnalysisSys, err := service.LoadPrompt("analyze_task_system")
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeServerError, err.Error())
|
||||
return
|
||||
}
|
||||
taskAnalysisUser, err := service.LoadPrompt("analyze_task_user")
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeServerError, err.Error())
|
||||
return
|
||||
}
|
||||
planGeneration, err := service.LoadPrompt("next_step")
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeServerError, err.Error())
|
||||
return
|
||||
}
|
||||
reflection, err := service.LoadPrompt("reflect")
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeServerError, err.Error())
|
||||
return
|
||||
}
|
||||
citationGuidelines, err := service.LoadPrompt("citation_prompt")
|
||||
if err != nil {
|
||||
jsonError(c, common.CodeServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeSuccess,
|
||||
"data": map[string]string{
|
||||
"task_analysis": fmt.Sprintf("%s\n\n%s", taskAnalysisSys, taskAnalysisUser),
|
||||
"plan_generation": planGeneration,
|
||||
"reflection": reflection,
|
||||
"citation_guidelines": citationGuidelines,
|
||||
},
|
||||
"message": "success",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -769,3 +769,38 @@ func TestListAgentTemplates_RequiresAuth(t *testing.T) {
|
||||
t.Errorf("expected non-success without auth, got body=%v", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPrompts_Success(t *testing.T) {
|
||||
c, w, _ := setupGinContextWithUserAndDB(t, http.MethodGet, "/api/v1/agents/prompts")
|
||||
|
||||
// Create handler with fake or real service.
|
||||
h := NewAgentHandler(service.NewAgentService(), nil)
|
||||
h.GetPrompts(c)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
|
||||
var resp map[string]interface{}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
code, _ := resp["code"].(float64)
|
||||
if code != float64(common.CodeSuccess) {
|
||||
t.Fatalf("expected code 0, got %v: %v", code, resp["message"])
|
||||
}
|
||||
|
||||
data, ok := resp["data"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("expected data map, got %T", resp["data"])
|
||||
}
|
||||
|
||||
// Check if keys exist
|
||||
expectedKeys := []string{"task_analysis", "plan_generation", "reflection", "citation_guidelines"}
|
||||
for _, key := range expectedKeys {
|
||||
if _, ok := data[key]; !ok {
|
||||
t.Errorf("expected key %s in data", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,6 +384,7 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
agents := v1.Group("/agents")
|
||||
{
|
||||
agents.GET("", r.agentHandler.ListAgents)
|
||||
agents.GET("/prompts", r.agentHandler.GetPrompts)
|
||||
agents.GET("/templates", r.agentHandler.ListTemplates)
|
||||
agents.GET("/:agent_id/versions", r.agentHandler.ListAgentVersions)
|
||||
agents.GET("/:agent_id/versions/:version_id", r.agentHandler.GetAgentVersion)
|
||||
|
||||
Reference in New Issue
Block a user