@windowkit/agent-chat 0.0.0-stage → 0.1.0

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.
Files changed (164) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -2
  3. package/dist/core/driver.d.ts +183 -0
  4. package/dist/core/driver.d.ts.map +1 -0
  5. package/dist/core/driver.js +12 -0
  6. package/dist/core/driver.js.map +1 -0
  7. package/dist/core/index.d.ts +8 -0
  8. package/dist/core/index.d.ts.map +1 -0
  9. package/dist/core/index.js +11 -0
  10. package/dist/core/index.js.map +1 -0
  11. package/dist/core/markdown.d.ts +7 -0
  12. package/dist/core/markdown.d.ts.map +1 -0
  13. package/dist/core/markdown.js +53 -0
  14. package/dist/core/markdown.js.map +1 -0
  15. package/dist/core/policy.d.ts +18 -0
  16. package/dist/core/policy.d.ts.map +1 -0
  17. package/dist/core/policy.js +67 -0
  18. package/dist/core/policy.js.map +1 -0
  19. package/dist/core/reducer.d.ts +61 -0
  20. package/dist/core/reducer.d.ts.map +1 -0
  21. package/dist/core/reducer.js +391 -0
  22. package/dist/core/reducer.js.map +1 -0
  23. package/dist/core/session.d.ts +105 -0
  24. package/dist/core/session.d.ts.map +1 -0
  25. package/dist/core/session.js +648 -0
  26. package/dist/core/session.js.map +1 -0
  27. package/dist/core/tools.d.ts +120 -0
  28. package/dist/core/tools.d.ts.map +1 -0
  29. package/dist/core/tools.js +120 -0
  30. package/dist/core/tools.js.map +1 -0
  31. package/dist/core/types.d.ts +295 -0
  32. package/dist/core/types.d.ts.map +1 -0
  33. package/dist/core/types.js +21 -0
  34. package/dist/core/types.js.map +1 -0
  35. package/dist/drivers/claude/index.d.ts +20 -0
  36. package/dist/drivers/claude/index.d.ts.map +1 -0
  37. package/dist/drivers/claude/index.js +727 -0
  38. package/dist/drivers/claude/index.js.map +1 -0
  39. package/dist/drivers/claude/input.d.ts +7 -0
  40. package/dist/drivers/claude/input.d.ts.map +1 -0
  41. package/dist/drivers/claude/input.js +46 -0
  42. package/dist/drivers/claude/input.js.map +1 -0
  43. package/dist/drivers/claude/peers.d.ts +16 -0
  44. package/dist/drivers/claude/peers.d.ts.map +1 -0
  45. package/dist/drivers/claude/peers.js +137 -0
  46. package/dist/drivers/claude/peers.js.map +1 -0
  47. package/dist/drivers/claude/schema.d.ts +5 -0
  48. package/dist/drivers/claude/schema.d.ts.map +1 -0
  49. package/dist/drivers/claude/schema.js +77 -0
  50. package/dist/drivers/claude/schema.js.map +1 -0
  51. package/dist/drivers/claude/sdk.d.ts +86 -0
  52. package/dist/drivers/claude/sdk.d.ts.map +1 -0
  53. package/dist/drivers/claude/sdk.js +47 -0
  54. package/dist/drivers/claude/sdk.js.map +1 -0
  55. package/dist/drivers/claude/tools.d.ts +18 -0
  56. package/dist/drivers/claude/tools.d.ts.map +1 -0
  57. package/dist/drivers/claude/tools.js +119 -0
  58. package/dist/drivers/claude/tools.js.map +1 -0
  59. package/dist/index.d.ts +8 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +12 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/testing/fake.d.ts +63 -0
  64. package/dist/testing/fake.d.ts.map +1 -0
  65. package/dist/testing/fake.js +270 -0
  66. package/dist/testing/fake.js.map +1 -0
  67. package/dist/testing/index.d.ts +2 -0
  68. package/dist/testing/index.d.ts.map +1 -0
  69. package/dist/testing/index.js +4 -0
  70. package/dist/testing/index.js.map +1 -0
  71. package/dist/view/AgentChat.d.ts +53 -0
  72. package/dist/view/AgentChat.d.ts.map +1 -0
  73. package/dist/view/AgentChat.js +87 -0
  74. package/dist/view/AgentChat.js.map +1 -0
  75. package/dist/view/CodeBlock.d.ts +9 -0
  76. package/dist/view/CodeBlock.d.ts.map +1 -0
  77. package/dist/view/CodeBlock.js +60 -0
  78. package/dist/view/CodeBlock.js.map +1 -0
  79. package/dist/view/Composer.d.ts +24 -0
  80. package/dist/view/Composer.d.ts.map +1 -0
  81. package/dist/view/Composer.js +144 -0
  82. package/dist/view/Composer.js.map +1 -0
  83. package/dist/view/Header.d.ts +3 -0
  84. package/dist/view/Header.d.ts.map +1 -0
  85. package/dist/view/Header.js +30 -0
  86. package/dist/view/Header.js.map +1 -0
  87. package/dist/view/MessageList.d.ts +9 -0
  88. package/dist/view/MessageList.d.ts.map +1 -0
  89. package/dist/view/MessageList.js +111 -0
  90. package/dist/view/MessageList.js.map +1 -0
  91. package/dist/view/QuestionCard.d.ts +6 -0
  92. package/dist/view/QuestionCard.d.ts.map +1 -0
  93. package/dist/view/QuestionCard.js +39 -0
  94. package/dist/view/QuestionCard.js.map +1 -0
  95. package/dist/view/TextBlock.d.ts +9 -0
  96. package/dist/view/TextBlock.d.ts.map +1 -0
  97. package/dist/view/TextBlock.js +22 -0
  98. package/dist/view/TextBlock.js.map +1 -0
  99. package/dist/view/ToolCard.d.ts +7 -0
  100. package/dist/view/ToolCard.d.ts.map +1 -0
  101. package/dist/view/ToolCard.js +155 -0
  102. package/dist/view/ToolCard.js.map +1 -0
  103. package/dist/view/Transcript.d.ts +5 -0
  104. package/dist/view/Transcript.d.ts.map +1 -0
  105. package/dist/view/Transcript.js +47 -0
  106. package/dist/view/Transcript.js.map +1 -0
  107. package/dist/view/context.d.ts +21 -0
  108. package/dist/view/context.d.ts.map +1 -0
  109. package/dist/view/context.js +37 -0
  110. package/dist/view/context.js.map +1 -0
  111. package/dist/view/fences.d.ts +13 -0
  112. package/dist/view/fences.d.ts.map +1 -0
  113. package/dist/view/fences.js +59 -0
  114. package/dist/view/fences.js.map +1 -0
  115. package/dist/view/files.d.ts +11 -0
  116. package/dist/view/files.d.ts.map +1 -0
  117. package/dist/view/files.js +109 -0
  118. package/dist/view/files.js.map +1 -0
  119. package/dist/view/look.d.ts +18 -0
  120. package/dist/view/look.d.ts.map +1 -0
  121. package/dist/view/look.js +37 -0
  122. package/dist/view/look.js.map +1 -0
  123. package/dist/view/types.d.ts +50 -0
  124. package/dist/view/types.d.ts.map +1 -0
  125. package/dist/view/types.js +14 -0
  126. package/dist/view/types.js.map +1 -0
  127. package/dist/view/use-agent.d.ts +11 -0
  128. package/dist/view/use-agent.d.ts.map +1 -0
  129. package/dist/view/use-agent.js +33 -0
  130. package/dist/view/use-agent.js.map +1 -0
  131. package/package.json +92 -4
  132. package/src/core/driver.ts +191 -0
  133. package/src/core/index.ts +54 -0
  134. package/src/core/markdown.ts +56 -0
  135. package/src/core/policy.ts +77 -0
  136. package/src/core/reducer.ts +490 -0
  137. package/src/core/session.ts +824 -0
  138. package/src/core/tools.ts +233 -0
  139. package/src/core/types.ts +321 -0
  140. package/src/drivers/claude/index.ts +825 -0
  141. package/src/drivers/claude/input.ts +47 -0
  142. package/src/drivers/claude/peers.ts +153 -0
  143. package/src/drivers/claude/schema.ts +99 -0
  144. package/src/drivers/claude/sdk.ts +138 -0
  145. package/src/drivers/claude/tools.ts +141 -0
  146. package/src/index.ts +51 -0
  147. package/src/testing/fake.ts +374 -0
  148. package/src/testing/index.ts +11 -0
  149. package/src/view/AgentChat.tsx +204 -0
  150. package/src/view/CodeBlock.tsx +108 -0
  151. package/src/view/Composer.tsx +230 -0
  152. package/src/view/Header.tsx +73 -0
  153. package/src/view/MessageList.tsx +290 -0
  154. package/src/view/QuestionCard.tsx +107 -0
  155. package/src/view/TextBlock.tsx +58 -0
  156. package/src/view/ToolCard.tsx +283 -0
  157. package/src/view/Transcript.tsx +81 -0
  158. package/src/view/context.ts +70 -0
  159. package/src/view/dom-globals.d.ts +10 -0
  160. package/src/view/fences.ts +73 -0
  161. package/src/view/files.ts +111 -0
  162. package/src/view/look.ts +53 -0
  163. package/src/view/types.ts +71 -0
  164. package/src/view/use-agent.ts +40 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrey Sidorov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,148 @@
1
- # Temporary Holding Version
1
+ # @windowkit/agent-chat
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A chat with a local AI agent harness, embedded in a
4
+ [react-x11](https://github.com/sidorares/react-x11) app.
5
+
6
+ ```tsx
7
+ import { AgentChat } from '@windowkit/agent-chat';
8
+
9
+ <AgentChat agent="claude" />;
10
+ ```
11
+
12
+ That is a working chat with Claude Code in the app's working directory: replies
13
+ stream in as markdown, tool calls show as cards with their output, anything
14
+ that changes something asks first, Enter sends and Escape stops. The message
15
+ box formats markdown as it is typed and sends exactly what was typed, with
16
+ `@` for a file, `/` for a command and Up for an earlier prompt. Everything
17
+ else is an opt-in on the same element: the app's context, its own functions
18
+ as tools, its own renderers for what the agent writes, and its own handlers
19
+ for anything the agent or the user does.
20
+
21
+ ![The chat, with a plan, an app tool's card, a code block with a Run button, and a command waiting for approval](docs/img/chat-light.png)
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ npm install @windowkit/agent-chat @react-x11/components react-x11 react
27
+ npm install @anthropic-ai/claude-agent-sdk # for agent="claude"
28
+ ```
29
+
30
+ `react`, `react-x11` and `@react-x11/components` are peers: a second copy of
31
+ either renderer package breaks element registration. The Claude Agent SDK is
32
+ an optional peer, installed only by an app that drives Claude, and
33
+ authenticates the way the SDK does (`ANTHROPIC_API_KEY`, Bedrock, Vertex,
34
+ Foundry).
35
+
36
+ ## Growing it
37
+
38
+ ```tsx
39
+ // Context: where it works, what it is told, which built-ins it has.
40
+ <AgentChat
41
+ agent="claude"
42
+ cwd={project.root}
43
+ instructions="You are the build assistant for Acme."
44
+ coreTools={{ web: false }}
45
+ />;
46
+
47
+ // The app's own tools, as functions. No MCP server to run.
48
+ const openTicket = defineTool({
49
+ description: 'Open a ticket in the tracker by id.',
50
+ parameters: z.object({ id: z.string() }),
51
+ run: ({ id }) => tracker.open(id),
52
+ render: ({ output }) => output && <TicketCard ticket={output} />,
53
+ });
54
+ <AgentChat agent="claude" tools={{ openTicket }} />;
55
+
56
+ // What the agent writes, drawn by the app — and the agent told it can.
57
+ <AgentChat
58
+ agent="claude"
59
+ fences={{
60
+ chart: {
61
+ render: (f) => <Chart spec={f.text} />,
62
+ describe: 'a Vega-Lite spec',
63
+ },
64
+ }}
65
+ />;
66
+
67
+ // Interception: a Run button that calls the app, a gate on every tool call,
68
+ // and the agent's own shell replaced by the app's function.
69
+ <AgentChat
70
+ agent="claude"
71
+ codeActions={[
72
+ copyCode,
73
+ {
74
+ id: 'run',
75
+ label: 'Run',
76
+ when: (f) => f.lang === 'sh',
77
+ run: (f) => app.run(f.text),
78
+ },
79
+ ]}
80
+ onToolCall={(call) => (call.kind === 'execute' ? 'ask' : undefined)}
81
+ coreTools={{ shell: sandboxShell }}
82
+ />;
83
+
84
+ // The app drives the session: the same options, moved into a hook.
85
+ const agent = useAgent({ agent: 'claude', tools: { openTicket } });
86
+ <AgentChat session={agent} />;
87
+
88
+ // Another session's words: drawn as theirs, and told to the agent as such.
89
+ agent.send({
90
+ text: draft,
91
+ from: { kind: 'peer', id: 'writer', name: 'Writer' },
92
+ });
93
+ ```
94
+
95
+ [docs/agent-chat.md](docs/agent-chat.md) has every prop, the gate, and the
96
+ session API.
97
+
98
+ ## Harnesses
99
+
100
+ The UI never asks which agent it drives; it asks what the session can do, and
101
+ draws only the actions that work. A driver per harness family does the rest.
102
+
103
+ | Driver | Harness | State |
104
+ | -------- | -------------------------------------------------------------------------------------------------- | ------- |
105
+ | `claude` | Claude Code, through the Claude Agent SDK, in-process tools | Built |
106
+ | `acp` | Any ACP agent: Gemini CLI, Copilot, Cursor, opencode, goose, Grok Build, Codex through its adapter | Planned |
107
+ | `codex` | `codex app-server` | Planned |
108
+
109
+ [docs/drivers.md](docs/drivers.md) says what each does, and how to write one.
110
+ [docs/design.md](docs/design.md) is the survey and the reasons.
111
+
112
+ ## Without a harness
113
+
114
+ ```bash
115
+ npm run examples:demo
116
+ ```
117
+
118
+ `fakeDriver` from `@windowkit/agent-chat/testing` plays a script through the
119
+ real session: streamed text, approvals, the app's tools, questions. The demo
120
+ and every test run on it, with no SDK, no key and no network.
121
+
122
+ The same demo over real Claude Code — the same tool, fence renderer and Run
123
+ button, with Claude deciding what to do. The SDK is a devDependency of this
124
+ repository, so `npm install` has brought it:
125
+
126
+ ```bash
127
+ DEMO_AGENT=claude DEMO_CWD=~/scratch/demo npm run examples:demo
128
+ ```
129
+
130
+ `DEMO_CWD` is where Claude works, made if it is missing (default: the current
131
+ directory), and it asks before changing anything there. It authenticates as Claude Code does:
132
+ `ANTHROPIC_API_KEY`, or the configuration it already has. `CLAUDE_PATH` runs
133
+ your installed `claude` instead of the SDK's copy; SDK 0.3.N ships Claude Code
134
+ 2.1.N, so keep the two in step.
135
+
136
+ ## Development
137
+
138
+ ```bash
139
+ npm install
140
+ npm test # headless: react-x11 runs an X server in-process
141
+ npm run typecheck
142
+ npm run build && npm run check:package
143
+ npm run screenshots # docs/img, both colour schemes
144
+ ```
145
+
146
+ ## Licence
147
+
148
+ MIT
@@ -0,0 +1,183 @@
1
+ import type { AnyToolDef, ToolResult } from './tools.js';
2
+ import type { Attachment, Capabilities, CoreToolKey, MessageSource, PeerSource, PermissionPolicy, PlanEntry, Question, SessionInfo, ToolCall, ToolKind, ToolOutput, ToolState, Usage } from './types.js';
3
+ /**
4
+ * What a driver reports. Deltas, never snapshots: the reducer accumulates
5
+ * them, so a tool part cannot vanish because a driver forgot to repeat it.
6
+ * `parent` names the tool call a subagent's event belongs under.
7
+ */
8
+ export type DriverEvent =
9
+ /** Assistant text: `delta` appends, `text` replaces (a finished block). */
10
+ {
11
+ type: 'text';
12
+ id: string;
13
+ delta?: string;
14
+ text?: string;
15
+ done?: boolean;
16
+ reasoning?: boolean;
17
+ parent?: string;
18
+ } | {
19
+ type: 'tool-start';
20
+ id: string;
21
+ name: string;
22
+ label?: string;
23
+ kind?: ToolKind;
24
+ title?: string;
25
+ input?: unknown;
26
+ app?: boolean;
27
+ parent?: string;
28
+ }
29
+ /** A piece of the arguments' JSON. */
30
+ | {
31
+ type: 'tool-input';
32
+ id: string;
33
+ delta: string;
34
+ } | {
35
+ type: 'tool-update';
36
+ id: string;
37
+ input?: unknown;
38
+ title?: string;
39
+ kind?: ToolKind;
40
+ state?: ToolState;
41
+ /** Replaces the outputs. */
42
+ output?: readonly ToolOutput[];
43
+ /** Appended to them. */
44
+ append?: ToolOutput;
45
+ progress?: string;
46
+ } | {
47
+ type: 'tool-end';
48
+ id: string;
49
+ state: 'done' | 'error' | 'denied' | 'cancelled';
50
+ output?: readonly ToolOutput[];
51
+ error?: string;
52
+ } | {
53
+ type: 'plan';
54
+ entries: readonly PlanEntry[];
55
+ parent?: string;
56
+ }
57
+ /**
58
+ * A message the harness took from someone other than the user — another
59
+ * session, a channel — and is acting on. A turn starts with it if none is
60
+ * running, as one does for `send`.
61
+ */
62
+ | {
63
+ type: 'message';
64
+ id: string;
65
+ text: string;
66
+ from: MessageSource;
67
+ } | {
68
+ type: 'notice';
69
+ level: 'info' | 'warning' | 'error';
70
+ text: string;
71
+ } | {
72
+ type: 'info';
73
+ info: Partial<SessionInfo>;
74
+ } | {
75
+ type: 'usage';
76
+ usage: Usage;
77
+ } | {
78
+ type: 'turn-end';
79
+ reason: 'done' | 'stopped' | 'error' | 'limit';
80
+ error?: string;
81
+ };
82
+ /** The policy's answer, fast, with no user involved. */
83
+ export type GateDecision = {
84
+ behavior: 'allow';
85
+ input?: unknown;
86
+ } | {
87
+ behavior: 'deny';
88
+ message: string;
89
+ }
90
+ /** The user must decide: the driver routes the call to `approve`. */
91
+ | {
92
+ behavior: 'ask';
93
+ }
94
+ /** No opinion: the harness's own permission mode decides. */
95
+ | {
96
+ behavior: 'defer';
97
+ };
98
+ /** The user's answer, through the approval row. */
99
+ export type ApprovalResult = {
100
+ behavior: 'allow';
101
+ input?: unknown;
102
+ } | {
103
+ behavior: 'deny';
104
+ message: string;
105
+ interrupt?: boolean;
106
+ };
107
+ /** What a driver may ask of the session. */
108
+ export interface DriverHost {
109
+ readonly config: DriverConfig;
110
+ emit(event: DriverEvent): void;
111
+ /** Before a tool runs: the app's `onToolCall`, then the policy. Never
112
+ * waits on the user, so a harness hook with a timeout can call it. */
113
+ gate(call: ToolCall): Promise<GateDecision>;
114
+ /** The approval row: waits on the user, and while the session is paused.
115
+ * Has no timeout. */
116
+ approve(call: ToolCall, signal?: AbortSignal): Promise<ApprovalResult>;
117
+ /** A question for the user (`AskUserQuestion`). `null` if dismissed. */
118
+ ask(id: string, questions: readonly Question[], signal?: AbortSignal): Promise<Record<string, string> | null>;
119
+ /** Run one of the app's tools. Never throws: a failure is a result. */
120
+ runTool(name: string, input: unknown, ctx: {
121
+ callId?: string;
122
+ signal?: AbortSignal;
123
+ }): Promise<ToolResult>;
124
+ }
125
+ /** The session's options, resolved for a driver. */
126
+ export interface DriverConfig {
127
+ cwd: string;
128
+ folders: readonly string[];
129
+ /** Appended to the harness's own system prompt. Empty for none. */
130
+ instructions: string;
131
+ /** Replaces the harness's system prompt. */
132
+ systemPrompt?: string;
133
+ /** Categories and harness names switched off. */
134
+ removed: readonly string[];
135
+ /** Categories and harness names that always ask. */
136
+ asking: readonly string[];
137
+ /** Categories replaced by one of `tools`, by the tool's name. */
138
+ replaced: Readonly<Partial<Record<CoreToolKey, string>>>;
139
+ /** The app's tools, replacements included, by name. */
140
+ tools: ReadonlyMap<string, AnyToolDef>;
141
+ permissions: PermissionPolicy;
142
+ model?: string;
143
+ mode?: string;
144
+ /** A harness session id to resume. */
145
+ resume?: string;
146
+ settings: 'cli' | 'isolated';
147
+ driverOptions: Readonly<Record<string, unknown>>;
148
+ }
149
+ /** A message on its way to the harness. */
150
+ export interface OutgoingMessage {
151
+ /** The transcript's id for it. */
152
+ id: string;
153
+ text: string;
154
+ attachments: readonly Attachment[];
155
+ /** Sent while a turn runs; the driver delivers it as steering. */
156
+ steer: boolean;
157
+ /** Sent on another session's behalf. Absent: the user's own. */
158
+ from?: PeerSource;
159
+ }
160
+ export interface DriverSession {
161
+ readonly capabilities: Capabilities;
162
+ send(message: OutgoingMessage): void;
163
+ /** Stop the turn. The driver ends it with `turn-end` `'stopped'`. */
164
+ interrupt(): Promise<void>;
165
+ setModel?(id: string): Promise<void>;
166
+ setMode?(id: string): Promise<void>;
167
+ close(): Promise<void>;
168
+ }
169
+ export interface AgentDriver {
170
+ /** `'claude'`, `'fake'`: shown, and `SessionInfo.agent`. */
171
+ readonly name: string;
172
+ /**
173
+ * Start the harness. Throw `AgentUnavailableError` when it cannot run
174
+ * here — no SDK, no binary, no key — which is an ordinary state of a
175
+ * healthy machine, and the view shows the `fallback`.
176
+ */
177
+ start(host: DriverHost): Promise<DriverSession>;
178
+ }
179
+ /** The harness cannot run here. Not a bug: the view shows its `fallback`. */
180
+ export declare class AgentUnavailableError extends Error {
181
+ readonly name = "AgentUnavailableError";
182
+ }
183
+ //# sourceMappingURL=driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/core/driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ // The seam between the session and a harness.
2
+ //
3
+ // A driver turns one harness's protocol into `DriverEvent`s, and asks the
4
+ // session — through `DriverHost` — every question the protocol asks the
5
+ // client: may this tool run, what did the user answer, run the app's tool.
6
+ // It is public for the reason `ProcessHost` is in `@react-x11/components`:
7
+ // driving a harness nobody wrapped yet should not need a fork.
8
+ /** The harness cannot run here. Not a bug: the view shows its `fallback`. */
9
+ export class AgentUnavailableError extends Error {
10
+ name = 'AgentUnavailableError';
11
+ }
12
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/core/driver.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,2EAA2E;AAC3E,2EAA2E;AAC3E,+DAA+D;AAqL/D,6EAA6E;AAC7E,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC5B,IAAI,GAAG,uBAAuB,CAAC;CAClD"}
@@ -0,0 +1,8 @@
1
+ export { createAgentSession, describeRenderers, type AgentOptions, type AgentSession, type CoreToolSetting, type SessionSnapshot, } from './session.js';
2
+ export { AgentUnavailableError, type AgentDriver, type ApprovalResult, type DriverConfig, type DriverEvent, type DriverHost, type DriverSession, type GateDecision, type OutgoingMessage, } from './driver.js';
3
+ export { defineTool, errorResult, isStandardSchema, jsonSchemaOf, normalizeResult, validateInput, type AnyToolDef, type InferInput, type JsonObjectSchema, type StandardSchemaLike, type ToolContext, type ToolDef, type ToolParameters, type ToolRenderInfo, type ToolResult, } from './tools.js';
4
+ export { reduce, restore, findLivePart, findPart, type TranscriptAction, } from './reducer.js';
5
+ export { categoryOf, policyDecision } from './policy.js';
6
+ export { messageMarkdown, sourceLabel, transcriptMarkdown, } from './markdown.js';
7
+ export * from './types.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,EACrB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,eAAe,EACf,WAAW,EACX,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,cAAc,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ // `@windowkit/agent-chat/core`: the session, the message model, the driver
2
+ // seam and the tool helpers. No React, and no renderer: a DOM or terminal
3
+ // front end can drive the same session.
4
+ export { createAgentSession, describeRenderers, } from './session.js';
5
+ export { AgentUnavailableError, } from './driver.js';
6
+ export { defineTool, errorResult, isStandardSchema, jsonSchemaOf, normalizeResult, validateInput, } from './tools.js';
7
+ export { reduce, restore, findLivePart, findPart, } from './reducer.js';
8
+ export { categoryOf, policyDecision } from './policy.js';
9
+ export { messageMarkdown, sourceLabel, transcriptMarkdown, } from './markdown.js';
10
+ export * from './types.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,wCAAwC;AAExC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAKlB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,qBAAqB,GAStB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,aAAa,GAUd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,GAET,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,eAAe,EACf,WAAW,EACX,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,cAAc,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AgentMessage, MessageSource } from './types.js';
2
+ /** What a message's author is called: a peer's name, or its id; a
3
+ * channel's server. */
4
+ export declare function sourceLabel(from: MessageSource): string;
5
+ export declare function messageMarkdown(message: AgentMessage): string;
6
+ export declare function transcriptMarkdown(messages: readonly AgentMessage[]): string;
7
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/core/markdown.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAQ,MAAM,YAAY,CAAC;AAEpE;wBACwB;AACxB,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAEvD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAE7D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAW5E"}
@@ -0,0 +1,53 @@
1
+ // A transcript as markdown: what Copy puts on the clipboard, and what an app
2
+ // saves. Text is written as the agent wrote it; a tool call is one line,
3
+ // since its output is the harness's and usually long.
4
+ /** What a message's author is called: a peer's name, or its id; a
5
+ * channel's server. */
6
+ export function sourceLabel(from) {
7
+ return from.kind === 'peer' ? from.name || from.id : from.server;
8
+ }
9
+ export function messageMarkdown(message) {
10
+ return message.parts.map(partMarkdown).filter(Boolean).join('\n\n');
11
+ }
12
+ export function transcriptMarkdown(messages) {
13
+ return messages
14
+ .map((m) => {
15
+ const body = messageMarkdown(m);
16
+ if (!body)
17
+ return '';
18
+ if (m.role !== 'user')
19
+ return body;
20
+ const who = m.from ? `From ${sourceLabel(m.from)}` : 'You';
21
+ return `**${who}:**\n\n${body}`;
22
+ })
23
+ .filter(Boolean)
24
+ .join('\n\n---\n\n');
25
+ }
26
+ function partMarkdown(part) {
27
+ switch (part.type) {
28
+ case 'text':
29
+ return part.text;
30
+ case 'reasoning':
31
+ return '';
32
+ case 'tool':
33
+ return `> ${part.title}${part.state === 'done' ? '' : ` (${part.state})`}`;
34
+ case 'plan':
35
+ return part.entries
36
+ .map((e) => `- [${e.status === 'completed' ? 'x' : ' '}] ${e.text}`)
37
+ .join('\n');
38
+ case 'question':
39
+ return part.questions
40
+ .map((q) => {
41
+ const a = part.answers?.[q.question];
42
+ return a ? `> ${q.question}\n>\n> ${a}` : `> ${q.question}`;
43
+ })
44
+ .join('\n\n');
45
+ case 'file':
46
+ return `[${part.label}]`;
47
+ case 'notice':
48
+ return `_${part.text}_`;
49
+ case 'data':
50
+ return '';
51
+ }
52
+ }
53
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/core/markdown.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,yEAAyE;AACzE,sDAAsD;AAItD;wBACwB;AACxB,MAAM,UAAU,WAAW,CAAC,IAAmB;IAC7C,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAqB;IACnD,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAiC;IAClE,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3D,OAAO,KAAK,GAAG,UAAU,IAAI,EAAE,CAAC;IAClC,CAAC,CAAC;SACD,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,aAAa,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,IAAU;IAC9B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,KAAK,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAC7E,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,OAAO;iBAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;iBACnE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,UAAU;YACb,OAAO,IAAI,CAAC,SAAS;iBAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBACrC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC9D,CAAC,CAAC;iBACD,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,KAAK,MAAM;YACT,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC;QAC3B,KAAK,QAAQ;YACX,OAAO,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC;QAC1B,KAAK,MAAM;YACT,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { DriverConfig, GateDecision } from './driver.js';
2
+ import type { CoreToolKey, ToolCall, ToolKind } from './types.js';
3
+ /** The `coreTools` category a tool kind belongs to. */
4
+ export declare function categoryOf(kind: ToolKind): CoreToolKey | undefined;
5
+ /**
6
+ * | policy | reads | edits | anything else |
7
+ * | ------------- | ----- | ----- | ------------- |
8
+ * | `'ask'` | run | ask | ask |
9
+ * | `'edits'` | run | run | ask |
10
+ * | `'read-only'` | run | deny | deny |
11
+ * | `'auto'` | the harness decides |
12
+ *
13
+ * Over all of it: an app tool runs unless its `ask` says otherwise, a
14
+ * category or name in `coreTools` set to `'ask'` always asks, and one set to
15
+ * `false` that a harness could not remove is denied.
16
+ */
17
+ export declare function policyDecision(call: ToolCall, config: DriverConfig): GateDecision;
18
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/core/policy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElE,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAgBlE;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,YAAY,GACnB,YAAY,CAiCd"}
@@ -0,0 +1,67 @@
1
+ // The permission policy: what runs without asking, before the app's
2
+ // `onToolCall` has had a say. Pure, so the table below is the whole story.
3
+ /** The `coreTools` category a tool kind belongs to. */
4
+ export function categoryOf(kind) {
5
+ switch (kind) {
6
+ case 'execute':
7
+ return 'shell';
8
+ case 'read':
9
+ case 'search':
10
+ return 'read';
11
+ case 'edit':
12
+ case 'delete':
13
+ case 'move':
14
+ return 'edit';
15
+ case 'fetch':
16
+ return 'web';
17
+ default:
18
+ return undefined;
19
+ }
20
+ }
21
+ const READS = new Set(['read', 'search', 'think']);
22
+ const EDITS = new Set(['edit', 'move']);
23
+ /**
24
+ * | policy | reads | edits | anything else |
25
+ * | ------------- | ----- | ----- | ------------- |
26
+ * | `'ask'` | run | ask | ask |
27
+ * | `'edits'` | run | run | ask |
28
+ * | `'read-only'` | run | deny | deny |
29
+ * | `'auto'` | the harness decides |
30
+ *
31
+ * Over all of it: an app tool runs unless its `ask` says otherwise, a
32
+ * category or name in `coreTools` set to `'ask'` always asks, and one set to
33
+ * `false` that a harness could not remove is denied.
34
+ */
35
+ export function policyDecision(call, config) {
36
+ const category = categoryOf(call.kind);
37
+ const named = (list) => list.includes(call.label) ||
38
+ (!call.app && !!category && list.includes(category));
39
+ if (named(config.removed)) {
40
+ return { behavior: 'deny', message: `${call.label} is turned off here.` };
41
+ }
42
+ if (call.app) {
43
+ const tool = config.tools.get(call.label);
44
+ return tool?.ask ? { behavior: 'ask' } : { behavior: 'allow' };
45
+ }
46
+ if (named(config.asking))
47
+ return { behavior: 'ask' };
48
+ switch (config.permissions) {
49
+ case 'auto':
50
+ return { behavior: 'defer' };
51
+ case 'read-only':
52
+ return READS.has(call.kind)
53
+ ? { behavior: 'allow' }
54
+ : {
55
+ behavior: 'deny',
56
+ message: 'This session is read-only: nothing may be changed.',
57
+ };
58
+ case 'edits':
59
+ return READS.has(call.kind) || EDITS.has(call.kind)
60
+ ? { behavior: 'allow' }
61
+ : { behavior: 'ask' };
62
+ case 'ask':
63
+ default:
64
+ return READS.has(call.kind) ? { behavior: 'allow' } : { behavior: 'ask' };
65
+ }
66
+ }
67
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/core/policy.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,2EAA2E;AAK3E,uDAAuD;AACvD,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;QACjB,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ;YACX,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,KAAK,GAA0B,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAC1E,MAAM,KAAK,GAA0B,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAc,EACd,MAAoB;IAEpB,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,CAAC,IAAuB,EAAE,EAAE,CACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QACzB,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvD,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,sBAAsB,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAErD,QAAQ,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3B,KAAK,MAAM;YACT,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAC/B,KAAK,WAAW;YACd,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;gBACzB,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE;gBACvB,CAAC,CAAC;oBACE,QAAQ,EAAE,MAAM;oBAChB,OAAO,EAAE,oDAAoD;iBAC9D,CAAC;QACR,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;gBACjD,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE;gBACvB,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC1B,KAAK,KAAK,CAAC;QACX;YACE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC9E,CAAC;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { DriverEvent } from './driver.js';
2
+ import type { AgentMessage, ApprovalOption, Part, Question, ToolOutput } from './types.js';
3
+ export type TranscriptAction = DriverEvent
4
+ /** The user sent a message. */
5
+ | {
6
+ type: 'user';
7
+ message: AgentMessage;
8
+ }
9
+ /** A queued message is being sent now. */
10
+ | {
11
+ type: 'unqueue';
12
+ id: string;
13
+ }
14
+ /** A tool call waits for the user. */
15
+ | {
16
+ type: 'approval';
17
+ id: string;
18
+ options: readonly ApprovalOption[];
19
+ reason?: string;
20
+ }
21
+ /** The user, or the policy, answered it. */
22
+ | {
23
+ type: 'approved';
24
+ id: string;
25
+ allowed: boolean;
26
+ } | {
27
+ type: 'question';
28
+ id: string;
29
+ questions: readonly Question[];
30
+ } | {
31
+ type: 'answered';
32
+ id: string;
33
+ answers: Readonly<Record<string, string>> | null;
34
+ }
35
+ /** The turn was stopped: what was open is cancelled. */
36
+ | {
37
+ type: 'stopped';
38
+ };
39
+ type Messages = readonly AgentMessage[];
40
+ export declare function reduce(messages: Messages, action: TranscriptAction, now?: number): Messages;
41
+ /**
42
+ * A transcript saved from an earlier session, made ready to show again:
43
+ * whatever was queued was never sent and is dropped, and whatever was still
44
+ * open ends as a stopped turn does — a stream stops streaming, a tool call
45
+ * is cancelled, a question is closed. Nothing in it is live any more.
46
+ */
47
+ export declare function restore(messages: Messages): Messages;
48
+ /** The part with this id, in any message. */
49
+ export declare function findPart(messages: Messages, id: string): Part | undefined;
50
+ /**
51
+ * The part with this id in a turn still under way: what an event may touch.
52
+ * A driver's ids are unique within a turn, not across a session — a script
53
+ * that names its calls runs the same names every turn — so a finished turn's
54
+ * parts are never the ones an event means. They keep the state they ended in.
55
+ */
56
+ export declare function findLivePart(messages: Messages, id: string): Part | undefined;
57
+ /** A tool's progress line: a text output it replaces as it goes, and drops
58
+ * when the tool ends. */
59
+ export declare function isProgress(o: ToolOutput): boolean;
60
+ export {};
61
+ //# sourceMappingURL=reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/core/reducer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,IAAI,EACJ,QAAQ,EACR,UAAU,EAGX,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,gBAAgB,GACxB,WAAW;AACb,+BAA+B;GAC7B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE;AACzC,0CAA0C;GACxC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE;AACjC,sCAAsC;GACpC;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACH,4CAA4C;GAC1C;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAA;CAAE,GAChE;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;CAClD;AACH,wDAAwD;GACtD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,KAAK,QAAQ,GAAG,SAAS,YAAY,EAAE,CAAC;AASxC,wBAAgB,MAAM,CACpB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,gBAAgB,EACxB,GAAG,GAAE,MAAmB,GACvB,QAAQ,CA+HV;AAuKD;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAKpD;AA0CD,6CAA6C;AAC7C,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAE7E;AAsED;0BAC0B;AAC1B,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAEjD"}