Skip to content

Commit 142b534

Browse files
authored
Merge pull request #22 from A3S-Lab/codex/work-office-core-6.3.0
feat(runtime): ship governed office execution in 6.3.0
2 parents 11f5561 + fab25c3 commit 142b534

97 files changed

Lines changed: 7122 additions & 1989 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [6.3.0] - 2026-07-22
11+
12+
### Added
13+
14+
- Added typed model-generation concurrency and admission contracts so hosts can
15+
declare and enforce bounded active generations without provider-name checks.
16+
- Added durable `MemoryObservation` and `MemoryObserver` extension points for
17+
auditable preference, skill, and knowledge projections after persistence.
18+
- Added run-scoped permission and confirmation snapshots plus targeted
19+
cancellation and expiry for pending tool approvals.
20+
21+
### Changed
22+
23+
- Serialized completed-turn memory extraction, drained accepted extractions at
24+
session close, and preserved canonical duplicate-consolidation results for
25+
observers.
26+
27+
### Fixed
28+
29+
- Kept LLM-authored learning titles, summaries, and instructions concise and
30+
user-facing, and excluded internal orchestration or handoff procedures from
31+
the learning signal contract.
32+
1033
## [6.2.0] - 2026-07-22
1134

1235
### Added
@@ -140,15 +163,84 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
140163

141164
### Added
142165

166+
- Added the Search 2 native `anysearch` and `tavily` providers to the built-in
167+
`web_search` engine catalog while preserving the existing default engine
168+
selection for ordinary callers. Provider results retain normalized
169+
publication dates and stable contributing-engine metadata in JSON output.
170+
- Added a typed model-generation concurrency contract and shared,
171+
cancellation-safe admission gate for structured generation. Providers that
172+
do not explicitly advertise safe parallel capacity default to
173+
single-flight. `generate_object` starts its active deadline only after
174+
admission, holds one permit across bounded schema-repair calls, and records
175+
queue wait, capacity, and active timeout in result metadata. A Flow step
176+
whose exact tool identity is `generate_object` acquires that same capacity
177+
before entering the bounded `program` VM, and the nested call reuses the
178+
one-shot identity-checked permit, so the VM deadline also excludes queue
179+
wait without permitting a foreign-gate or concurrent-reuse bypass.
180+
- Added per-run snapshot hooks to `PermissionChecker` and
181+
`ConfirmationProvider`. Agent invocations bind the frozen checker and
182+
confirmation route into their tool context so delegated, parallel, Skill,
183+
and background child runs keep their admitted authority across later
184+
session-policy changes.
185+
- Added an extended `BashSandbox` request/result contract and an
186+
`SrtBashSandbox` adapter with timeout, bounded streaming output, explicit
187+
environment, network denial, workspace/scratch write limits, protected
188+
control metadata, credential-read denial, and no unsandboxed fallback.
189+
Verified constructors now accept an exact npm installation and an explicitly
190+
selected Node executable so lifecycle-owning hosts do not rediscover either
191+
process from `PATH`.
192+
- Added opt-in `LocalWorkspaceAccessPolicy::CredentialBoundary` enforcement
193+
for local and manifest-backed workspace services. Direct file reads,
194+
range reads, writes, and indexed or fallback grep now share the local
195+
command sandbox's credential and source-hardlink boundary while preserving
196+
ordinary package-store hardlinks. Guarded local Git diff first enumerates
197+
NUL-delimited changed paths and regenerates output only for allowed files.
143198
- Delegation tools now publish a deterministic live catalog of visible worker
144199
names and purposes in both their descriptions and parameter schemas. Workers
145200
registered after session creation become model-discoverable on the next run;
146201
hidden or unregistered workers are omitted.
147202
- Tool implementations can override their complete model-facing definition
148203
when descriptions or schemas depend on live runtime state.
204+
- The Code TUI now projects A3S Use's built-in local PP-OCRv6 MCP and Skill
205+
surfaces, reports its pinned model and ONNX Runtime status, and provides the
206+
explicit `a3s install use/ocr` repair command.
207+
208+
### Removed
209+
210+
- Removed the unused `document_parser.ocr` backend configuration. OCR in Code
211+
is owned exclusively by A3S Use and runs locally through PP-OCRv6.
149212

150213
### Fixed
151214

215+
- Preferred the semantic HTML `<main>` element before falling back to `<body>`
216+
in `web_fetch`, removing site navigation and footer chrome from ordinary
217+
evidence pages while preserving the existing bounded conversion and SSRF
218+
boundary. The oversized fetch test module now lives in its own concern file.
219+
- Decoded Anthropic and OpenAI-compatible SSE response bodies with one
220+
incremental UTF-8 decoder per stream. Multibyte text split across arbitrary
221+
network chunks now reaches event parsing intact instead of producing Unicode
222+
replacement characters in streamed research and conversation output.
223+
- Made provider generation admission session-owned. Rebuilding an `AgentLoop`
224+
for each concurrent host-direct tool call now reuses the same typed capacity
225+
gate, so separate DynamicWorkflow calls cannot each manufacture an
226+
independent single-flight slot.
227+
- Extended the local SRT credential boundary to existing `.env*` files at
228+
every governed source-tree depth and read/write-masked pre-existing
229+
multi-link source files, closing nested credential and hardlink-alias reads.
230+
- Closed the built-in workspace-tool path around the local command sandbox:
231+
guarded `read`, `grep`, `write`, `edit`, and `patch` operations can no
232+
longer expose or mutate protected credential files or source hardlink
233+
aliases.
234+
- Hardened read-only Git output: diff targets cannot be interpreted as
235+
options, guarded diffs omit sensitive and multi-link paths, and displayed
236+
remote URLs remove embedded HTTP credentials, query strings, and fragments.
237+
- Auto-mode hosts can declare confirmation unavailable before Core emits a
238+
confirmation event. Unexpected parent or tool-owned escalation therefore
239+
fails closed instead of opening HITL or being automatically authorized.
240+
- Propagated the parent sandbox and confirmation boundary into delegated,
241+
workflow, and Skill child runs. Child-local allow rules and automatic
242+
confirmation can narrow execution but can no longer replace the host
243+
boundary, and explicit Bash host escalation is now tool-declared.
152244
- Live MCP additions and removals now refresh task delegation, and natural
153245
language action tokens can select matching MCP tools without requiring the
154246
caller to know their underscored protocol names.
@@ -1482,43 +1574,15 @@ conflicts. They now `switch` / `match` on `error_kind.type` instead.
14821574

14831575
- **HWPX Table Extraction**: Added structured table extraction from Korean HWPX documents. Parses `tbl/tr/tc` XML hierarchy and includes `structured_payload` for `tables[]` output.
14841576

1485-
- **Vision OCR Provider**: New OCR backend supporting OpenAI-compatible vision APIs for document OCR fallback.
1486-
1487-
```hcl
1488-
document_parser {
1489-
ocr {
1490-
enabled = true
1491-
model = "openai/gpt-4.1-mini"
1492-
api_key = "sk-..."
1493-
base_url = "https://api.openai.com/v1" # optional
1494-
prompt = "Extract all text from this document..."
1495-
max_images = 8
1496-
dpi = 144
1497-
}
1498-
}
1499-
```
1500-
1501-
Provider priority: External provider > Vision API (if model+api_key configured) > Builtin tesseract
1502-
15031577
#### Search Ranking
15041578

15051579
- **Tabular Query Intent Detection**: Automatically detects when queries relate to tables (keywords: table, column, row, spreadsheet, excel, csv, cell, data, record, etc.) and boosts table line matches by +10 keyword hits plus 1.3x relevance multiplier.
15061580

15071581
- **Heading Inheritance Boost**: When search matches appear under headings that also match the query, those matches receive a relevance boost (up to 1.3x). Looks backwards to find the closest preceding heading.
15081582

1509-
### Changed
1510-
1511-
#### Configuration
1512-
1513-
- `DocumentOcrConfig` extended with new fields:
1514-
- `provider: Option<String>` - Backend selection ("vision" or "builtin")
1515-
- `base_url: Option<String>` - Custom API endpoint
1516-
- `api_key: Option<String>` - API authentication
1517-
15181583
#### Dependencies
15191584

15201585
- Added `calamine = "0.26"` for XLSB parsing
1521-
- Added `reqwest/blocking` feature for Vision API HTTP calls
15221586

15231587
### Fixed
15241588

Cargo.lock

Lines changed: 14 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ object-only backend that cannot execute it.
280280
| Workspace search | `glob`, `grep` | Bounded matching with explicit result metadata and continuation |
281281
| Code Intelligence | `code_symbols`, `code_navigation`, `code_diagnostics` | Saved-file semantic metadata and locations with bounded results; source retrieval and mutation stay in the existing file tools |
282282
| Commands and source control | `bash`, `git` | Bounded output, cancellation, process-group termination on Unix, and typed Git operations |
283-
| Web evidence | `web_search`, `web_fetch` | AnySearch by default, optional Tavily and conventional engines, normalized sources, SSRF protections, extraction, and bounded pages |
283+
| Web evidence | `web_search`, `web_fetch` | Ranked multi-engine search, including native AnySearch and Tavily providers, normalized sources, semantic `<main>` extraction with `<body>` fallback, SSRF protections, and bounded pages |
284284
| Structured output | `generate_object` | Schema-constrained model generation with validation and repair |
285285
| Composition | `batch`, `program` | Safe batch scheduling and sandboxed JavaScript programmatic tool calling |
286286
| Delegation | `task`, `parallel_task` | Foreground/background workers, bounded parallelism, partial results, and task tracking |
@@ -317,10 +317,10 @@ language/bootstrap injection variables. It keeps stdout and stderr distinct
317317
under one global capture limit. Its deadline covers output draining and the
318318
child's complete lifetime, including a process that closes both streams before
319319
it exits; timeout or cancellation terminates the Unix process group. It never
320-
searches `PATH` for a sandbox runtime and never falls back to the host runner
321-
when its explicitly provisioned runtime is missing or fails. The embedding host
322-
remains responsible for choosing whether an unavailable sandbox causes an
323-
interactive escalation or a deterministic denial.
320+
searches `PATH` for a sandbox runtime and never falls back to the host runner
321+
when its explicitly provisioned runtime is missing or fails. The embedding host
322+
remains responsible for choosing whether an unavailable sandbox causes an
323+
interactive escalation or a deterministic denial.
324324

325325
Shell isolation does not automatically govern in-process workspace tools.
326326
Interactive hosts should construct `LocalWorkspaceBackend` or
@@ -427,7 +427,20 @@ Confirmation managers, hooks, budget guards, security providers, stream
427427
sanitization, retention limits, circuit breakers, duplicate-call guards, and
428428
no-progress detection compose around the same invocation path. Trusted direct
429429
host calls skip model-facing permission prompts, so an embedding application
430-
must authorize its callers.
430+
must authorize its callers. Only built-in control-plane orchestrators may carry
431+
that authority into host-selected nested calls. A public custom tool's
432+
`InvocationRuntime`, and every model sub-run created from a direct host context,
433+
produce ordinary governed invocations instead of inheriting ambient trust.
434+
435+
Delegated tasks, workflow steps, and Skill child runs retain the parent sandbox
436+
and intersect their local permission policy with the parent checker. A
437+
child-local `Ask` follows that worker's `auto_approve`, `deny_on_ask`, or
438+
`inherit_parent` policy, while an `Ask` introduced by the parent remains under
439+
the parent confirmation provider. If both scopes ask, both remain effective and
440+
the same provider is de-duplicated. Tool-owned confirmation after both policies
441+
allow is also governed by the parent, so a child-local auto-approver cannot
442+
waive a host escalation boundary. Cancellation and timeout settle only the
443+
matching confirmation ID; unrelated concurrent prompts remain pending.
431444

432445
### Workspace backends
433446

@@ -466,8 +479,15 @@ transcript data, not as a new source of executable instructions.
466479
The memory layer separates working, short-term, and durable long-term state.
467480
It supports relevance and recency scoring, typed memories, relations,
468481
successful and failed pattern capture, file or custom stores, optional pruning,
469-
and context injection. Significant completed turns can use the active model to
470-
extract a bounded set of durable memories; hosts can disable or tune extraction.
482+
and context injection. By default, every completed non-empty session turn is
483+
sent to the active model for a semantic value judgment; the model returns an
484+
empty set when nothing is reusable. Automatic extraction writes only validated
485+
semantic or procedural memories and never mechanically persists tool results or
486+
turn history. Streaming turns register extraction before publishing their final
487+
event, run through a FIFO background queue, and graceful session close drains
488+
already-accepted work for a bounded period. Stored extractor metadata records
489+
source, confidence, scope, reason, workspace, session, and schema version.
490+
Hosts can disable extraction or tune its input and output bounds.
471491

472492
### Models and MCP
473493

@@ -477,6 +497,26 @@ reasoning, tool calls, usage, images, retries, cancellation, and streaming where
477497
the provider supports them. Structured generation uses native response formats
478498
when available and a schema-validated prompt fallback otherwise.
479499

500+
Anthropic and OpenAI-compatible SSE transports decode UTF-8 incrementally
501+
across raw network chunks before splitting events. A multibyte character may
502+
therefore cross any transport boundary without being replaced or corrupting the
503+
event payload.
504+
505+
`LlmClient::model_generation_concurrency` is the typed admission contract for
506+
structured model transactions. The default is conservative single-flight;
507+
providers may explicitly report a larger finite bound.
508+
Each `AgentSession` owns one cancellation-safe gate and reuses it across
509+
conversation loops, host-direct calls, and rebuilt direct-tool runtimes.
510+
`generate_object` waits on that gate before starting its active deadline,
511+
retains the permit through schema repairs, and reports the queue wait
512+
separately in metadata. `DynamicWorkflowRuntime` recognizes the exact
513+
`generate_object` Flow step identity and acquires the same capacity before
514+
starting its bounded `program` VM. The nested generation reuses that one-shot
515+
identity-checked permit, so neither the generation deadline nor the Program
516+
deadline includes admission queue time, parallel nested calls cannot reuse one
517+
reservation, and concurrent host-direct workflows cannot create independent
518+
provider gates.
519+
480520
If an established response stream closes before its final response, Core
481521
restarts the same LLM turn with the same message snapshot up to ten times. The
482522
delay grows exponentially from one second and is capped at thirty seconds, with
@@ -490,7 +530,11 @@ MCP connections support stdio, HTTP SSE, streamable HTTP, and OAuth client
490530
credentials. Global managers can seed new sessions and refresh cached tools;
491531
session managers can connect, disconnect, and live-add or remove isolated
492532
servers. Tools remain source qualified so separate servers do not silently
493-
share ownership.
533+
share ownership. A local stdio server leads a dedicated Unix process group.
534+
Transport close or drop stops its pipe tasks, fails pending requests, reaps the
535+
direct child, and terminates descendants; stderr is drained independently so a
536+
diagnostic-heavy server cannot block the protocol pipe. This lifecycle
537+
containment does not make the configured server an untrusted sandbox.
494538

495539
Hosts can add or replace a Skill in a running session with
496540
`AgentSession::add_skill`, inspect the effective names with `skill_names`, and

core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "a3s-code-core"
3-
version = "6.2.0"
3+
version = "6.3.0"
44
edition = "2021"
55
authors = ["A3S Lab Team"]
66
license = "MIT"

core/src/agent.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ mod tool_completion_runtime;
5454
mod tool_execution_runtime;
5555
mod tool_guard_runtime;
5656
mod tool_invoker;
57-
mod tool_memory_runtime;
5857
mod tool_result_runtime;
5958
mod tool_turn;
6059
mod turn_context;
@@ -82,6 +81,13 @@ pub(crate) struct AgentConfig {
8281
pub permission_policy: Option<PermissionPolicy>,
8382
/// Optional confirmation manager for HITL (Human-in-the-Loop)
8483
pub confirmation_manager: Option<Arc<dyn ConfirmationProvider>>,
84+
/// Child-local resolution policy for `Ask` decisions.
85+
///
86+
/// This marker remains separate from `confirmation_manager` because both
87+
/// `deny_on_ask` and `inherit_parent` intentionally start without a
88+
/// child-local provider and must be distinguished when the parent boundary
89+
/// is composed into a delegated run.
90+
pub confirmation_inheritance: Option<crate::subagent::ConfirmationInheritance>,
8591
/// Serializable confirmation policy used to build the manager, when available.
8692
pub confirmation_policy: Option<crate::hitl::ConfirmationPolicy>,
8793
/// Serializable queue configuration used to build the optional command queue.
@@ -192,6 +198,7 @@ impl std::fmt::Debug for AgentConfig {
192198
.field("permission_checker", &self.permission_checker.is_some())
193199
.field("permission_policy", &self.permission_policy.is_some())
194200
.field("confirmation_manager", &self.confirmation_manager.is_some())
201+
.field("confirmation_inheritance", &self.confirmation_inheritance)
195202
.field("confirmation_policy", &self.confirmation_policy.is_some())
196203
.field("queue_config", &self.queue_config.is_some())
197204
.field("context_providers", &self.context_providers.len())
@@ -241,6 +248,7 @@ impl Default for AgentConfig {
241248
permission_checker: None,
242249
permission_policy: None,
243250
confirmation_manager: None,
251+
confirmation_inheritance: None,
244252
confirmation_policy: None,
245253
queue_config: None,
246254
context_providers: Vec::new(),
@@ -823,6 +831,7 @@ impl SessionCommand for ToolCommand {
823831
#[derive(Clone)]
824832
pub(crate) struct AgentLoop {
825833
llm_client: Arc<dyn LlmClient>,
834+
model_generation_admission: crate::llm::ModelGenerationAdmission,
826835
tool_executor: Arc<ToolExecutor>,
827836
tool_context: ToolContext,
828837
config: AgentConfig,

0 commit comments

Comments
 (0)