Merge branch 'codex/invariant-package-registration-gate' into codex/package-invariant-checks
# Conflicts: # .agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.i18n.yaml # .agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.md # .agents/notes/implemented/architecture/2026-07-19-package-invariant-runtime-contracts.zh.md # .agents/notes/implemented/architecture/2026-07-19-package-owned-invariant-service.i18n.yaml # docs/rfc/INDEX.md # packages/AGENTS.md
This commit is contained in:
@@ -40,48 +40,88 @@ The tool never calls a provider's `available()` and never enumerates providers
|
||||
|
||||
### System prompt
|
||||
|
||||
**What the model sees**: Search and fetch contribute the web-search and web-fetch guidance below. A scoped tool restriction does not remove these independently registered sections.
|
||||
#### What the model sees
|
||||
|
||||
**Token effect**: Fixed guidance cost per request for each config-enabled tool, even when a restriction hides its schema.
|
||||
Search and fetch contribute the web-search and web-fetch guidance below. A scoped tool restriction does not remove these independently registered sections.
|
||||
|
||||
#### Web search guidance
|
||||
##### Web search guidance
|
||||
|
||||
```markdown
|
||||
Use the web_search tool to discover current information on the web. It returns an optional answer plus a list of source URLs. Follow up with web_fetch when you need the full content of a specific result, and cite the relevant URLs as markdown links.
|
||||
```
|
||||
|
||||
#### Web fetch guidance
|
||||
##### Web fetch guidance
|
||||
|
||||
```markdown
|
||||
Use the web_fetch tool to retrieve the content of a specific HTTP(S) URL (for example a result from web_search). It returns the page content decoded to text. Cite the URL as a markdown link when you use its content.
|
||||
```
|
||||
|
||||
#### Token effect
|
||||
|
||||
Fixed guidance cost per request for each config-enabled tool, even when a restriction hides its schema.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
Prefix-stable while enabled tools, scope, and guidance text are unchanged. Config enablement or plugin lifecycle may invalidate reuse from the first changed prompt section; scoped schema restrictions do not remove it.
|
||||
|
||||
### Tool schemas
|
||||
|
||||
**What the model sees**: The model sees the generated [`web_search` and `web_fetch` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-web). Result-count and timeout budgets are deployment settings, not model arguments.
|
||||
#### What the model sees
|
||||
|
||||
**Token effect**: Fixed schema cost per request; config disablement removes both schema and guidance, while a scoped restriction removes only the schema.
|
||||
The model sees the generated [`web_search` and `web_fetch` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-web). Result-count and timeout budgets are deployment settings, not model arguments.
|
||||
|
||||
#### Token effect
|
||||
|
||||
Fixed schema cost per request; config disablement removes both schema and guidance, while a scoped restriction removes only the schema.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
Prefix-stable while definitions and visibility are unchanged. Config enablement, plugin lifecycle, or scoped restrictions may invalidate reuse from the first changed schema token.
|
||||
|
||||
### Search result
|
||||
|
||||
**What the model sees**: The optional provider-owned answer is followed by `Sources:` and data-dependent lines shaped exactly `- [<title-or-url>](<url>)`, optionally suffixed ` — <snippet> (<publishedAt>)`. With neither answer nor sources the result says `No results found.` A capped list adds `(Showing the first <count> sources. Refine the query for more.)`; every result ends `Cite the relevant URLs above as markdown links in your answer.`
|
||||
#### What the model sees
|
||||
|
||||
**Token effect**: Data-dependent results are resent until compaction and sources are capped by `searchMaxResults`.
|
||||
The optional provider-owned answer is followed by `Sources:` and data-dependent lines shaped exactly `- [<title-or-url>](<url>)`, optionally suffixed ` — <snippet> (<publishedAt>)`. With neither answer nor sources the result says `No results found.` A capped list adds `(Showing the first <count> sources. Refine the query for more.)`; every result ends `Cite the relevant URLs above as markdown links in your answer.`
|
||||
|
||||
#### Token effect
|
||||
|
||||
Data-dependent results are resent until compaction and sources are capped by `searchMaxResults`.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Fetch result
|
||||
|
||||
**What the model sees**: A successful fetch is exactly `Fetched <finalUrl> (HTTP <statusCode>)`, a blank line, and the provider-owned decoded body. Truncation adds a blank line and `(Content truncated. Fetch a more specific URL or section for the full text.)`; failures become `Error: <message>`. Queries and URLs remain in call history.
|
||||
#### What the model sees
|
||||
|
||||
**Token effect**: Provider caps bound body size; retained call arguments and results are resent until compaction, and timeout policy can replace a late result with a short error.
|
||||
A successful fetch is exactly `Fetched <finalUrl> (HTTP <statusCode>)`, a blank line, and the provider-owned decoded body. Truncation adds a blank line and `(Content truncated. Fetch a more specific URL or section for the full text.)`; failures become `Error: <message>`. Queries and URLs remain in call history.
|
||||
|
||||
#### Token effect
|
||||
|
||||
Provider caps bound body size; retained call arguments and results are resent until compaction, and timeout policy can replace a late result with a short error.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
### Argument errors
|
||||
|
||||
**What the model sees**: Blank inputs become exactly `Error: query must be a non-empty string` or `Error: url must be a non-empty string`.
|
||||
#### What the model sees
|
||||
|
||||
**Token effect**: Only the failing call adds these retained tokens.
|
||||
Blank inputs become exactly `Error: query must be a non-empty string` or `Error: url must be a non-empty string`.
|
||||
|
||||
#### Token effect
|
||||
|
||||
Only the failing call adds these retained tokens.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **`htmlToMarkdown` is a minimal regex converter, not an HTML parser** — it strips script/style/noscript, keeps headings/bullets/links, and decodes about a dozen named entities; tables, images, and nested formatting are lost.
|
||||
- **The model-facing surface is minimal by design, with promotions deferred** — `max_results` stays a config bound (not a model argument), and `web_fetch` takes only `url` (no `format`/`prompt`/LLM-summarization mode); both are named later steps in [the seam RFC](../../../docs/rfc/implemented/architecture/2026-06-24-web-capability-seam.md).
|
||||
- **The model-facing surface is minimal by design, with promotions deferred** — `max_results` stays a config bound (not a model argument), and `web_fetch` takes only `url` (no `format`/`prompt`/LLM-summarization mode); both are named later steps in [the seam Agent Note](../../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.md).
|
||||
- **No web-specific permission policy** — both tools execute without requesting `ctx.approval`; a deployment that needs confirmation must add a `tools/pre-execute` policy, and the package does not define persistent URL/domain grants.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Showcase integration: the real `web_fetch` tool + the real spill stack
|
||||
* (`dsh-spill-local` backend + `dsh-spill-policy`), exercised through
|
||||
* `ctx.tools.execute()`. Proves the RFC's default local-backend path — a large
|
||||
* `ctx.tools.execute()`. Proves the Agent Note's default local-backend path — a large
|
||||
* formatted fetch result is automatically retained and spilled with NO
|
||||
* tool-specific spill code, and the model-facing text changes ONLY by the
|
||||
* deliberate spill notice (the full formatted result lands in the spill file).
|
||||
@@ -48,7 +48,7 @@ beforeEach(async () => {
|
||||
await ctx.plugin(ToolRegistry)
|
||||
await ctx.plugin(WebService, { fetchProvider: WebFetchLocal.LOCAL_FETCH_PROVIDER_ID })
|
||||
// Provider cap generous so the tool returns a large formatted result; the
|
||||
// policy cap is what triggers the spill (the RFC's separation of concerns).
|
||||
// policy cap is what triggers the spill (the Agent Note's separation of concerns).
|
||||
await ctx.plugin(WebFetchLocal, { maxBodyChars: 500_000 })
|
||||
await ctx.plugin(LocalSpillStore, { root: spillRoot })
|
||||
await ctx.plugin(SpillPolicy, { maxInlineBytes: MAX_INLINE_BYTES })
|
||||
|
||||
Reference in New Issue
Block a user