Repository navigation
[web] Add the supported self-hosted Session creation and executor connection flow #28
Description
Context
Parsar Core at immutable revision 2b34ea4630a5a0daf90e745fe1af3edcfa4f0e9e publicly supports creating a Codex self_hosted Environment only as part of Session creation:
{
"agent_id": "agent_...",
"environment": {
"type": "self_hosted",
"workspace_directory": "/workspace",
"capability_directories": []
},
"stream": false
}The supported profile requires a Core configured with execution plus an executor registry, an absolute executor-host Workspace path, and empty/default capability_directories. The Session response exposes the safe connection target (environment.id, remote_url, workspace_directory, and normalized capability_directories). An operator-issued credential file is consumed on caller-controlled Linux executor compute by agents-api-codex-executor; the browser neither issues nor receives that credential.
The Web already types this request/response, retrieves one Session-bound Environment, renders durable/live status, and treats environment_connection as a non-function required action. It still creates only environment:none Sessions and gives the user no self-hosted creation/connection flow.
Parsar does not expose a public Environment list/standalone CRUD API, Environment templates, browser-facing Environment-key API, Files/Artifacts browser, hosted sandbox, or runtime-capability discovery route. This Issue must not emulate any of them.
Bounded outcome
Add one shared Start Session flow, inspired by the OpenAI self-hosted UX but limited to the Parsar contract above:
- choose a saved Agent;
- choose No environment or Self-hosted;
- for Self-hosted, enter the absolute Workspace directory that already exists on the executor host;
- create an idle Session with no initial model input;
- after successful creation, show a Connect Environment guide for that Session using only Core-returned safe connection fields and credential/binary path placeholders;
- continue using the existing durable Environment read, SSE projection, and
environment_connectionaction as the status source.
Because Core has no capability-discovery endpoint, the Self-hosted option must be controlled by an explicit non-secret operator build flag and remain hidden by default. Health, Agent creation, SSE, and saved model values are not capability evidence.
Acceptance criteria
- Global Create -> Start Session, Sessions -> Create, Agent-row Start Session, and the Agent-setup continuation enter the same Session setup flow; Agent-origin entry points preselect that Agent instead of silently creating
environment:none. - The default remains No environment and preserves the current
{ "type": "none" }request. - The Self-hosted option is hidden unless an explicit non-secret operator build flag enables this known Core profile.
- Self-hosted is described as an Environment supplied and managed by the user/operator. The UI does not offer OpenAI-hosted, Docker provisioning, E2B, templates, or other providers.
- Self-hosted creation requires a non-empty absolute POSIX
workspace_directory; reject relative paths,~, NUL/CR/LF, backslashes, and unsupported extra Environment fields before sending. - The request contains only
type,workspace_directory, and emptycapability_directories;remote_url, Environment ID, credentials, setup commands, and env values can never be supplied by the browser. - Creation is idle (
stream:false, noinput) and uses the existing saved-Agent admission checks and idempotency boundary. - Core 4xx/5xx/network/unknown outcomes leave the setup open, create no optimistic local Environment, preserve a safe error, and are never retried automatically.
- After successful self-hosted creation, select the returned Session and expose a keyboard-accessible Connect Environment guide while connection is pending, disconnected, expired, failed, unavailable, or explicitly required.
- The guide explains that the launcher runs on user-chosen executor compute (local Linux, Docker/VM, or remote Linux), and that
workspace_directoryrefers to that compute, not the browser/Web host or daemon container. - A copyable launcher template is shown only when the Session has a complete
self_hostedprojection, a canonical Environment UUID, and a strictly valid Core-returned HTTP(S) executor origin. Otherwise fail closed and show no runnable command. - The template uses pinned
agents-api-codex-executorsyntax with static$REMOTE_URL/$ENVIRONMENT_IDvariables and credential/binary path placeholders; it never embeds a token, caller bearer, database URL, model/provider credential, query string, fragment, or userinfo. - The Web never asks the user to paste an Environment key, reads a credential file, starts a process/container, or connects to executor/native transports.
-
environment_connectionremains non-actionable protocol state: no Function Result form and no fabricated completion event. - Existing durable/live precedence, Core/Session/Environment identity fencing, secret-safe error rendering, URL handling, cancellation, and
environment:nonechat behavior remain intact. - Protocol docs, connection guidance, fixtures, and the immutable Parsar baseline are updated to
2b34ea4630a5a0daf90e745fe1af3edcfa4f0e9efor every new claim. - No top-level Environments catalog/navigation or Environment-template/key Create entry is added, because Core exposes no corresponding public list/management API.
Validation
- Unit/component tests for both Environment choices, absolute-path validation, shared-entry-point Agent preselection, exact request bodies, draft preservation, duplicate-submit prevention, and Core rejection/uncertain outcomes.
- Security tests for malformed URLs/IDs, shell metacharacters, query/fragment/userinfo, placeholder-only credentials, and absence of secret-bearing fields in DOM, copied command, state, fixtures, logs, and URLs.
- Environment-state tests for pending, connected, disconnected, expired, failed, unavailable,
environment_connection, reconnect/reload, Session/Core switch, and stale event/read fencing. - Fixture E2E for create -> select -> Connect Environment guide -> status transition; verify
environment:noneremains unchanged at desktop and narrow widths with keyboard/screen-reader semantics. - Optional local real-Core acceptance may create an idle self-hosted Session and connect a controlled executor to observe durable status transition. Do not send a model Turn or make a paid provider call for this Issue.
- Run
pnpm check, Playwright acceptance, andgit diff --check.
Non-goals
- No standalone Environment create/list/update/delete page or catalog.
- No OpenAI-hosted Environment, template, provider selector, automatic Docker/VM/sandbox provisioning, or Workspace lifecycle management.
- No Environment-key issuance, read-back, input, storage, rotation, revocation, or browser exposure.
- No Files, Plugins, Skills, Artifacts, Vault, Workspace browser/editor, or local file URLs.
- No browser connection to executor/native transports and no daemon/executor/Core implementation changes.
- No readiness/capability inference from health, SSE, Agent creation, saved model, Environment creation, or connection alone.
- No paid model request, deployment, release, merge, branch deletion, or Worktree deletion.
Dependencies
- Builds on closed [agent] Add self-hosted Environment and Workspace status UI #5 and [agent] Hydrate durable Environment status from Parsar retrieve API #16 and narrows the Environment gap tracked by [tracking] OpenAI Agents API gaps blocked on Parsar Core #8.
- [tracking] OpenAI Agents API gaps blocked on Parsar Core #8 remains the capability tracker; it is not suitable as this implementation Issue because it explicitly forbids being used as an
agent-readytask.
Activity
feat(web): add self-hosted Session connection flow (#29)