@agent-link/agent 0.1.338 → 0.1.339

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 (78) hide show
  1. package/dist/backends/types.d.ts +58 -0
  2. package/dist/backends/types.js +15 -4
  3. package/dist/backends/types.js.map +1 -1
  4. package/dist/connection.js +231 -28
  5. package/dist/connection.js.map +1 -1
  6. package/dist/copilot-capabilities-offline.d.ts +254 -0
  7. package/dist/copilot-capabilities-offline.js +392 -0
  8. package/dist/copilot-capabilities-offline.js.map +1 -0
  9. package/dist/copilot-capabilities.d.ts +43 -0
  10. package/dist/copilot-capabilities.js +128 -0
  11. package/dist/copilot-capabilities.js.map +1 -0
  12. package/dist/copilot-capability-service.d.ts +24 -0
  13. package/dist/copilot-capability-service.js +116 -0
  14. package/dist/copilot-capability-service.js.map +1 -0
  15. package/dist/copilot-command-bridge.d.ts +184 -0
  16. package/dist/copilot-command-bridge.js +1800 -0
  17. package/dist/copilot-command-bridge.js.map +1 -0
  18. package/dist/copilot-compaction-barrier.d.ts +36 -0
  19. package/dist/copilot-compaction-barrier.js +152 -0
  20. package/dist/copilot-compaction-barrier.js.map +1 -0
  21. package/dist/copilot-compaction-lifecycle.d.ts +34 -0
  22. package/dist/copilot-compaction-lifecycle.js +88 -0
  23. package/dist/copilot-compaction-lifecycle.js.map +1 -0
  24. package/dist/copilot-compaction-policy.d.ts +5 -0
  25. package/dist/copilot-compaction-policy.js +7 -0
  26. package/dist/copilot-compaction-policy.js.map +1 -0
  27. package/dist/copilot-configuration.d.ts +63 -0
  28. package/dist/copilot-configuration.js +283 -0
  29. package/dist/copilot-configuration.js.map +1 -0
  30. package/dist/copilot-event-scope.d.ts +13 -0
  31. package/dist/copilot-event-scope.js +26 -0
  32. package/dist/copilot-event-scope.js.map +1 -0
  33. package/dist/copilot-fork-metadata.d.ts +9 -0
  34. package/dist/copilot-fork-metadata.js +86 -0
  35. package/dist/copilot-fork-metadata.js.map +1 -0
  36. package/dist/copilot-message-kind.d.ts +21 -0
  37. package/dist/copilot-message-kind.js +45 -0
  38. package/dist/copilot-message-kind.js.map +1 -0
  39. package/dist/copilot-plan-state.d.ts +19 -0
  40. package/dist/copilot-plan-state.js +180 -0
  41. package/dist/copilot-plan-state.js.map +1 -0
  42. package/dist/copilot-request-dispatch.d.ts +10 -0
  43. package/dist/copilot-request-dispatch.js +31 -0
  44. package/dist/copilot-request-dispatch.js.map +1 -0
  45. package/dist/copilot-review-documents.d.ts +17 -0
  46. package/dist/copilot-review-documents.js +162 -0
  47. package/dist/copilot-review-documents.js.map +1 -0
  48. package/dist/copilot-session-activity.d.ts +3 -0
  49. package/dist/copilot-session-activity.js +94 -0
  50. package/dist/copilot-session-activity.js.map +1 -0
  51. package/dist/copilot-sidecar.d.ts +2 -0
  52. package/dist/copilot-sidecar.js +17 -0
  53. package/dist/copilot-sidecar.js.map +1 -0
  54. package/dist/copilot-turn-journal.d.ts +36 -0
  55. package/dist/copilot-turn-journal.js +246 -0
  56. package/dist/copilot-turn-journal.js.map +1 -0
  57. package/dist/copilot-user-requests.d.ts +11 -0
  58. package/dist/copilot-user-requests.js +84 -0
  59. package/dist/copilot-user-requests.js.map +1 -0
  60. package/dist/copilot.d.ts +194 -9
  61. package/dist/copilot.js +5012 -240
  62. package/dist/copilot.js.map +1 -1
  63. package/dist/history-message-transform.d.ts +47 -1
  64. package/dist/history-message-transform.js +67 -0
  65. package/dist/history-message-transform.js.map +1 -1
  66. package/dist/history.d.ts +8 -0
  67. package/dist/history.js.map +1 -1
  68. package/dist/provider-command-discovery.d.ts +5 -0
  69. package/dist/provider-command-discovery.js +49 -1
  70. package/dist/provider-command-discovery.js.map +1 -1
  71. package/dist/provider-command-types.d.ts +5 -0
  72. package/dist/provider-command-types.js.map +1 -1
  73. package/dist/runtime.d.ts +1 -1
  74. package/dist/runtime.js +1 -1
  75. package/dist/runtime.js.map +1 -1
  76. package/dist/search-sessions.js +2 -1
  77. package/dist/search-sessions.js.map +1 -1
  78. package/package.json +3 -1
@@ -0,0 +1,246 @@
1
+ import { closeSync, openSync, readSync, statSync } from 'fs';
2
+ import { isCopilotChildEvent } from './copilot-event-scope.js';
3
+ /** Request-scoped, read-only reconciliation of the Provider's own event journal. */
4
+ export class CopilotTurnJournal {
5
+ path;
6
+ onEvent;
7
+ offset = 0;
8
+ partial = Buffer.alloc(0);
9
+ seen = new Set();
10
+ tasks = new Set();
11
+ completedTasks = new Set();
12
+ childRuns = new Map();
13
+ childWrites = new Map();
14
+ continuation = false;
15
+ currentTurn;
16
+ finalTurn;
17
+ finalEnded = false;
18
+ finalCheckpoint = false;
19
+ compacting = false;
20
+ pendingInputs = new Set();
21
+ complete = false;
22
+ constructor(path, onEvent) {
23
+ this.path = path;
24
+ this.onEvent = onEvent;
25
+ try {
26
+ this.offset = statSync(path).size;
27
+ }
28
+ catch { /* New sessions may not have a journal yet. */ }
29
+ }
30
+ get pending() {
31
+ return this.tasks.size > 0 || this.childrenPending || this.continuation || this.compacting || this.pendingInputs.size > 0;
32
+ }
33
+ get childrenPending() {
34
+ return [...this.childRuns.values()].some(run => run.active || run.writes.size > 0);
35
+ }
36
+ observeChildRuns(event) {
37
+ const data = event.data || {};
38
+ const agentId = event.agentId || data.agentId;
39
+ const getRun = (id) => {
40
+ let run = this.childRuns.get(id);
41
+ if (!run) {
42
+ run = { active: false, initial: false, writes: new Set() };
43
+ this.childRuns.set(id, run);
44
+ }
45
+ return run;
46
+ };
47
+ const write = (id, name, args) => {
48
+ if (!id || name !== 'write_agent' || typeof args?.agent_id !== 'string' || this.childWrites.has(id))
49
+ return;
50
+ this.childWrites.set(id, args.agent_id);
51
+ getRun(args.agent_id).writes.add(id);
52
+ this.continuation = true;
53
+ this.resetFinal();
54
+ };
55
+ if (event.type === 'tool.execution_start')
56
+ write(data.toolCallId, data.toolName, data.arguments);
57
+ if (event.type === 'assistant.message') {
58
+ for (const tool of data.toolRequests || [])
59
+ write(tool.toolCallId, tool.name, tool.arguments);
60
+ }
61
+ if (event.type === 'tool.execution_complete' && data.success === false) {
62
+ const target = this.childWrites.get(data.toolCallId);
63
+ if (target)
64
+ getRun(target).writes.delete(data.toolCallId);
65
+ }
66
+ if (!agentId)
67
+ return;
68
+ const run = getRun(agentId);
69
+ if (event.type === 'subagent.started') {
70
+ run.active = true;
71
+ run.initial = true;
72
+ }
73
+ if (event.type === 'user.message') {
74
+ if (data.interactionId && data.interactionId === run.interaction)
75
+ return;
76
+ if (run.initial) {
77
+ run.initialInteraction = data.interactionId;
78
+ run.initial = false;
79
+ }
80
+ else {
81
+ const first = run.writes.values().next().value;
82
+ if (first)
83
+ run.writes.delete(first);
84
+ }
85
+ run.interaction = data.interactionId;
86
+ run.active = true;
87
+ run.finalTurn = undefined;
88
+ this.continuation = true;
89
+ this.resetFinal();
90
+ }
91
+ if (event.type === 'assistant.turn_start') {
92
+ run.active = true;
93
+ run.finalTurn = undefined;
94
+ }
95
+ if (event.type === 'assistant.message' && !data.toolRequests?.length
96
+ && (data.phase === 'final_answer' || (!data.phase && data.content?.trim())))
97
+ run.finalTurn = data.turnId;
98
+ if (event.type === 'assistant.turn_end' && run.finalTurn !== undefined && data.turnId === run.finalTurn) {
99
+ run.active = false;
100
+ run.finalTurn = undefined;
101
+ }
102
+ // subagent.completed acknowledges initial dispatch only. It must not settle
103
+ // queued write_agent work or a newer interaction already running on that ID.
104
+ if (['subagent.completed', 'subagent.failed'].includes(event.type || '')
105
+ && (!run.interaction || run.interaction === run.initialInteraction))
106
+ run.active = false;
107
+ }
108
+ resetFinal() {
109
+ this.finalTurn = undefined;
110
+ this.finalEnded = false;
111
+ this.finalCheckpoint = false;
112
+ this.complete = false;
113
+ }
114
+ read() {
115
+ let fd;
116
+ try {
117
+ const size = statSync(this.path).size;
118
+ if (size < this.offset) {
119
+ this.offset = 0;
120
+ this.partial = Buffer.alloc(0);
121
+ }
122
+ if (size === this.offset)
123
+ return;
124
+ fd = openSync(this.path, 'r');
125
+ // Bound work per tick; keep UTF-8 bytes intact across partial writes.
126
+ let budget = 4 * 1024 * 1024;
127
+ while (this.offset < size && budget > 0) {
128
+ const bytes = Buffer.alloc(Math.min(256 * 1024, size - this.offset, budget));
129
+ const count = readSync(fd, bytes, 0, bytes.length, this.offset);
130
+ if (!count)
131
+ break;
132
+ this.offset += count;
133
+ budget -= count;
134
+ this.partial = Buffer.concat([this.partial, bytes.subarray(0, count)]);
135
+ let end;
136
+ while ((end = this.partial.indexOf(10)) >= 0) {
137
+ const line = this.partial.subarray(0, end).toString('utf8');
138
+ this.partial = this.partial.subarray(end + 1);
139
+ let event;
140
+ try {
141
+ event = JSON.parse(line);
142
+ }
143
+ catch {
144
+ continue;
145
+ }
146
+ this.observe(event);
147
+ }
148
+ }
149
+ }
150
+ catch { /* Missing/locked journals must not fail or create Provider sessions. */ }
151
+ finally {
152
+ if (fd !== undefined)
153
+ closeSync(fd);
154
+ }
155
+ }
156
+ observe(event) {
157
+ if (event.id && this.seen.has(event.id))
158
+ return;
159
+ if (event.id)
160
+ this.seen.add(event.id);
161
+ const data = event.data || {};
162
+ const child = isCopilotChildEvent(event);
163
+ this.observeChildRuns(event);
164
+ const addTask = (id, name, args) => {
165
+ if (id && name === 'task' && args?.mode === 'background' && !this.completedTasks.has(id)) {
166
+ this.tasks.add(id);
167
+ this.continuation = true;
168
+ this.resetFinal();
169
+ }
170
+ };
171
+ if (event.type === 'tool.execution_start')
172
+ addTask(data.toolCallId, data.toolName, data.arguments);
173
+ if (event.type === 'assistant.message') {
174
+ for (const tool of data.toolRequests || [])
175
+ addTask(tool.toolCallId, tool.name, tool.arguments);
176
+ }
177
+ if (event.type === 'subagent.started' && data.toolCallId && !this.completedTasks.has(data.toolCallId)) {
178
+ this.tasks.add(data.toolCallId);
179
+ this.continuation = true;
180
+ this.resetFinal();
181
+ }
182
+ if (event.type === 'subagent.completed' || event.type === 'subagent.failed'
183
+ || (event.type === 'tool.execution_complete' && data.success === false && this.tasks.has(data.toolCallId))) {
184
+ this.tasks.delete(data.toolCallId);
185
+ this.completedTasks.add(data.toolCallId);
186
+ if (event.type === 'tool.execution_complete' && this.tasks.size === 0)
187
+ this.continuation = false;
188
+ }
189
+ if (!child) {
190
+ if (event.type === 'assistant.turn_start' || event.type === 'assistant.message') {
191
+ if (typeof data.turnId === 'string')
192
+ this.currentTurn = data.turnId;
193
+ }
194
+ if (event.type === 'assistant.turn_start') {
195
+ this.resetFinal();
196
+ }
197
+ if (event.type === 'session.compaction_start') {
198
+ this.compacting = true;
199
+ this.complete = false;
200
+ }
201
+ if (event.type === 'session.compaction_complete' || event.type === 'session.compaction_failed')
202
+ this.compacting = false;
203
+ if (event.type === 'user_input.requested' && data.requestId)
204
+ this.pendingInputs.add(data.requestId);
205
+ if (event.type === 'user_input.completed')
206
+ this.pendingInputs.delete(data.requestId);
207
+ if (event.type === 'assistant.message' && data.phase === 'final_answer'
208
+ && !data.toolRequests?.length && this.tasks.size === 0 && !this.childrenPending) {
209
+ // The Provider can finish with an explicitly empty final after having
210
+ // already published its answer and performed follow-up verification.
211
+ // Content is not lifecycle evidence; still require this main turn's
212
+ // end/checkpoint and every pending-work gate below before completing.
213
+ this.resetFinal();
214
+ this.finalTurn = data.turnId;
215
+ }
216
+ else if (event.type === 'tool.execution_start' || event.type === 'user_input.requested') {
217
+ this.resetFinal();
218
+ }
219
+ // Goal can finish exclusively through task_complete (empty assistant
220
+ // content + tool request), with no phase:final_answer message. Bind its
221
+ // authoritative success to the main native turn, then still require the
222
+ // matching turn end/checkpoint and all existing completion gates.
223
+ if (event.type === 'session.task_complete' && data.success === true && this.currentTurn !== undefined) {
224
+ this.resetFinal();
225
+ this.finalTurn = this.currentTurn;
226
+ this.continuation = true;
227
+ }
228
+ if (event.type === 'assistant.turn_end' && this.finalTurn !== undefined && data.turnId === this.finalTurn) {
229
+ this.finalEnded = true;
230
+ }
231
+ // The final checkpoint can precede background compaction completion.
232
+ // Retain that evidence for this final turn so clearing the compaction
233
+ // gate does not require a second checkpoint that may never arrive.
234
+ if (event.type === 'session.usage_checkpoint' && this.finalEnded)
235
+ this.finalCheckpoint = true;
236
+ if ((event.type === 'session.usage_checkpoint' || event.type === 'session.compaction_complete'
237
+ || event.type === 'session.compaction_failed') && this.finalCheckpoint && this.finalEnded && !this.compacting
238
+ && this.tasks.size === 0 && !this.childrenPending && this.pendingInputs.size === 0) {
239
+ this.continuation = false;
240
+ this.complete = true;
241
+ }
242
+ }
243
+ this.onEvent(event);
244
+ }
245
+ }
246
+ //# sourceMappingURL=copilot-turn-journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-turn-journal.js","sourceRoot":"","sources":["../src/copilot-turn-journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { HistoryMessage } from './history-message-transform.js';
2
+ export interface CopilotUserRequest extends HistoryMessage {
3
+ role: 'user';
4
+ copilotRequestId: string;
5
+ copilotRequestState: 'pending' | 'delivered' | 'cancelled' | 'failed';
6
+ backendTurnId: string;
7
+ timestamp: string;
8
+ }
9
+ export declare function readCopilotUserRequests(root: string, sessionId: string): CopilotUserRequest[];
10
+ export declare function saveCopilotUserRequest(root: string, sessionId: string, request: CopilotUserRequest): void;
11
+ export declare function mergeCopilotUserRequests(history: HistoryMessage[], requests: CopilotUserRequest[], liveRequestId?: string): HistoryMessage[];
@@ -0,0 +1,84 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join, resolve, sep } from 'path';
3
+ import { atomicWriteCopilotSidecar } from './copilot-sidecar.js';
4
+ const FILE = '.agentlink-user-requests.json';
5
+ function requestFile(root, sessionId) {
6
+ const base = resolve(root), dir = resolve(root, sessionId);
7
+ if (!dir.startsWith(base + sep))
8
+ throw new Error('Invalid Copilot request Session');
9
+ return join(dir, FILE);
10
+ }
11
+ export function readCopilotUserRequests(root, sessionId) {
12
+ const file = requestFile(root, sessionId);
13
+ if (!existsSync(file))
14
+ return [];
15
+ const stored = JSON.parse(readFileSync(file, 'utf8'));
16
+ if (stored.version !== 1 || !Array.isArray(stored.requests)
17
+ || stored.requests.some((r) => !r || r.role !== 'user'
18
+ || typeof r.copilotRequestId !== 'string' || typeof r.content !== 'string'
19
+ || !['pending', 'delivered', 'cancelled', 'failed'].includes(r.copilotRequestState))) {
20
+ throw new Error('Invalid Copilot user-request history');
21
+ }
22
+ return stored.requests;
23
+ }
24
+ export function saveCopilotUserRequest(root, sessionId, request) {
25
+ const file = requestFile(root, sessionId);
26
+ if (!existsSync(resolve(root, sessionId)))
27
+ return; // A new Session is not created for bookkeeping.
28
+ const requests = readCopilotUserRequests(root, sessionId);
29
+ const index = requests.findIndex(row => row.copilotRequestId === request.copilotRequestId);
30
+ if (index < 0)
31
+ requests.push({ ...request });
32
+ else
33
+ requests[index] = { ...request };
34
+ atomicWriteCopilotSidecar(file, JSON.stringify({ version: 1, requests }));
35
+ }
36
+ // Only pending submissions without a live owner are cancelled on restore. They
37
+ // remain visible, but are never automatically submitted after an Agent restart.
38
+ export function mergeCopilotUserRequests(history, requests, liveRequestId) {
39
+ const rows = history.map(row => ({ ...row }));
40
+ const ordered = [...requests].sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
41
+ const normalize = (text) => text.replace(/^\/(plan|goal)\s+/, '').trim();
42
+ for (let i = 0; i < ordered.length; i++) {
43
+ const request = ordered[i];
44
+ let target = rows.find(row => row.copilotRequestId === request.copilotRequestId
45
+ || (request.copilotUserMessageId && row.copilotUserMessageId === request.copilotUserMessageId));
46
+ // Native history can flush just before the SDK callback associates its ID.
47
+ // Match only one exact request in its submission interval, never globally
48
+ // deduplicate equal text from separate turns or cancelled attempts.
49
+ if (!target) {
50
+ const start = Date.parse(request.timestamp), end = Date.parse(ordered[i + 1]?.timestamp) || Infinity;
51
+ target = rows.find(row => row.role === 'user' && row.copilotUserMessageId && !row.copilotRequestId
52
+ && Date.parse(row.timestamp || '') >= start && Date.parse(row.timestamp || '') < end
53
+ && normalize(row.content) === normalize(request.content));
54
+ }
55
+ if (target) {
56
+ target.copilotRequestId = request.copilotRequestId;
57
+ target.copilotRequestState = 'delivered';
58
+ // Preflight compaction precedes the CLI's user event, but follows the
59
+ // user's actual submission. Keep native in-turn compactions untouched.
60
+ const targetIndex = rows.indexOf(target);
61
+ const acceptedAt = Date.parse(request.timestamp), nativeAt = Date.parse(target.timestamp || '');
62
+ let first = targetIndex;
63
+ while (first > 0 && rows[first - 1].compaction) {
64
+ const compact = rows[first - 1].compaction;
65
+ if (compact.scope !== 'main' || compact.startedAt == null || compact.startedAt < acceptedAt
66
+ || compact.completedAt == null || compact.completedAt > nativeAt)
67
+ break;
68
+ first--;
69
+ }
70
+ if (first < targetIndex) {
71
+ target.timestamp = request.timestamp;
72
+ rows.splice(targetIndex, 1);
73
+ rows.splice(first, 0, target);
74
+ }
75
+ continue;
76
+ }
77
+ const row = { ...request, copilotRequestState: request.copilotRequestState === 'pending'
78
+ && request.copilotRequestId !== liveRequestId ? 'cancelled' : request.copilotRequestState };
79
+ const index = rows.findIndex(value => Date.parse(value.timestamp || '') > Date.parse(row.timestamp));
80
+ rows.splice(index < 0 ? rows.length : index, 0, row);
81
+ }
82
+ return rows;
83
+ }
84
+ //# sourceMappingURL=copilot-user-requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-user-requests.js","sourceRoot":"","sources":["../src/copilot-user-requests.ts"],"names":[],"mappings":"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"}
package/dist/copilot.d.ts CHANGED
@@ -1,19 +1,26 @@
1
1
  /**
2
2
  * Copilot CLI process driver for AgentLink.
3
3
  *
4
- * Parallel to claude.ts but simpler:
5
- * - Each turn spawns a new `copilot --output-format json` process
6
- * - Prompt is written to stdin to avoid command-line length limits
7
- * - No persistent process, no control_request protocol
8
- * - JSONL stdout parsed and emitted as backend_event messages
9
- * - Session state stored at ~/.copilot/session-state/<id>/
4
+ * Parallel to claude.ts, with a conversation-scoped persistent SDK runtime:
5
+ * - Chat, Plan, /goal, and /compact share one provider Session; discovery is static
6
+ * - Agency attachments use SDK; Direct native attachments retain the CLI fallback
7
+ * - Provider events are normalized into backend_event messages
8
+ * - Session state remains stored at ~/.copilot/session-state/<id>/
10
9
  */
11
10
  import { type ChildProcess } from 'child_process';
11
+ import { CopilotReviewDocuments, type CopilotReviewDocument } from './copilot-review-documents.js';
12
+ import { type CopilotUserRequest } from './copilot-user-requests.js';
13
+ import { CopilotCompactionBarrier } from './copilot-compaction-barrier.js';
14
+ import { CopilotCompactionLifecycle, type CopilotCompactionRecord } from './copilot-compaction-lifecycle.js';
12
15
  import type { SendFn } from './claude.js';
13
16
  import type { SessionInfo } from './history.js';
14
17
  import { type HistoryMessage } from './history-message-transform.js';
15
- import { copilotCapabilities } from './backends/types.js';
18
+ import { copilotCapabilities, type UsageInfo } from './backends/types.js';
19
+ import { CopilotCommandRuntime } from './copilot-command-bridge.js';
20
+ import type { ProviderCommand } from './provider-command-types.js';
21
+ import { type CopilotConfiguration } from './copilot-configuration.js';
16
22
  export interface CopilotConversationState {
23
+ configuration?: CopilotConfiguration;
17
24
  conversationId: string;
18
25
  child: ChildProcess | null;
19
26
  abortController: AbortController | null;
@@ -21,6 +28,8 @@ export interface CopilotConversationState {
21
28
  lastCopilotSessionId: string | null;
22
29
  workDir: string;
23
30
  turnActive: boolean;
31
+ turnStartedAt?: number;
32
+ userRequest?: CopilotUserRequest;
24
33
  providerId: string;
25
34
  model: string | null;
26
35
  contextTier: CopilotContextTier | null;
@@ -30,9 +39,100 @@ export interface CopilotConversationState {
30
39
  heartbeatTimer: ReturnType<typeof setInterval> | null;
31
40
  /** True once we've sent session_started for sidebar refresh */
32
41
  sessionNotified: boolean;
42
+ copilotMode: CopilotSessionMode;
43
+ planMode: boolean;
44
+ planModePending: boolean;
45
+ isCompacting: boolean;
46
+ commandRuntime: CopilotCommandRuntime | null;
47
+ commandSessionId: string | null;
48
+ deferredCommandUsage: UsageInfo | null;
49
+ runtimeInitPromise: Promise<void> | null;
50
+ runtimeDisposal: Promise<void> | null;
51
+ runtimeConfigKey: string | null;
52
+ runtimeGeneration: number;
53
+ runtimeUnused: boolean;
54
+ cachedCommands: ProviderCommand[] | null;
55
+ activeOperation: 'chat' | 'command' | 'auto-compact' | null;
56
+ activeCommand?: CopilotNativeCommand;
57
+ /** A changed configuration skips maintenance before its first real request. */
58
+ skipNextPreRequestCompaction?: boolean;
59
+ lastUsage: UsageInfo | null;
60
+ contextUsageBeforeOptionsChange?: UsageInfo;
61
+ /** Invalidates a recount across native usage, compaction and cancellation. */
62
+ contextMeasurementVersion?: number;
63
+ contextPublishSequence?: number;
64
+ nativeContextFloor?: {
65
+ generation: number;
66
+ key: string;
67
+ tokens: number;
68
+ at: number;
69
+ activity: number;
70
+ };
71
+ contextActivityVersion?: number;
72
+ compactionBarrier?: CopilotCompactionBarrier;
73
+ compactionStartAt?: number;
74
+ compactionBase?: {
75
+ systemTokens?: number;
76
+ toolDefinitionsTokens?: number;
77
+ currentTokens?: number;
78
+ conversationTokens?: number;
79
+ model?: string;
80
+ contextTier?: string;
81
+ generation: number;
82
+ };
83
+ publishedUsage?: UsageInfo | null;
84
+ pendingTurnCompletion?: boolean;
85
+ contextCompactionAt?: number;
86
+ contextBoundarySessionId?: string;
87
+ compactionEventKeys?: Set<string>;
88
+ lastCompactionEventAt?: number;
89
+ compactionLifecycle?: CopilotCompactionLifecycle;
90
+ compactionLifecycleGeneration?: number;
91
+ compactionRecord?: CopilotCompactionRecord;
92
+ compactionRecords?: Map<string, CopilotCompactionRecord>;
93
+ compactionPublications?: Map<string, string>;
94
+ autoCompactionWatermark: string | null;
95
+ autoCompactionPending: boolean;
96
+ compactionFailed: boolean;
97
+ compactionTrigger: string | null;
98
+ /** Allow the next provider usage sample to cross a confirmed compaction boundary. */
99
+ contextUsageDecreaseAllowed: boolean;
100
+ /** Actual session usage reported during maintenance, committed only on success. */
101
+ pendingCompactionUsage?: Partial<UsageInfo> | null;
102
+ compactionHasConfirmedUsage?: boolean;
103
+ toolNamesByCallId: Map<string, string>;
104
+ toolStartKeys?: Set<string>;
105
+ reviewDocuments?: CopilotReviewDocuments;
106
+ streamedMessageTextById: Map<string, string>;
107
+ finalizedMessageIds: Set<string>;
108
+ lastMainMessageId?: string;
109
+ pendingMainReply?: {
110
+ id: string;
111
+ text: string;
112
+ published: boolean;
113
+ };
114
+ assistantReplyStarted?: boolean;
115
+ subagentMessages?: Map<string, Map<string, {
116
+ text: string;
117
+ thinking: string;
118
+ }>>;
119
+ subagentToolIds?: Map<string, string>;
120
+ /** Agency ACP text is held until reasoning and tool blocks for the turn finish. */
121
+ agencyResponseBuffer: string;
122
+ taskCompleteReplyEmitted: boolean;
123
+ taskCompleteSucceeded: boolean;
124
+ pendingPlanReview: PendingCopilotPlanReview | null;
125
+ nativePlanExit?: boolean;
126
+ planControlPending?: boolean;
127
+ readyPlanId: string | null;
128
+ planImplementationStarting: boolean;
129
+ createdAt: number;
130
+ lastActivityAt: number;
131
+ timestampMessageId?: string;
33
132
  }
34
133
  export type CopilotContextTier = 'default' | 'long_context';
35
134
  export type CopilotReasoningEffort = 'none' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
135
+ export type CopilotSessionMode = 'interactive' | 'plan' | 'autopilot';
36
136
  export interface CopilotRunOptions {
37
137
  model?: string;
38
138
  context?: string;
@@ -48,7 +148,58 @@ interface CopilotChatFile {
48
148
  mimeType: string;
49
149
  data: string;
50
150
  }
151
+ export declare const COPILOT_AUTO_COMPACTION_THRESHOLD: 0.8;
152
+ export declare const COPILOT_IDLE_CONVERSATION_TIMEOUT_MS: number;
153
+ export declare const COPILOT_STALE_RUNTIME_TIMEOUT_MS: number;
154
+ export declare const COPILOT_MAX_CONVERSATIONS = 15;
155
+ interface CopilotDecisionRequestPayload {
156
+ reviewDocuments?: CopilotReviewDocument[];
157
+ questions: Array<{
158
+ question: string;
159
+ header?: string;
160
+ options: Array<{
161
+ label: string;
162
+ value?: string;
163
+ description?: string;
164
+ }>;
165
+ multiSelect?: boolean;
166
+ }>;
167
+ source: 'tool_request_user_input';
168
+ presentation: 'inline';
169
+ kind?: 'plan_input';
170
+ allowFreeform: boolean;
171
+ expiresAt?: number;
172
+ timeoutAction?: 'first_option' | 'continue_plan';
173
+ }
174
+ interface PendingCopilotPlanReview {
175
+ sessionId: string;
176
+ content?: string;
177
+ languageHint: string;
178
+ }
179
+ export interface CopilotPlanQuestion {
180
+ question: string;
181
+ options: Array<{
182
+ label: string;
183
+ description?: string;
184
+ }>;
185
+ multiSelect?: boolean;
186
+ }
187
+ interface CopilotPlanAnswerRecord extends CopilotPlanQuestion {
188
+ answer: string;
189
+ }
190
+ export interface PendingCopilotDecisionSnapshot {
191
+ requestId: string;
192
+ conversationId: string;
193
+ providerId: string;
194
+ sessionId: string;
195
+ request: CopilotDecisionRequestPayload;
196
+ }
51
197
  export declare function addCopilotSendFn(fn: SendFn): () => void;
198
+ export declare function getPendingCopilotDecisions(conversationId: string): PendingCopilotDecisionSnapshot[];
199
+ export declare function handleCopilotUserAnswer(requestId: string, answers: Record<string, unknown>, scope?: {
200
+ conversationId?: string;
201
+ providerId?: string;
202
+ }): boolean;
52
203
  export declare function getCopilotConversation(conversationId: string): CopilotConversationState | undefined;
53
204
  export declare function getCopilotConversations(): Map<string, CopilotConversationState>;
54
205
  /**
@@ -63,23 +214,48 @@ export declare function createCopilotPlaceholder(conversationId: string, opts?:
63
214
  export declare function restartCopilotConversation(conversationId: string, opts?: {
64
215
  providerId?: string;
65
216
  model?: string;
217
+ preserveSession?: boolean;
66
218
  }): {
67
219
  wasTurnActive: boolean;
68
220
  copilotSessionId: string | null;
69
221
  };
70
222
  export declare function setModel(conversationId: string | undefined, model: string): void;
223
+ export type CopilotNativeCommand = 'compact' | 'plan' | 'goal';
224
+ /** Change routing without allocating a replacement native Session or Runtime. */
225
+ export declare function setCopilotProvider(conversationId: string, providerId: string, options?: {
226
+ resumeSessionId?: string;
227
+ workDir?: string;
228
+ restoreOnly?: boolean;
229
+ }): string;
230
+ export declare function parseCopilotPlanAnswerHistory(content: string): CopilotPlanAnswerRecord[];
231
+ export declare function extractCopilotPlanQuestions(content: string): CopilotPlanQuestion[];
232
+ export declare function discoverCopilotCommandsForConversation(_conversationId: string, _providerId: string, _workDir: string, _copilotOptions?: CopilotRunOptions): Promise<ProviderCommand[]>;
233
+ export declare function executeCopilotCommand(conversationId: string, command: CopilotNativeCommand, input: string, workDir: string, options?: CopilotChatOptions): Promise<void>;
234
+ export declare function setCopilotPlanMode(conversationId: string, enabled: boolean, workDir: string, providerId?: string, copilotOptions?: CopilotRunOptions, resumeSessionId?: string): Promise<void>;
235
+ export declare function startCopilotPlanImplementation(conversationId: string, planId: string, workDir: string, options?: {
236
+ providerId?: string;
237
+ resumeSessionId?: string;
238
+ prompt?: string;
239
+ copilotOptions?: CopilotRunOptions;
240
+ }): Promise<void>;
71
241
  export interface CopilotChatOptions {
242
+ /** User-visible input for implicit Plan dispatch; never the expanded prompt. */
243
+ displayPrompt?: string;
72
244
  resumeSessionId?: string;
73
245
  providerId?: string;
74
246
  copilotOptions?: CopilotRunOptions;
247
+ forkSourceSessionId?: string;
248
+ /** Internal: mode override for the legacy native-attachment CLI path. */
249
+ oneShotMode?: 'plan' | 'autopilot';
75
250
  }
76
251
  export declare function normalizeCopilotRunOptions(input?: CopilotRunOptions): {
77
252
  options: NormalizedCopilotRunOptions;
78
253
  error?: string;
79
254
  };
80
- export declare function handleCopilotChat(conversationId: string, text: string, workDir: string, options?: CopilotChatOptions, files?: CopilotChatFile[]): void;
255
+ export declare function handleCopilotChat(conversationId: string, text: string, workDir: string, options?: CopilotChatOptions, files?: CopilotChatFile[]): Promise<void>;
81
256
  export declare function cancelCopilotExecution(conversationId: string): void;
82
257
  export declare function cleanupAllCopilotConversations(): void;
258
+ export declare function readCopilotSessionProvider(sessionId: string): string | undefined;
83
259
  interface CopilotSessionPage {
84
260
  sessions: SessionInfo[];
85
261
  hasMore: boolean;
@@ -93,6 +269,10 @@ interface CopilotGlobalSessionInfo {
93
269
  title: string;
94
270
  firstPrompt: string;
95
271
  lastModified: number;
272
+ providerId?: string;
273
+ isFork?: boolean;
274
+ forkNumber?: number;
275
+ forkSourceSessionId?: string;
96
276
  }
97
277
  interface CopilotGlobalSessionPage {
98
278
  sessions: CopilotGlobalSessionInfo[];
@@ -111,6 +291,8 @@ export declare function listCopilotSessionsPage(workDir: string, options?: {
111
291
  export declare function readCopilotSessionMessages(_workDir: string, sessionId: string, options?: {
112
292
  strictReadErrors?: boolean;
113
293
  }): HistoryMessage[];
294
+ export declare function readCopilotSessionMode(sessionId: string): CopilotSessionMode;
295
+ export declare function readCopilotSessionUsage(sessionId: string): UsageInfo | null;
114
296
  export declare function getCopilotSessionWorkDir(sessionId: string): string | undefined;
115
297
  export declare function listAllCopilotSessions(limit?: number): Array<{
116
298
  sessionId: string;
@@ -119,6 +301,9 @@ export declare function listAllCopilotSessions(limit?: number): Array<{
119
301
  title: string;
120
302
  firstPrompt: string;
121
303
  lastModified: number;
304
+ isFork?: boolean;
305
+ forkNumber?: number;
306
+ forkSourceSessionId?: string;
122
307
  }>;
123
308
  export declare function listAllCopilotSessionsPage(options?: {
124
309
  limit?: number;
@@ -126,5 +311,5 @@ export declare function listAllCopilotSessionsPage(options?: {
126
311
  }): CopilotGlobalSessionPage;
127
312
  export declare function renameCopilotSession(_workDir: string, sessionId: string, newTitle: string): boolean;
128
313
  export declare function moveCopilotSession(_fromWorkDir: string, toWorkDir: string, sessionId: string): boolean;
129
- export declare function deleteCopilotSession(_workDir: string, sessionId: string): boolean;
314
+ export declare function deleteCopilotSession(_workDir: string, sessionId: string): Promise<boolean>;
130
315
  export { copilotCapabilities };