pinecallDocs
Running an agent / pinecall start

pinecall start

Hold the agent's line: the process you deploy.

pinecall start [agent.tsx] [--agent <name>] [--prod] [--ui] [--events] [--show-prompt]
               [--inspect[=host:port] | --inspect-brk]

At a project's root with no file named, every agents/<name>/agent.tsx is held at once, in one process: see The project. They must be in one language, as one process serves them; a project with a Ruby agent and a TypeScript one is told to name one with --agent.

Two processes, two sockets. start never loads your class. It starts the agent's language's serve entry — the project's @pinecall/agents/serve for TypeScript, Pinecall::Serve for Ruby, through bundler when the project has a Gemfile, python -m pinecall.serve for Python, with the project's .venv/bin/python when it has one and python3 when not — which holds the agents and serves their calls, and it watches that process: its lines are what start prints. Beside it, start holds a socket of its own that takes no call and answers the console's screens (answers_dev); the panel beside a conversation is drawn by the class's process. pinecall agent list shows both, the second named pinecall-cli/<version>. --inspect opens the agent's process to a debugger.

The app registered on the gateway and answering: this is the process you deploy, the same one on a laptop and on a server. With nothing said it holds the sandbox agent — at PINECALL_URL, with the project's key, saying pinecall-env: sandbox (above) — and in the sandbox the agent is held per person: two developers of one tenant each run the same agent and each reaches their own, while a number is one endpoint and rings in one place — a developer's own phone reaches their copy, and anybody else's call lands where the line was claimed (line). An admin, and whoever runs the gateway, see every corner of the sandbox rather than only their own.

--prod runs production's agent, the one the org's customers reach, at PINECALL_URL. On a server that is a production server's token in PINECALL_KEY, which was made for it and is refused without the flag; on a person's key it opens only while their production switch is on, and the gateway's refusal is printed before anything registers. How a server runs it — under the process manager, or inside your own Node app — is Production.

It binds no port and serves no page. One line per log entry on stdout, and under the connected line where its console is — and there are two consoles, one per environment, both served by the one gateway: the sandbox's under /sandbox, production's at the root. In the sandbox the line reads console https://cloud.pinecall.io/sandbox/a/clinica-norte?login=lc_… and in production console https://cloud.pinecall.io/a/clinica-norte?login=lc_…: a one-use code the gateway minted in that environment for the key this process holds, dead in five minutes, which the page spends for a key of its own and never sees this process's. Only in a terminal: when stdout is not one — pm2, systemd, a container, a hosted app — the line is the console's address with no code (console https://cloud.pinecall.io/a/clinica-norte) and none is minted, because that output is a log somebody else reads later. Opening a console without one asks for an email, a password, and the org only when the person belongs to several.

In the sandbox, every time the socket comes up — the first connect and each reconnect, in every mode — start re-sends the phone pinecall line from kept for the sandbox, whatever agents it holds — no class declares a number, so there is no way to tell from here which agent has one. The gateway keeps that phone only beside its live table, so a gateway that restarted learns it back at once instead of sending your test call to production. A gateway that goes away is one line — gateway … — reconnecting, then gateway back — and never a stack per redial.

A signal drains before it leaves. SIGTERM (a deploy) or SIGINT (Ctrl-C, or q in --ui) is passed to the agent's process once, which sends agent.drain for every agent: the gateway hands the live calls to another process holding the agent, or keeps them for the next one that registers, and the tools running now are let finish, up to 30 s. One line on stderr says what happened — draining · 1 live call kept for the next process · 1 tool finished — and then both processes exit. A second signal kills the agent's process at once, and so does one it has not left by in 40 s. If start itself is killed, the agent's process sees its stdin close and drains on its own. Give it that long under its manager (Production).

Terminal
$ pinecall start
clinica-norte · clinica · sandbox · connected to https://cloud.pinecall.io · key from .env · tools 4
console  https://cloud.pinecall.io/sandbox/a/clinica-norte?login=lc_9f2   (opens within five minutes, once)
doors    web · phone +34910000000
line     rings in this terminal · also running: carla@clinica.test
› Clínica Norte, good morning. How can I help you?
‹ I'd like to change an appointment
→ findPatient({"name":"Ana García","phone":"600000001"})
← findPatient {"id":"p-1041","appointment":"Thursday at ten"}
flag
--prod production's agent, at PINECALL_URL: a production server's token, or a person's key while their switch is on
--ui the full-screen terminal view. p pause · c clear · e events · q quit. The prompt a call is in is not on screen: the gateway keeps a hash of each block, not its text — pinecall prompt prints the page a state produces
--events the agent's process's own lines: one JSON object per wire entry, {"type","agent","call","data"} with data as the gateway wrote it (snake_case), agent.registered first, for a pipe
--show-prompt the prompt a fresh instance would produce, through the agent's serve entry, then exit. No key, no gateway
--inspect · --inspect-brk Node's own flag, given to the agent's process; a Ruby or Python agent runs no Node and is refused it

It answers the console for this directory. What a screen needs of the agent's directory — a written call to the agent here, a simulation, the goldens and a suite, the documents pushed and their golden asked, the memory goldens, a call promoted to a candidate, the drift, a reproduction a broken run left — the console asks the gateway, and the gateway asks THIS process over its companion socket (dev.request → dev.answer; the runtime's docs/protocol/dev-verbs.md), which reaches the agent's process by its app id when a call is needed. The lines those verbs print land here, as if you had typed them. A pinecall start in another agent's directory answers simulate with a sentence saying so.