Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.16.0 — RFC-0024 Workflow I/O Contracts + RFC-0025 Human-in-the-Loop + OpenAI Adapter Hardening
Summary
This PR ships two new protocol RFCs — typed input/output contracts for workflow phases (RFC-0024) and first-class human-in-the-loop intent suspension (RFC-0025) — plus a follow-on patch that hardens the OpenAI adapter and
trydemo script against themax_tokensdeprecation in gpt-5+ and o-series models. All changes are fully backward compatible.RFC-0024: Workflow I/O Contracts
Resolves RFC-0012 Open Question #4. The executor now owns all data wiring between phases; agents simply read
ctx.inputand return a plain dict.What's new
outputsschema onPhaseConfigDeclare what a phase produces as a key → type mapping. Supported types:
string,number,boolean,object,array, any named type from the top-leveltypesblock, or an inline{type, required: false}dict for optional fields. The legacy list-of-strings form is normalised automatically, so existing YAML continues to work.inputswiring onPhaseConfigMap local key names to upstream references. The executor resolves these before invoking the agent handler and places the result in
ctx.input.Parse-time wiring validation
Every
from_yaml()/from_string()call now validates that everyphase_name.keyinput reference names a phase listed independs_onand a key declared in that phase'soutputs. RaisesInputWiringErrorimmediately — broken wiring is caught at startup, not at runtime.Three executor-owned gates
resolve_task_inputs()ctx.inputfrom upstream outputs, trigger payload, or initial statevalidate_claim_inputs()validate_task_outputs()Named error types — all exported from
openintenttop-level:MissingOutputError— required output key absent from agent return valueOutputTypeMismatchError— value doesn't match declared type (primitive, named struct, or enum)UnresolvableInputError— declared input ref can't be resolved from available stateInputWiringError— structural error detected at parse timetypesblockDefine reusable named struct and enum types at the top of any workflow YAML:
Incremental adoption
Phases without
outputsorinputsare completely unaffected. Validation only activates for phases that declare contracts — you can adopt RFC-0024 one phase at a time.RFC-0025: Human-in-the-Loop Intent Suspension
Agents can now suspend an intent mid-execution, ask an operator a structured question, and resume after a response arrives — all as a first-class protocol primitive.
What's new
suspended_awaiting_inputlifecycle stateNew
IntentStatusvalue. The reaper and lease-expiry workers skip intents in this state; lease renewal succeeds for suspended intents so agents retain ownership across the suspension window.BaseAgent.request_input()The primary API. Suspends the intent, fires
@on_input_requestedhooks, polls for operator response, and returns the response value.ResponseTypeenum —choice,confirm,text,formSuspensionChoice— structured operator option withvalue,label,description,style("primary"/"danger"/"default"), and arbitrarymetadata.should_request_input()Rule-based engagement-decision engine. Returns one of four modes:
autonomousrequest_inputrequire_inputdeferPOST /api/v1/intents/{id}/suspend/respondREST endpoint for operators (or bots) to submit responses. Validates
suspension_idand choice value, transitions intent back toactive, emitsintent.resumed, and broadcasts via SSE. Returnschoice_labelandchoice_descriptionin the response body.Four new lifecycle decorators
New exception types
InputTimeoutError— raised whenfallback_policy="fail"and the suspension window expiresInputCancelledError— raised when a suspension is explicitly cancelledOpenAI Adapter:
max_tokens→max_completion_tokensfor gpt-5+ / o-seriesOpenAI deprecated
max_tokensfor newer model families (gpt-5*,o1*,o3*), which caused 400 errors in thetrydemo script and any direct adapter call using that parameter.openai_adapter.pyAdded
OpenAIAdapter._requires_max_completion_tokens(model)— a static helper that matches model names against the affected families via regex. In_create_completion, if the caller passesmax_tokensand the model matches, it is silently remapped tomax_completion_tokens(unless the caller already suppliedmax_completion_tokensexplicitly). Older models (gpt-4,gpt-3.5-turbo, etc.) are unaffected.client/public/trydemo scriptUpdated
ResearchAgent._do_researchandSummarizerAgent._summarizeto passmax_completion_tokensdirectly instead ofmax_tokensin both the streaming and non-streaming paths.Tests
tests/test_workflow_io.pyresolve_task_inputs,validate_task_outputs,validate_claim_inputs,_check_value_type(all primitives + named struct + enum), incremental adoption, package exportstests/test_hitl.pytests/test_workflow.pytests/test_adapters.pymax_tokensdetection + remapping (7 new), existing adapter coverage228 tests passing, zero failures.
Docs
docs/rfcs/0024-workflow-io-contracts.md— full RFC-0024 specificationdocs/rfcs/0025-human-in-the-loop.md— full RFC-0025 specificationdocs/guide/human-in-the-loop.md— HITL user guide with quick-start, decorator reference, fallback policies, and a complete refund-agent examplemkdocs.yml— RFC-0024 and RFC-0025 added to nav; HITL guide added to User Guide nav; announcement bar updated to v0.16.0CHANGELOG.md— full v0.16.0 entryVersion bumps
pyproject.toml:0.15.1→0.16.0mcp-server/package.json:0.15.1→0.16.0mcp-server/src/index.ts:0.15.1→0.16.0openintent/__init__.py:__version__already at0.16.0Checklist
openintent/workflow.pyandopenintent/agents.pyopenintenttop-levelfrom_yaml()/from_string()validate_task_outputscovers primitives, named structs, and enumsOpenAIAdapter._requires_max_completion_tokens()remaps parameter for gpt-5+ / o-seriestrydemo script usesmax_completion_tokensin all call pathsruff checkandruff formatcleantsc --noEmitclean