@myagentroam/agent 0.9.159 → 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.
Files changed (128) hide show
  1. package/dist/agent-core/extensions/agents.d.ts +69 -0
  2. package/dist/agent-core/extensions/agents.js +160 -0
  3. package/dist/agent-core/extensions/contracts.d.ts +260 -0
  4. package/dist/agent-core/extensions/contracts.js +1 -0
  5. package/dist/agent-core/extensions/data.d.ts +84 -0
  6. package/dist/agent-core/extensions/data.js +83 -0
  7. package/dist/agent-core/extensions/environment.d.ts +27 -0
  8. package/dist/agent-core/extensions/environment.js +52 -0
  9. package/dist/agent-core/extensions/files.d.ts +64 -0
  10. package/dist/agent-core/extensions/files.js +26 -0
  11. package/dist/agent-core/extensions/hooks.d.ts +32 -0
  12. package/dist/agent-core/extensions/hooks.js +135 -0
  13. package/dist/agent-core/extensions/manager.d.ts +39 -0
  14. package/dist/agent-core/extensions/manager.js +458 -0
  15. package/dist/agent-core/extensions/mcp.d.ts +99 -0
  16. package/dist/agent-core/extensions/mcp.js +433 -0
  17. package/dist/agent-core/extensions/model-request.d.ts +60 -0
  18. package/dist/agent-core/extensions/model-request.js +167 -0
  19. package/dist/agent-core/extensions/model-stream.d.ts +9 -0
  20. package/dist/agent-core/extensions/model-stream.js +101 -0
  21. package/dist/agent-core/extensions/models.d.ts +43 -0
  22. package/dist/agent-core/extensions/models.js +1 -0
  23. package/dist/agent-core/extensions/network.d.ts +32 -0
  24. package/dist/agent-core/extensions/network.js +97 -0
  25. package/dist/agent-core/extensions/operation.d.ts +29 -0
  26. package/dist/agent-core/extensions/operation.js +98 -0
  27. package/dist/agent-core/extensions/processes.d.ts +52 -0
  28. package/dist/agent-core/extensions/processes.js +283 -0
  29. package/dist/agent-core/extensions/prompt-composition.d.ts +24 -0
  30. package/dist/agent-core/extensions/prompt-composition.js +106 -0
  31. package/dist/agent-core/extensions/prompt-input.d.ts +23 -0
  32. package/dist/agent-core/extensions/prompt-input.js +46 -0
  33. package/dist/agent-core/extensions/resources.d.ts +27 -0
  34. package/dist/agent-core/extensions/resources.js +221 -0
  35. package/dist/agent-core/extensions/services.d.ts +31 -0
  36. package/dist/agent-core/extensions/services.js +61 -0
  37. package/dist/agent-core/extensions/session-input.d.ts +151 -0
  38. package/dist/agent-core/extensions/session-input.js +351 -0
  39. package/dist/agent-core/extensions/session-messages.d.ts +41 -0
  40. package/dist/agent-core/extensions/session-messages.js +76 -0
  41. package/dist/agent-core/extensions/session.d.ts +68 -0
  42. package/dist/agent-core/extensions/session.js +593 -0
  43. package/dist/agent-core/extensions/settings.d.ts +59 -0
  44. package/dist/agent-core/extensions/settings.js +115 -0
  45. package/dist/agent-core/extensions/store.d.ts +10 -0
  46. package/dist/agent-core/extensions/store.js +131 -0
  47. package/dist/agent-core/extensions/tools.d.ts +61 -0
  48. package/dist/agent-core/extensions/tools.js +266 -0
  49. package/dist/agent-core/host/contracts.d.ts +25 -0
  50. package/dist/agent-core/host/local-agent-host.d.ts +10 -1
  51. package/dist/agent-core/host/local-agent-host.js +132 -20
  52. package/dist/agent-core/host/local-file-access.d.ts +30 -0
  53. package/dist/agent-core/host/local-file-access.js +107 -0
  54. package/dist/agent-core/host/local-network-access.d.ts +6 -0
  55. package/dist/agent-core/host/local-network-access.js +97 -0
  56. package/dist/agent-core/host/local-process-executor.d.ts +5 -1
  57. package/dist/agent-core/host/local-session-environment.d.ts +18 -0
  58. package/dist/agent-core/host/local-session-environment.js +102 -0
  59. package/dist/agent-core/model/anthropic-messages.js +73 -23
  60. package/dist/agent-core/model/contracts.d.ts +12 -0
  61. package/dist/agent-core/model/openai-responses.js +73 -12
  62. package/dist/agent-core/model/text-blocks.d.ts +7 -0
  63. package/dist/agent-core/model/text-blocks.js +40 -0
  64. package/dist/agent-core/prompts/index.d.ts +6 -2
  65. package/dist/agent-core/prompts/index.js +38 -24
  66. package/dist/agent-core/runtime/context/gc-tokens.js +6 -1
  67. package/dist/agent-core/runtime/context/normalize.js +21 -1
  68. package/dist/agent-core/runtime/context/projection.js +35 -1
  69. package/dist/agent-core/runtime/context/request-budget.js +5 -2
  70. package/dist/agent-core/runtime/context/restore.d.ts +5 -0
  71. package/dist/agent-core/runtime/context/restore.js +47 -4
  72. package/dist/agent-core/runtime/context/usage.js +2 -3
  73. package/dist/agent-core/runtime/contracts.d.ts +2 -0
  74. package/dist/agent-core/runtime/execution.js +5 -2
  75. package/dist/agent-core/sdk/agent.js +177 -40
  76. package/dist/agent-core/sdk/extension-agents.d.ts +9 -0
  77. package/dist/agent-core/sdk/extension-agents.js +51 -0
  78. package/dist/agent-core/sdk/extension-models.d.ts +13 -0
  79. package/dist/agent-core/sdk/extension-models.js +128 -0
  80. package/dist/agent-core/sdk/extension-session.d.ts +30 -0
  81. package/dist/agent-core/sdk/extension-session.js +103 -0
  82. package/dist/agent-core/sdk/extension-tools.d.ts +16 -0
  83. package/dist/agent-core/sdk/extension-tools.js +126 -0
  84. package/dist/agent-core/sdk/session.d.ts +26 -2
  85. package/dist/agent-core/sdk/session.js +1215 -506
  86. package/dist/agent-core/sdk/types.d.ts +3 -0
  87. package/dist/agent-core/session/context-gc-checkpoint.js +1 -1
  88. package/dist/agent-core/session/jsonl-store.d.ts +28 -8
  89. package/dist/agent-core/session/jsonl-store.js +124 -84
  90. package/dist/agent-core/session/types.d.ts +4 -1
  91. package/dist/agent-core/storage/file-lock.d.ts +4 -0
  92. package/dist/agent-core/storage/file-lock.js +83 -0
  93. package/dist/agent-core/subagent/contracts.d.ts +11 -1
  94. package/dist/agent-core/subagent/scheduler.d.ts +8 -0
  95. package/dist/agent-core/subagent/session-controller.d.ts +22 -1
  96. package/dist/agent-core/subagent/session-controller.js +355 -98
  97. package/dist/agent-core/tools/agent/agent-start.d.ts +1 -1
  98. package/dist/agent-core/tools/code-mode/cells.js +5 -15
  99. package/dist/agent-core/tools/code-mode/dispatch.d.ts +1 -0
  100. package/dist/agent-core/tools/code-mode/dispatch.js +13 -1
  101. package/dist/agent-core/tools/code-mode/index.js +1 -2
  102. package/dist/agent-core/tools/code-mode/observations.d.ts +5 -0
  103. package/dist/agent-core/tools/code-mode/observations.js +16 -5
  104. package/dist/agent-core/tools/code-mode/quickjs-engine.js +10 -5
  105. package/dist/agent-core/tools/execution.d.ts +11 -2
  106. package/dist/agent-core/tools/execution.js +58 -21
  107. package/dist/agent-core/tools/input.d.ts +2 -0
  108. package/dist/agent-core/tools/input.js +36 -0
  109. package/dist/agent-core/tools/local/apply-patch.js +21 -17
  110. package/dist/agent-core/tools/local/exec.d.ts +4 -4
  111. package/dist/agent-core/tools/local/exec.js +234 -62
  112. package/dist/agent-core/tools/local/registry.d.ts +6 -0
  113. package/dist/agent-core/tools/local/registry.js +60 -9
  114. package/dist/agent-core/tools/mcp/catalog.d.ts +6 -2
  115. package/dist/agent-core/tools/mcp/catalog.js +4 -4
  116. package/dist/agent-core/tools/mcp/history.js +2 -2
  117. package/dist/agent-core/tools/mcp/tool-search.d.ts +3 -1
  118. package/dist/agent-core/tools/mcp/tool-search.js +2 -2
  119. package/dist/agent-core/tools/output-projection.d.ts +3 -1
  120. package/dist/agent-core/tools/output-projection.js +11 -2
  121. package/dist/agent-core/tools/runtime-context.d.ts +1 -0
  122. package/dist/agent-core/tools/runtime.d.ts +3 -1
  123. package/dist/agent-core/tools/runtime.js +22 -7
  124. package/dist/agent-core/tools/scheduler.d.ts +2 -0
  125. package/dist/agent-core/tools/scheduler.js +43 -6
  126. package/dist/index.d.ts +21 -0
  127. package/dist/sandbox/linux/bubblewrap-sandbox-executor.js +5 -2
  128. package/package.json +1 -1
@@ -0,0 +1,283 @@
1
+ import { MarAgentError } from '../error.js';
2
+ export function validateCoreProcessInput(input) {
3
+ if (!input ||
4
+ typeof input.executable !== 'string' ||
5
+ !input.executable ||
6
+ input.executable.includes('\0') ||
7
+ (input.argv !== undefined &&
8
+ (!Array.isArray(input.argv) ||
9
+ input.argv.some((value) => typeof value !== 'string' || value.includes('\0')))) ||
10
+ (input.cwd !== undefined && (typeof input.cwd !== 'string' || input.cwd.includes('\0'))) ||
11
+ (input.env !== undefined &&
12
+ (!input.env ||
13
+ typeof input.env !== 'object' ||
14
+ Array.isArray(input.env) ||
15
+ Object.entries(input.env).some(([key, value]) => !key ||
16
+ key.includes('=') ||
17
+ key.includes('\0') ||
18
+ typeof value !== 'string' ||
19
+ value.includes('\0')))) ||
20
+ (input.input !== undefined &&
21
+ typeof input.input !== 'string' &&
22
+ !(input.input instanceof Uint8Array)))
23
+ throw new MarAgentError('MAR_AGENT_PROCESS_INPUT_INVALID', 'Process input is invalid.');
24
+ }
25
+ function copyProcessInput(input) {
26
+ validateCoreProcessInput(input);
27
+ return {
28
+ ...input,
29
+ ...(input.argv === undefined ? {} : { argv: [...input.argv] }),
30
+ ...(input.env === undefined ? {} : { env: { ...input.env } }),
31
+ ...(input.input instanceof Uint8Array ? { input: new Uint8Array(input.input) } : {})
32
+ };
33
+ }
34
+ export function bindCoreProcesses(backend, run, scope, hooks, diagnose) {
35
+ const acquire = async (input, call, emitExit = true) => {
36
+ input = copyProcessInput(input);
37
+ if (typeof backend.spawn !== 'function')
38
+ throw new MarAgentError('MAR_AGENT_HOST_PORT_UNAVAILABLE', 'Native process port is unavailable.');
39
+ let closed = false;
40
+ const iterators = [];
41
+ let pending;
42
+ const resource = scope.effect(() => async () => {
43
+ closed = true;
44
+ call.signal.removeEventListener('abort', abort);
45
+ const handle = await pending.catch(() => undefined);
46
+ let firstError;
47
+ let failed = false;
48
+ try {
49
+ if (typeof handle?.cancel === 'function')
50
+ await handle.cancel();
51
+ }
52
+ catch (error) {
53
+ failed = true;
54
+ firstError = error;
55
+ }
56
+ const released = await Promise.allSettled(iterators.map((iterator) => Promise.resolve().then(() => iterator.return?.())));
57
+ const failure = released.find((result) => result.status === 'rejected');
58
+ if (failed || failure?.status === 'rejected') {
59
+ const error = failed
60
+ ? firstError
61
+ : failure?.status === 'rejected'
62
+ ? failure.reason
63
+ : undefined;
64
+ throw new MarAgentError('MAR_AGENT_PROCESS_CLEANUP_FAILED', 'Native process cleanup failed.', {
65
+ details: {
66
+ reasonCode: error instanceof MarAgentError ? error.code : 'BACKEND_CLEANUP_FAILED'
67
+ }
68
+ });
69
+ }
70
+ });
71
+ const cancel = () => resource.dispose();
72
+ const abort = () => {
73
+ void cancel().catch(() => diagnose());
74
+ };
75
+ pending = Promise.resolve().then(() => backend.spawn(input, call));
76
+ call.signal.addEventListener('abort', abort, { once: true });
77
+ let handle;
78
+ try {
79
+ handle = await pending;
80
+ if (!handle ||
81
+ typeof handle.processId !== 'string' ||
82
+ !handle.processId ||
83
+ typeof handle.wait !== 'function' ||
84
+ typeof handle.cancel !== 'function' ||
85
+ typeof handle.stdout?.[Symbol.asyncIterator] !== 'function' ||
86
+ typeof handle.stderr?.[Symbol.asyncIterator] !== 'function')
87
+ throw new MarAgentError('MAR_AGENT_PROCESS_OUTPUT_INVALID', 'Native process handle is invalid.');
88
+ await resource.ready;
89
+ call.signal.throwIfAborted();
90
+ }
91
+ catch (error) {
92
+ try {
93
+ await cancel();
94
+ }
95
+ catch {
96
+ diagnose();
97
+ }
98
+ call.signal.throwIfAborted();
99
+ throw error;
100
+ }
101
+ const stream = (source) => {
102
+ const iterator = source[Symbol.asyncIterator]();
103
+ iterators.push(iterator);
104
+ let done = false;
105
+ let tail = Promise.resolve();
106
+ async function pull() {
107
+ if (done || closed)
108
+ return { done: true, value: undefined };
109
+ try {
110
+ return await scope.run(async (signal) => {
111
+ signal.throwIfAborted();
112
+ const next = await iterator.next();
113
+ signal.throwIfAborted();
114
+ if (next.done) {
115
+ done = true;
116
+ return { done: true, value: undefined };
117
+ }
118
+ if (!(next.value instanceof Uint8Array))
119
+ throw new MarAgentError('MAR_AGENT_PROCESS_OUTPUT_INVALID', 'Process stream must yield raw bytes.');
120
+ return { done: false, value: new Uint8Array(next.value) };
121
+ }, call.signal);
122
+ }
123
+ catch (error) {
124
+ done = true;
125
+ try {
126
+ await cancel();
127
+ }
128
+ catch {
129
+ diagnose();
130
+ }
131
+ throw error;
132
+ }
133
+ }
134
+ return {
135
+ [Symbol.asyncIterator]() {
136
+ return this;
137
+ },
138
+ next() {
139
+ const pending = tail.then(pull);
140
+ tail = pending.catch(() => undefined);
141
+ return pending;
142
+ },
143
+ async return() {
144
+ done = true;
145
+ await cancel();
146
+ return { done: true, value: undefined };
147
+ }
148
+ };
149
+ };
150
+ let completion;
151
+ return {
152
+ processId: handle.processId,
153
+ stdout: stream(handle.stdout),
154
+ stderr: stream(handle.stderr),
155
+ cancel,
156
+ wait: () => (completion ??= scope
157
+ .run(async (signal) => {
158
+ signal.throwIfAborted();
159
+ const exit = await handle.wait();
160
+ signal.throwIfAborted();
161
+ if (!exit ||
162
+ (exit.code !== null && !Number.isInteger(exit.code)) ||
163
+ (exit.signal !== null && typeof exit.signal !== 'string'))
164
+ throw new MarAgentError('MAR_AGENT_PROCESS_OUTPUT_INVALID', 'Native process exit result is invalid.');
165
+ if (emitExit)
166
+ await hooks.emit('process.completed', { processId: handle.processId, ...exit }, call);
167
+ return exit;
168
+ }, call.signal)
169
+ .catch(async (error) => {
170
+ try {
171
+ await cancel();
172
+ }
173
+ catch {
174
+ diagnose();
175
+ }
176
+ throw error;
177
+ }))
178
+ };
179
+ };
180
+ return {
181
+ spawn: async (input) => {
182
+ input = copyProcessInput(input);
183
+ return run((call) => hooks.invoke('process.spawn', input, call, (input, effective) => acquire(input, effective)), input.signal);
184
+ },
185
+ run: async (input) => {
186
+ input = copyProcessInput(input);
187
+ return run((call) => hooks.invoke('process.run', input, call, async (input, effective) => {
188
+ const limit = input.outputLimitBytes ?? 4_194_304;
189
+ const timeout = input.timeoutMs ?? 30_000;
190
+ if (!Number.isSafeInteger(limit) ||
191
+ limit < 0 ||
192
+ !Number.isSafeInteger(timeout) ||
193
+ timeout <= 0)
194
+ throw new MarAgentError('MAR_AGENT_PROCESS_INPUT_INVALID', 'Process timeout and output limit are invalid.');
195
+ const handle = await acquire(input, effective, false);
196
+ let timedOut = false;
197
+ const due = performance.now() + timeout;
198
+ let timer;
199
+ let timeoutWork;
200
+ const arm = () => {
201
+ timer = setTimeout(() => {
202
+ if (performance.now() < due) {
203
+ arm();
204
+ return;
205
+ }
206
+ timedOut = true;
207
+ timeoutWork = handle.cancel();
208
+ void timeoutWork.catch(() => undefined);
209
+ }, Math.min(Math.max(0, due - performance.now()), 2_147_483_647));
210
+ timer.unref();
211
+ };
212
+ arm();
213
+ const collect = async (stream) => {
214
+ const chunks = [];
215
+ let total = 0;
216
+ let retained = 0;
217
+ for await (const chunk of stream) {
218
+ total += chunk.length;
219
+ const keep = Math.min(chunk.length, limit - retained);
220
+ if (keep > 0) {
221
+ chunks.push(chunk.slice(0, keep));
222
+ retained += keep;
223
+ }
224
+ }
225
+ const bytes = new Uint8Array(retained);
226
+ let offset = 0;
227
+ for (const chunk of chunks) {
228
+ bytes.set(chunk, offset);
229
+ offset += chunk.length;
230
+ }
231
+ return { bytes, total };
232
+ };
233
+ let failed = false;
234
+ const work = [handle.wait(), collect(handle.stdout), collect(handle.stderr)];
235
+ try {
236
+ const [exit, stdout, stderr] = await Promise.all(work);
237
+ await timeoutWork;
238
+ await hooks.emit('process.completed', {
239
+ ...exit,
240
+ processId: handle.processId,
241
+ stdoutBytes: stdout.total,
242
+ stderrBytes: stderr.total,
243
+ truncated: stdout.total > limit || stderr.total > limit,
244
+ timedOut
245
+ }, effective);
246
+ return {
247
+ ...exit,
248
+ processId: handle.processId,
249
+ stdout: stdout.bytes,
250
+ stderr: stderr.bytes,
251
+ stdoutBytes: stdout.total,
252
+ stderrBytes: stderr.total,
253
+ truncated: stdout.total > limit || stderr.total > limit,
254
+ timedOut
255
+ };
256
+ }
257
+ catch (error) {
258
+ failed = true;
259
+ try {
260
+ await handle.cancel();
261
+ }
262
+ catch {
263
+ diagnose();
264
+ }
265
+ await Promise.allSettled(work);
266
+ throw error;
267
+ }
268
+ finally {
269
+ clearTimeout(timer);
270
+ try {
271
+ await handle.cancel();
272
+ }
273
+ catch (error) {
274
+ if (failed)
275
+ diagnose();
276
+ else
277
+ throw error;
278
+ }
279
+ }
280
+ }), input.signal);
281
+ }
282
+ };
283
+ }
@@ -0,0 +1,24 @@
1
+ import type { ExecutionMode } from '../runtime/contracts.js';
2
+ import type { CoreDomainFacts, CoreDomainOperations, CorePromptSection } from './contracts.js';
3
+ import type { ExtensionHooks } from './hooks.js';
4
+ import type { CoreOperationContext } from './operation.js';
5
+ export interface CorePromptPart {
6
+ readonly id: string;
7
+ readonly text: string | null;
8
+ readonly scope?: 'shared' | 'session';
9
+ }
10
+ export interface CorePromptFacts {
11
+ readonly modelId?: string;
12
+ readonly mode?: ExecutionMode;
13
+ readonly tools?: readonly string[];
14
+ }
15
+ export interface CorePromptComposition {
16
+ readonly sections: readonly CorePromptPart[];
17
+ readonly facts?: CorePromptFacts;
18
+ }
19
+ export interface CorePromptSectionInput extends CorePromptPart {
20
+ readonly facts?: CorePromptFacts;
21
+ }
22
+ export declare function normalizePromptComposition(value: unknown): CorePromptComposition;
23
+ export declare function renderPromptSections(sections: readonly CorePromptPart[]): string;
24
+ export declare function composePromptSections(hooks: ExtensionHooks<CoreDomainOperations, CoreDomainFacts>, input: CorePromptComposition, registered: readonly CorePromptSection[], call: CoreOperationContext): Promise<CorePromptComposition>;
@@ -0,0 +1,106 @@
1
+ import { MarAgentError } from '../error.js';
2
+ function invalid() {
3
+ throw new MarAgentError('MAR_AGENT_EXTENSION_PROMPT_INVALID', 'Prompt composition is invalid.');
4
+ }
5
+ function object(value) {
6
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
7
+ invalid();
8
+ return value;
9
+ }
10
+ function text(value) {
11
+ if (value !== null && typeof value !== 'string')
12
+ invalid();
13
+ return value;
14
+ }
15
+ export function normalizePromptComposition(value) {
16
+ const source = object(value);
17
+ const sections = source.sections;
18
+ const facts = source.facts;
19
+ if (!Array.isArray(sections))
20
+ invalid();
21
+ const ids = new Set();
22
+ let sessionScope = false;
23
+ const parts = Array.from(sections, (value) => {
24
+ const source = object(value);
25
+ const id = source.id;
26
+ const content = source.text;
27
+ const scope = source.scope;
28
+ if (typeof id !== 'string' || !id.trim())
29
+ invalid();
30
+ if (ids.has(id))
31
+ throw new MarAgentError('MAR_AGENT_EXTENSION_PROMPT_CONFLICT', 'Prompt section id conflicts.');
32
+ ids.add(id);
33
+ if (scope !== undefined && scope !== 'shared' && scope !== 'session')
34
+ invalid();
35
+ if (scope === 'shared' && sessionScope)
36
+ invalid();
37
+ if (scope === 'session')
38
+ sessionScope = true;
39
+ return Object.freeze({ id, text: text(content), ...(scope === undefined ? {} : { scope }) });
40
+ });
41
+ let copiedFacts;
42
+ if (facts !== undefined) {
43
+ const source = object(facts);
44
+ const modelId = source.modelId;
45
+ const mode = source.mode;
46
+ const tools = source.tools;
47
+ const copiedTools = Array.isArray(tools) ? Array.from(tools) : undefined;
48
+ if (modelId !== undefined && (typeof modelId !== 'string' || !modelId))
49
+ invalid();
50
+ if (mode !== undefined && mode !== 'run' && mode !== 'plan' && mode !== 'compact')
51
+ invalid();
52
+ if (tools !== undefined &&
53
+ (copiedTools === undefined || copiedTools.some((name) => typeof name !== 'string' || !name)))
54
+ invalid();
55
+ copiedFacts = Object.freeze({
56
+ ...(modelId === undefined ? {} : { modelId: modelId }),
57
+ ...(mode === undefined ? {} : { mode: mode }),
58
+ ...(copiedTools === undefined ? {} : { tools: Object.freeze(copiedTools) })
59
+ });
60
+ }
61
+ return Object.freeze({
62
+ sections: Object.freeze(parts),
63
+ ...(copiedFacts === undefined ? {} : { facts: copiedFacts })
64
+ });
65
+ }
66
+ export function renderPromptSections(sections) {
67
+ return sections
68
+ .map((part) => part.text)
69
+ .filter(Boolean)
70
+ .join('\n\n');
71
+ }
72
+ export async function composePromptSections(hooks, input, registered, call) {
73
+ const snapshot = normalizePromptComposition({
74
+ ...input,
75
+ sections: [...input.sections, ...registered]
76
+ });
77
+ const result = await hooks.invoke('prompt.sections', snapshot, call, async (input, call) => {
78
+ const selected = normalizePromptComposition(input);
79
+ const sections = [];
80
+ for (const part of selected.sections) {
81
+ const output = await hooks.invoke('prompt.section', Object.freeze({
82
+ ...part,
83
+ ...(selected.facts === undefined ? {} : { facts: selected.facts })
84
+ }), call, async (input, call) => {
85
+ call.signal.throwIfAborted();
86
+ const selected = normalizePromptComposition({
87
+ sections: [input],
88
+ facts: object(input).facts
89
+ });
90
+ // A text handler cannot silently retarget its captured section. Whole-list edits use prompt.sections.
91
+ if (selected.sections[0].id !== part.id)
92
+ invalid();
93
+ return selected.sections[0].text;
94
+ });
95
+ call.signal.throwIfAborted();
96
+ sections.push({
97
+ id: part.id,
98
+ text: text(output),
99
+ ...(part.scope === undefined ? {} : { scope: part.scope })
100
+ });
101
+ }
102
+ return normalizePromptComposition({ ...selected, sections });
103
+ });
104
+ call.signal.throwIfAborted();
105
+ return normalizePromptComposition(result);
106
+ }
@@ -0,0 +1,23 @@
1
+ import type { RunInputImage } from '../runtime/contracts.js';
2
+ import type { CoreDomainOperations, CoreDomainFacts } from './contracts.js';
3
+ import type { ExtensionHooks } from './hooks.js';
4
+ import type { CoreOperationContext } from './operation.js';
5
+ /** Content only. Identity, queue policy and lifetime come from the physical ingress. */
6
+ export interface CorePromptInput {
7
+ readonly text: string;
8
+ readonly modelText?: string;
9
+ readonly context?: readonly string[];
10
+ /** Optional model projection; context remains the original admitted content. */
11
+ readonly modelContext?: readonly string[];
12
+ readonly images?: readonly RunInputImage[];
13
+ }
14
+ export interface CorePromptResult {
15
+ /** An interceptor answer, not proof of queue admission or a storage write. */
16
+ readonly value?: unknown;
17
+ }
18
+ export declare function captureCorePromptInput(input: CorePromptInput): CorePromptInput;
19
+ /** One admission chain for SDK input and queued Extension input, before either writer or FIFO. */
20
+ export declare function invokeCorePromptSubmission(hooks: ExtensionHooks<CoreDomainOperations, CoreDomainFacts>, input: CorePromptInput, call: CoreOperationContext, leaf: (input: CorePromptInput, call: CoreOperationContext) => Promise<CorePromptResult>): Promise<{
21
+ readonly entered: number;
22
+ readonly result: CorePromptResult;
23
+ }>;
@@ -0,0 +1,46 @@
1
+ import { MarAgentError } from '../error.js';
2
+ export function captureCorePromptInput(input) {
3
+ if (!input ||
4
+ typeof input.text !== 'string' ||
5
+ (input.modelText !== undefined && typeof input.modelText !== 'string') ||
6
+ (input.context !== undefined &&
7
+ (!Array.isArray(input.context) ||
8
+ !Array.from(input.context).every((item) => typeof item === 'string'))) ||
9
+ (input.modelContext !== undefined &&
10
+ (!Array.isArray(input.modelContext) ||
11
+ !Array.from(input.modelContext).every((item) => typeof item === 'string'))) ||
12
+ (input.images !== undefined &&
13
+ (!Array.isArray(input.images) ||
14
+ !Array.from(input.images).every((image) => image &&
15
+ typeof image.name === 'string' &&
16
+ typeof image.mimeType === 'string' &&
17
+ typeof image.dataBase64 === 'string'))))
18
+ throw new MarAgentError('MAR_AGENT_SESSION_INPUT_INVALID', 'Prompt content is invalid.');
19
+ return structuredClone({
20
+ text: input.text,
21
+ ...(input.modelText === undefined ? {} : { modelText: input.modelText }),
22
+ ...(input.context === undefined ? {} : { context: input.context }),
23
+ ...(input.modelContext === undefined ? {} : { modelContext: input.modelContext }),
24
+ ...(input.images === undefined ? {} : { images: input.images })
25
+ });
26
+ }
27
+ /** One admission chain for SDK input and queued Extension input, before either writer or FIFO. */
28
+ export async function invokeCorePromptSubmission(hooks, input, call, leaf) {
29
+ let entered = 0;
30
+ let tail = Promise.resolve();
31
+ const result = await hooks.invoke('prompt.submit', captureCorePromptInput(input), call, (input, effective) => {
32
+ const captured = captureCorePromptInput(input);
33
+ // Concurrent next calls keep their invocation order at the single writer/FIFO boundary.
34
+ const pending = tail.then(async () => {
35
+ effective.signal.throwIfAborted();
36
+ const result = await leaf(captured, effective);
37
+ entered++;
38
+ return result;
39
+ });
40
+ tail = pending.catch(() => undefined);
41
+ return pending;
42
+ });
43
+ if (!result || typeof result !== 'object' || Array.isArray(result))
44
+ throw new MarAgentError('MAR_AGENT_SESSION_INPUT_INVALID', 'Prompt admission result is invalid.');
45
+ return { entered, result };
46
+ }
@@ -0,0 +1,27 @@
1
+ export type CoreDisposer = () => void | Promise<void>;
2
+ export interface CoreResourceRegistration {
3
+ readonly ready: Promise<void>;
4
+ dispose(): Promise<void>;
5
+ }
6
+ export interface CoreResourceScope {
7
+ effect(acquire: () => CoreDisposer | Promise<CoreDisposer>): CoreResourceRegistration;
8
+ }
9
+ /** An instance's managed resources, not an OS sandbox or a process-wide resource owner. */
10
+ export declare class ExtensionResourceScope implements CoreResourceScope {
11
+ #private;
12
+ readonly instanceId: `${string}-${string}-${string}-${string}-${string}`;
13
+ static get initializing(): boolean;
14
+ static initialize<T>(run: () => Promise<T>): Promise<T>;
15
+ get state(): "STAGED" | "ACTIVE" | "RETIRING" | "DISPOSED";
16
+ get signal(): AbortSignal;
17
+ activate(): void;
18
+ effect(acquire: () => CoreDisposer | Promise<CoreDisposer>): CoreResourceRegistration;
19
+ run<T>(operation: (signal: AbortSignal) => Promise<T>, parent?: AbortSignal): Promise<T>;
20
+ after(durationMs: number, callback: (signal: AbortSignal) => void | Promise<void>, onError?: (error: unknown) => void): CoreResourceRegistration;
21
+ every(durationMs: number, callback: (signal: AbortSignal) => void | Promise<void>, onError?: (error: unknown) => void): CoreResourceRegistration;
22
+ sleep(durationMs: number, parent?: AbortSignal): Promise<void>;
23
+ /** Wait for acquisitions added by setup before publishing any callbacks. */
24
+ ready(): Promise<void>;
25
+ retire(): void;
26
+ dispose(): Promise<void>;
27
+ }