Commit Graph
22 Commits
Author SHA1 Message Date
weichen bdb45c3c2c Add the memory port with loop recall injection and the memory_write tool (N3 WP5)
ci / vet-and-test (pull_request) Successful in 49s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: the completion doc assigns the Memory port to the library; today
memory recall is a product-side interface assertion with no library
surface, AgentSpec.MemoryScope has no consumer, and the model has no
write-back path.
Evidence: GOWORK=off go vet + go test -count=1 ./... green;
TestLoopInjectsMemoryAndRegistersWrite (recall block lands after the
system section, memory_write executes through the loop),
TestEmptyRecallInjectsNothing (empty recall changes nothing),
TestBlockRenderOrderingAndCaps (deterministic order, expiry/empty
pruning), TestWriteToolValidation (fail-closed scope/type/content).
Impact: new opt-in Config.Memory/MemoryScope; nil port keeps behavior
byte-identical; injection is request-scoped (never persisted, never
accumulates) and deterministic ([记忆] text shape preserved for the
product migration).
Refs: Agent-System-Documents#43 (N3 plan WP5)
2026-10-07 16:05:36 +00:00
weichen fc0558fc93 Align spans with the OTel GenAI convention (N3 WP4)
ci / vet-and-test (pull_request) Successful in 51s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: acceptance clause 3 requires span names and attributes to follow
the convention; today names were bare words with two ad-hoc attribute
keys, and every span got a fresh random trace with no parentage.
Evidence: GOWORK=off go vet + go test -count=1 ./... green;
TestSpanNamesFollowGenAIConvention (name suffixes, gen_ai.* key enum,
intValue usage, service.name resource, prompt/reserved-key exclusion),
TestLoopSpansFollowGenAIConvention (invoke_agent root with shared
trace, chat/execute_tool children with parent links, usage attrs on
chat spans); the pre-existing prompt-body denylist test passes
unchanged.
Impact: span names become invoke_agent <agent> / chat <model> /
execute_tool <tool>; attributes move to gen_ai.* with usage as
intValue; one Run shares one trace with invoke_agent as root. New
Config.AgentName/ProviderName (documented defaults keep old hosts
meaningful); telemetry StartFunc gains WithServiceName/WithEndpoint
options (defaults preserve current behavior).
Refs: Agent-System-Documents#43 (N3 plan WP4)
2026-10-07 15:36:35 +00:00
weichen e2be33f008 Add JournalOnly sessions and persist one-time history seeds (N3 WP2)
ci / vet-and-test (pull_request) Successful in 50s
ci / docker-checkout-hostgateway (pull_request) Successful in 0s
Why: the product conversation path needs the intent journal and
recovery pairing, but making the transcript the authoritative context
would freeze the assembled system prefix (memory/plans/injections go
stale). JournalOnly keeps the session as journal-only: recovery runs
against it, the context always comes from History, and the recovered
outcomes are injected as a system note. Separately, the one-time
History seed was memory-only and silently lost from the second run on
(authority mode); it is now persisted except in JournalOnly mode.
Evidence: GOWORK=off go vet + go test -count=1 ./... green;
TestJournalOnlyRecoversWithoutTranscriptAuthority (journal gets the
replayed pair exactly once, history never enters the journal, the
recovery note precedes the new user message, seeds stay out);
persistedProjection honors JournalOnly; all pre-existing durable and
harness tests pass unchanged (default semantics untouched).
Impact: new opt-in Config.JournalOnly; default (false) behavior is
byte-identical.
Refs: Agent-System-Documents#43 (N3 plan WP2)
2026-10-07 15:21:48 +00:00
weichen 5abb231efe Repair orphan tool-call tails on resume and stop mutating memory on Stop.Replacement (N3 WP1)
ci / vet-and-test (pull_request) Successful in 50s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: a kill between persist(assistant) and commitToolIntent left an
unpaired tail that no recovery path repaired (acceptance clause 1's
library gap), and Stop.Replacement mutated the in-memory assistant
while the transcript kept the original (audit N6 residual).
Evidence: GOWORK=off go vet + go test -count=1 ./... green;
TestResumePairsOrphanTailAfterCrashWindow (no-intent window pairs with
crashInterrupted, run continues), TestResumeMixedIntentAndOrphanTail
(intent path and tail repair never double-pair),
TestRepairOrphanTailNoopOnHealthyTranscript; the harness assertion now
pins replacement-as-user-note (forged=4, notes=3).
Impact: every next Run repairs the trailing assistant's resultless
calls before the first request; replacement text now appears only as a
user message in both memory and transcript (intentional, recorded in
the N3 card).
Refs: Agent-System-Documents#43 (N3 plan WP1)
2026-10-07 15:02:16 +00:00
weichen ae42c9402d Spill cleared tool results to disk and pin the cache-stability contract (N2 WP1)
ci / vet-and-test (pull_request) Successful in 52s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: the completion doc's N2 requires old tool results to become file
paths (ZCode compact pattern) and cache-friendly prefix rules; today the
micro-compactor only left a transcript pointer and nothing pinned prefix
stability. alignToolTail had no direct edge tests.
Evidence: GOWORK=off go vet + go test -count=1 ./... green; new
TestClearOldToolResultsSpillsToDisk / TestSpillResultSanitizesCallID /
TestAlignToolTailEdges / TestSystemTextDeterministicAcrossIdenticalBuilds;
legacy placeholder bytes unchanged when ResultsDir is empty
(TestClearOldToolResultsEmptyDirKeepsLegacyPlaceholder).
Impact: opt-in via Config.ResultsDir; the native adapter wires it to
<workDir>/.agentx/results. No behavior change for other hosts.
Refs: 2026-10-07-agent-stack-n2-plan WP1
2026-10-07 12:59:05 +00:00
weichen 948ca36ca2 Add AgentSpec, three guardrail ports, subagent events, and ask passthrough
ci / vet-and-test (pull_request) Successful in 47s
ci / docker-checkout-hostgateway (pull_request) Successful in 0s
Why: N1 increment three (WP1/WP4) - agents need a canonical spec
format with plugin restrictions, hosts need typed input/output/tool
guardrails, delegation needs lifecycle events, and squad adapters
need to pass the permission ask port through.

Evidence: go vet clean; go test ./... 26 packages ok, including new
agentspec (12 tests), guardrails (5), loop_guardrails (5), and
subagent hook tests (3).

Impact: new runtime/agentspec and runtime/guardrails packages; loop
consumes UserPromptSubmit outcomes (deny skips the loop, modify
appends the rewrite); subagent gains RegisterWithHooks emitting
SubagentStart/Stop around delegation; GateOptions gains PermissionAsk
forwarded into the kernel config. All additions are opt-in: nil
ports preserve prior behavior exactly.

Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md WP1/WP4
2026-10-07 05:04:58 +00:00
weichen 9758a8d8d0 Add permission ask loop, lifecycle hook emissions, and Policy type
ci / vet-and-test (pull_request) Successful in 48s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: The N1 harness phase needs the kernel to resolve ask decisions
through the host (paired HITL), emit the full hook lifecycle the plan
promises, and carry mode/rules/session-allow in one named object.

Evidence: go vet clean; go test ./... 24 packages ok, including new
loop_hooks_lifecycle_test.go (lifecycle order, prompt text, ask
allow/deny/legacy paths, stop continuation counts) and three new
policy tests (struct-form parity, session-allow store, nil store).

Impact: hooks adds PostToolBatch and SessionEnd events; loop emits
SessionStart/UserPromptSubmit/PostToolBatch/SessionEnd and PreCompact
lands in AgentSession.Compact; gateTool consults PermissionAsk on ask
and keeps ask=reject when the port is unset; policy gains Policy,
SessionAllows, and MemoryAllows. SubagentStart/Stop emissions are
deferred to the adapters assembly increment (factory site has no bus
access yet).

Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md WP2/WP3
2026-10-07 03:01:17 +00:00
weichenandCursor fb2b3b796c Record tool intent before execution and add file checkpoints
ci / vet-and-test (pull_request) Successful in 46s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: a crash after a tool was about to run left the call unpaired, and workspace writes could not be rewound.
Evidence: GOWORK=off go test ./runtime/ ./runtime/llm/ ./runtime/checkpoint/ ./runtime/telemetry/ ./runtime/tools/ ./runtime/session/ ./adapters/native/
Impact: pending calls rerun only when both the stored and current replay declarations are safe; otherwise the result is an error. Empty fallback lists and a nil checkpoint log keep the previous behavior.
Refs: feature/durable-rewind
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 17:27:04 +00:00
weichenandCursor 0a52d9f976 Add a hook bus and permission decisions for tool calls
ci / vet-and-test (pull_request) Successful in 46s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: Squad members never saw the direct-run stop, reminder, and before-tool gates, and there was no shared place to decide deny, ask, or allow.
Evidence: GOWORK=off go test ./runtime/hooks/ ./runtime/policy/ ./runtime/ ./adapters/native/ passed, including an A/B run where hook adapters match the old callbacks.
Impact: An empty bus leaves stop reason, reminder count, and deny count unchanged. Callers opt in by setting GateOptions.
Refs: feature/permission-hooks
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 17:02:28 +00:00
weichenandCursor 6fd1d441a9 Keep tool pairs and fold reminders into the last result
ci / vet-and-test (pull_request) Successful in 45s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: Old tool results were filling the window, compaction could split a tool group or commit a stale summary, and reminders arrived as extra user messages.
Evidence: Compaction retries a conflict and opens the circuit after three failures; clearing keeps the last five tool results; a stale file write is rejected; RPC reports started, queued, or handled.
Impact: Requests over the context window replace older tool results with a placeholder. Rewriting an existing file now requires a read in the same run. Subagent text over 32000 characters is capped.
Refs: feature/context-engineering
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 16:19:36 +00:00
weichenandCursor 9f5751c205 Retry model streams only before the first delta
ci / vet-and-test (pull_request) Successful in 47s
ci / docker-checkout-hostgateway (pull_request) Successful in 1s
Why: Buffering a whole attempt hid live output, overflow detection missed common provider errors, and a cut-off tool call could still run.
Evidence: GOWORK=off go test -race -count=1 ./runtime/llm/ ./runtime/ passed.
Impact: WithRetry forwards events immediately and retries only when nothing has been forwarded. Length or an unclean end drops unfinished tool calls. Loop usage keeps a billing sum and the last request separately.
Refs: feature/llm-robustness
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 15:52:08 +00:00
weichenandCursor 17f2a4ecfa Close the native P1 gaps the audit listed for this batch
Why: token budget let the current tool batch run, compaction could split a tool pair or race an append, writes were not crash-atomic, and several MCP and session edges only existed as comments.
Evidence: GOWORK=off go test -count=1 -race ./runtime/ ./runtime/llm/ ./runtime/session/ ./runtime/tools/ ./runtime/mcp/ ./adapters/native/ ./adapters/intentgate/ passed, including the TestR2* cases for budget, replacement, cancel, compaction, SSE, UTF-8, schema, MCP retry, session terminate, poison reload, and registry reload.
Impact: over-budget tool calls are skipped and paired; Stop.Replacement is appended to the session; the intent gate can follow Registry.Reload.
Refs: N5, N6, N7, N8, N9, N11, N12, N15, N16, N17, N18, N19, N21, I9
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 13:05:58 +00:00
weichenandCursor 694b08cdbe Pair skipped tool calls and close the stdio and fetch gaps
ci / vet-and-test (pull_request) Failing after 2s
ci / docker-checkout-hostgateway (pull_request) Successful in 2s
Why: a tool-budget stop left tool calls without results, host callbacks raced, a canceled MCP read stole the next response, and fetch re-resolved after the SSRF check.
Evidence: GOWORK=off go vet ./... && go test -count=1 ./... && go test -race ./runtime/... ./adapters/native/... passed, including TestLoopBudgetToolCallCap, TestParallelHostCallbacksAreSerial, TestStdioSlowCancelThenEcho, TestPresetsAndClientForChatCompletions, TestFetchResolveChangesToLoopbackRejected, and TestFetchHostCheckRedirectStillRejectsPrivate.
Impact: over-budget calls get an error result and no tool event; one Run serializes host callbacks; MCP dispatches by id; anthropic and google presets use OpenAI-compatible chat endpoints; fetch dials the address it just checked. deps/agent-intent is 3130190; error-code-system and logging-system are a3ee67b and 49b5d8b.
Refs: N1, N2, N3, N4, N13, N14
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 01:10:29 +00:00
weichenandCursor c6d867cde7 Let length continuations and Anthropic output run unbounded
ci / vet-and-test (pull_request) Failing after 1m30s
ci / docker-checkout-hostgateway (pull_request) Failing after 7m5s
Why: A fixed continuation cap and a 4096-token Anthropic fallback stopped long replies before the agent finished.
Evidence: go test ./runtime/ ./runtime/llm/
Impact: MaxLengthContinuations of 0 keeps the old cap of 3; a negative value removes it. Unset Anthropic max_tokens defaults to 128000.
Refs: feature/stream-display-overhaul
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-02 02:11:43 +00:00
weichenandCursor a34689c78f Delegate unregistered tool calls when a fallback is set
ci / vet-and-test (pull_request) Failing after 2m48s
ci / docker-checkout-hostgateway (pull_request) Failing after 31s
Why: the direct chat path still executes model-emitted calls that are not in the profile allow-list, while squad keeps the unknown-tool error when the fallback is unset.
Evidence: go test ./runtime/ passed, including TestLoopUnknownToolFallsThrough and the existing unknown-tool cases.
Impact: Config.UnknownTool is optional. Nil preserves today's registry error.
Refs: feature/agent-harness-p1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 13:27:36 +00:00
weichenandCursor e2815bbf94 Report token usage on each message end
Why: the direct-path adapter accounts usage per turn, including runs that stop on a budget error before the final usage event.
Evidence: go test ./runtime/ ./runtime/llm/ after the field was added.
Impact: message_end and usage events carry TotalTokens. Callers that ignore the new field are unchanged.
Refs: feature/agent-harness-p1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 13:25:58 +00:00
weichenandCursor 35f65a3c49 Add optional stop, reminder, and continuation hooks to the turn loop
Why: the direct chat path needs one shared loop for deliverable checks, tool pairing, reminders, and truncated replies, while squad callers keep today's behavior when the new fields stay unset.
Evidence: go test ./... in agent-native passed, including Stop cap, BeforeTool pairing, reminders absent from the session, repeat-guard cap, length continuation, and zero-value loop tests.
Impact: runtime.Config and llm.Event grow optional fields; AgentSession.Prompt copies them through. Squad sessions that leave them zero are unchanged.
Refs: feature/agent-harness-p1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 13:23:07 +00:00
weichenandCursor 2dedc0d20c Add an AgentSession with steer and follow-up queues
Why: Steering hooks existed on the loop but nothing owned the queues, abort, or a model change during a run.
Evidence: go test -count=1 ./runtime/
Impact: Run still emits the existing event names. message_start, tool_execution_update, and agent_settled are added beside them.
Refs: feature/pi-headless N3
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 10:11:19 +00:00
weichenandCursor 951c141f95 Let hosts register tools and observe token usage
Why: product runners need register_artifact and card tools inside the kernel loop, and the UI needs token usage on the same event stream as text and tool calls.
Evidence: go test ./... in agent-native; TestHostToolAndUsageEvent and TestHostToolNameConflictFailsClosed.
Impact: Options.HostTools fail closed on name clashes; ProcessEvent and runtime events gain a usage type with token counts. Existing callers that ignore unknown event types stay compatible.
Refs: deliverable-quality-system B1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 08:57:21 +00:00
weichen dd2ac11b31 Extend exec.Request with capability fields and enforce budgets end to end
Why: the frozen exec port could not express per-request model, tool
allowlist, skills, budget, or identifiers, so squad roles and product
profiles had no way to steer one execution; contract v0.1.0 semantics
(budget/cancel) stayed unconsumed (parity-matrix #4/#10/#16).

Evidence: go vet ./... clean; go test ./... all ok, including new
loop budget caps (tool calls, prompt tokens, deadline), cancel
propagation into a blocking tool, registry Restrict fail-closed
policy tests, native adapter v2 tests (model override, allowlist,
deadline-bound context, execution-id log header, skills prompt line),
and settle classification marking budget_exceeded permanent.

Impact: exec.Request gains optional Model/ToolAllowlist/Skills/Budget/
SessionScope/ExecutionID/Env (zero value = legacy behavior); runtime
loop enforces a shared budget and emits budget_exceeded events;
adapters/native consumes all new fields. Consumers on the old port
keep compiling and behaving identically.

Refs: docs/parity-matrix.md rows #4/#10/#16 (Batch2 scope); deps/
development-guidelines standards/agent-execution.md (shared budget
across retry layers).
2026-10-01 05:26:19 +00:00
weichenandCursor e65c6ba604 Align execution errors with the shared catalog and add optional logs.
Contract codes now use the agent.* values, and runtime can emit structured logs without changing results when no logger is configured.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 14:24:11 +00:00
weichenandCursor fedf671a48 Import the current agent-native module as a fresh history.
ci / vet-and-test (push) Successful in 5s
ci / docker-checkout-hostgateway (push) Successful in 3s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 12:29:04 +00:00