@myagentroam/agent 0.9.158 → 0.9.160
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/dist/agent-core/extensions/agents.d.ts +69 -0
- package/dist/agent-core/extensions/agents.js +160 -0
- package/dist/agent-core/extensions/contracts.d.ts +260 -0
- package/dist/agent-core/extensions/contracts.js +1 -0
- package/dist/agent-core/extensions/data.d.ts +84 -0
- package/dist/agent-core/extensions/data.js +83 -0
- package/dist/agent-core/extensions/environment.d.ts +27 -0
- package/dist/agent-core/extensions/environment.js +52 -0
- package/dist/agent-core/extensions/files.d.ts +64 -0
- package/dist/agent-core/extensions/files.js +26 -0
- package/dist/agent-core/extensions/hooks.d.ts +32 -0
- package/dist/agent-core/extensions/hooks.js +135 -0
- package/dist/agent-core/extensions/manager.d.ts +39 -0
- package/dist/agent-core/extensions/manager.js +458 -0
- package/dist/agent-core/extensions/mcp.d.ts +99 -0
- package/dist/agent-core/extensions/mcp.js +433 -0
- package/dist/agent-core/extensions/model-request.d.ts +60 -0
- package/dist/agent-core/extensions/model-request.js +167 -0
- package/dist/agent-core/extensions/model-stream.d.ts +9 -0
- package/dist/agent-core/extensions/model-stream.js +101 -0
- package/dist/agent-core/extensions/models.d.ts +43 -0
- package/dist/agent-core/extensions/models.js +1 -0
- package/dist/agent-core/extensions/network.d.ts +32 -0
- package/dist/agent-core/extensions/network.js +97 -0
- package/dist/agent-core/extensions/operation.d.ts +29 -0
- package/dist/agent-core/extensions/operation.js +98 -0
- package/dist/agent-core/extensions/processes.d.ts +52 -0
- package/dist/agent-core/extensions/processes.js +283 -0
- package/dist/agent-core/extensions/prompt-composition.d.ts +24 -0
- package/dist/agent-core/extensions/prompt-composition.js +106 -0
- package/dist/agent-core/extensions/prompt-input.d.ts +23 -0
- package/dist/agent-core/extensions/prompt-input.js +46 -0
- package/dist/agent-core/extensions/resources.d.ts +27 -0
- package/dist/agent-core/extensions/resources.js +221 -0
- package/dist/agent-core/extensions/services.d.ts +31 -0
- package/dist/agent-core/extensions/services.js +61 -0
- package/dist/agent-core/extensions/session-input.d.ts +151 -0
- package/dist/agent-core/extensions/session-input.js +351 -0
- package/dist/agent-core/extensions/session-messages.d.ts +41 -0
- package/dist/agent-core/extensions/session-messages.js +76 -0
- package/dist/agent-core/extensions/session.d.ts +68 -0
- package/dist/agent-core/extensions/session.js +593 -0
- package/dist/agent-core/extensions/settings.d.ts +59 -0
- package/dist/agent-core/extensions/settings.js +115 -0
- package/dist/agent-core/extensions/store.d.ts +10 -0
- package/dist/agent-core/extensions/store.js +131 -0
- package/dist/agent-core/extensions/tools.d.ts +61 -0
- package/dist/agent-core/extensions/tools.js +266 -0
- package/dist/agent-core/host/contracts.d.ts +25 -0
- package/dist/agent-core/host/local-agent-host.d.ts +10 -1
- package/dist/agent-core/host/local-agent-host.js +132 -20
- package/dist/agent-core/host/local-file-access.d.ts +30 -0
- package/dist/agent-core/host/local-file-access.js +107 -0
- package/dist/agent-core/host/local-network-access.d.ts +6 -0
- package/dist/agent-core/host/local-network-access.js +97 -0
- package/dist/agent-core/host/local-process-executor.d.ts +5 -1
- package/dist/agent-core/host/local-session-environment.d.ts +18 -0
- package/dist/agent-core/host/local-session-environment.js +102 -0
- package/dist/agent-core/model/anthropic-messages.js +73 -23
- package/dist/agent-core/model/contracts.d.ts +21 -0
- package/dist/agent-core/model/openai-responses.d.ts +3 -1
- package/dist/agent-core/model/openai-responses.js +248 -97
- package/dist/agent-core/model/text-blocks.d.ts +7 -0
- package/dist/agent-core/model/text-blocks.js +40 -0
- package/dist/agent-core/prompts/index.d.ts +6 -2
- package/dist/agent-core/prompts/index.js +38 -24
- package/dist/agent-core/runtime/context/gc-tokens.js +6 -1
- package/dist/agent-core/runtime/context/normalize.js +21 -1
- package/dist/agent-core/runtime/context/projection.js +35 -1
- package/dist/agent-core/runtime/context/request-budget.js +5 -2
- package/dist/agent-core/runtime/context/restore.d.ts +5 -0
- package/dist/agent-core/runtime/context/restore.js +47 -4
- package/dist/agent-core/runtime/context/usage.js +2 -3
- package/dist/agent-core/runtime/contracts.d.ts +2 -0
- package/dist/agent-core/runtime/execution.js +5 -2
- package/dist/agent-core/sdk/agent.js +177 -40
- package/dist/agent-core/sdk/extension-agents.d.ts +9 -0
- package/dist/agent-core/sdk/extension-agents.js +51 -0
- package/dist/agent-core/sdk/extension-models.d.ts +13 -0
- package/dist/agent-core/sdk/extension-models.js +128 -0
- package/dist/agent-core/sdk/extension-session.d.ts +30 -0
- package/dist/agent-core/sdk/extension-session.js +103 -0
- package/dist/agent-core/sdk/extension-tools.d.ts +16 -0
- package/dist/agent-core/sdk/extension-tools.js +126 -0
- package/dist/agent-core/sdk/session.d.ts +26 -2
- package/dist/agent-core/sdk/session.js +1215 -506
- package/dist/agent-core/sdk/types.d.ts +3 -0
- package/dist/agent-core/session/context-gc-checkpoint.js +1 -1
- package/dist/agent-core/session/jsonl-store.d.ts +28 -8
- package/dist/agent-core/session/jsonl-store.js +124 -84
- package/dist/agent-core/session/types.d.ts +4 -1
- package/dist/agent-core/storage/file-lock.d.ts +4 -0
- package/dist/agent-core/storage/file-lock.js +83 -0
- package/dist/agent-core/subagent/contracts.d.ts +11 -1
- package/dist/agent-core/subagent/scheduler.d.ts +8 -0
- package/dist/agent-core/subagent/session-controller.d.ts +22 -1
- package/dist/agent-core/subagent/session-controller.js +355 -98
- package/dist/agent-core/tools/agent/agent-start.d.ts +1 -1
- package/dist/agent-core/tools/code-mode/cells.js +5 -15
- package/dist/agent-core/tools/code-mode/dispatch.d.ts +1 -0
- package/dist/agent-core/tools/code-mode/dispatch.js +13 -1
- package/dist/agent-core/tools/code-mode/index.js +1 -2
- package/dist/agent-core/tools/code-mode/observations.d.ts +5 -0
- package/dist/agent-core/tools/code-mode/observations.js +16 -5
- package/dist/agent-core/tools/code-mode/quickjs-engine.js +10 -5
- package/dist/agent-core/tools/execution.d.ts +11 -2
- package/dist/agent-core/tools/execution.js +58 -21
- package/dist/agent-core/tools/input.d.ts +2 -0
- package/dist/agent-core/tools/input.js +36 -0
- package/dist/agent-core/tools/local/apply-patch.js +21 -17
- package/dist/agent-core/tools/local/exec.d.ts +4 -4
- package/dist/agent-core/tools/local/exec.js +234 -62
- package/dist/agent-core/tools/local/registry.d.ts +6 -0
- package/dist/agent-core/tools/local/registry.js +60 -9
- package/dist/agent-core/tools/local/view-image.js +108 -2
- package/dist/agent-core/tools/mcp/catalog.d.ts +6 -2
- package/dist/agent-core/tools/mcp/catalog.js +4 -4
- package/dist/agent-core/tools/mcp/history.js +2 -2
- package/dist/agent-core/tools/mcp/tool-search.d.ts +3 -1
- package/dist/agent-core/tools/mcp/tool-search.js +2 -2
- package/dist/agent-core/tools/output-projection.d.ts +3 -1
- package/dist/agent-core/tools/output-projection.js +11 -2
- package/dist/agent-core/tools/runtime-context.d.ts +1 -0
- package/dist/agent-core/tools/runtime.d.ts +3 -1
- package/dist/agent-core/tools/runtime.js +22 -7
- package/dist/agent-core/tools/scheduler.d.ts +2 -0
- package/dist/agent-core/tools/scheduler.js +43 -6
- package/dist/index.d.ts +21 -0
- package/dist/sandbox/linux/bubblewrap-sandbox-executor.js +5 -2
- package/package.json +1 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { MarAgentError } from '../error.js';
|
|
2
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
/** An instance's managed resources, not an OS sandbox or a process-wide resource owner. */
|
|
5
|
+
export class ExtensionResourceScope {
|
|
6
|
+
instanceId = randomUUID();
|
|
7
|
+
static #initialization = new AsyncLocalStorage();
|
|
8
|
+
static get initializing() {
|
|
9
|
+
return this.#initialization.getStore()?.active === true;
|
|
10
|
+
}
|
|
11
|
+
static async initialize(run) {
|
|
12
|
+
const frame = { active: true };
|
|
13
|
+
return this.#initialization.run(frame, async () => {
|
|
14
|
+
try {
|
|
15
|
+
return await run();
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
frame.active = false;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
#state = 'STAGED';
|
|
23
|
+
#controller = new AbortController();
|
|
24
|
+
#resources = [];
|
|
25
|
+
#operations = new Set();
|
|
26
|
+
#activators = new Set();
|
|
27
|
+
#disposal;
|
|
28
|
+
get state() {
|
|
29
|
+
return this.#state;
|
|
30
|
+
}
|
|
31
|
+
get signal() {
|
|
32
|
+
return this.#controller.signal;
|
|
33
|
+
}
|
|
34
|
+
activate() {
|
|
35
|
+
this.#assertOpen();
|
|
36
|
+
if (this.#state === 'ACTIVE')
|
|
37
|
+
return;
|
|
38
|
+
this.#state = 'ACTIVE';
|
|
39
|
+
for (const activate of this.#activators)
|
|
40
|
+
activate();
|
|
41
|
+
this.#activators.clear();
|
|
42
|
+
}
|
|
43
|
+
effect(acquire) {
|
|
44
|
+
this.#assertOpen();
|
|
45
|
+
const acquired = Promise.resolve()
|
|
46
|
+
.then(acquire)
|
|
47
|
+
.then((release) => {
|
|
48
|
+
if (typeof release !== 'function')
|
|
49
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_RESOURCE_INVALID', 'Resource acquisition must return a disposer.');
|
|
50
|
+
return release;
|
|
51
|
+
});
|
|
52
|
+
let releasing;
|
|
53
|
+
const disposalFrame = new AsyncLocalStorage();
|
|
54
|
+
const registration = {
|
|
55
|
+
ready: acquired.then(() => undefined),
|
|
56
|
+
dispose: () => {
|
|
57
|
+
if (disposalFrame.getStore())
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
releasing ??= acquired.then(async (release) => {
|
|
60
|
+
if (typeof release !== 'function')
|
|
61
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_RESOURCE_INVALID', 'Resource acquisition must return a disposer.');
|
|
62
|
+
await disposalFrame.run(true, release);
|
|
63
|
+
}, () => undefined);
|
|
64
|
+
return releasing;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
// Acquisition errors remain observable through ready, without unhandled rejection noise.
|
|
68
|
+
void registration.ready.catch(() => undefined);
|
|
69
|
+
this.#resources.push(registration);
|
|
70
|
+
return registration;
|
|
71
|
+
}
|
|
72
|
+
async run(operation, parent) {
|
|
73
|
+
if (this.#state !== 'ACTIVE' &&
|
|
74
|
+
!(this.#state === 'STAGED' && ExtensionResourceScope.initializing))
|
|
75
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_RETIRED', 'Extension is not active.');
|
|
76
|
+
const signal = parent ? AbortSignal.any([this.signal, parent]) : this.signal;
|
|
77
|
+
signal.throwIfAborted();
|
|
78
|
+
const running = Promise.resolve().then(() => {
|
|
79
|
+
signal.throwIfAborted();
|
|
80
|
+
return operation(signal);
|
|
81
|
+
});
|
|
82
|
+
this.#operations.add(running);
|
|
83
|
+
try {
|
|
84
|
+
const result = await running;
|
|
85
|
+
signal.throwIfAborted();
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
this.#operations.delete(running);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
after(durationMs, callback, onError = () => { }) {
|
|
93
|
+
return this.#timer(durationMs, false, callback, onError);
|
|
94
|
+
}
|
|
95
|
+
every(durationMs, callback, onError = () => { }) {
|
|
96
|
+
return this.#timer(durationMs, true, callback, onError);
|
|
97
|
+
}
|
|
98
|
+
async sleep(durationMs, parent) {
|
|
99
|
+
if (!Number.isFinite(durationMs) || durationMs < 0)
|
|
100
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_TIMER_INVALID', 'Sleep duration must be finite and non-negative.');
|
|
101
|
+
return this.run(async (signal) => {
|
|
102
|
+
const deadline = performance.now() + durationMs;
|
|
103
|
+
let timer;
|
|
104
|
+
let abort;
|
|
105
|
+
try {
|
|
106
|
+
await new Promise((resolve, reject) => {
|
|
107
|
+
abort = () => reject(signal.reason);
|
|
108
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
109
|
+
const schedule = () => {
|
|
110
|
+
const remaining = deadline - performance.now();
|
|
111
|
+
if (remaining <= 0) {
|
|
112
|
+
resolve();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
timer = setTimeout(schedule, Math.min(remaining, 2_147_483_647));
|
|
116
|
+
};
|
|
117
|
+
schedule();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
if (timer)
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
signal.removeEventListener('abort', abort);
|
|
124
|
+
}
|
|
125
|
+
}, parent);
|
|
126
|
+
}
|
|
127
|
+
/** Wait for acquisitions added by setup before publishing any callbacks. */
|
|
128
|
+
async ready() {
|
|
129
|
+
let count = -1;
|
|
130
|
+
while (count !== this.#resources.length) {
|
|
131
|
+
count = this.#resources.length;
|
|
132
|
+
await Promise.all(this.#resources.map((resource) => resource.ready));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
retire() {
|
|
136
|
+
if (this.#state === 'DISPOSED')
|
|
137
|
+
return;
|
|
138
|
+
this.#state = 'RETIRING';
|
|
139
|
+
this.#controller.abort();
|
|
140
|
+
this.#activators.clear();
|
|
141
|
+
}
|
|
142
|
+
#timer(durationMs, repeat, callback, onError) {
|
|
143
|
+
this.#assertOpen();
|
|
144
|
+
if (!Number.isFinite(durationMs) || durationMs < 0 || (repeat && durationMs === 0))
|
|
145
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_TIMER_INVALID', 'Timer duration must be finite and non-negative; repeating timers must be positive.');
|
|
146
|
+
let stopped = false;
|
|
147
|
+
let timer;
|
|
148
|
+
const timerController = new AbortController();
|
|
149
|
+
const callbacks = new AsyncLocalStorage();
|
|
150
|
+
let running;
|
|
151
|
+
const schedule = () => {
|
|
152
|
+
if (stopped || this.#state !== 'ACTIVE')
|
|
153
|
+
return;
|
|
154
|
+
const due = performance.now() + durationMs;
|
|
155
|
+
const arm = () => {
|
|
156
|
+
timer = setTimeout(() => {
|
|
157
|
+
timer = undefined;
|
|
158
|
+
if (stopped || this.#state !== 'ACTIVE')
|
|
159
|
+
return;
|
|
160
|
+
if (performance.now() < due) {
|
|
161
|
+
arm();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
running = this.run(async (signal) => {
|
|
165
|
+
await callbacks.run(true, () => callback(signal));
|
|
166
|
+
}, timerController.signal)
|
|
167
|
+
.catch((error) => {
|
|
168
|
+
if (!this.signal.aborted && !timerController.signal.aborted)
|
|
169
|
+
onError(error);
|
|
170
|
+
})
|
|
171
|
+
.finally(() => {
|
|
172
|
+
if (repeat)
|
|
173
|
+
schedule();
|
|
174
|
+
});
|
|
175
|
+
void running.catch(() => undefined);
|
|
176
|
+
}, Math.min(Math.max(0, due - performance.now()), 2_147_483_647));
|
|
177
|
+
timer.unref?.();
|
|
178
|
+
};
|
|
179
|
+
arm();
|
|
180
|
+
};
|
|
181
|
+
const registration = this.effect(() => async () => {
|
|
182
|
+
stopped = true;
|
|
183
|
+
this.#activators.delete(schedule);
|
|
184
|
+
if (timer !== undefined)
|
|
185
|
+
clearTimeout(timer);
|
|
186
|
+
timerController.abort();
|
|
187
|
+
if (!callbacks.getStore())
|
|
188
|
+
await running;
|
|
189
|
+
});
|
|
190
|
+
if (this.#state === 'ACTIVE')
|
|
191
|
+
schedule();
|
|
192
|
+
else
|
|
193
|
+
this.#activators.add(schedule);
|
|
194
|
+
return registration;
|
|
195
|
+
}
|
|
196
|
+
dispose() {
|
|
197
|
+
if (this.#disposal)
|
|
198
|
+
return this.#disposal;
|
|
199
|
+
this.retire();
|
|
200
|
+
this.#disposal = Promise.resolve().then(async () => {
|
|
201
|
+
await Promise.allSettled([...this.#operations]);
|
|
202
|
+
let failures = 0;
|
|
203
|
+
for (const resource of [...this.#resources].reverse()) {
|
|
204
|
+
try {
|
|
205
|
+
await resource.dispose();
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
failures++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (failures)
|
|
212
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_CLEANUP_FAILED', 'Extension resource cleanup failed.', { details: { failures } });
|
|
213
|
+
this.#state = 'DISPOSED';
|
|
214
|
+
});
|
|
215
|
+
return this.#disposal;
|
|
216
|
+
}
|
|
217
|
+
#assertOpen() {
|
|
218
|
+
if (this.#state === 'RETIRING' || this.#state === 'DISPOSED')
|
|
219
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_RETIRED', 'Extension resource scope is retired.');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CoreResourceScope } from './resources.js';
|
|
2
|
+
export interface CoreServiceKey<T> {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly scope: 'agent' | 'session';
|
|
5
|
+
/** Compile-time service contract; never examined at runtime. */
|
|
6
|
+
readonly contract?: (implementation: T) => T;
|
|
7
|
+
}
|
|
8
|
+
export interface CoreServiceRegistry {
|
|
9
|
+
provide<T>(key: CoreServiceKey<T>, implementation: T): void;
|
|
10
|
+
replace<T>(key: CoreServiceKey<T>, implementation: T): void;
|
|
11
|
+
wrap<T>(key: CoreServiceKey<T>, factory: (below: T) => T): void;
|
|
12
|
+
consume<T>(key: CoreServiceKey<T>, options?: {
|
|
13
|
+
readonly optional?: boolean;
|
|
14
|
+
}): T | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** A composition's typed values, not a dynamic IoC container or dependency solver. */
|
|
17
|
+
export declare class ExtensionServices {
|
|
18
|
+
#private;
|
|
19
|
+
readonly scope: 'agent' | 'session';
|
|
20
|
+
readonly parent?: ExtensionServices | undefined;
|
|
21
|
+
constructor(scope: 'agent' | 'session', parent?: ExtensionServices | undefined);
|
|
22
|
+
has(key: {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly scope: 'agent' | 'session';
|
|
25
|
+
}): boolean;
|
|
26
|
+
hasOwned(key: {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly scope: 'agent' | 'session';
|
|
29
|
+
}, owner: CoreResourceScope): boolean;
|
|
30
|
+
bind(owner: CoreResourceScope): CoreServiceRegistry;
|
|
31
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { MarAgentError } from '../error.js';
|
|
2
|
+
/** A composition's typed values, not a dynamic IoC container or dependency solver. */
|
|
3
|
+
export class ExtensionServices {
|
|
4
|
+
scope;
|
|
5
|
+
parent;
|
|
6
|
+
#entries = new Map();
|
|
7
|
+
constructor(scope, parent) {
|
|
8
|
+
this.scope = scope;
|
|
9
|
+
this.parent = parent;
|
|
10
|
+
}
|
|
11
|
+
has(key) {
|
|
12
|
+
return this.#find(key) !== undefined;
|
|
13
|
+
}
|
|
14
|
+
hasOwned(key, owner) {
|
|
15
|
+
return (key.scope === this.scope &&
|
|
16
|
+
(this.#entries.get(key.id)?.some((entry) => entry.owner === owner) ?? false));
|
|
17
|
+
}
|
|
18
|
+
bind(owner) {
|
|
19
|
+
const consume = (key, options) => {
|
|
20
|
+
const entry = this.#find(key);
|
|
21
|
+
if (!entry && !options?.optional)
|
|
22
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_DEPENDENCY_MISSING', 'Required service is unavailable.');
|
|
23
|
+
return entry?.value;
|
|
24
|
+
};
|
|
25
|
+
const publish = (key, value, replace) => {
|
|
26
|
+
if (key.scope !== this.scope)
|
|
27
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_SERVICE_SCOPE', 'Service publication uses the wrong scope.');
|
|
28
|
+
if (!key.id.trim())
|
|
29
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_SERVICE_INVALID', 'Service key is empty.');
|
|
30
|
+
const entries = this.#entries.get(key.id) ?? [];
|
|
31
|
+
if (entries.length && !replace)
|
|
32
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_SERVICE_CONFLICT', 'Service is already provided.');
|
|
33
|
+
if (!entries.length && replace)
|
|
34
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_DEPENDENCY_MISSING', 'Service replacement has no lower provider.');
|
|
35
|
+
const entry = { value, owner };
|
|
36
|
+
owner.effect(() => () => {
|
|
37
|
+
const index = entries.indexOf(entry);
|
|
38
|
+
if (index !== -1)
|
|
39
|
+
entries.splice(index, 1);
|
|
40
|
+
});
|
|
41
|
+
entries.push(entry);
|
|
42
|
+
this.#entries.set(key.id, entries);
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
provide: (key, value) => publish(key, value, false),
|
|
46
|
+
replace: (key, value) => publish(key, value, true),
|
|
47
|
+
wrap: (key, factory) => {
|
|
48
|
+
const entry = this.#find(key);
|
|
49
|
+
if (!entry)
|
|
50
|
+
throw new MarAgentError('MAR_AGENT_EXTENSION_DEPENDENCY_MISSING', 'Service wrapper has no lower provider.');
|
|
51
|
+
publish(key, factory(entry.value), true);
|
|
52
|
+
},
|
|
53
|
+
consume
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
#find(key) {
|
|
57
|
+
if (key.scope === this.scope)
|
|
58
|
+
return this.#entries.get(key.id)?.at(-1);
|
|
59
|
+
return this.parent ? this.parent.#find(key) : undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { CoreOperationContext } from './operation.js';
|
|
2
|
+
import type { SessionSource } from '../session/types.js';
|
|
3
|
+
import { type CorePromptInput } from './prompt-input.js';
|
|
4
|
+
import type { CoreRequestSnapshot } from './model-request.js';
|
|
5
|
+
import type { CorePromptComposition, CorePromptFacts } from './prompt-composition.js';
|
|
6
|
+
import type { CoreSessionMessages, CoreSessionMessagesInput } from './session-messages.js';
|
|
7
|
+
export type { CoreSessionMessages, CoreSessionMessagesInput, CoreSessionMessage } from './session-messages.js';
|
|
8
|
+
export interface CoreAppendInput {
|
|
9
|
+
readonly content: string;
|
|
10
|
+
readonly textBlocks?: readonly {
|
|
11
|
+
readonly text: string;
|
|
12
|
+
}[];
|
|
13
|
+
readonly visibility?: 'model' | 'transcript';
|
|
14
|
+
/** Immediate records commit without scheduling an input or waking a model round. */
|
|
15
|
+
readonly delivery?: 'boundary' | 'immediate';
|
|
16
|
+
readonly attribution?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CoreInputSource {
|
|
19
|
+
readonly operationId: string;
|
|
20
|
+
readonly actor?: CoreOperationContext['actor'];
|
|
21
|
+
readonly extensionId?: string;
|
|
22
|
+
readonly ownerInstanceId?: string;
|
|
23
|
+
readonly provenance?: string;
|
|
24
|
+
/** Presentation intent only; it never changes the actual author or authority. */
|
|
25
|
+
readonly modelAttribution?: 'none';
|
|
26
|
+
}
|
|
27
|
+
export interface CoreSubmitInput extends CorePromptInput {
|
|
28
|
+
readonly provenance?: string;
|
|
29
|
+
readonly modelAttribution?: 'none';
|
|
30
|
+
readonly delivery?: 'boundary' | 'idle';
|
|
31
|
+
readonly waitFor?: 'admission' | 'start' | 'commit';
|
|
32
|
+
/** Explicit lifetime after admission; the Extension owner remains authoritative. */
|
|
33
|
+
readonly queueSignal?: AbortSignal;
|
|
34
|
+
}
|
|
35
|
+
export interface CoreCompactInput {
|
|
36
|
+
readonly focus?: string;
|
|
37
|
+
}
|
|
38
|
+
export type CoreSessionRequest = {
|
|
39
|
+
readonly kind: 'append';
|
|
40
|
+
readonly input: CoreAppendInput;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: 'submit';
|
|
43
|
+
readonly input: CoreSubmitInput;
|
|
44
|
+
} | {
|
|
45
|
+
readonly kind: 'compact';
|
|
46
|
+
readonly input: CoreCompactInput;
|
|
47
|
+
};
|
|
48
|
+
export type CoreSessionOperationStatus = 'queued' | 'accepted' | 'in-progress' | 'committed' | 'completed' | 'handled' | 'cancelled' | 'failed';
|
|
49
|
+
export interface CoreSessionReceipt {
|
|
50
|
+
/** The actual committed record, absent before the writer has completed. */
|
|
51
|
+
readonly recordId?: string;
|
|
52
|
+
readonly operationId: string;
|
|
53
|
+
readonly sequence: number;
|
|
54
|
+
readonly kind: CoreSessionRequest['kind'];
|
|
55
|
+
readonly status: CoreSessionOperationStatus;
|
|
56
|
+
readonly executionId?: string;
|
|
57
|
+
readonly errorCode?: string;
|
|
58
|
+
readonly changed?: boolean;
|
|
59
|
+
readonly handledValue?: unknown;
|
|
60
|
+
readonly ownerInstanceId?: string;
|
|
61
|
+
readonly extensionId?: string;
|
|
62
|
+
readonly parentOperationId?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface CoreSessionInspection {
|
|
65
|
+
readonly sessionId: string;
|
|
66
|
+
readonly epoch: number;
|
|
67
|
+
readonly activeExecutionId?: string;
|
|
68
|
+
readonly operations: readonly CoreSessionReceipt[];
|
|
69
|
+
}
|
|
70
|
+
export interface CoreSessionDescription {
|
|
71
|
+
readonly sessionId: string;
|
|
72
|
+
readonly source?: SessionSource;
|
|
73
|
+
readonly cwd?: string;
|
|
74
|
+
readonly root?: string;
|
|
75
|
+
readonly modelId: string;
|
|
76
|
+
readonly modelName: string;
|
|
77
|
+
readonly startedAt: number;
|
|
78
|
+
readonly userTurns: number;
|
|
79
|
+
}
|
|
80
|
+
export interface CoreSessionApi {
|
|
81
|
+
captureRequest(input?: {
|
|
82
|
+
readonly completed?: boolean;
|
|
83
|
+
}): Promise<CoreRequestSnapshot | undefined>;
|
|
84
|
+
inspect(): Promise<CoreSessionInspection>;
|
|
85
|
+
describe(): Promise<CoreSessionDescription>;
|
|
86
|
+
messages(input?: CoreSessionMessagesInput): Promise<CoreSessionMessages>;
|
|
87
|
+
append(input: CoreAppendInput): Promise<CoreSessionReceipt>;
|
|
88
|
+
submit(input: CoreSubmitInput): Promise<CoreSessionReceipt>;
|
|
89
|
+
compact(input?: CoreCompactInput): Promise<CoreSessionReceipt>;
|
|
90
|
+
}
|
|
91
|
+
export interface CoreSessionActionResult {
|
|
92
|
+
/** The physical boundary deliberately skipped a record before any commit. */
|
|
93
|
+
readonly handled?: true;
|
|
94
|
+
readonly changed: boolean;
|
|
95
|
+
readonly recordId?: string;
|
|
96
|
+
readonly modelChanged?: boolean;
|
|
97
|
+
readonly executionId?: string;
|
|
98
|
+
}
|
|
99
|
+
export type CoreSessionAction = (request: CoreSessionRequest, call: CoreOperationContext, leaf: (request: CoreSessionRequest, call: CoreOperationContext) => Promise<CoreSessionActionResult>) => Promise<CoreSessionActionResult>;
|
|
100
|
+
export interface CoreSessionBackend {
|
|
101
|
+
describe?(call: CoreOperationContext): Promise<CoreSessionDescription>;
|
|
102
|
+
composePrompt?(facts: CorePromptFacts, call: CoreOperationContext): Promise<CorePromptComposition>;
|
|
103
|
+
captureRequest(call: CoreOperationContext, input?: {
|
|
104
|
+
readonly completed?: boolean;
|
|
105
|
+
}): Promise<CoreRequestSnapshot | undefined>;
|
|
106
|
+
inspect(call: CoreOperationContext): Promise<CoreSessionInspection>;
|
|
107
|
+
messages(input: CoreSessionMessagesInput, call: CoreOperationContext): Promise<CoreSessionMessages>;
|
|
108
|
+
enqueue(request: CoreSessionRequest, call: CoreOperationContext, action: CoreSessionAction): Promise<CoreSessionReceipt>;
|
|
109
|
+
own(instanceId: string): () => Promise<void>;
|
|
110
|
+
handled(input: CoreSubmitInput, call: CoreOperationContext, value?: unknown): CoreSessionReceipt;
|
|
111
|
+
}
|
|
112
|
+
export interface SessionInputEntry {
|
|
113
|
+
readonly request: CoreSessionRequest;
|
|
114
|
+
readonly source: CoreOperationContext;
|
|
115
|
+
readonly action: CoreSessionAction;
|
|
116
|
+
receipt: CoreSessionReceipt;
|
|
117
|
+
readonly parentMessage?: unknown;
|
|
118
|
+
readonly started: Promise<void>;
|
|
119
|
+
start(): void;
|
|
120
|
+
readonly terminal: Promise<void>;
|
|
121
|
+
complete(): void;
|
|
122
|
+
}
|
|
123
|
+
/** Internal writer evidence survives errors after commit, without settling the operation early. */
|
|
124
|
+
export declare function recordSessionInputCommit(entry: SessionInputEntry, outcome: CoreSessionActionResult): void;
|
|
125
|
+
/** One Session FIFO shared by native writes and the existing parent mailbox. No model loop. */
|
|
126
|
+
export declare class SessionInputCoordinator {
|
|
127
|
+
#private;
|
|
128
|
+
readonly diagnose: (receipt: CoreSessionReceipt) => void;
|
|
129
|
+
constructor(diagnose?: (receipt: CoreSessionReceipt) => void);
|
|
130
|
+
get hasPending(): boolean;
|
|
131
|
+
get hasBoundaryPending(): boolean;
|
|
132
|
+
get executing(): boolean;
|
|
133
|
+
currentCompact(): CoreSessionReceipt | undefined;
|
|
134
|
+
inspect(): readonly CoreSessionReceipt[];
|
|
135
|
+
performAppend(input: CoreAppendInput, call: CoreOperationContext, action: CoreSessionAction, leaf: (entry: SessionInputEntry, request: CoreSessionRequest, call: CoreOperationContext) => Promise<CoreSessionActionResult>): Promise<CoreSessionReceipt>;
|
|
136
|
+
/** SDK manual/automatic compaction shares the same active receipt as queued compaction. */
|
|
137
|
+
recordCompactCommit(outcome: CoreSessionActionResult): void;
|
|
138
|
+
performCompact(input: CoreCompactInput, call: CoreOperationContext, action: (commit: (outcome: CoreSessionActionResult) => void) => Promise<CoreSessionActionResult>): Promise<CoreSessionActionResult>;
|
|
139
|
+
accept(request: CoreSessionRequest, source: CoreOperationContext, action: CoreSessionAction, status: 'accepted' | 'queued', parentMessage?: unknown): SessionInputEntry;
|
|
140
|
+
handled(input: CoreSubmitInput, call: CoreOperationContext, value?: unknown): CoreSessionReceipt;
|
|
141
|
+
drain(leaf: (entry: SessionInputEntry, request: CoreSessionRequest, call: CoreOperationContext) => Promise<CoreSessionActionResult>, execution?: {
|
|
142
|
+
readonly executionId: string;
|
|
143
|
+
readonly turnId: string;
|
|
144
|
+
readonly signal: AbortSignal;
|
|
145
|
+
}, limit?: number): Promise<boolean>;
|
|
146
|
+
idle(): Promise<void>;
|
|
147
|
+
retire(instanceId?: string): Promise<void>;
|
|
148
|
+
startExecution(entry: SessionInputEntry, executionId: string): void;
|
|
149
|
+
settleExecution(executionId: string, status: 'completed' | 'failed' | 'cancelled'): void;
|
|
150
|
+
}
|
|
151
|
+
export declare function validateCoreSessionRequest(request: CoreSessionRequest): void;
|