Refactor buildRequestMessage to use structured JSON format for agent communication
- Updated the buildRequestMessage function to construct a JSON object for structured communication with the agent, replacing the previous string formatting approach. - Enhanced the handling of extra parameters, scenarios, and retry context by incorporating them into the JSON structure. - Improved the parseResult function to extract additional fields such as explain and warnings from the response, ensuring comprehensive result handling. - Streamlined the code for better readability and maintainability while preserving existing functionality.
This commit is contained in:
parent
1d965420ad
commit
01bf7dce58
1 changed files with 43 additions and 26 deletions
|
|
@ -103,35 +103,43 @@ func (p *AgentProvider) Generate(ctx *agentContext.Context, input *Input) (*Resu
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildRequestMessage constructs the request message for the agent
|
// buildRequestMessage constructs the request message for the agent
|
||||||
// Format follows the querydsl agent prompts.yml:
|
// Returns JSON format for structured communication with the agent
|
||||||
// "用户查询\nSchema:\n{schema JSON}"
|
|
||||||
func (p *AgentProvider) buildRequestMessage(input *Input, attempt int, lastLintErrors string) string {
|
func (p *AgentProvider) buildRequestMessage(input *Input, attempt int, lastLintErrors string) string {
|
||||||
// Build schema from extra params if provided
|
// Build request data as JSON
|
||||||
var schemaJSON string
|
requestData := map[string]interface{}{
|
||||||
if input.ExtraParams != nil {
|
"query": input.Query,
|
||||||
if schema, ok := input.ExtraParams["schema"]; ok {
|
"models": input.ModelIDs,
|
||||||
schemaBytes, _ := json.Marshal(schema)
|
"limit": input.Limit,
|
||||||
schemaJSON = string(schemaBytes)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build message in the expected format
|
// Add schema from extra params if provided
|
||||||
message := input.Query
|
if input.ExtraParams != nil {
|
||||||
if schemaJSON != "" {
|
if schema, ok := input.ExtraParams["schema"]; ok {
|
||||||
message = fmt.Sprintf("%s\nSchema:\n%s", input.Query, schemaJSON)
|
requestData["schema"] = schema
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add scenario hint if specified (filter, aggregation, join, complex)
|
// Add scenario hint if specified (filter, aggregation, join, complex)
|
||||||
if input.Scenario != "" {
|
if input.Scenario != "" {
|
||||||
message = fmt.Sprintf("%s\nScenario: %s", message, input.Scenario)
|
requestData["scenario"] = string(input.Scenario)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add allowed fields if specified
|
||||||
|
if len(input.AllowedFields) > 0 {
|
||||||
|
requestData["allowed_fields"] = input.AllowedFields
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add retry context if this is a retry attempt
|
// Add retry context if this is a retry attempt
|
||||||
if attempt > 1 && lastLintErrors != "" {
|
if attempt > 1 && lastLintErrors != "" {
|
||||||
message = fmt.Sprintf("%s\n\nPrevious attempt failed with errors:\n%s\n\nPlease fix the errors and regenerate.", message, lastLintErrors)
|
requestData["retry"] = map[string]interface{}{
|
||||||
|
"attempt": attempt,
|
||||||
|
"lint_errors": lastLintErrors,
|
||||||
|
"instructions": "The previous QueryDSL was invalid. Please fix the errors and regenerate.",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return message
|
jsonBytes, _ := json.Marshal(requestData)
|
||||||
|
return string(jsonBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateDSL validates the generated QueryDSL using the linter
|
// validateDSL validates the generated QueryDSL using the linter
|
||||||
|
|
@ -158,12 +166,11 @@ func (p *AgentProvider) parseResult(result interface{}) (*Result, error) {
|
||||||
|
|
||||||
// Handle *context.Response directly (most common case from Stream())
|
// Handle *context.Response directly (most common case from Stream())
|
||||||
if resp, ok := result.(*agentContext.Response); ok {
|
if resp, ok := result.(*agentContext.Response); ok {
|
||||||
genResult := &Result{}
|
|
||||||
if resp.Next != nil {
|
if resp.Next != nil {
|
||||||
// Next contains the QueryDSL from hook
|
// Next contains the hook response, recursively parse it
|
||||||
genResult.DSL = p.extractDSL(resp.Next)
|
return p.parseResult(resp.Next)
|
||||||
}
|
}
|
||||||
return genResult, nil
|
return &Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to convert to map first
|
// Try to convert to map first
|
||||||
|
|
@ -238,12 +245,22 @@ func (p *AgentProvider) parseResult(result interface{}) (*Result, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for "dsl" field wrapper
|
// Check for "dsl" field wrapper: { dsl: {...} }
|
||||||
if dsl, ok := data["dsl"]; ok {
|
if dsl, ok := data["dsl"]; ok {
|
||||||
genResult.DSL = p.extractDSL(dsl)
|
genResult.DSL = p.extractDSL(dsl)
|
||||||
} else if d, ok := data["data"]; ok {
|
if explain, ok := data["explain"].(string); ok {
|
||||||
|
genResult.Explain = explain
|
||||||
|
}
|
||||||
|
if warnings, ok := data["warnings"]; ok {
|
||||||
|
genResult.Warnings = p.extractWarnings(warnings)
|
||||||
|
}
|
||||||
|
return genResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for "data" field wrapper: { data: { dsl: {...}, explain: "...", warnings: [] } }
|
||||||
|
if d, ok := data["data"]; ok {
|
||||||
if dm, ok := d.(map[string]interface{}); ok {
|
if dm, ok := d.(map[string]interface{}); ok {
|
||||||
// Check if data.data is a wrapped DSL: { dsl: {...} }
|
// Check if data.data contains dsl field: { data: { dsl: {...} } }
|
||||||
if dsl, ok := dm["dsl"]; ok {
|
if dsl, ok := dm["dsl"]; ok {
|
||||||
genResult.DSL = p.extractDSL(dsl)
|
genResult.DSL = p.extractDSL(dsl)
|
||||||
} else if _, hasFrom := dm["from"]; hasFrom {
|
} else if _, hasFrom := dm["from"]; hasFrom {
|
||||||
|
|
@ -253,21 +270,21 @@ func (p *AgentProvider) parseResult(result interface{}) (*Result, error) {
|
||||||
// data.data is directly a QueryDSL
|
// data.data is directly a QueryDSL
|
||||||
genResult.DSL = p.extractDSL(dm)
|
genResult.DSL = p.extractDSL(dm)
|
||||||
}
|
}
|
||||||
|
// Extract explain and warnings from data.data
|
||||||
if explain, ok := dm["explain"].(string); ok {
|
if explain, ok := dm["explain"].(string); ok {
|
||||||
genResult.Explain = explain
|
genResult.Explain = explain
|
||||||
}
|
}
|
||||||
if warnings, ok := dm["warnings"]; ok {
|
if warnings, ok := dm["warnings"]; ok {
|
||||||
genResult.Warnings = p.extractWarnings(warnings)
|
genResult.Warnings = p.extractWarnings(warnings)
|
||||||
}
|
}
|
||||||
|
return genResult, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get explain if present
|
// Fallback: Get explain and warnings from top level
|
||||||
if explain, ok := data["explain"].(string); ok {
|
if explain, ok := data["explain"].(string); ok {
|
||||||
genResult.Explain = explain
|
genResult.Explain = explain
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get warnings if present
|
|
||||||
if warnings, ok := data["warnings"]; ok {
|
if warnings, ok := data["warnings"]; ok {
|
||||||
genResult.Warnings = p.extractWarnings(warnings)
|
genResult.Warnings = p.extractWarnings(warnings)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue