Sessions

session.prompt()

Add a new user input into a Session actor and get back a turn handle

session.prompt()

session.prompt() is the unified Session input API for both local Agent and RemoteAgent.

You do not decide whether a new input is:

  • the first turn
  • a mid-run correction
  • a queued next turn

You always call the same method:

const turn = await session.prompt({
  query: "Analyze this repository",
});

await turn.finished;

Passing a parts array

query also accepts a SessionUserMessagePart array, so you can include images, files, and other parts:

import type { SessionUserMessagePart } from "@downcity/agent";

const parts: SessionUserMessagePart[] = [
  { type: "text", text: "Analyze this image" },
  { type: "file", mediaType: "image/png", url: "https://example.com/image.png" },
];

const turn = await session.prompt({
  query: parts,
});

await turn.finished;

Image file parts can also use a local absolute path or a file:// URL. A local Agent reads the file and converts it to data:<mediaType>;base64,... before calling the model:

const turn = await session.prompt({
  query: [
    { type: "text", text: "What does this image say?" },
    {
      type: "file",
      mediaType: "image/png",
      filename: "image.png",
      url: "/Users/me/project/.downcity/input/image.png",
    },
  ],
});

Example

const session = await agent.session_collection().get_session("repo-analysis");

const turn = await session.prompt({
  query: "Analyze this repository",
});

await session.prompt({
  query: "Only look at the Downcity path",
});

await turn.finished;

What it returns

prompt() resolves only after the new input has been attached to a concrete turn.

The returned handle gives you:

  • turn.id
  • turn.finished
  • turn.result

What the Session does internally

  • if the session is idle, it starts a new turn
  • if the current turn can still absorb new user input, it merges it
  • otherwise it queues the input for the next turn

The caller does not need to manage a second queue or a second runtime.