Summary
Tool.createWithDocs returns empty parameter descriptions for a very common F# doc-comment style, even on 0.2.0 where #10 is fixed. The cause is on the F# compiler side, not in AgentNet, but it silently defeats <param> extraction and is worth documenting in the README.
What happens
The F# compiler has two modes for a /// block:
- If the first non-blank character is
<, the block is treated as XML you wrote and emitted verbatim.
- Otherwise the whole block is treated as plain text: it is wrapped in an implicit
<summary> and its contents are XML-escaped.
So a prose-first block with <param> lines, which is how most people write them:
/// Switches the weekly timesheet view to a specific week.
/// <param name="input">One of: "current", "last", "next", or an ISO date within the desired week.</param>
let selectWeek (deps: IProvider) (input: string) : Task<string> = ...
compiles to this in the assembly's .xml doc file:
<member name="M:TimeBotTools.selectWeek(IProvider,System.String)">
<summary>
Switches the weekly timesheet view to a specific week.
<param name="input">One of: "current", "last", "next", or an ISO date within the desired week.</param>
</summary>
</member>
createWithDocs reads the <summary> child (works, so the tool description is fine) and looks for <param> children of <member> (none exist), so every ParamInfo.Description is "". As a bonus the model receives the escaped param text as trailing prose inside the tool description, which masks the problem: routing mostly still works, so nobody notices.
What works
Start the block with an explicit <summary> and close it before the first <param>:
/// <summary>
/// Switches the weekly timesheet view to a specific week.
/// </summary>
/// <param name="input">One of: "current", "last", "next", or an ISO date within the desired week.</param>
let selectWeek (deps: IProvider) (input: string) : Task<string> = ...
which compiles to a real <summary> element followed by a real <param> element, and createWithDocs picks up both.
A prose-only block with no <param> lines is fine as is; the implicit summary is exactly what the extractor wants.
Suggested README note
Something like:
XML doc comments in F#. If a tool's doc comment includes <param> lines, the comment must start with an explicit <summary> tag. The F# compiler only emits a /// block as XML when it begins with an element; a block that starts with prose is wrapped in an implicit summary with its contents escaped, so the <param> tags never reach the doc file and the parameter descriptions come back empty. A summary-only comment needs no tags.
Optionally the compiler can enforce it: <WarnOn>3390</WarnOn> in the project file turns on XML doc validation, which flags malformed structures at build time.
Context
Found while upgrading TimeBridge to 0.2.0 and pinning #10 with a test that asserts every model-facing parameter has a non-empty description. The test failed on 0.2.0 too until the doc comments were rewritten in the explicit form; the same test passes after that change. Happy to send a README PR if you would rather.
Summary
Tool.createWithDocsreturns empty parameter descriptions for a very common F# doc-comment style, even on 0.2.0 where #10 is fixed. The cause is on the F# compiler side, not in AgentNet, but it silently defeats<param>extraction and is worth documenting in the README.What happens
The F# compiler has two modes for a
///block:<, the block is treated as XML you wrote and emitted verbatim.<summary>and its contents are XML-escaped.So a prose-first block with
<param>lines, which is how most people write them:compiles to this in the assembly's
.xmldoc file:createWithDocsreads the<summary>child (works, so the tool description is fine) and looks for<param>children of<member>(none exist), so everyParamInfo.Descriptionis"". As a bonus the model receives the escaped param text as trailing prose inside the tool description, which masks the problem: routing mostly still works, so nobody notices.What works
Start the block with an explicit
<summary>and close it before the first<param>:which compiles to a real
<summary>element followed by a real<param>element, andcreateWithDocspicks up both.A prose-only block with no
<param>lines is fine as is; the implicit summary is exactly what the extractor wants.Suggested README note
Something like:
Optionally the compiler can enforce it:
<WarnOn>3390</WarnOn>in the project file turns on XML doc validation, which flags malformed structures at build time.Context
Found while upgrading TimeBridge to 0.2.0 and pinning #10 with a test that asserts every model-facing parameter has a non-empty description. The test failed on 0.2.0 too until the doc comments were rewritten in the explicit form; the same test passes after that change. Happy to send a README PR if you would rather.