Skip to content

Add AI-powered documentation generation (core)#3302

Open
mjwolf wants to merge 7 commits intoelastic:mainfrom
mjwolf:doc_update_1
Open

Add AI-powered documentation generation (core)#3302
mjwolf wants to merge 7 commits intoelastic:mainfrom
mjwolf:doc_update_1

Conversation

@mjwolf
Copy link
Contributor

@mjwolf mjwolf commented Feb 24, 2026

Add the elastic-package update documentation command that uses an LLM (Gemini) to generate package documentation via a section-based generate-validate workflow.

Core components:

  • docagent: orchestrates documentation generation with per-section validation loops, response analysis, and section normalization
  • executor: ADK-based LLM executor with tool support
  • workflow: multi-agent pipeline (generator, critic, validators)
  • validators: static and LLM-based validators for structure, completeness, accuracy, accessibility, style, placeholders, URLs
  • parsing: markdown section parser and combiner
  • prompts: embedded prompt templates and section-specific instructions
  • tools: package file tools (list_directory, read_file, write_file, get_example, get_service_info)
  • postprocessor: data stream template and agentless section enforcement

Co-authored-by: Jonathan Molinatto <jonathan.molinatto@gmail.com>
Co-authored-by: Quan Nguyen <quan.nguyen@elastic.co>
Co-authored-by: Cursor <cursoragent@cursor.com>
@mjwolf mjwolf self-assigned this Feb 24, 2026
@mjwolf mjwolf requested a review from a team as a code owner February 24, 2026 02:15
@mjwolf mjwolf added enhancement New feature or request Team:Ecosystem Label for the Packages Ecosystem team labels Feb 24, 2026
## Evaluation Criteria
Evaluate against these criteria (rate each 1-10):

1. **Voice/Tone**: Friendly, uses "you", contractions, active voice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure this coincides with the vale rules

3. **Grammar**: American English, present tense, Oxford comma, sentence case headings
- Sentence case: "### Vendor-specific issues" NOT "### Vendor-Specific Issues"

4. **Structure**: Clear summary, scannable sections, short paragraphs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add the avoid 'via' here?

if _, exists := r.agents[name]; !exists {
r.order = append(r.order, name)
}
r.agents[name] = agent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could probably move this inside the if block, too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is right as it is. If the agent already exists with the name, the last line will replace it with the new one. If it was moved in, this couldn't modify the agent if the name already exists.

@@ -0,0 +1,142 @@
# Style guide for Elastic integration documentation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this still used? i saw a similar prompt in the generator code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was still needed, it's used as the system prompt when making revisions.

I think it wasn't in a good location though, it's not clear what the use was. I reorganized all the prompts to keep them closer to the location where they're used, and I've added more of the Vale rules to the generator and validator instructions, so a lot of the code around the prompts has been changed and reorganized now.

// ConfirmInstructionsUnderstood asks the LLM to confirm it understood the system instructions.
// This should be called before any documentation workflow to ensure proper adherence.
func (d *DocumentationAgent) ConfirmInstructionsUnderstood(ctx context.Context) error {
fmt.Println("🔍 Verifying LLM understands documentation guidelines...")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you found this necessary? it seems like it would just waste context and another LLM call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I haven't ever seen a difference without this, and I've never seen the LLM respond that it doesn't understand. I'll take out this prompt.

}

// Skip AI-generated notice
if strings.HasPrefix(line, "> **Note**: This documentation was generated") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might need updated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this to the new prompt

// GenerateAllSectionsWithWorkflow generates all sections using the multi-agent workflow.
// This method uses a configurable pipeline of agents (generator, critic, validator, etc.)
// to iteratively refine each section. Sections are generated in parallel.
func (d *DocumentationAgent) GenerateAllSectionsWithWorkflow(ctx context.Context, workflowCfg workflow.Config) ([]Section, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't seem to be used. is this used somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it wasn't used, I've removed it.

*/}}

## Scaling
### Vendor resources
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we keeping links in only 2 places, next to setup steps and at the end. So should we remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I removed it. There's almost never troubleshooting specific documentation available, so this section isn't useful.

cmd/update.go Outdated
cmd.AddCommand(updateDocumentationCmd)
cmd.PersistentFlags().StringP(cobraext.ProfileFlagName, "p", "", fmt.Sprintf(cobraext.ProfileFlagDescription, install.ProfileNameEnvVar))

return cobraext.NewCommand(cmd, cobraext.ContextGlobal)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of any scenario where we would run it outside of a Package. Should we change the context to cobraext.ContextPackage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I changed this to ContextPackage

var outputs []string

// Track input for LLM span
inputMessages := []tracing.Message{{Role: "user", Content: truncate(prompt, truncateLen)}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not truncate messages used for Tracing. For logs it's okay, but if we do it in traces, it would reduce visibility.

Same comment for L281 ( outputMessagers )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not truncate messages used for Tracing. For logs it's okay, but if we do it in traces, it would reduce visibility.

Same comment for L281 ( outputMessagers )

I've removed truncate from the tracing, and it's only used for debug logging now.

mjwolf added 4 commits March 6, 2026 10:39
Add broader inclusive-language checks (disability-defining terms, gendered
job titles, execute/abort variants), Git conflict marker detection, and
new static style checks (banned words, latinisms, exclamation points,
ellipses, version terms, article misuse). Extend style-rule prompts with
wordiness, negation, and device-agnostic language guidance. Remove unused
parallel generation helpers and trim the readme template.

Made-with: Cursor
Move stylerules/ into prompts/ (now a dependency-free leaf package),
relocate sectioninstructions.go to docagent/ (its only consumer),
drop the _static/ subdirectory, compose AgentInstructions from
FullFormattingRules to eliminate duplication, and extract shared
validator JSON output suffix into prompts.ValidatorOutputSuffix.

Made-with: Cursor
@mjwolf mjwolf requested review from jrmolin and vinit-chauhan March 6, 2026 21:42
@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @mjwolf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Team:Ecosystem Label for the Packages Ecosystem team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants