9 Commits
Author SHA1 Message Date
Shaojin Wen e98e4db75e perf(managed-agent): cache parsed statements on the MySQL pools by default (#16414)
Connector/J parses a statement's SQL on every prepareStatement unless its
per-connection parse cache is on, and that parse was the largest share of
the control plane's Java CPU under load. The server and embedded MySQL
pools now add cachePrepStmts=true, prepStmtCacheSize=512 and
prepStmtCacheSqlLimit=8192 as connection properties.

A connection property overrides the URL in Connector/J, so each setting is
added only when neither the URL nor the Druid connection properties name
it, ignoring case, percent-encoding and surrounding spaces. Nothing is
added when either names useServerPrepStmts or useCursorFetch, since the
cache would then hold statements open on the server.

The server pool binds spring.datasource.druid inside its factory, before
the defaults are added: @ConfigurationProperties bound it only after the
factory returned, and the string form of connection-properties replaces
every connection property.
2026-11-06 18:45:34 +00:00
jinyeandQwen-Coder e777fc7502 feat(managed-agent): enable automation by default (#16448)
* feat(managed-agent): enable automation by default

Co-authored-by: Qwen-Coder <[email protected]>

* style(docs): match pinned Prettier formatting

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-11-06 18:42:51 +08:00
jinye 07ed0e260e feat(managed-agent): support full model configuration at session creation (#16153)
* feat(managed-agent): support session model configuration

* codex: fix CI failure on PR #16153

* codex: address PR review feedback (#16153)

* codex: address PR review feedback (#16153)

* codex: address PR review feedback (#16153)

* codex: address PR review feedback (#16153)
2026-11-03 04:23:45 +00:00
jinyeandQwen-Coder 90eb13e4c6 refactor(managed-agent): Make runtime backends optional Maven modules (#16141)
* refactor(managed-agent): Split runtime backends into optional modules

Extract five backend implementations behind the shared provider SPI and support selected-backend executable distributions. Preserve SQL ownership, defer unavailable historical work, and make Spring own SSH connection cleanup.

Co-authored-by: Qwen-Coder <[email protected]>

* refactor(managed-agent): Narrow backend split to Maven modules

Keep optional backend dependencies and safe assembly while deferring selective standalone distributions. Restore default packaging and document the provider configuration.

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-11-03 02:04:43 +00:00
Shaojin Wen 43415ed8a4 docs(managed-agent): note the private CSI receipt exception and correct lease wording (#16000)
The artifacts.enabled row said committed tool receipts are always
recorded for projection. Sessions created through the private CSI lane
(csi-session) are the exception: ManagedSessionStore records receipts
only when the commit has no CSI original, and the projection claim skips
csi_guard Sessions as well.

The automation.lease row now counts the lease from the claim of each
definition rather than from a scanner tick, matching the scanner-threads
row. The AutomationLedgerStore Javadoc no longer says an expired lease
alone stops a writer: its writes check owner and fence, so they are
refused only once another writer claims the definition.
2026-10-31 18:14:56 +08:00
Shaojin Wen d33c1debc5 test(managed-agent): pin the OSS open retry on client timeouts (#15983)
* test(managed-agent): pin the OSS open retry on client timeouts

The configuration reference's read-timeout row (#15980) says that a
request to open a stored object that times out is retried up to three
times. Nothing tested it: the store retries a ClientException only when
its error code is in TRANSIENT_CLIENT_ERRORS, and the existing tests
covered OSS service errors and an unclassified ClientException, whose
one-argument constructor leaves the code null.

Add a socket timeout that recovers on the second attempt, and socket and
connection timeouts that persist through four attempts. Removing
SocketTimeout or ConnectionTimeout from the set, or never retrying in
the ClientException branch, now fails these tests; the other tests stay
green under each change.

* docs(managed-agent): leave the lease start point to the lease row

The scanner-threads row restated that a lease counts from its row's
claim, which automation.lease already says. Keep only the consequence
for a long tick and point at the lease row, so the start point has one
owner.

* test(managed-agent): say what the one-argument ClientException really sets

The timeout() helper's comment said the one-argument constructor leaves
the error code null. In aliyun-sdk-oss 3.18.4 it delegates to the
(String, Throwable) constructor, which stores the literal "Unknown"; only
the no-argument constructor leaves the code null. Such a fixture is
refused by the transient-set check, not by the null branch, so a reader
following the comment would cover the wrong operand.

* test(managed-agent): reach the null-code guard of the OSS read retry

The store's ClientException branch refuses to retry when the code is
null as well as when it is not transient. No fixture had a null code:
ClientException("unknown") carries "Unknown", and only the no-argument
constructor leaves the code null. Without the guard, Set.of(...)
.contains(null) throws NullPointerException instead of the neutral
ToolPublicationStorageException.

Add new ClientException() to the not-retried cases. Deleting the null
check now fails that test with the NPE from SetN.contains.

* test(managed-agent): pin the whole retry classification of the OSS read

Review rounds on #15983 kept finding one more unpinned operand of
AliyunToolPublicationObjectStore.read(). Cover the method's
classification in one place instead:

- every member of TRANSIENT_SERVICE_ERRORS and TRANSIENT_CLIENT_ERRORS
  is retried once and then succeeds;
- OSSException(String), whose code is null, joins the not-retried cases,
  so the null-code guards of both catch arms are reached;
- the two persistent-failure cases carry @Timeout(10), so a lost retry
  bound fails instead of hanging.

The ClientException helper is renamed clientError, since it now builds
more than timeouts. Removing any of the eight codes, either null-code
guard or either retry bound fails at least one test.
2026-10-31 15:42:30 +08:00
Shaojin Wen 107e1cfab1 docs(managed-agent): qualify the storage stall and keep the per-row lease note (#15980)
The read-timeout row said one storage read that receives nothing for 50
seconds ends a download. Only a stall in the object's content stream
does: opening the object retries a socket timeout up to three times while
the download's guard allows. Say that.

The scanner-threads row now keeps what the removed README table said:
each row's lease runs from its own claim, so a long tick hands out no
already-expired lease.
2026-10-31 12:42:19 +08:00
Shaojin Wen 5fc28ade51 docs(managed-agent): point the server README at the configuration reference (#15965)
The server README repeated three setting tables (O3 artifacts, H6
automation, Runtime retention), a commented block for two Broker settings
and the create-Session request that the deployment guide now carries.
Replace each with a link to the generated configuration reference or to
the guide's first-Session step, so a setting is described in one place.
The README's Session lifecycle examples move to the guide's `default`
tenant so they still find a Session created there.

Facts that only the README had move into configuration-descriptions.json
after checking them against the code: receipts are recorded for projection
while artifacts.enabled is false; a stalled storage read (the OSS client's
default 50-second socket timeout) or a lapsed read lease between chunks
ends a download whatever read-timeout says; what a revocation still lets
through; the automation fence after a reclaim; the slot walk that the
per-tick limit does not shorten; the Harness's fixed 30-minute Tool v3
wait; and the Broker listener's lack of per-tenant authorization. The
README's claim that the two-minute read lease caps read-timeout is not
carried over: the lease renews per chunk.
2026-10-31 11:42:10 +08:00
Shaojin Wen e7fe14ee83 docs(managed-agent): generate the server configuration reference from its metadata (#15939)
* docs(managed-agent): generate the server configuration reference from its metadata

The server has about 180 settings, 84 of them mapped to QWEN_MANAGED_AGENT_*
variables, and no list of them with their variables, defaults and limits:
operators read a 2000-line developer README for them.

- The server module runs spring-boot-configuration-processor once more,
  over ManagedAgentProperties only (the two Druid beans share a prefix,
  which the processor refuses), and writes the configuration metadata.
  The compiled classes are unchanged. runtime-broker.ssh is marked
  @NestedConfigurationProperty, and STRICT_HARNESS_KEYS @Getter(NONE), so
  the metadata lists the one and not the other.
- configuration-descriptions.json holds an English and a Chinese
  description for each setting and section.
- scripts/generate-managed-agent-configuration-reference.mjs writes
  docs/users/managed-agent-configuration-reference{,.zh-CN}.md from the
  metadata, the packaged application.yml (variables and defaults), the
  ${qwen.managed-agent.*} placeholders in the main sources (settings read
  outside the properties class) and the descriptions. --check fails on a
  setting without a description, a description of no setting, or a stale
  page; the reference workflow runs it after the Java build.
- The archive ships the pages as docs/configuration{,.zh-CN}.md, and the
  deployment guide and the README link them.

* fix(managed-agent): link the shipped documents by their archive names

The archive renames each document it ships, so a link written against
the repository, such as the configuration reference's language switch or
the guide's link to it, named a file the archive does not have. The
packager now points every link between shipped documents at the
document's name in the archive and leaves every other link as written.

* build(managed-agent): take the configuration processor's version from the BOM

spring-boot.version is defined nowhere in this build, so the processor
path's <version> only resolved because the compiler plugin falls back to
dependency management. Say so by naming no version.

* test(managed-agent): name no tracked Markdown in a link fixture

classify-profile.test.mjs requires every Markdown file a test names to be
in TEST_READ_MARKDOWN, and the kept-link fixture's docs/runtime-broker.md
matched packages/managed-agent-server/docs/runtime-broker.md, which no
test reads. The fixture only needs a link to a file the archive does not
ship, so it names one that does not exist.
2026-10-31 03:23:30 +08:00