Skip to content

[FEATURE]: add sleep() in codemode #56940

Open

Description

@soyasoya5

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Add a sleep global in codemode so LLMs can throttle tool calls. This is helpful in cases where simple rate limits are needed.

Activity

  1. opencode-agent commented on Oct 19, 2026

    @opencode-agent
    Contributor

    Thanks for the suggestion! You're asking for a sleep() global in Code Mode so the model can space out tool calls, for example to stay under an API's rate limit. Right now Code Mode deliberately has no timers (the only extra global is fetch), and plugins can't add new globals. Maintainers will consider this, but I can't promise when or whether it will happen.

    In the meantime, a small plugin can register a sleep tool that Code Mode can call. Save this as .opencode/plugins/codemode-sleep.ts in your project, or as ~/.config/opencode/plugins/codemode-sleep.ts to use it everywhere:

    import { Plugin } from "@opencode/plugin"
    
    const MAX_MS = 60_000
    
    export default Plugin.define({
      id: "codemode-sleep",
      setup: async (ctx) => {
        await ctx.tool.transform((editor) => {
          editor.add({
            name: "sleep",
            description: `Wait for the given number of milliseconds (max ${MAX_MS}) before continuing, e.g. to throttle rate-limited calls.`,
            input: {
              type: "object",
              properties: { ms: { type: "integer", minimum: 0, maximum: MAX_MS } },
              required: ["ms"],
              additionalProperties: false,
            },
            options: { codemode: true },
            execute: async (input, context) => {
              const ms = Math.min(Math.max(0, Number((input as { ms: number }).ms) || 0), MAX_MS)
              await new Promise<void>((resolve, reject) => {
                const timer = setTimeout(resolve, ms)
                context.signal.addEventListener("abort", () => {
                  clearTimeout(timer)
                  reject(context.signal.reason)
                }, { once: true })
              })
              return { content: `Slept ${ms}ms` }
            },
          })
        })
      },
    })

    The model should then be able to call await tools.sleep({ ms: 1000 }) between calls inside execute. Each call is capped at 60 seconds, and stopping the session cancels the wait. I've checked that this type-checks against @opencode/plugin but haven't tested it in a running OpenCode.

    Related issues:

  2. aviralb1311 commented on Oct 19, 2026

    @aviralb1311

    I'd like to implement sleep(ms) as a native Code Mode global for intentional pauses between tool calls.

    Proposed behavior:

    • Support await sleep(1000) and resolve with undefined.
    • Accept finite, non-negative millisecond durations and reject invalid values rather than silently coercing them.
    • Cap each wait at 60 seconds, consistent with the limit discussed in this issue.
    • Implement the wait with Effect.sleep so execution interruption and timeout cancel the pending wait through the existing Effect runtime.
    • Add focused tests for elapsed waiting, invalid and out-of-range values, the maximum duration, and interruption.

    I'll register the global through the existing interpreter globals mechanism and follow the current native-function conventions. Does this API and limit fit the intended Code Mode design before I proceed with the implementation?

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions