Commit Graph

27 Commits

Author SHA1 Message Date
Tianyi Cui
7e0bf44f09 Merge branch 'codex/simp-ui-identity-residue' into codex/simp-hide-concrete-agent-loop 2026-07-19 02:39:09 +08:00
Tianyi Cui
0c84c2a842 Merge branch 'codex/simp-agent-entry-state' into codex/simp-unify-agent-session-id 2026-07-19 02:39:09 +08:00
Tianyi Cui
6f01d4d099 Merge branch 'codex/simp-ui-identity-residue' into codex/simp-hide-concrete-agent-loop
# Conflicts:
#	docs/event-producer-consumer.md
#	examples/coding-agent/tests/code-mode.e2e.ts
#	examples/coding-agent/tests/harness.ts
#	examples/coding-agent/tests/resume.e2e.ts
#	examples/cordis-agent/tests/harness.ts
#	packages/bash/tool-bash/tests/integration.spec.ts
#	packages/compact/compact-basic/tests/compact-loop-repro.spec.ts
#	packages/cordis/tool-cordis/tests/integration.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts
#	packages/hooks/hooks-claude/tests/bridge.spec.ts
#	packages/hooks/hooks-claude/tests/coverage.spec.ts
#	packages/hooks/hooks-codex/tests/bridge.spec.ts
#	packages/hooks/hooks-codex/tests/coverage.spec.ts
#	packages/todo/tool-todo/tests/integration.spec.ts
2026-07-18 12:33:49 +08:00
Tianyi Cui
59dc310bb5 Merge branch 'codex/simp-agent-entry-state' into codex/simp-unify-agent-session-id
# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	examples/coding-agent/tests/code-mode.e2e.ts
#	examples/coding-agent/tests/coding-task.e2e.ts
#	examples/coding-agent/tests/compaction.e2e.ts
#	examples/coding-agent/tests/full-loop.e2e.ts
#	examples/coding-agent/tests/todo-write.e2e.ts
#	examples/cordis-agent/tests/cordis-tools.e2e.ts
#	packages/bash/tool-bash/tests/integration.spec.ts
#	packages/bash/tool-bash/tests/tools.spec.ts
#	packages/compact/compact-basic/tests/compact-loop-repro.spec.ts
#	packages/context/time-context/tests/time-context.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/cordis/tool-cordis/tests/integration.spec.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent-loop/src/index.ts
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/core/agent-loop/tests/cancel.spec.ts
#	packages/core/agent-loop/tests/config-session-id.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/core/agent-loop/tests/coverage-edges.spec.ts
#	packages/core/agent-loop/tests/interception.spec.ts
#	packages/core/agent-loop/tests/loop.spec.ts
#	packages/core/agent-loop/tests/properties.spec.ts
#	packages/core/agent-loop/tests/request-cache.e2e.ts
#	packages/core/agent-loop/tests/request-reconstruction.spec.ts
#	packages/core/agent-loop/tests/resume.spec.ts
#	packages/core/agent-loop/tests/scope-lifecycle.spec.ts
#	packages/core/agent-loop/tests/tool-order.spec.ts
#	packages/core/agent-loop/tests/turn-stop.spec.ts
#	packages/core/agent/src/types.ts
#	packages/examples/agent-spine-demo/README.md
#	packages/examples/agent-spine-demo/tests/agent-core.spec.ts
#	packages/examples/stdio-demo/README.md
#	packages/examples/stdio-demo/src/index.ts
#	packages/examples/stdio-demo/tests/stdio-agent.spec.ts
#	packages/fs/tool-fs/tests/fs-tools.e2e.ts
#	packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts
#	packages/hooks/hooks-claude/tests/bridge.spec.ts
#	packages/hooks/hooks-claude/tests/coverage.spec.ts
#	packages/hooks/hooks-codex/tests/bridge.spec.ts
#	packages/hooks/hooks-codex/tests/coverage.spec.ts
#	packages/subagent/subagent-fork/tests/multi-subagent.spec.ts
#	packages/subagent/subagent-fork/tests/subagent-fork.spec.ts
#	packages/subagent/subagent-inprocess/tests/structured.spec.ts
#	packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts
#	packages/subagent/subagent-spawn/tests/spawn.e2e.ts
#	packages/subagent/subagent-spawn/tests/subagent-spawn.spec.ts
#	packages/todo/tool-todo/tests/integration.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/workflow/workflow-workerthread/tests/integration.spec.ts
2026-07-18 12:21:15 +08:00
Tianyi Cui
1f58c07f1e Merge remote-tracking branch 'origin/master' into codex/simp-drop-unused-schema-default 2026-07-18 11:55:33 +08:00
Tianyi Cui
53680ee6bc Merge remote-tracking branch 'origin/master' into worktree/provider-routed-llm-adapters
# Conflicts:
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	packages/context/time-context/tests/time-context.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/session/README.md
#	packages/core/session/src/types.ts
#	packages/core/session/tests/surface.spec.ts
#	packages/examples/acp-demo/tests/acp-agent.spec.ts
#	packages/examples/stdio-demo/tests/stdio-agent.spec.ts
#	packages/hooks/hooks-claude/tests/coverage.spec.ts
#	packages/hooks/hooks-codex/tests/coverage.spec.ts
#	packages/session-query/session-query/tests/session-query.spec.ts
#	packages/support/invariants/tests/invariants.spec.ts
#	packages/ui/acp/tests/harness.ts
2026-07-17 21:56:10 +08:00
Yichen Jiang
d3b959389a test(support): add shared AgentLoop testkit 2026-07-16 17:39:53 +08:00
Yichen Jiang
815365dbbe Merge remote-tracking branch 'origin/master' into worktree/provider-routed-llm-adapters
# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.md
#	docs/event-producer-consumer.md
#	docs/persistence-catalog.md
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.1.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.2.jsonl
#	examples/acp-agent/tests/snapshots/advanced-toolchain/session.jsonl
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/hook-cc-pretool-ask/session.jsonl
#	examples/acp-agent/tests/snapshots/skill-load/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	examples/sandbox-acp-agent/cordis.yml
#	examples/sandbox-acp-agent/tests/snapshots/escalation-approved/session.jsonl
#	examples/sandbox-acp-agent/tests/snapshots/escalation-rejected/session.jsonl
#	examples/sandbox-acp-agent/tests/snapshots/mode-switching/session.jsonl
#	packages/compact/compact-basic/README.md
#	packages/compact/compact-basic/src/index.ts
#	packages/compact/compact-basic/tests/compact-basic.spec.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/src/loop.ts
#	packages/core/agent-loop/tests/properties.spec.ts
#	packages/core/session/README.md
#	packages/core/session/src/types.ts
#	packages/core/session/tests/derived-cache.spec.ts
#	packages/llm/llm-deepseek/src/index.ts
#	packages/llm/llm-pi-ai/README.md
#	packages/llm/llm-pi-ai/src/adapter.ts
#	packages/llm/llm-pi-ai/src/convert.ts
#	packages/llm/llm-pi-ai/tests/adapter.spec.ts
#	packages/llm/llm/README.md
#	packages/llm/llm/src/call-config.ts
#	packages/llm/llm/src/index.ts
#	packages/ui/acp-agent/src/index.ts
#	packages/ui/acp/tests/harness.ts
#	packages/ui/jsonrpc/README.md
#	packages/ui/jsonrpc/src/server.ts
#	packages/ui/stdio-agent/README.md
#	packages/ui/stdio-agent/src/index.ts
#	python/sdk/README.i18n.yaml
2026-07-14 22:17:50 +08:00
Yichen Jiang
e547980d77 feat(llm): route adapters by provider 2026-07-14 21:57:52 +08:00
Tianyi Cui
47503a2b1b Merge branch 'codex/simp-drop-assembled-section-order' into codex/simp-drop-unused-schema-default 2026-07-14 19:06:49 +08:00
Tianyi Cui
93dc0f30a9 Merge branch 'codex/simp-ui-identity-residue' into codex/simp-hide-concrete-agent-loop
# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
2026-07-14 18:58:29 +08:00
Tianyi Cui
83271191d1 Merge branch 'codex/simp-agent-entry-state' into codex/simp-unify-agent-session-id
# Conflicts:
#	docs/config-catalog.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/rfc/implemented/architecture/2026-06-18-agent-lifecycle-and-ownership-seams.md
#	docs/rfc/implemented/architecture/2026-06-20-branded-ids.md
#	docs/rfc/implemented/simplification/2026-06-20-remove-agent-boundary-mirror-events.md
#	docs/rfc/proposed/feature/2026-07-07-claude-code-and-codex-subagent-backends.md
#	docs/rfc/proposed/simplification/2026-06-20-unify-agent-and-session-id.md
#	packages/bash/tool-bash/README.md
#	packages/bash/tool-bash/src/index.ts
#	packages/bash/tool-bash/tests/tools.spec.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/tests/properties.spec.ts
#	packages/core/agent/README.md
#	packages/core/agent/src/index.ts
#	packages/guard/repeat-tool-guard/src/index.ts
#	packages/hooks/hooks-claude/tests/bridge.spec.ts
#	packages/subagent/subagent-acp/tests/mock-acp-server.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/stdio-agent/src/index.ts
#	packages/ui/stdio-agent/src/stdio-chat.ts
#	packages/ui/stdio-agent/tests/stdio-chat.spec.ts
#	packages/util/brand/src/index.ts
2026-07-14 18:51:24 +08:00
Tianyi Cui
863116daaf fix: retain dynamic tool schema defaults 2026-07-14 05:23:17 +08:00
Tianyi Cui
225796c90d refactor: hide the concrete agent loop 2026-07-14 02:32:35 +08:00
Tianyi Cui
709cc7200e refactor: unify agent and session identity 2026-07-14 01:59:21 +08:00
Tianyi Cui
148046b9c8 docs: rebalance prose cleanup and add trimming skill 2026-07-13 23:27:00 +08:00
Tianyi Cui
74ada5777c Merge PR #224 updates into prose cleanup 2026-07-12 23:36:49 +08:00
Tianyi Cui
c5b1a7941f fix(scope): harden lifecycle ownership foundation
Make Cordis construction and teardown ownership reentrancy-safe, then carry caller and provider ownership through reservation, setup, publication, quiescence, and sentinel retirement.

Stabilize registry carriers and factory/workflow boundaries, add adversarial lifecycle regressions, and align the rewritten RFC plus generated contracts with the enforced behavior.
2026-07-12 08:57:05 +08:00
Tianyi Cui
75838e10b5 docs: trim generated prose 2026-07-12 03:36:43 +08:00
imccyu
fe4da9244f fix(tool-cordis): validate a dynamic tool's execute return shape after the realm round-trip
The sandbox execute wrapper JSON round-tripped the return and blindly cast it
to ToolExecuteReturn. A JSON-valid but wrong-shape return — a bare string,
{ content: 'ok' }, blocks without a type tag — sailed through: the registry
spreads result.content, so { content: 'ok' } became ['o','k'], passed the
session log's isJsonValue gate, and the DeepSeek serializer then flattened it
to '(no output)' — silent corruption of the next model request and every
replay, instead of a contained tool error.

The round-tripped value is now shape-checked against the two ToolExecuteReturn
forms (array of content blocks, or { content: blocks, meta? }); block checks
are structural only (plain object + string type tag) because the ContentBlock
union is merge-extensible. A wrong shape — and the formerly cryptic
forgot-return/bare-string cases — fails that one call with a teaching error
echoing a truncated preview of what was returned and the two valid forms.
New specs pin the object-form pass-through (meta included), six rejection
shapes, and the preview truncation; per-file 100% coverage holds.
2026-07-09 22:12:30 +08:00
imccyu
f1e54d737b fix(tool-cordis): pass primitive provided service values through the façade
cordis provide() accepts any value and cross-mount composition advertises
ctx.provide('name', value), but the façade's readService unconditionally
proxied every declared service — new Proxy('42') throws "Cannot create proxy
with a non-object as target or handler", so a consumer of a primitive-valued
service crashed on first read with an error naming neither the service nor
the fix. A primitive or null value now passes through unwrapped (after the
denyContext check); only object- and function-valued services are proxied —
a primitive has no method that could hand back a Context, so nothing is lost.
New cross-mount spec pins both read paths (ctx.<name> and ctx.get) for a
number and a null provided value.
2026-07-09 19:30:49 +08:00
imccyu
3e9527278a fix(tool-cordis): gate façade services on inject, and make tools.get read-only
Two review findings (#220) on the sandbox context façade:

- Undeclared services were reachable: the façade resolved any live global via
  ctx.get(name), so ctx.bash worked without inject: ['bash']. A cross-mount
  consumer could then depend on a provider cordis never saw — unmounting the
  provider would neither park the consumer nor unwind its registered tools,
  leaving a model-visible tool that fails only at execution. The façade now
  reads ctx.fiber.inject and refuses any service the mount did not declare
  (with a teaching error naming the inject fix), so the dependency is always
  visible to cordis and its activation/unload semantics bind.

- ctx.tools.get returned the live ToolDefinition, including execute — mount
  code could call another tool directly and bypass ToolRegistry.execute and
  its pre/post-execute hooks and accounting. get now returns the same
  read-only name/description/parameters view as schemas(), never an invocable.

Adds inject-gate and schema-view regression cases to sandbox-context.spec.ts
(undeclared property/get denied, declared allowed, the cross-mount zombie-tool
scenario refused at call time, get exposes no execute). Package stays at
per-file 100% coverage. RFC, mount description, and tool-catalog updated.
2026-07-09 13:57:03 +08:00
imccyu
1b1ba96d4f fix(tool-cordis): replace the pass-through ctx proxy with a whitelist façade
Review finding (#220): the guarded proxy only special-cased ctx.tools, so
mount code could reach an UNGUARDED context through ctx.root, ctx.extend(), or
a service instance's .ctx, then ctx.root.tools.register({…}) to bypass the
marker check and host-realm normalization — a raw vm-realm result would later
error a real agent turn at the session-log plainness check.

The sandbox ctx is now a whitelist façade, not a pass-through proxy: it exposes
only what a mount needs — tools.register (marker-guarded), on/once, provide, the
timer helpers, and injected services resolved through a guarded get — and denies
every framework-plumbing member (root, parent, fiber, reflect, registry, extend,
isolate, intercept, plugin, set, mixin, …) with a teaching error. Injected
services are wrapped so a method returning a Context is rejected on the way back
(the .ctx escape), closing the one indirect leak. There is no context-valued
member left to reach; cross-mount provide/inject is untouched (the plugin's own
inject and the fiber's pending/active gating are unchanged). ctx.plugin (child
plugins) and ctx.set are denied by design; ctx.effect is deferred (FIXME).

Adds tests/sandbox-context.spec.ts covering the escape class (root/extend/fiber/
plugin/set/… denied, the classic root.tools.register bypass, the .ctx escape,
read-only writes) plus the async-service and symbol/in-operator paths for 100%
coverage. RFC/README/tool-catalog/config-catalog updated; api-catalog.ts
regenerated (also picks up the codeRuntime service that entered on the master
merge and was left stale).
2026-07-09 13:57:03 +08:00
imccyu
ea66641b84 feat(tool-cordis): flatten the inspect plugins section to a capability list
The tree SHAPE was the wrong surface for the model: what it needs from
cordis_inspect is what services, plugins, and capabilities are loaded, not the
fiber hierarchy. The plugins section is now a flat name + lifecycle-state list
from ctx.registry (deterministically sorted, one line per instance); the ASCII
tree renderer, the parent→child rebuild, and the dyn-id tree annotation are
deleted — dynamic mounts keep their own richer dynamic section (id, state,
provides, waits). Net -49 lines; RFC and READMEs state the flat-list contract.
2026-07-09 13:57:03 +08:00
imccyu
a500c791f7 fix(tool-cordis): normalize the JSON-Schema dialect at the defineTool boundary
Field sessions showed models writing tool schemas in the JSON-Schema dialect
by strong prior — type: 'integer', required: false, then the full
{ type:'object', properties, required: [...] } wrapper — and the rejection
text itself pushed a nearly-correct DSL attempt BACK to raw JSON Schema: one
stats tool cost three consecutive schema errors before mounting. The boundary
now normalizes wherever the input has exactly one meaning (wrapper unwrapped
with the required array becoming per-property flags at any nesting level,
integer → number, required: false → optional, all rebuilt as fresh host-realm
objects) and rejects only genuinely meaningless input, enumerating the valid
vocabulary in the error. Re-running the failing session mounts first-try.
The mount description documents both accepted forms.
2026-07-09 13:57:03 +08:00
imccyu
db45769513 feat(tool-cordis): Node-API traps + fs/web capability routing
The sandbox deliberately provides no Node API, and now says so instead of
letting a bare ReferenceError teach nothing: require, the timers, and fetch
are callable traps whose error redirects to the cordis alternative (inject:
['fs'] + ctx.fs, ['web'] + ctx.web, ['bash'] + ctx.bash, ['timer'] +
ctx.setTimeout — a fiber effect, unwound on unmount). Only function-shaped
globals are trapped; process/Buffer stay undefined so typeof feature probes
stay inert. The mount description and the demo persona state the routing rule,
and the demo mounts ctx.fs (local provider) and ctx.web (seam + keyless local
fetch provider) so agent-built plugins have real capabilities to build on.
Live-validated: a model that reached for Node setTimeout self-corrected to
inject: ['timer'] in one step and built a working ctx.web fetch tool.
2026-07-09 13:57:03 +08:00
imccyu
ee1da1ce5b feat(cordis): @deepseek-ai/dsh-tool-cordis — inspect/mount/unmount over the live runtime
New top-level packages/cordis/ group with the self-referential toolset:
cordis_inspect (services / plugin tree / tools / dynamic mounts / api / events,
the api section intersecting the generated catalog with the live service store),
cordis_mount (model-written code evaluated in a node:vm sandbox, mounted under
one cordis-dynamic group fiber as dyn-<n>), cordis_unmount (awaited disposal to
quiescence). Boundary mechanisms: dual-realm instanceof, JSON realm
normalization of dynamic tool results, marker-guarded registration, SchemaSpec
teaching errors, parse failures surfaced with the offending line + caret and a
line-scoped TypeScript hint, and the unmount-first recipe on tool-name
collisions. Config: vmTimeoutMs (schemastery, default 5000). Design record:
docs/rfc/implemented/feature/2026-07-08-self-referential-cordis-toolset.md.

The tool-catalog boot manifest, its regenerated output, and the pinned
tool-name list land here rather than with the other repo registration: the
completeness guard globs packages/*/tool-* and fails the generator (and the
core/tools spec) the moment the package directory exists.
2026-07-09 13:57:03 +08:00