Skip to content

Add AI-powered documentation generation (core)#3302

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

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

Conversation

@mjwolf
Copy link
Copy Markdown
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
Comment thread internal/llmagent/docagent/agents/critic.go
Comment thread internal/llmagent/docagent/agents/critic.go
Comment thread internal/llmagent/docagent/agents/registry.go
Comment thread internal/llmagent/docagent/prompts/_static/agent_instructions.md Outdated
Comment thread internal/llmagent/docagent/docagent.go
Comment thread internal/llmagent/docagent/docagent.go Outdated
Comment thread internal/llmagent/docagent/docagent.go Outdated
Comment thread internal/packages/archetype/_static/package-docs-readme.md.tmpl Outdated
Comment thread cmd/update.go Outdated
Comment thread internal/llmagent/docagent/workflow/workflow.go Outdated
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
Comment thread internal/llmagent/docagent/agents/validators/stylevalidator.go Outdated
Comment thread internal/llmagent/docagent/prompts/stylerules.go Outdated
Comment thread internal/llmagent/docagent/agents/validators/urlvalidator.go
Comment thread internal/llmagent/docagent/promptsbuilder.go Outdated
Comment thread internal/llmagent/docagent/promptsbuilder.go Outdated
@mjwolf mjwolf requested a review from vinit-chauhan March 12, 2026 00:06
Copy link
Copy Markdown
Contributor

@vinit-chauhan vinit-chauhan left a comment

Choose a reason for hiding this comment

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

LGTM

@elasticmachine
Copy link
Copy Markdown
Collaborator

elasticmachine commented Apr 6, 2026

⏳ Build in-progress, with failures

Failed CI Steps

History

cc @mjwolf @vinit-chauhan

Copy link
Copy Markdown
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

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

Thanks for the work here!

Reviewing by now only the code out of internal/llmagent. Regarding the parts under cmd, I would try to keep them minimal, moving LLM specific parts to internal packages. Also, try to reuse existing helpers for documentation, in consistency with other commands.

Comment thread .github/CODEOWNERS
internal/stack/versions.go @elastic/ecosystem

# LLM based functionality owned by integration-experience
internal/llmagent/ @elastic/integration-experience
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍

Comment on lines +35 to +36
- LLM_PROVIDER / llm.provider: Provider name (only Gemini provider currently supported).
- Gemini: GOOGLE_API_KEY / llm.gemini.api_key, GEMINI_MODEL / llm.gemini.model, GEMINI_THINKING_BUDGET / llm.gemini.thinking_budget`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We use to prefix environment variables supported by elastic-package with ELASTIC_PACKAGE_, using environment.WithElasticPackagePrefix. Maybe we don't need to do this for the provider specific variables, but we should probably use this for LLM_PROVIDER.

}

// getLLMConfig returns provider, api key, model ID, and optional thinking budget.
func getLLMConfig(profile *profile.Profile) (provider, apiKey, modelID string, thinkingBudget *int32) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit. Consider returning an struct instead of so many values.

}

// getLLMConfig returns provider, api key, model ID, and optional thinking budget.
func getLLMConfig(profile *profile.Profile) (provider, apiKey, modelID string, thinkingBudget *int32) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit. Consider moving LLM specific helpers to some internal package.

provider = defaultProvider
}
if provider != defaultProvider {
apiKey = getConfigValue(profile, "", "llm."+provider+".api_key", "")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

profile.Config could be directly used here, right?

Suggested change
apiKey = getConfigValue(profile, "", "llm."+provider+".api_key", "")
apiKey = profile.Config("llm."+provider+".api_key", "")

FieldsCacheName = "fields"
KibanaConfigCacheName = "kibana_config"

llm = "llm_config"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use the Dir suffix as other constants here. And the _config suffix may be redundant in this context.

Suggested change
llm = "llm_config"
llmDir = "llm"

KibanaConfigCacheName = "kibana_config"

llm = "llm_config"
mcpJson = "mcp.json"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
mcpJson = "mcp.json"
mcpJsonName = "mcp.json"

Comment on lines +107 to +110
// MCPJson returns the file location for the MCP server configuration
func (loc LocationManager) MCPJson() string {
return filepath.Join(loc.LLMDir(), mcpJson)
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit. Maybe we don't need to be so specific to have a method for mcp.json file. Other internal packages manage their files inside directories given by locations.

Comment thread README.md
* `stack.fleet_auto_install_task_interval` sets the interval for the Fleet auto-install content packages task.
Supported in Kibana 9.2 and later. Defaults to "10m".

### AI-powered Documentation Configuration
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider moving this section to a file under docs/howto.

Comment thread .gitignore

.cursor/

batch_results/ No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is batch_results?

@jsoriano
Copy link
Copy Markdown
Member

jsoriano commented Apr 9, 2026

CI failures are not related, we have skipped them by now, you can update your branch to get green build.

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.

5 participants