Description
Agent.create() is typed and implemented as Promise<SDKAgent>. Two cookbook embedders treat the return value as an agent handle and call .send() / .close() / Symbol.asyncDispose on the promise.
Coding Agent CLI
CodingAgentSession stores the create promise on this.agent: SDKAgent and never awaits it in the constructor or replaceAgent():
https://github.com/cursor/cookbook/blob/main/sdk/coding-agent-cli/src/agent.ts#L80-L88
constructor(options: CodingAgentSessionOptions) {
this.apiKey = options.apiKey
this.cwd = options.cwd
this.force = options.force
this.mode = options.executionMode ?? "local"
this.modelSelection = options.model
this.agent = this.createAgent()
this.agentKey = this.currentAgentKey()
}
https://github.com/cursor/cookbook/blob/main/sdk/coding-agent-cli/src/agent.ts#L230-L235
private async replaceAgent() {
const previousAgent = this.agent
this.agent = this.createAgent()
this.agentKey = this.currentAgentKey()
await previousAgent[Symbol.asyncDispose]()
}
sendPrompt() then does await this.agent.send(...). If this.agent is still a Promise, that is Promise.send, which is not a function.
App Builder project-name helper
The session path already awaits correctly (session.agent = await Agent.create(...)). The project-name path does not:
https://github.com/cursor/cookbook/blob/main/sdk/app-builder/src/lib/app-builder/server.ts#L337-L353
const agent = Agent.create({
apiKey,
model: { id: process.env.CURSOR_PROJECT_NAME_MODEL ?? "composer-2" },
})
try {
const run = await agent.send(buildProjectNamePrompt(context))
// ...
} finally {
agent.close()
}
Expected
Every Agent.create() / Agent.resume() call is awaited before the handle is used, matching the quickstart and getOrCreateAgent().
Suggested fix
- CLI: make
createAgent() async, await it in the constructor (or defer create until first sendPrompt), and await the new agent in replaceAgent() before disposing the old one.
- App Builder:
const agent = await Agent.create(...) in promptProjectNameWithXml.
Description
Agent.create()is typed and implemented asPromise<SDKAgent>. Two cookbook embedders treat the return value as an agent handle and call.send()/.close()/Symbol.asyncDisposeon the promise.Coding Agent CLI
CodingAgentSessionstores the create promise onthis.agent: SDKAgentand never awaits it in the constructor orreplaceAgent():https://github.com/cursor/cookbook/blob/main/sdk/coding-agent-cli/src/agent.ts#L80-L88
https://github.com/cursor/cookbook/blob/main/sdk/coding-agent-cli/src/agent.ts#L230-L235
sendPrompt()then doesawait this.agent.send(...). Ifthis.agentis still aPromise, that isPromise.send, which is not a function.App Builder project-name helper
The session path already awaits correctly (
session.agent = await Agent.create(...)). The project-name path does not:https://github.com/cursor/cookbook/blob/main/sdk/app-builder/src/lib/app-builder/server.ts#L337-L353
Expected
Every
Agent.create()/Agent.resume()call is awaited before the handle is used, matching the quickstart andgetOrCreateAgent().Suggested fix
createAgent()async, await it in the constructor (or defer create until firstsendPrompt), and await the new agent inreplaceAgent()before disposing the old one.const agent = await Agent.create(...)inpromptProjectNameWithXml.