Changeset 0.29.3 (#198)

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit is contained in:
2026-03-18 00:15:18 +00:00
committed by xcaliber
parent 115004a3ab
commit 7f191e18cd
22 changed files with 1625 additions and 77 deletions

View File

@@ -1259,15 +1259,10 @@ func (h *CompletionHandler) conversationHasPersonaMessages(ctx context.Context,
// buildWorkflowFormHint loads the current workflow stage's form_template
// and returns a system message instructing the persona what to collect.
// Returns empty string if not a workflow or no template defined.
// v0.29.3: migrated from raw database.DB to stores, stage_mode aware.
func (h *CompletionHandler) buildWorkflowFormHint(ctx context.Context, channelID string) string {
var workflowID *string
var currentStage int
_ = database.DB.QueryRowContext(ctx, database.Q(`
SELECT workflow_id, COALESCE(current_stage, 0)
FROM channels WHERE id = $1 AND type = 'workflow'
`), channelID).Scan(&workflowID, &currentStage)
if workflowID == nil || *workflowID == "" {
ws, err := h.stores.Channels.GetWorkflowStatus(ctx, channelID)
if err != nil || ws == nil || ws.WorkflowID == nil || *ws.WorkflowID == "" {
return ""
}
@@ -1275,17 +1270,47 @@ func (h *CompletionHandler) buildWorkflowFormHint(ctx context.Context, channelID
return ""
}
stages, err := h.stores.Workflows.ListStages(ctx, *workflowID)
if err != nil || currentStage >= len(stages) {
stages, err := h.stores.Workflows.ListStages(ctx, *ws.WorkflowID)
if err != nil || ws.CurrentStage >= len(stages) {
return ""
}
stage := stages[ws.CurrentStage]
// v0.29.3: form_only stages don't use LLM — no hint needed
if stage.StageMode == models.StageModeFormOnly {
return ""
}
stage := stages[currentStage]
if len(stage.FormTemplate) == 0 || string(stage.FormTemplate) == "{}" {
return ""
}
// Parse form template to extract field descriptions
// v0.29.3: Try typed form template first
if tpl := models.ParseTypedFormTemplate(stage.FormTemplate); tpl != nil {
hint := "You are in workflow stage: " + stage.Name + ".\n\n"
if stage.StageMode == models.StageModeFormChat {
hint += "A form has been provided for the visitor to fill in structured data. " +
"You can assist them with questions about the form fields or discuss related topics.\n\n" +
"Form fields:\n"
} else {
hint += "Collect the following information from the user through natural conversation:\n\n"
}
for _, f := range tpl.Fields {
hint += "- " + f.Label
if f.Required {
hint += " (required)"
}
hint += "\n"
}
if stage.StageMode != models.StageModeFormChat {
hint += "\nWhen you have gathered all required information, call the workflow_advance tool " +
"with the collected data as a JSON object. Do not advance until all required fields are filled."
}
return hint
}
// Legacy format: map[string]interface{} with {description, required}
var fields map[string]interface{}
if err := json.Unmarshal(stage.FormTemplate, &fields); err != nil {
return ""