ConversationHandle
Invocation-bound conversation handles: what a task phase (TaskRuntime.conversation) or a tool execution
(ToolCall.conversation) uses to drive another conversation, such as a subagent’s. Every operation, and every
operation of a submission it returns, fails with InvocationEnded once the invocation that obtained the handle has
ended, and an operation in flight when it ends is interrupted with that error. Work already admitted stays durable.
import { type Ids, TaskRuntime } from "@effective-harness/core"import * as Effect from "effect/Effect"import * as Option from "effect/Option"
declare const childId: Ids.ConversationId
const program = Effect.gen(function* () { const child = yield* TaskRuntime.conversation(childId) if (Option.isSome(child)) { const submission = yield* child.value.submit({ type: "input", content: "Summarize the plot" }) const settled = yield* submission.wait }})Since v0.0.0
ConversationHandle (interface)
Section titled “ConversationHandle (interface)”Signature
export interface ConversationHandle { readonly id: ConversationId /** * Admit an input, as `Conversation.submit`. The admission is checked on the commit line: it fails with * `InvocationEnded` (or `TaskRejected`, once the invoking task is abort-marked) instead of landing after its * invocation stopped. */ readonly submit: ( draft: InputDraft ) => Effect.Effect<SubmissionHandle, CommitError | ConversationBusy | InvocationEnded | SchedulerClosed> /** Withdraw the queued inputs, abort the ordinary work and wait until idle, as `Conversation.abort`. */ readonly abort: (options?: { readonly background?: boolean }) => Effect.Effect<void, CommitError | SchedulerClosed | InvocationEnded> /** Wait until the conversation has no live non-background work. */ readonly waitForIdle: Effect.Effect<void, SchedulerClosed | InvocationEnded>}Since v0.0.0
InputDraft (type alias)
Section titled “InputDraft (type alias)”A user input; passive entries are written with ordinary transaction writes instead.
Signature
type InputDraft = Extract<SubmissionDraft, { readonly type: "input" }>Since v0.0.0
SubmissionHandle (interface)
Section titled “SubmissionHandle (interface)”An admitted submission, bound to the invocation that made it.
Signature
export interface SubmissionHandle { readonly id: SubmissionId /** The committed record; see `Submission.status`. */ readonly status: Effect.Effect< SubmissionRecord, SubmissionNotFound | StorageFailure | SessionPoisoned | InvocationEnded > /** Wait until it settles; see `Submission.wait`. */ readonly wait: Effect.Effect<Settled, SubmissionNotFound | StorageFailure | SessionPoisoned | InvocationEnded> /** Withdraw it while it is queued; see `Submission.abort`. */ readonly abort: Effect.Effect< "aborted" | "already_placed" | "settled", SubmissionNotFound | CommitError | InvocationEnded >}Since v0.0.0
Submitter (interface)
Section titled “Submitter (interface)”How the scheduler’s handles admit and follow submissions. The Harness supplies it; a scheduler without one gives
handles whose submit dies.
Signature
export interface Submitter { /** Admit an input in the current commit (`Tx` provided), as `Conversation.submit` does in its own. */ readonly admit: ( conversationId: ConversationId, draft: InputDraft ) => Effect.Effect<SubmissionId, CommitError | ConversationBusy, Tx> readonly status: ( id: SubmissionId ) => Effect.Effect<SubmissionRecord, SubmissionNotFound | StorageFailure | SessionPoisoned> readonly wait: (id: SubmissionId) => Effect.Effect<Settled, SubmissionNotFound | StorageFailure | SessionPoisoned> readonly abort: ( id: SubmissionId ) => Effect.Effect<"aborted" | "already_placed" | "settled", SubmissionNotFound | CommitError>}Since v0.0.0