Skip to content

Latest commit

 

History

History
112 lines (82 loc) · 18 KB

AGENTS.md

File metadata and controls

112 lines (82 loc) · 18 KB

OpenAgentCore development

Design principles

OpenAgentCore is protocol-first and modular. Core orchestrates operations that protocols define; Sandbox Providers, Runtimes, Harnesses and model providers are replaceable implementations of those protocols. Architecture describes each component's responsibilities.

Infrastructure standard

OpenAgentCore is infrastructure. Change a boundary only when the existing protocol cannot express the behavior, and make that the smallest change that leaves the design intact. Hold the code to the standard of a careful, widely used open-source service.

Simplicity and performance

Do not multiply entities without necessity. The long-term goal is minimal code, dependencies and runtime overhead while preserving protocol correctness, isolation and clear ownership.

  • Before adding an abstraction, package, dependency, service, execution path or setting, show why existing code and maintained standard SDKs cannot meet a current requirement cleanly. Prefer reuse, simplification and deletion; do not build extension points for hypothetical needs. Expose no port, route, command or setting without a caller.
  • Keep cohesive responsibilities together and remove redundant layers and indirection. Split code at a real responsibility or protocol boundary, not to meet a file-size target. Fewer files or packages alone do not establish simplicity.
  • Justify performance optimizations with reproducible measurements against a baseline under representative workloads. Compare the relevant latency, throughput, allocations, memory use, startup time or distribution size, and account for added complexity and resource costs. Keep the simplest implementation that meets the measured requirement.

Protocols at every boundary

  • Each boundary between components has exactly one protocol: one code file (interface, wire types and validators) and one document. A protocol change edits both and every implementation in one change, reviewed on its own.
  • Protocols are deterministic. Every operation is declared and every outcome is typed. Implementations declare what they support, and callers validate each selected combination against those declarations. Support is never discovered through type assertions, name checks or implicit fallbacks. An unsupported operation or combination returns a typed error. Core never substitutes another implementation, and a capability means the same for every implementation.
  • A component joins the system only by implementing a protocol, never through a private entry point, side channel or path selected by its name.
  • Each rule has one authored definition. Generate cross-language projections from it or check them against shared fixtures.
Boundary Protocol code Protocol doc
Application–Core (/v1) Official schema pinned by contracts/agents-api/upstream.json plus Go-owned x_agents_core extensions; make openapi generates public Go types and contracts/agents-api/openapi.yaml Agents API guide
Web and operators–Core (/core/v1) Route annotations in services/core/internal/api/; make openapi generates contracts/agents-api/core.openapi.yaml Core administration API
Nodes and daemons–Core (/api/v1 HTTP routes; the node and daemon wire protocols are separate rows) internal/machineapi/machineapi.go (wire types) plus route annotations in services/core/internal/api/; make openapi generates contracts/agents-api/runtime.openapi.yaml Machine connection API
Core and sandbox nodes–Workspace filesystem services/core/internal/workspacefs/workspacefs.go Workspace filesystem protocol
Core–Sandbox Provider services/core/internal/sandbox/sandbox_provider.go Sandbox Provider protocol
Core–sandbox node services/core/internal/sandbox/node/wire.go Sandbox node protocol
Provider–Runtime startup internal/runtimebootstrap/bootstrap.go Runtime bootstrap
Core–Runtime wire internal/agentdaemon/proto/ Core–Runtime protocol
Runtime–Harness apps/daemon/internal/agent/harness.go Harness protocol
Harness–Model provider internal/modelprovider/config.go Model execution

Complexity stays in the adapter

  • A new Sandbox Provider, Harness, model provider or vendor feature changes only its adapter. It adds no Core execution path, store table or column, migration, deployment or configuration field, API field or Web UI specific to one vendor or Harness. The Sandbox Provider protocol and Harness protocol describe how to add an adapter.
  • When the protocol cannot express what an adapter needs, change the protocol. Never add an optional side interface for one implementation.
  • Implementing the declared checkpoint lifecycle in one vendor's Provider is an adapter change. A vendor-only pause interface, a Core path for that vendor, vendor receipts in the store or a vendor idle setting in the deployment is not.
  • Fix shared lifecycle, admission, cancellation, reuse and performance problems in the common flow, never in a branch selected by Harness, Runtime or vendor name. Core preparation and execution never branch on operating system or Environment source; platform support requires native CI builds and automated tests.
  • Each Harness runs its own model and tool loop through a maintained upstream SDK or native protocol, in the Environment's declared workspace directory. Its native history or configuration directory is never the workspace. Never build a second executor, a hand-written model/tool loop or a compatibility framework to fabricate parity. The public API and persistence never depend on one engine's native item types.

Core assembles, Harnesses run natively

Choosing a Harness and a model behaves like running that Harness locally with that model. The only differences are the cloud Environment, isolation, credentials and unattended operation.

  • Core assembles configuration and passes it through. When a Harness or model natively supports what an official field expresses, the adapter maps the field to the native setting and the native side runs it. If the provider cannot run it, the provider's own error returns unchanged. Core qualifies nothing on a provider's behalf. It adds nothing to model input and has no fallback, retry or substitute path. Authentication, isolation and credential protection are assembly and stay in Core.
  • A Harness joins through one declaration file, internal/harnessconfig/<package>/declaration.go, plus its adapter code (declare the Harness). The declaration is the only source of support facts, and every other projection is generated from it.
  • An official field with no native home returns a typed error. Dropping it silently would be a fallback.
  • A default defined by the pinned official API applies. Everything else follows the native default, and Core sends nothing for it.
  • An adapter overrides a native default only when the Harness cannot otherwise run unattended in the cloud. The allowed reasons are: tools run without approval prompts, no ask-the-user tool, the workspace and state paths, credential isolation, bounded failure instead of waiting, no work that outlives its Turn, and no feature that needs an account credential Core does not hold. Each override has a one-line reason beside it, and the adapter guide lists it.
  • Never branch on the model or provider. When a model lacks a feature, the Harness handles it as it would locally.

Public API

  • The target is the complete OpenAI Agents API (openai/openai-python beta/agents) as pinned in contracts/agents-api/upstream.json: paths, methods, headers, field presence, nullability, discriminators, defaults, status transitions, pagination, errors and streaming. Engine limitations are gaps to close, never grounds to narrow or redefine the contract. Operations or fields newer than the pinned baseline wait for a protocol upgrade.
  • Record each native Harness difference, and any unspecified or unverified behavior, in the OpenAI compatibility. Reject explicit enablement of an unsupported feature and never invent official semantics. When a material difference has no clear mapping, stop and ask before changing its semantics. Native differences never relax authentication, isolation, credential protection or data consistency.
  • Applications, including the Parsar product, reach Core only through the public contract, with no privileged endpoint and no shared tables. Core never interprets their product payloads.

One home for each setting and datum

Each setting and each piece of data is written in one place and read from that place: no second copy, no environment-variable or file fallback and no alias. A new setting joins its category and lives beside its peers.

The categories are process settings, secrets, and Core's database for runtime settings and execution data. Configuration reference owns the installation layout and the settings themselves.

Pre-release: no compatibility layers

OpenAgentCore has had no public release. Replace superseded interfaces, execution paths and files outright. Keep no version fallback, compatibility shim or migration for superseded behavior. An installation of another release is reinstalled, never upgraded. A schema change adds a forward migration, so existing development and test databases follow it; the migrations may be folded into one baseline at any time. Keep the pinned official public protocol, valid data and still-used, verified infrastructure. Do not rewrite working infrastructure only to rename it.

Documentation

  • One fact, one place. Link to the owning document instead of restating it. The owner map is Documentation ownership.
  • Leave out filler, hedging, process history (PR or design numbers, "retired", "former", "this candidate") and task chronology. Delete obsolete and duplicate documentation. Qualification evidence stays only while it qualifies current behavior.
  • Do not hard-wrap prose. Write each paragraph, list item and blockquote on one line.
  • User-facing documentation uses Web's exact page and action names.
  • Application examples read the endpoint and key from OPENAI_BASE_URL and OPENAI_API_KEY.
  • Maintain authored documentation under docs/ and contracts/agents-api/ in English and Simplified Chinese in the same change. English files keep their paths; Chinese translations mirror them under docs/zh/ and contracts/agents-api/zh/. Preserve protocol identifiers, executable examples and English heading anchors. Each translation records its English source and SHA-256 source_hash in frontmatter; website checks reject missing or stale translations. Generated references remain owned by their generators and are excluded from manual translation. Keep code comments in English. The root README also has a Chinese version; user-facing product copy may be bilingual.
  • Markdown in docs/, component guides and contracts/ is the authored source. Generated files, such as the OpenAPI documents and the Harness catalog reference, are never edited by hand: change the source and regenerate.
  • Update the owning document in the same change as the rule, workflow or generated contract it describes.

Working in this repository

  • For each new task, create a new Git worktree. Name its directory after that change's commit subject, in kebab-case, beside the checkout. Run git pull --ff-only on the base branch, and create the feature branch in that worktree before development.
  • After every push to a pull request, wait 60 seconds, then run gh pr checks and confirm CI passes. Fix any failure before reporting the work as done.
  • When documents conflict, apply the latest explicit user decision and update the affected current guidance; recorded evidence does not override it.
  • Review every change through the independent review gate.
  • CONTRIBUTING.md: documentation ownership, repository boundary, workflow, the review contract, required checks and naming.
  • Develop OpenAgentCore: setup, the repository map, focused checks and each extension boundary.
  • API namespaces and credentials: each route's caller and credential.

Independent review gate

Apply this gate to every change, including documentation, before declaring the work complete: documents under docs/ and contracts/ include protocol and contract sources.

  1. Freeze a review range the reviewer can reproduce, and do not commit or edit while a reviewer is running: normally main...HEAD for committed work, or, for uncommitted work, the working tree against its merge base with main, with new files marked by git add -N. Make sure every in-scope modification is visible in that range.
  2. Choose reviewers for an implementation's first round by risk. By default, start one fresh, independent subagent with no inherited conversation context. Start two such reviewers when the change touches a protocol's code or document (a row of the table under Protocols at every boundary), database schema or migrations, authentication, credentials or isolation, or a shared lifecycle, admission, cancellation or reuse flow. Every reviewer inspects that round's complete range. Do not use codex exec as a substitute reviewer.
  3. Give each reviewer detailed but neutral context: the user's goal, intended behavior, acceptance criteria, task boundaries, relevant constraints, the repository path, repository layout, architectural boundaries, authoritative contracts or documentation, the exact review range, relevant read-only validation commands, and the dimensions to inspect (correctness, regressions, data integrity, concurrency, security, performance, compatibility, UI state, i18n, and tests). Before the review starts, tell the user the requirements, criteria and boundaries given to the reviewer.
  4. Do not tell reviewers the implementation approach, what changes or fixes were made, the chosen design rationale, a self-assessment, known concerns, prior review findings, or another reviewer's conclusions. Reviewers must independently infer how the code attempts to meet the stated requirements.
  5. Reviewers are read-only. Require prioritized findings with severity (blocker, high, medium or low; data integrity is a category at any severity), confidence, an exact file and line, a concrete failure scenario, reasoning, and a recommended direction. Require an explicit "no findings" result when applicable. Style-only comments are not findings unless they create a maintenance or correctness risk.
  6. The primary agent must independently validate every finding against the source and tests. Do not apply reviewer suggestions mechanically. A problem the change causes or worsens is in scope wherever it appears. A validated pre-existing or unrelated problem that cannot be fixed within the task boundaries is recorded and reported to the user instead of fixed, and does not block completion. When an in-scope finding is deliberately left unfixed, such as to keep upstream-compatible behavior, record the decision and its reason and list it in the final report. Later reviewers receive deliberate decisions as intended behavior, and known out-of-boundary problems as task boundaries, among the constraints in step 3. Leaving an in-scope finding unfixed never satisfies step 10: an unfixed validated blocker, high-severity or data-integrity finding still blocks completion.
  7. Fix confirmed in-scope issues, confirm each fixed failure scenario with a test or a reproduction, and run proportionate regression tests. After fixing a blocker, high-severity or data-integrity finding, or after any other material fix, review the changes made since the reviewed range with one new blind reviewer, started and briefed as in steps 2 to 5; when uncommitted new changes cannot be separated, review the whole working-tree range again.
  8. Track findings by underlying invariant or failure scenario, not wording. Run at most three review rounds for one implementation, and end the gate in one of two ways:
    • If the third round's validated in-scope findings are all medium or low and none concerns data integrity, finish without another round: fix the small, localized findings, confirm each with a test or a reproduction, and list the rest in the final report.
    • If the third round reports a validated in-scope blocker, high-severity or data-integrity finding, or earlier if review and repair begin cycling, patches contradict earlier patches, or the same invariant repeatedly fails, stop patching and reassess the design: ownership, component boundaries, state model, data flow, contracts, and test strategy. A corrected design that fits within the task boundaries, which come from the user, goes through this gate once as a new implementation. If the design holds, or the task boundaries themselves look wrong, stop and report to the user.
  9. If the design-level correction reaches either condition of the second case, stop and report the unresolved condition, review history, conflicting constraints, and viable options. Never start a second correction or broaden the task.
  10. Completion requires no validated in-scope blocker, high-severity or data-integrity finding, all relevant checks passing, and a final primary-agent audit of the complete diff.

The reviewer count is a review-quality gate, not a requirement to split the implementation into multiple pull requests; a protocol change is still reviewed on its own.