Skip to content

FEATURE: Add Session API for pipe-based bash sessions in execd#104

Open
Pangjiping wants to merge 18 commits intoalibaba:mainfrom
Pangjiping:feat/run_in_session
Open

FEATURE: Add Session API for pipe-based bash sessions in execd#104
Pangjiping wants to merge 18 commits intoalibaba:mainfrom
Pangjiping:feat/run_in_session

Conversation

@Pangjiping
Copy link
Collaborator

@Pangjiping Pangjiping commented Jan 18, 2026

Summary

This PR adds a dedicated Session API to the execd web layer, exposing three endpoints for creating, running code in, and deleting pipe-based bash sessions. These sessions are independent of the existing code execution flow: the existing Bash language context (e.g. POST /code/context with language: bash) continues to use the Jupyter kernel; the new Session API uses the in-process, pipe-based bash implementation only.

Motivation

  • Callers need a way to manage stateful bash sessions (create once, run multiple commands with shared env/cwd) without going through Jupyter.
  • The existing /code and /code/context APIs are built around language runtimes (Jupyter for Bash/Python/etc.). Keeping the new session lifecycle separate avoids mixing concerns and preserves backward compatibility for Bash-as-a-language.

New API

All routes live under the /session group and use the same auth middleware as other execd APIs (e.g. access token header when configured).

Method Path Description
POST /session Create a new pipe-based bash session. Returns a session_id.
POST /session/:sessionId/run Run code in the given session. Streams output via SSE (same event shape as /code).
DELETE /session/:sessionId Delete the session and release resources.

Request / response

  • Create session

    • Body (optional): { "cwd": "/optional/working/dir" }
    • Response: { "session_id": "<uuid>" }
  • Run in session

    • Body: { "code": "<shell script>", "cwd": "<optional>", "timeout_ms": <optional, non-negative> }
    • Response: SSE stream (e.g. init, stdout, stderr, execution_complete, error), same as /code.
  • Delete session

    • No body.
    • Success: 200 with no body.
    • 404 if sessionId is not found.

Runtime (codeRunner) changes

  • Controller

    • jupyterClientMap, defaultLanguageSessions, and commandClientMap are now sync.Map for concurrent access; bashSessionClientMap (also sync.Map) was added for pipe-based bash sessions.
    • Bash language execution is unchanged: CreateContext and Execute for language: bash still use the Jupyter backend. No behavior change for existing /code and /code/context callers.
  • Session-only entrypoints (used only by the new API)

    • CreateBashSession(req *CreateContextRequest) (string, error) — creates a pipe-based bash session and returns its ID.
    • RunInBashSession(ctx, req *ExecuteCodeRequest) error — runs code in an existing session; req.Context must be the session ID.
    • DeleteBashSession(sessionID string) error — closes the session and removes it from the map.
  • Context / cleanup

    • DeleteContext / GetContext / ListContext continue to operate only on Jupyter-backed contexts. Pipe-based sessions are not listed or deleted via these; they are managed solely via the new Session API.

Web layer

  • Models (pkg/web/model/session.go): CreateSessionRequest, CreateSessionResponse, RunInSessionRequest (with validation).
  • Handlers (in CodeInterpretingController): CreateSession, RunInSession, DeleteSession, each calling the corresponding runtime method above.
  • Router (pkg/web/router.go): new /session group with the three routes.

Testing

  • Not run (explain why)
  • Unit tests
  • Integration tests
  • e2e / manual verification

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Checklist

  • Linked Issue or clearly described motivation
  • Added/updated docs (if needed)
  • Added/updated tests (if needed)
  • Security impact considered
  • Backward compatibility considered

@Pangjiping Pangjiping added the feature New feature or request label Jan 18, 2026
@jwx0925
Copy link
Collaborator

jwx0925 commented Jan 19, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b20500ddb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@hittyt hittyt self-requested a review February 3, 2026 01:07
hittyt
hittyt previously approved these changes Feb 3, 2026
Copy link
Collaborator

@hittyt hittyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Pangjiping Pangjiping marked this pull request as draft February 4, 2026 01:37
@Pangjiping Pangjiping changed the title FEATURE: optmize bash execution by pty FEATURE: Add Session API for pipe-based bash sessions in execd Mar 15, 2026
@Pangjiping Pangjiping marked this pull request as ready for review March 15, 2026 13:39
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dc145d1587

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +202 to +203
ctx, cancel := context.WithTimeout(context.Background(), wait)
defer cancel()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate caller cancellation into bash session execution

RunInSession passes a request-scoped context, but bashSession.run discards it and always starts from context.Background(). In practice, if the client disconnects or the server cancels the request, the spawned bash process keeps running until the internal timeout (24h by default when timeout_ms is omitted), which can leave long-running commands consuming resources after the API call is gone.

Useful? React with 👍 / 👎.

Comment on lines +474 to +476
s.started = false
s.env = nil
s.cwd = ""

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Terminate running bash process when closing a session

Session close currently only flips in-memory flags and clears state, but never signals the active child process. Since both interrupt and delete paths call this close logic, a running command like sleep 600 will continue executing even after the API reports success, which breaks interrupt semantics and can leave orphaned work running in the container.

Useful? React with 👍 / 👎.

Comment on lines +45 to +46
func (c *Controller) createBashSession(_ *CreateContextRequest) (string, error) {
session := newBashSession(nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply requested cwd during bash session creation

createBashSession ignores the incoming CreateContextRequest entirely and always initializes the session with default state. As a result, POST /session with a cwd does not actually set the starting working directory, so the first command runs in an unexpected directory until callers manually cd.

Useful? React with 👍 / 👎.

Comment on lines +242 to +243
if err := c.bindJSON(&request); err != nil {
c.RespondError(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept empty request bodies for session creation

CreateSession always decodes JSON and treats decode errors as bad requests, so an empty body returns EOF and 400. Because CreateSessionRequest has no required fields and callers should be able to create a session without options, this makes a no-body POST /session fail unless clients send {} explicitly.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/execd feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants