@slopus/happy-terminal 0.3.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/LICENSE-CODEX +203 -0
- package/LICENSE-GROK-BUILD +204 -0
- package/LICENSE-HAPPY +21 -0
- package/README.md +60 -0
- package/THIRD-PARTY-NOTICES.md +34 -0
- package/dist/HappyTerminalUserError.d.ts +12 -0
- package/dist/app/AppTranscriptEntry.d.ts +33 -0
- package/dist/app/AppendOnlyStreamingRender.d.ts +12 -0
- package/dist/app/CodexFileDiff.d.ts +20 -0
- package/dist/app/CodexMcpToolCall.d.ts +25 -0
- package/dist/app/CodingAssistantAgentBackend.d.ts +81 -0
- package/dist/app/CodingAssistantApp.d.ts +128 -0
- package/dist/app/CompletedTurn.d.ts +11 -0
- package/dist/app/FileMentionAutocomplete.d.ts +30 -0
- package/dist/app/HappyTerminalProcessTerminal.d.ts +7 -0
- package/dist/app/NoticeChild.d.ts +4 -0
- package/dist/app/SecretMenuController.d.ts +31 -0
- package/dist/app/SelectionList.d.ts +24 -0
- package/dist/app/SessionDraftSync.d.ts +51 -0
- package/dist/app/StartupStatusApp.d.ts +34 -0
- package/dist/app/StartupStatusCardModel.d.ts +22 -0
- package/dist/app/TemporaryFullscreenController.d.ts +9 -0
- package/dist/app/TerminalColorLevel.d.ts +1 -0
- package/dist/app/TerminalOutputTrace.d.ts +12 -0
- package/dist/app/TerminalTheme.d.ts +11 -0
- package/dist/app/TranscriptEntryRenderCache.d.ts +10 -0
- package/dist/app/applyWorkflowRunUpdate.d.ts +2 -0
- package/dist/app/blendComposerBackground.d.ts +2 -0
- package/dist/app/boundedJsonStringify.d.ts +1 -0
- package/dist/app/calculateCacheHitPercent.d.ts +2 -0
- package/dist/app/codexDiffAnsi.d.ts +17 -0
- package/dist/app/compactCompletedTurnEntries.d.ts +2 -0
- package/dist/app/containsMarkdownTable.d.ts +1 -0
- package/dist/app/createAgentMarkdownTheme.d.ts +3 -0
- package/dist/app/createBackgroundTerminalViewer.d.ts +16 -0
- package/dist/app/createCompletedTurn.d.ts +6 -0
- package/dist/app/createEditorTheme.d.ts +3 -0
- package/dist/app/createFileMentionAutocompleteItems.d.ts +3 -0
- package/dist/app/createSecretInputPanel.d.ts +12 -0
- package/dist/app/createSelectionPanel.d.ts +14 -0
- package/dist/app/createSerialTaskQueue.d.ts +1 -0
- package/dist/app/createSessionPicker.d.ts +17 -0
- package/dist/app/createSlashCommands.d.ts +7 -0
- package/dist/app/createStopOnceHandler.d.ts +1 -0
- package/dist/app/createSubagentMonitor.d.ts +17 -0
- package/dist/app/createTerminalInputBurstHandler.d.ts +5 -0
- package/dist/app/createWorkflowMonitor.d.ts +15 -0
- package/dist/app/defaultTerminalTheme.d.ts +1 -0
- package/dist/app/describeModelChoice.d.ts +4 -0
- package/dist/app/describeProviderSignIn.d.ts +2 -0
- package/dist/app/describeReasoningLevel.d.ts +4 -0
- package/dist/app/detectCodexDiffLanguage.d.ts +1 -0
- package/dist/app/encodeModelChoice.d.ts +1 -0
- package/dist/app/endsAfterOpeningCodeFence.d.ts +1 -0
- package/dist/app/findFileMentionContext.d.ts +9 -0
- package/dist/app/findFileMentionPrefix.d.ts +5 -0
- package/dist/app/formatActivityElapsedTime.d.ts +1 -0
- package/dist/app/formatCodexMcpToolResult.d.ts +3 -0
- package/dist/app/formatCompactTokens.d.ts +1 -0
- package/dist/app/formatFileMention.d.ts +1 -0
- package/dist/app/formatProviderError.d.ts +6 -0
- package/dist/app/formatRelativeTime.d.ts +2 -0
- package/dist/app/formatResetDuration.d.ts +1 -0
- package/dist/app/formatSessionPickerEntry.d.ts +14 -0
- package/dist/app/formatSessionTokenStatus.d.ts +6 -0
- package/dist/app/formatSessionUsageSummary.d.ts +3 -0
- package/dist/app/formatStartupStatusUsageRemaining.d.ts +2 -0
- package/dist/app/formatStartupStatusUsageRows.d.ts +2 -0
- package/dist/app/formatSubagentToolCall.d.ts +10 -0
- package/dist/app/formatToolPermissionNotice.d.ts +3 -0
- package/dist/app/formatToolResultForDisplay.d.ts +2 -0
- package/dist/app/formatTurnUsageSummary.d.ts +2 -0
- package/dist/app/formatWorkUsageSummary.d.ts +14 -0
- package/dist/app/highlightAgentCode.d.ts +1 -0
- package/dist/app/highlightCodexDiffLine.d.ts +2 -0
- package/dist/app/highlightShellCommand.d.ts +1 -0
- package/dist/app/humanizeGoalStatus.d.ts +2 -0
- package/dist/app/humanizeMcpName.d.ts +1 -0
- package/dist/app/humanizePermissionMode.d.ts +2 -0
- package/dist/app/humanizePermissionReviewLevel.d.ts +2 -0
- package/dist/app/humanizeProviderId.d.ts +1 -0
- package/dist/app/humanizeReasoningLevel.d.ts +1 -0
- package/dist/app/humanizeSubagentStatus.d.ts +2 -0
- package/dist/app/humanizeToolName.d.ts +1 -0
- package/dist/app/humanizeWorkflowStatus.d.ts +2 -0
- package/dist/app/installResumeInstructions.d.ts +26 -0
- package/dist/app/installTerminalCrashCleanup.d.ts +26 -0
- package/dist/app/isLightTerminalBackground.d.ts +2 -0
- package/dist/app/layoutCodexFileDiff.d.ts +13 -0
- package/dist/app/looksLikeAuthenticationFailure.d.ts +5 -0
- package/dist/app/nearestXtermColorIndex.d.ts +2 -0
- package/dist/app/parseCodexMcpToolInvocation.d.ts +2 -0
- package/dist/app/parseSessionCommand.d.ts +6 -0
- package/dist/app/providerErrorResetAt.d.ts +2 -0
- package/dist/app/providerQuotaToStartupStatusUsage.d.ts +3 -0
- package/dist/app/readClipboardImage.d.ts +9 -0
- package/dist/app/renderActivityWave.d.ts +3 -0
- package/dist/app/renderAgentMarkdown.d.ts +8 -0
- package/dist/app/renderBackgroundTerminalCompletion.d.ts +1 -0
- package/dist/app/renderBackgroundTerminalInteraction.d.ts +2 -0
- package/dist/app/renderBackgroundTerminalSummary.d.ts +1 -0
- package/dist/app/renderChildRows.d.ts +13 -0
- package/dist/app/renderCodexDiffLine.d.ts +3 -0
- package/dist/app/renderCodexFileDiff.d.ts +7 -0
- package/dist/app/renderCodexMcpToolCall.d.ts +2 -0
- package/dist/app/renderCompletedTurnStats.d.ts +2 -0
- package/dist/app/renderExecCommand.d.ts +11 -0
- package/dist/app/renderExploration.d.ts +9 -0
- package/dist/app/renderFullscreenComponent.d.ts +8 -0
- package/dist/app/renderHappyTerminalBanner.d.ts +6 -0
- package/dist/app/renderHappyTerminalVersion.d.ts +1 -0
- package/dist/app/renderNoticeWithChildren.d.ts +7 -0
- package/dist/app/renderPendingSteeringMessages.d.ts +1 -0
- package/dist/app/renderStartupStatusCard.d.ts +7 -0
- package/dist/app/renderSubagentSummary.d.ts +6 -0
- package/dist/app/renderTurnCompletionSeparator.d.ts +1 -0
- package/dist/app/renderWorkflowSummary.d.ts +1 -0
- package/dist/app/resolveInputBackground.d.ts +3 -0
- package/dist/app/resolveStartupProviderQuota.d.ts +3 -0
- package/dist/app/resolveStartupSessionId.d.ts +18 -0
- package/dist/app/resolveTerminalColorLevel.d.ts +2 -0
- package/dist/app/resolveTerminalStyle.d.ts +1 -0
- package/dist/app/resolveTerminalTheme.d.ts +5 -0
- package/dist/app/runApp.d.ts +27 -0
- package/dist/app/runClipboardCommand.d.ts +8 -0
- package/dist/app/sanitizeTerminalText.d.ts +1 -0
- package/dist/app/shortenHomePath.d.ts +2 -0
- package/dist/app/sortSubagentsForDisplay.d.ts +2 -0
- package/dist/app/subagentElapsedMs.d.ts +2 -0
- package/dist/app/subagentLogMessageText.d.ts +2 -0
- package/dist/app/surfaceThemedLine.d.ts +3 -0
- package/dist/app/truncatePathToWidth.d.ts +1 -0
- package/dist/app/truncateTextForDisplay.d.ts +5 -0
- package/dist/app/truncateUtf8BytesForDisplay.d.ts +1 -0
- package/dist/app/upsertSubagentSummary.d.ts +2 -0
- package/dist/app/workflowDisplay.d.ts +2 -0
- package/dist/client/HappyAgentEventHub.d.ts +25 -0
- package/dist/client/RemoteAgent.d.ts +74 -0
- package/dist/client/RemoteAgentRunError.d.ts +4 -0
- package/dist/client/RemoteTerminalAttachment.d.ts +19 -0
- package/dist/client/RemoteTerminalClientReplica.d.ts +14 -0
- package/dist/client/ensureLocalProtocolServer.d.ts +10 -0
- package/dist/client/fetchProviderQuotas.d.ts +10 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/loadAgentCatalog.d.ts +32 -0
- package/dist/config/createProjectConfigSecurityNotice.d.ts +10 -0
- package/dist/config/defaultConfig.d.ts +2 -0
- package/dist/config/getDefaultGlobalConfigPath.d.ts +1 -0
- package/dist/config/getDefaultLocalConfigPath.d.ts +1 -0
- package/dist/config/getDefaultRuntimeConfigPath.d.ts +1 -0
- package/dist/config/getHappyConfigDirectory.d.ts +1 -0
- package/dist/config/getHappyTerminalHome.d.ts +1 -0
- package/dist/config/index.d.ts +15 -0
- package/dist/config/loadConfig.d.ts +2 -0
- package/dist/config/mergeConfigValues.d.ts +2 -0
- package/dist/config/parseConfigToml.d.ts +7 -0
- package/dist/config/readConfigFile.d.ts +2 -0
- package/dist/config/readProjectConfigFile.d.ts +2 -0
- package/dist/config/resolveConfigPaths.d.ts +2 -0
- package/dist/config/runtimeConfigLock.d.ts +1 -0
- package/dist/config/types.d.ts +74 -0
- package/dist/config/updateRuntimeConfig.d.ts +2 -0
- package/dist/config/updateRuntimePreferences.d.ts +2 -0
- package/dist/config/withoutProjectMachineSettings.d.ts +7 -0
- package/dist/config/writeRuntimeConfig.d.ts +3 -0
- package/dist/config/writeRuntimeConfigDefaults.d.ts +2 -0
- package/dist/daemon/createUnixSocketFetch.d.ts +2 -0
- package/dist/daemon/daemonPid.d.ts +11 -0
- package/dist/daemon/ensureHappyAgentBinary.d.ts +15 -0
- package/dist/daemon/ensureLocalProtocolServer.d.ts +24 -0
- package/dist/daemon/getHappyDaemonPaths.d.ts +16 -0
- package/dist/daemon/happyAgentBinaryConfig.d.ts +15 -0
- package/dist/daemon/index.d.ts +5 -0
- package/dist/daemon/runDaemonCommand.d.ts +4 -0
- package/dist/debug/DebugLog.d.ts +11 -0
- package/dist/debug/closeNodeInspector.d.ts +1 -0
- package/dist/debug/createDebugJsonReplacer.d.ts +1 -0
- package/dist/debug/createRequestDebugDirectory.d.ts +1 -0
- package/dist/debug/getDebugRootDirectory.d.ts +1 -0
- package/dist/debug/getNodeInspectorUrl.d.ts +1 -0
- package/dist/debug/index.d.ts +8 -0
- package/dist/debug/openNodeInspector.d.ts +1 -0
- package/dist/debug/registerHappyTerminalDebugRoot.d.ts +5 -0
- package/dist/docs/DESIGN.md +2191 -0
- package/dist/docs/README.md +93 -0
- package/dist/docs/agents-and-collaboration.md +365 -0
- package/dist/docs/architecture.md +468 -0
- package/dist/docs/extending.md +561 -0
- package/dist/docs/happy.md +386 -0
- package/dist/docs/permissions-and-sandbox.md +342 -0
- package/dist/docs/workspaces.md +281 -0
- package/dist/errorToMessage.d.ts +1 -0
- package/dist/formatCliFailure.d.ts +10 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +17151 -0
- package/dist/main.js +18946 -0
- package/dist/observability/daemonContext.d.ts +16 -0
- package/dist/observability/index.d.ts +1 -0
- package/dist/processes/BoundedOutputBuffer.d.ts +20 -0
- package/dist/processes/NativeProcessManager.d.ts +66 -0
- package/dist/processes/ProcessGroupReaper.d.ts +32 -0
- package/dist/processes/index.d.ts +7 -0
- package/dist/processes/isProcessRunning.d.ts +1 -0
- package/dist/processes/isTargetProcessAlive.d.ts +1 -0
- package/dist/processes/killProcessTree.d.ts +2 -0
- package/dist/processes/resolveSystemShell.d.ts +1 -0
- package/dist/processes/startProcessTransport.d.ts +33 -0
- package/dist/processes/types.d.ts +41 -0
- package/dist/processes/waitForProcessExit.d.ts +2 -0
- package/dist/protocol/AppletProtocol.d.ts +101 -0
- package/dist/protocol/Attachment.d.ts +96 -0
- package/dist/protocol/ClientProtocolTypes.d.ts +481 -0
- package/dist/protocol/DocumentProtocol.d.ts +109 -0
- package/dist/protocol/EventId.d.ts +1 -0
- package/dist/protocol/FolderProtocol.d.ts +236 -0
- package/dist/protocol/FolderSharingProtocol.d.ts +97 -0
- package/dist/protocol/GitHubPluginProtocol.d.ts +43 -0
- package/dist/protocol/GlobalSecurityProtocol.d.ts +7 -0
- package/dist/protocol/HappyCloudProtocol.d.ts +178 -0
- package/dist/protocol/InstallationProtocol.d.ts +80 -0
- package/dist/protocol/OnboardingProtocol.d.ts +47 -0
- package/dist/protocol/P2pCredentialProtocol.d.ts +273 -0
- package/dist/protocol/P2pIdentityProtocol.d.ts +8 -0
- package/dist/protocol/P2pPairingProtocol.d.ts +68 -0
- package/dist/protocol/P2pProtocol.d.ts +185 -0
- package/dist/protocol/PluginWireTypes.d.ts +81 -0
- package/dist/protocol/ProfileProtocol.d.ts +127 -0
- package/dist/protocol/ProjectFileProtocol.d.ts +63 -0
- package/dist/protocol/ProjectProtocol.d.ts +646 -0
- package/dist/protocol/ProtocolVersion.d.ts +8 -0
- package/dist/protocol/ServiceNotice.d.ts +175 -0
- package/dist/protocol/SessionProtocol.d.ts +1156 -0
- package/dist/protocol/SharingProtocol.d.ts +159 -0
- package/dist/protocol/SlotProtocol.d.ts +270 -0
- package/dist/protocol/TimelineProtocol.d.ts +88 -0
- package/dist/protocol/WorkletProtocol.d.ts +159 -0
- package/dist/protocol/createEventIdFactory.d.ts +7 -0
- package/dist/protocol/index.d.ts +34 -0
- package/dist/readPackageVersion.d.ts +1 -0
- package/dist/readPackageVersion.js +16 -0
- package/dist/reportCliFailure.d.ts +2 -0
- package/dist/runHappyTerminal.d.ts +6 -0
- package/dist/terminal/index.d.ts +2 -0
- package/dist/terminal/types.d.ts +39 -0
- package/dist/types.d.ts +6 -0
- package/dist/writeStderrSync.d.ts +5 -0
- package/package.json +97 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Happy Agent and Happy documentation
|
|
2
|
+
|
|
3
|
+
Welcome. If you are a coding agent reading this, you are almost certainly
|
|
4
|
+
_running inside the system these pages describe_. This folder ships with Happy Agent
|
|
5
|
+
itself and is exposed read-only to agents: on the local host at the installed
|
|
6
|
+
package's `dist/docs` folder, and inside managed Docker containers at
|
|
7
|
+
`/happy/docs`. Its purpose is simple: give you enough understanding of Happy Agent and
|
|
8
|
+
Happy that you can work well inside them — and, when asked, **extend them**.
|
|
9
|
+
|
|
10
|
+
## What is Happy Agent?
|
|
11
|
+
|
|
12
|
+
Happy Agent is an open-source coding-agent harness that recreates the best of Codex,
|
|
13
|
+
Claude Code, and Grok Build in one consistent local runtime. Each model gets its
|
|
14
|
+
_native_ prompts and tools — GPT models see a Codex-shaped world, Claude models
|
|
15
|
+
see a Claude Code-shaped world, Grok sees Grok Build — while everything around
|
|
16
|
+
inference is shared: one permission model, one sandbox, one persistence layer,
|
|
17
|
+
one terminal interface, one way to spawn and talk to agents.
|
|
18
|
+
|
|
19
|
+
Happy Agent adds no account of its own. It uses the credentials already managed by the
|
|
20
|
+
coding agents installed on the machine, and it never pools or resells provider
|
|
21
|
+
access. The headless daemon holds durable sessions. Happy Terminal is the reusable Pi TUI client,
|
|
22
|
+
used by the `happy` CLI, its standalone `happy-terminal` and `rig` commands, embedded Node.js
|
|
23
|
+
applications, and Happy Desktop. Other clients attach through `@slopus/happy-agent-client`.
|
|
24
|
+
|
|
25
|
+
The deeper idea: **agents never die**. Every conversation, every subagent, is a
|
|
26
|
+
durable session that can always receive another message and resume with its
|
|
27
|
+
full context. Agents recognize each other by unguessable Agent IDs and can
|
|
28
|
+
message each other, schedule messages into the future, wait durably, and
|
|
29
|
+
delegate work into isolated Git workspaces.
|
|
30
|
+
|
|
31
|
+
## What is Happy?
|
|
32
|
+
|
|
33
|
+
Happy is a family of two products, built by the same authors as Happy Agent, that put
|
|
34
|
+
people in touch with their coding agents:
|
|
35
|
+
|
|
36
|
+
- **Happy** is end-to-end encrypted remote access to your agents. A mobile and
|
|
37
|
+
web client lets you watch and steer agents running on your own machine from
|
|
38
|
+
anywhere; the relay in between carries only ciphertext and can read nothing.
|
|
39
|
+
- **Happy 2** is its desktop collaborative sibling: a self-hosted, Slack-like
|
|
40
|
+
workspace where people and coding agents build together — conversations,
|
|
41
|
+
files, documents, workspaces, and agents in one web and desktop app, started
|
|
42
|
+
with a single `npx happy2` command, with all state kept locally under
|
|
43
|
+
`.happy2`. It runs its agents on Happy Agent: a private Happy Agent runtime, each agent
|
|
44
|
+
conversation bound to a sandboxed container, Happy Agent sessions, terminals, and
|
|
45
|
+
tools surfaced in its UI.
|
|
46
|
+
|
|
47
|
+
When you are driven through either of them rather than a terminal,
|
|
48
|
+
[happy.md](happy.md) explains what changes for you.
|
|
49
|
+
|
|
50
|
+
## The map
|
|
51
|
+
|
|
52
|
+
Read these in whatever order your task demands; each page stands alone.
|
|
53
|
+
|
|
54
|
+
| Page | What it tells you |
|
|
55
|
+
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| [architecture.md](architecture.md) | How Happy Agent is put together: daemon and TUI, the protocol between them, sessions and durability, providers and model catalogs, inference and compaction, persistence, and how the codebase is organized into packages. |
|
|
57
|
+
| [workspaces.md](workspaces.md) | What a workspace is (a Git worktree on its own branch), how to create, delegate into, and archive one, where they live on disk, and when making one is actually the right call. |
|
|
58
|
+
| [agents-and-collaboration.md](agents-and-collaboration.md) | Subagents, follow-up messages, the `agent_me` / `agent_info` / `agent_send` handshake, scheduling, durable waits, presence, and the concurrency model. |
|
|
59
|
+
| [permissions-and-sandbox.md](permissions-and-sandbox.md) | The four permission modes, the single cross-provider sandbox, how Auto review works, escalation syntax per provider, and why a denied action must never be retried by another route. |
|
|
60
|
+
| [extending.md](extending.md) | How to extend Happy Agent from inside: plugins (TypeScript processes with MCP tools and UI), skills, MCP servers, Happy Agent Connect integrations, and subagents as a runtime extension mechanism. |
|
|
61
|
+
| [DESIGN.md](DESIGN.md) | The visual specification for a Happy plugin app: host style variables, surfaces, layout grid, typography, controls, states, and a copyable baseline. Read it before designing or building a Happy applet or plugin UI. |
|
|
62
|
+
| [happy.md](happy.md) | The Happy family: encrypted remote access to agents with Happy, the collaborative desktop workspace of Happy 2, how each connects to Happy Agent, and what an agent should know when driven through them. |
|
|
63
|
+
|
|
64
|
+
## If you want to extend yourself
|
|
65
|
+
|
|
66
|
+
That is an explicitly supported goal. The short version:
|
|
67
|
+
|
|
68
|
+
1. **Write a plugin** — TypeScript, one `happy.plugin.json` manifest, a
|
|
69
|
+
generated icon, installed with `plugin_install`. A plugin runs as its own
|
|
70
|
+
sandboxed process, talks to Happy Agent over an authenticated socket through the
|
|
71
|
+
`happy-plugins` SDK, and can create workspaces, message agents, expose MCP
|
|
72
|
+
tools to every model, and contribute a local UI. Start with
|
|
73
|
+
[extending.md](extending.md).
|
|
74
|
+
2. **Write a skill** — a `SKILL.md` file with instructions a model loads on
|
|
75
|
+
demand. No process, no manifest beyond frontmatter.
|
|
76
|
+
3. **Spawn agents** — delegate bounded work to subagents on any available
|
|
77
|
+
model, or create a workspace and delegate a whole task into it. See
|
|
78
|
+
[agents-and-collaboration.md](agents-and-collaboration.md).
|
|
79
|
+
4. **Change Happy Agent itself** — Happy Agent is developed with Happy Agent. When you have the Happy Agent
|
|
80
|
+
source checked out, follow the contributor instructions that ship with the
|
|
81
|
+
repository before touching anything.
|
|
82
|
+
|
|
83
|
+
## Ground rules worth internalizing
|
|
84
|
+
|
|
85
|
+
- **One permission model everywhere.** No provider, tool name, or clever
|
|
86
|
+
command phrasing widens what you may do. Escalation is per-action, reviewed,
|
|
87
|
+
and scoped to that one execution.
|
|
88
|
+
- **Durability is the default.** Sessions, transcripts, scheduled messages,
|
|
89
|
+
and waits survive daemon restarts. Design your work around resuming, not
|
|
90
|
+
around finishing in one breath.
|
|
91
|
+
- **A denial is an answer.** When a permission review refuses an action, do
|
|
92
|
+
not pursue the same outcome by another route; take a materially safer
|
|
93
|
+
alternative or stop and explain.
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Agents and collaboration
|
|
2
|
+
|
|
3
|
+
Happy Agent runs many agents at once: the conversation the user is talking to, subagents
|
|
4
|
+
it spawned, agents working in other workspaces, and agents the user connected by
|
|
5
|
+
hand. This document describes how they are started, how they talk to each other,
|
|
6
|
+
how work is scheduled in time, and what the human sees while it happens.
|
|
7
|
+
|
|
8
|
+
One rule underpins the rest: **agents never die**. A subagent that finished its
|
|
9
|
+
task is not gone — its parent can send it a follow-up and it resumes with its
|
|
10
|
+
full context.
|
|
11
|
+
|
|
12
|
+
## Sessions and subagents
|
|
13
|
+
|
|
14
|
+
- A **primary session** is a conversation the user can see and talk to. It owns
|
|
15
|
+
the workspace tools, `schedule_message`, and `cancel_ask`.
|
|
16
|
+
- A **subagent** is an agent spawned and driven by another agent rather than by a
|
|
17
|
+
person. It is not human-visible in the ordinary session list.
|
|
18
|
+
|
|
19
|
+
Subagents are limited by depth and by concurrency:
|
|
20
|
+
|
|
21
|
+
| Limit | Default |
|
|
22
|
+
| --------------------------------------- | ------- |
|
|
23
|
+
| Nesting depth | 3 |
|
|
24
|
+
| Concurrently running subagents per tree | 8 |
|
|
25
|
+
| Same, for Codex v2 collaboration models | 10 |
|
|
26
|
+
|
|
27
|
+
A subagent at maximum
|
|
28
|
+
depth is told to finish the task itself, and a subagent may only delegate further
|
|
29
|
+
when its parent explicitly said so in the assigned task. Having collaboration
|
|
30
|
+
tools is not permission to use them for nested delegation.
|
|
31
|
+
|
|
32
|
+
## Spawning a subagent
|
|
33
|
+
|
|
34
|
+
Each provider keeps its own tool names and schemas; the behavior underneath is
|
|
35
|
+
the same.
|
|
36
|
+
|
|
37
|
+
| Provider | Spawn | Follow-up | Wait / read | Stop |
|
|
38
|
+
| ----------------- | ---------------- | ------------------------------- | -------------------------------------------------------------- | -------------------------- |
|
|
39
|
+
| Claude | `Agent` | `SendMessage` | `TaskOutput` | `TaskStop` |
|
|
40
|
+
| Codex (v2 models) | `spawn_agent` | `followup_task`, `send_message` | `wait_agent`, `list_agents` | `interrupt_agent` |
|
|
41
|
+
| Codex (v1 models) | `spawn_agent` | `resume_agent`, `send_input` | `wait_agent` | `close_agent` |
|
|
42
|
+
| Grok | `spawn_subagent` | `followup_subagent` | `wait_commands_or_subagents`, `get_command_or_subagent_output` | `kill_command_or_subagent` |
|
|
43
|
+
|
|
44
|
+
Which Codex set a model gets is decided per model.
|
|
45
|
+
|
|
46
|
+
The Claude-shaped tool shows every argument that matters:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"description": "Audit retry semantics",
|
|
51
|
+
"prompt": "Read the provider layer and report where retries are replayed...",
|
|
52
|
+
"provider": "claude",
|
|
53
|
+
"model": "anthropic/sonnet-5",
|
|
54
|
+
"effort": "medium",
|
|
55
|
+
"run_in_background": true,
|
|
56
|
+
"context": "task",
|
|
57
|
+
"read_only": true,
|
|
58
|
+
"service_tier": "priority"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Model and effort are required, and are never inherited.** Write the model ID
|
|
63
|
+
exactly as it appears in the _Available models_ section of the system prompt, and
|
|
64
|
+
pick an effort from that model's allowed levels. Use the model's default effort,
|
|
65
|
+
or lower, for research, review, and other bounded work; reserve `xhigh`, `max`,
|
|
66
|
+
and `ultra` for work the user asked to run that way. `provider` is optional and
|
|
67
|
+
is otherwise inferred from recent successful use, the current provider, or the
|
|
68
|
+
first available match.
|
|
69
|
+
|
|
70
|
+
**Context inheritance** is the `context` argument, a Happy Agent extension:
|
|
71
|
+
|
|
72
|
+
- `"task"` (default) — the child starts with only the delegated prompt. Prefer
|
|
73
|
+
this; it keeps the child's context small and its task unambiguous.
|
|
74
|
+
- `"parent"` — the child continues with the parent thread's context.
|
|
75
|
+
|
|
76
|
+
**Background versus foreground**: `run_in_background` defaults to `true`. A
|
|
77
|
+
background spawn returns immediately with `status: "async_launched"` and a task
|
|
78
|
+
name; a foreground spawn (`run_in_background: false`) blocks and returns the
|
|
79
|
+
child's final output. Choose foreground only when you cannot continue without the
|
|
80
|
+
result.
|
|
81
|
+
|
|
82
|
+
**Permissions**: `read_only: true` runs the child in Read only; omitting it means
|
|
83
|
+
the child inherits the parent's permission mode. The same flag on `SendMessage`
|
|
84
|
+
and `agent_send` can tighten or restore a child's mode later.
|
|
85
|
+
|
|
86
|
+
**Service tier**: `service_tier: "priority"` requests priority service when the
|
|
87
|
+
selected provider supports it.
|
|
88
|
+
|
|
89
|
+
### Waiting for background work — do not poll
|
|
90
|
+
|
|
91
|
+
A background subagent notifies its parent when it finishes, even while the parent
|
|
92
|
+
is idle. `TaskOutput` therefore defaults to a one-hour wait for agents (30 seconds
|
|
93
|
+
for shell tasks and workflows). Wait once for a long time, or simply end the turn.
|
|
94
|
+
Every short wait that times out costs a full model turn over the whole context and
|
|
95
|
+
teaches you nothing.
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{ "task_id": "<sessionId>" }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`TaskStop` stops a running or suspended agent; `TaskOutput` with `block: false`
|
|
102
|
+
peeks at its status without waiting.
|
|
103
|
+
|
|
104
|
+
### Follow-up work
|
|
105
|
+
|
|
106
|
+
A finished subagent is still reachable. `SendMessage` resumes it with its context
|
|
107
|
+
preserved:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"to": "audit-retry-semantics",
|
|
112
|
+
"message": "Now check the Grok provider too and update your report.",
|
|
113
|
+
"summary": "Extend the audit",
|
|
114
|
+
"effort": "high"
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`to` accepts the task name, the path, or the agent ID. `effort` changes the
|
|
119
|
+
child's effort for the continued work; `read_only` changes its permission mode.
|
|
120
|
+
Codex uses `followup_task` and Grok uses `followup_subagent` for the same thing.
|
|
121
|
+
|
|
122
|
+
## Talking to any agent: `agent_me`, `agent_info`, `agent_send`
|
|
123
|
+
|
|
124
|
+
Subagent tools only reach your own children. To reach _any_ agent in the system —
|
|
125
|
+
a delegated workspace session, another primary conversation, an agent on another
|
|
126
|
+
machine — Happy Agent uses agent IDs.
|
|
127
|
+
|
|
128
|
+
An agent ID is unguessable. There is no discovery and no listing by design: the
|
|
129
|
+
user shares IDs by hand, or you obtain one from a tool that returns it, such as
|
|
130
|
+
`delegate_to_workspace` or `list_workspace_sessions`.
|
|
131
|
+
|
|
132
|
+
The handshake is three steps:
|
|
133
|
+
|
|
134
|
+
1. **`agent_me`** — your own ID and title. Show it to the human so they can hand
|
|
135
|
+
it to another agent.
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
2. **`agent_info`** — inspect an exact, already-known ID. This _cannot_ search or
|
|
142
|
+
list. It answers with the target's title and either `diskShared: true` plus a
|
|
143
|
+
`path` you can actually use, or `diskShared: false` with a notice that you
|
|
144
|
+
cannot reach its folder.
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{ "agent_id": "agt_..." }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
3. **`agent_send`** — deliver a steering message. Calling `agent_info` for that
|
|
151
|
+
exact ID first is enforced: without it, the send is rejected with "Call
|
|
152
|
+
agent_info with this agent ID before sending it a message."
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{ "agent_id": "agt_...", "message": "Please rebase on origin/main and re-run the suite." }
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The receiver is told who sent the message — the sender's agent ID and title, and
|
|
159
|
+
the sender's folder when the disks are shared — so it can answer through the same
|
|
160
|
+
handshake. `agent_send` also accepts `read_only` for a child this agent started:
|
|
161
|
+
`true` restricts it to Read only, `false` restores the sender's current mode.
|
|
162
|
+
|
|
163
|
+
## Delegating into a workspace
|
|
164
|
+
|
|
165
|
+
Two tools start work in another workspace; see
|
|
166
|
+
[`workspaces.md`](workspaces.md) for the workspace side.
|
|
167
|
+
|
|
168
|
+
- **`spawn_workspace_agent`** — a hidden managed subagent whose working directory
|
|
169
|
+
is the workspace. Appears under your session, reports its result to you, and is
|
|
170
|
+
driven with the ordinary subagent tools.
|
|
171
|
+
- **`delegate_to_workspace`** — a visible conversation with its own place in the
|
|
172
|
+
user's session list. It keeps your session as its parent and returns an
|
|
173
|
+
`agentId`, so you keep talking to it with `agent_info` + `agent_send`.
|
|
174
|
+
|
|
175
|
+
A delegated session sends the run's completion status and result back to its
|
|
176
|
+
delegator. Messages the user writes in that conversation stay in that
|
|
177
|
+
conversation.
|
|
178
|
+
|
|
179
|
+
Only a primary session can delegate, and never into its own workspace.
|
|
180
|
+
|
|
181
|
+
## Scheduling
|
|
182
|
+
|
|
183
|
+
Every model on every provider gets `wait` and `wait_until`. Agents that are not
|
|
184
|
+
subagents also get `schedule_message`; subagents never do.
|
|
185
|
+
|
|
186
|
+
### Durable waits
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{ "duration": "1h 30m" }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`wait` accepts `seconds`, `hours`, `days` (fractional allowed) or a human-readable
|
|
193
|
+
`duration`, up to about 24 hours. `wait_until` takes a date at most 24 hours away
|
|
194
|
+
as ISO 8601, RFC 2822, Unix seconds, or Unix milliseconds:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{ "at": "2026-08-01T18:30:00Z" }
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Both are **durable**: the wait survives a daemon restart, and while it runs the
|
|
201
|
+
session state shows the session as waiting. Any new message in that chat ends the
|
|
202
|
+
wait early. The result says what actually happened:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"started_at": "...",
|
|
207
|
+
"due_at": "...",
|
|
208
|
+
"ended_at": "...",
|
|
209
|
+
"elapsed_seconds": 412,
|
|
210
|
+
"interrupted": true,
|
|
211
|
+
"reason": "message_received"
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Use a wait for real elapsed time — a rate limit, a scheduled event, a deployment
|
|
216
|
+
window. Do not use it as a polling loop over a background subagent.
|
|
217
|
+
|
|
218
|
+
### Scheduled messages
|
|
219
|
+
|
|
220
|
+
`schedule_message` sends a message at a future time to any agent whose exact
|
|
221
|
+
agent ID you know, including yourself:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"agent_id": "agt_...",
|
|
226
|
+
"message": "Check whether the nightly build went green and summarize it.",
|
|
227
|
+
"hours": 8
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Use either `at` (a date) or a delay (`duration`/`seconds`/`hours`/`days`), never
|
|
232
|
+
both. The tool returns `{ id, due_at, status: "pending", target_agent_id }`. If
|
|
233
|
+
delivery fails, the scheduled message stays with the sender. Scheduled messages
|
|
234
|
+
and their updates synchronize on reconnect so the UI can show them, they remain
|
|
235
|
+
in history when an agent stops, and the user can cancel one by hand.
|
|
236
|
+
|
|
237
|
+
Scheduling a message to yourself is the ordinary way to pick work back up later
|
|
238
|
+
without holding a session open.
|
|
239
|
+
|
|
240
|
+
## The Inbox
|
|
241
|
+
|
|
242
|
+
The Inbox is the durable place where agents reach the human. When a model asks a
|
|
243
|
+
question — `AskUserQuestion` for Claude, `request_user_input` for Codex — the
|
|
244
|
+
question appears in the chat _and_ in the Inbox as one shared state. Answering it
|
|
245
|
+
in either place closes it in both; a question answered in the terminal still shows
|
|
246
|
+
in the Inbox, as answered.
|
|
247
|
+
|
|
248
|
+
Because a human may not be looking, a question can hang for a long time, so ask
|
|
249
|
+
well: include the context the person needs to decide without opening the chat, not
|
|
250
|
+
an abstract one-liner.
|
|
251
|
+
|
|
252
|
+
When presence stops the wait before the human answers, the tool returns a
|
|
253
|
+
description that names the presence, says how long it waited, and gives an **ask
|
|
254
|
+
id**. The question stays in the Inbox. You then either continue on your own
|
|
255
|
+
judgement, or withdraw it:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{ "ask_id": "ask_...", "reason": "I went with the safer default and no longer need this." }
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`cancel_ask` is available to primary sessions, not to subagents.
|
|
262
|
+
|
|
263
|
+
## Presence
|
|
264
|
+
|
|
265
|
+
Presence tells every agent whether the human can be reached and what to do when
|
|
266
|
+
they cannot.
|
|
267
|
+
|
|
268
|
+
| State | `answerWaitMs` | Meaning |
|
|
269
|
+
| --------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
270
|
+
| Online 🟢 | `null` | The user is at the keyboard; a question may wait indefinitely. |
|
|
271
|
+
| Away 🌙 | `0` | The user cannot be reached; never wait. Decide with your best judgement, keep working, and record anything they should look at later. |
|
|
272
|
+
|
|
273
|
+
The user can define custom states in configuration. A state carries a title, an
|
|
274
|
+
emoji, a model-facing prompt, and a wait budget that may be unlimited (`null`),
|
|
275
|
+
immediate (`0`), or finite — for example fifteen minutes, after which the agent is
|
|
276
|
+
told to continue on its own. A state can also be temporary, with a fallback state
|
|
277
|
+
to return to when it expires.
|
|
278
|
+
|
|
279
|
+
The current presence is injected into every model, and when it changes mid-run the
|
|
280
|
+
model receives a system notice with the new state and its instructions. Follow the
|
|
281
|
+
active presence's instructions until Happy Agent says they changed. In practice: under
|
|
282
|
+
Away, never block on a human — ask if it is genuinely useful, note it in the
|
|
283
|
+
Inbox, and carry on.
|
|
284
|
+
|
|
285
|
+
## Concurrency model
|
|
286
|
+
|
|
287
|
+
Happy Agent's concurrency is built from a few small lowercase functions, not from classes
|
|
288
|
+
or ad-hoc promise chains:
|
|
289
|
+
|
|
290
|
+
- `asyncLock` / `asyncQueue` — an object with `runInLock`. A lock already
|
|
291
|
+
guarantees order, so the two are functionally identical and the name is chosen
|
|
292
|
+
for readability at the call site. Semaphores are almost never needed.
|
|
293
|
+
- `delay` — a plain wait, and an aborting variant that throws an abort exception
|
|
294
|
+
when the program starts shutting down. That exception is normal, not a failure;
|
|
295
|
+
it is handled or rethrown at the level that cares.
|
|
296
|
+
- `backoff` — exponential retry, infinite by default, honouring an abort signal.
|
|
297
|
+
- `retry` — a backoff bounded in time; it throws when the time runs out.
|
|
298
|
+
- `forever` — a named loop of `backoff` with a delay between passes, running until
|
|
299
|
+
shutdown. The name is what tells you which loop is holding up a shutdown.
|
|
300
|
+
- `gracefulShutdown` — a named map of async handlers the daemon awaits, so a slow
|
|
301
|
+
shutdown can be attributed to a name.
|
|
302
|
+
|
|
303
|
+
Provider usage polling is the model case: one named `forever` per provider, every
|
|
304
|
+
fifteen minutes, providers polled in parallel, answers kept in memory with their
|
|
305
|
+
capture time and handed out by an endpoint that clients poll. Nothing there is
|
|
306
|
+
durable or pushed. `get_provider_usage` reads these values, so they may be up to
|
|
307
|
+
fifteen minutes old.
|
|
308
|
+
|
|
309
|
+
### What actually runs in parallel
|
|
310
|
+
|
|
311
|
+
- **Tool calls within one turn.** Independent tool calls issued in the same
|
|
312
|
+
response run together; dependent ones must wait for the value they need.
|
|
313
|
+
- **Subagents.** Up to the active limit above, per agent tree. Background spawns
|
|
314
|
+
return immediately; the parent should keep doing useful work rather than idling.
|
|
315
|
+
- **Delegated sessions and workspace agents.** Each runs in its own workspace, so
|
|
316
|
+
their file changes cannot collide.
|
|
317
|
+
- **Waits and scheduled messages.** Durable, daemon-owned, and independent of
|
|
318
|
+
whether a session is currently rendering.
|
|
319
|
+
|
|
320
|
+
### Identity across asynchronous boundaries
|
|
321
|
+
|
|
322
|
+
Run IDs, message IDs, tool-call IDs, session IDs, and agent IDs stay stable across
|
|
323
|
+
async boundaries, and Happy Agent relies on that: durable waits are keyed by tool-call and
|
|
324
|
+
batch identity so a restart resumes the same call, delegation notifications name
|
|
325
|
+
the delegate's session ID and agent ID, and workspace creation reconciles to one
|
|
326
|
+
entity across the local result, the response, live events, refresh, and reconnect.
|
|
327
|
+
When you write code in this area, treat delayed, duplicated, reordered, rejected,
|
|
328
|
+
and already-applied outcomes as expected, and publish notifications only after the
|
|
329
|
+
durable transaction commits.
|
|
330
|
+
|
|
331
|
+
The outer agent loop never replays a provider request, tool, command, or session
|
|
332
|
+
mutation on its own; retry semantics belong to each provider.
|
|
333
|
+
|
|
334
|
+
## Observing a tree of agents
|
|
335
|
+
|
|
336
|
+
- **`get_agent_tree_usage`** — exact lifetime token usage for this session and
|
|
337
|
+
every recursively linked descendant, including hidden subagents, delegated
|
|
338
|
+
sessions, and finished ones, each counted once.
|
|
339
|
+
- **`read_agent_history`** — read or search Happy Agent's durable low-level inference
|
|
340
|
+
history for this agent or another agent in the tree (`target` accepts a task
|
|
341
|
+
path, task name, or session ID; `/root` is the parent). Useful after a model
|
|
342
|
+
change or when earlier context was summarized. Responses are simplified and
|
|
343
|
+
capped, so page with the returned cursors.
|
|
344
|
+
- **`list_workspace_sessions`** — what conversations exist and which agent started
|
|
345
|
+
each one.
|
|
346
|
+
|
|
347
|
+
## Practical guidance
|
|
348
|
+
|
|
349
|
+
1. Do simple work yourself. Delegate concrete, bounded work that is genuinely
|
|
350
|
+
independent or benefits from separate context.
|
|
351
|
+
2. Give each child one clear task and complete instructions; a child started with
|
|
352
|
+
`context: "task"` knows only what you wrote.
|
|
353
|
+
3. Pick the model and effort deliberately for the child's task — defaults are not
|
|
354
|
+
inherited, and cheap bounded work does not need a top-tier model at high
|
|
355
|
+
effort.
|
|
356
|
+
4. Spawn in the background, keep working, and let the completion notification come
|
|
357
|
+
to you.
|
|
358
|
+
5. Use follow-ups instead of respawning: a finished subagent still holds its
|
|
359
|
+
context.
|
|
360
|
+
6. Use `agent_info` before `agent_send`, always — it is enforced.
|
|
361
|
+
7. Under Away presence, never block on the human. Ask in the Inbox with full
|
|
362
|
+
context, continue on your best judgement, and withdraw the question with
|
|
363
|
+
`cancel_ask` if it stops mattering.
|
|
364
|
+
8. Isolate parallel work in separate workspaces; keep subtasks of one task in the
|
|
365
|
+
current workspace.
|