@myagentroam/agent 0.9.159 → 0.9.161

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 (130) 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-limits.d.ts +0 -1
  106. package/dist/agent-core/tools/execution-limits.js +0 -1
  107. package/dist/agent-core/tools/execution.d.ts +11 -2
  108. package/dist/agent-core/tools/execution.js +58 -21
  109. package/dist/agent-core/tools/input.d.ts +2 -0
  110. package/dist/agent-core/tools/input.js +36 -0
  111. package/dist/agent-core/tools/local/apply-patch.js +21 -17
  112. package/dist/agent-core/tools/local/exec.d.ts +4 -4
  113. package/dist/agent-core/tools/local/exec.js +242 -63
  114. package/dist/agent-core/tools/local/registry.d.ts +6 -0
  115. package/dist/agent-core/tools/local/registry.js +60 -9
  116. package/dist/agent-core/tools/mcp/catalog.d.ts +6 -2
  117. package/dist/agent-core/tools/mcp/catalog.js +4 -4
  118. package/dist/agent-core/tools/mcp/history.js +2 -2
  119. package/dist/agent-core/tools/mcp/tool-search.d.ts +3 -1
  120. package/dist/agent-core/tools/mcp/tool-search.js +2 -2
  121. package/dist/agent-core/tools/output-projection.d.ts +3 -1
  122. package/dist/agent-core/tools/output-projection.js +11 -2
  123. package/dist/agent-core/tools/runtime-context.d.ts +1 -0
  124. package/dist/agent-core/tools/runtime.d.ts +3 -1
  125. package/dist/agent-core/tools/runtime.js +22 -7
  126. package/dist/agent-core/tools/scheduler.d.ts +2 -0
  127. package/dist/agent-core/tools/scheduler.js +43 -6
  128. package/dist/index.d.ts +21 -0
  129. package/dist/sandbox/linux/bubblewrap-sandbox-executor.js +5 -2
  130. package/package.json +1 -1
@@ -0,0 +1,101 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { MarAgentError } from '../error.js';
3
+ import { modelStreamEventObservedAt, observeModelStreamEvent } from '../model/sse.js';
4
+ /** Pull-through transformation: no speculative reads, background producer, or stream replay. */
5
+ export async function* transformCoreModelStream(start, parent, transform, diagnoseCleanup) {
6
+ const controller = new AbortController();
7
+ const signal = AbortSignal.any([parent, controller.signal]);
8
+ signal.throwIfAborted();
9
+ const iterator = start(signal)[Symbol.asyncIterator]();
10
+ let failed = false;
11
+ try {
12
+ while (true) {
13
+ signal.throwIfAborted();
14
+ const next = await iterator.next();
15
+ if (next.done)
16
+ return;
17
+ signal.throwIfAborted();
18
+ const sourceRef = next.value.type === 'response.item' ? randomUUID() : undefined;
19
+ const view = sourceRef
20
+ ? { type: 'opaque', sourceRef }
21
+ : structuredClone(next.value);
22
+ const event = await transform(view, signal);
23
+ signal.throwIfAborted();
24
+ if (event === undefined)
25
+ continue;
26
+ if (!event || typeof event !== 'object' || !validEvent(event))
27
+ throw new MarAgentError('MAR_AGENT_MODEL_EVENT_INVALID', 'Model event is invalid.');
28
+ if (event.type === 'opaque') {
29
+ if (!sourceRef || event.sourceRef !== sourceRef)
30
+ throw new MarAgentError('MAR_AGENT_MODEL_EVENT_INVALID', 'Model event reference is invalid.');
31
+ yield next.value;
32
+ }
33
+ else {
34
+ if (event.type === 'response.item')
35
+ throw new MarAgentError('MAR_AGENT_MODEL_EVENT_INVALID', 'Provider-private model events require their opaque reference.');
36
+ yield observeModelStreamEvent(structuredClone(event), modelStreamEventObservedAt(next.value));
37
+ }
38
+ }
39
+ }
40
+ catch (error) {
41
+ failed = true;
42
+ throw error;
43
+ }
44
+ finally {
45
+ controller.abort();
46
+ try {
47
+ await iterator.return?.();
48
+ }
49
+ catch (error) {
50
+ if (!failed)
51
+ throw error;
52
+ diagnoseCleanup?.();
53
+ }
54
+ }
55
+ }
56
+ function validEvent(event) {
57
+ switch (event.type) {
58
+ case 'opaque':
59
+ return typeof event.sourceRef === 'string';
60
+ case 'response.started':
61
+ return typeof event.responseId === 'string';
62
+ case 'output.delta':
63
+ case 'output.reset':
64
+ return true;
65
+ case 'text.delta':
66
+ return (typeof event.itemId === 'string' &&
67
+ typeof event.delta === 'string' &&
68
+ ['commentary', 'final_answer'].includes(event.phase));
69
+ case 'text.completed':
70
+ return (typeof event.itemId === 'string' &&
71
+ typeof event.text === 'string' &&
72
+ (event.phase === undefined || ['commentary', 'final_answer'].includes(event.phase)));
73
+ case 'reasoning.summary':
74
+ return typeof event.itemId === 'string' && typeof event.text === 'string';
75
+ case 'client_tool.call':
76
+ return (typeof event.callId === 'string' &&
77
+ typeof event.name === 'string' &&
78
+ (event.inputMode === undefined || ['json', 'freeform'].includes(event.inputMode)));
79
+ case 'hosted_tool':
80
+ return (typeof event.itemId === 'string' &&
81
+ ['WEB_SEARCH', 'WEB_FETCH'].includes(event.kind) &&
82
+ ['RUNNING', 'COMPLETED', 'FAILED'].includes(event.status) &&
83
+ !!event.summary &&
84
+ typeof event.summary === 'object');
85
+ case 'citation':
86
+ return (!!event.citation &&
87
+ typeof event.citation.id === 'string' &&
88
+ typeof event.citation.url === 'string');
89
+ case 'usage':
90
+ return (!!event.usage &&
91
+ typeof event.usage === 'object' &&
92
+ Object.values(event.usage).every((value) => value === undefined ||
93
+ (typeof value === 'number' && Number.isFinite(value) && value >= 0)));
94
+ case 'unknown':
95
+ return typeof event.nativeType === 'string';
96
+ case 'completed':
97
+ return ['completed', 'tool_use', 'max_output', 'pause', 'cancelled'].includes(event.reason);
98
+ default:
99
+ return false;
100
+ }
101
+ }
@@ -0,0 +1,43 @@
1
+ import type { MarAgentReasoningEffort } from '../model/configuration.js';
2
+ import type { ModelStopReason, ModelUsage, ModelTextBlock } from '../model/contracts.js';
3
+ import type { CoreModelMessage, CoreModelRequest, CoreRequestSnapshot } from './model-request.js';
4
+ import type { CoreOperationContext } from './operation.js';
5
+ import type { CoreModelEvent } from './model-stream.js';
6
+ export interface CoreModelDescription {
7
+ readonly id: string;
8
+ readonly name: string;
9
+ /** Actual model service ID, distinct from the configuration ID and display name. */
10
+ readonly modelId?: string;
11
+ readonly contextWindowTokens: number;
12
+ readonly maxOutputTokens: number;
13
+ readonly inputCapabilities: readonly string[];
14
+ readonly reasoningEfforts: readonly MarAgentReasoningEffort[];
15
+ readonly isDefault: boolean;
16
+ }
17
+ export type CoreModelTextBlock = ModelTextBlock;
18
+ export interface CoreGenerateInput {
19
+ readonly signal?: AbortSignal;
20
+ readonly requestSnapshot?: CoreRequestSnapshot;
21
+ readonly modelId?: string;
22
+ readonly system?: string | readonly CoreModelTextBlock[];
23
+ readonly messages?: readonly CoreModelMessage[];
24
+ readonly prompt?: string | readonly CoreModelTextBlock[];
25
+ readonly retainToolCatalog?: boolean;
26
+ readonly outputLimit?: number;
27
+ readonly reasoningEffort?: MarAgentReasoningEffort;
28
+ }
29
+ export interface CoreGenerateResult {
30
+ readonly outcome: 'text' | 'empty' | 'cancelled';
31
+ readonly text: string;
32
+ readonly stopReason: ModelStopReason;
33
+ readonly usage?: Readonly<ModelUsage>;
34
+ }
35
+ export interface CoreModelsApi {
36
+ list(): readonly CoreModelDescription[];
37
+ generate(input: CoreGenerateInput): Promise<CoreGenerateResult>;
38
+ }
39
+ /** Application model configuration stays at the SDK boundary, not in plugin bindings or logs. */
40
+ export interface CoreModelsBackend {
41
+ list(): readonly CoreModelDescription[];
42
+ generate(input: CoreGenerateInput, call: CoreOperationContext, transform: (request: CoreModelRequest) => Promise<CoreModelRequest>, transformEvent: (event: CoreModelEvent, signal: AbortSignal) => Promise<CoreModelEvent | undefined>, diagnoseCleanup?: (code: string) => void): Promise<CoreGenerateResult>;
43
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { CoreDomainFacts, CoreDomainOperations } from './contracts.js';
2
+ import type { ExtensionHooks } from './hooks.js';
3
+ import type { CoreOperationContext } from './operation.js';
4
+ import type { ExtensionResourceScope } from './resources.js';
5
+ export interface CoreHttpRequest {
6
+ readonly url: string;
7
+ readonly method?: string;
8
+ readonly headers?: readonly (readonly [string, string])[];
9
+ readonly body?: string | Uint8Array;
10
+ readonly redirect?: 'follow' | 'manual' | 'error';
11
+ readonly signal?: AbortSignal;
12
+ }
13
+ export interface CoreHttpResponse {
14
+ readonly url: string;
15
+ readonly status: number;
16
+ readonly statusText: string;
17
+ readonly redirected: boolean;
18
+ readonly headers: readonly (readonly [string, string])[];
19
+ readonly body: AsyncIterable<Uint8Array>;
20
+ close(): Promise<void>;
21
+ }
22
+ export interface CoreNetworkApi {
23
+ fetch(input: CoreHttpRequest): Promise<CoreHttpResponse>;
24
+ }
25
+ export interface CoreNetworkBackend {
26
+ fetch(input: CoreHttpRequest, call: CoreOperationContext): Promise<CoreHttpResponse>;
27
+ }
28
+ export interface CoreHttpCompletion {
29
+ readonly status: number;
30
+ readonly redirected: boolean;
31
+ }
32
+ export declare function bindCoreNetwork(backend: CoreNetworkBackend, run: <Value>(operation: (call: CoreOperationContext) => Promise<Value>, signal?: AbortSignal) => Promise<Value>, scope: ExtensionResourceScope, hooks: ExtensionHooks<CoreDomainOperations, CoreDomainFacts>, diagnose: () => void): CoreNetworkApi;
@@ -0,0 +1,97 @@
1
+ import { MarAgentError } from '../error.js';
2
+ export function bindCoreNetwork(backend, run, scope, hooks, diagnose) {
3
+ return {
4
+ fetch: (input) => run((call) => hooks.invoke('network.fetch', input, call, async (input, effective) => {
5
+ if (typeof backend.fetch !== 'function')
6
+ throw new MarAgentError('MAR_AGENT_HOST_PORT_UNAVAILABLE', 'Native HTTP port is unavailable.');
7
+ const response = await backend.fetch(input, effective);
8
+ let iterator;
9
+ const close = async () => {
10
+ // Close the transport first so an in-flight pull is released before iterator cleanup.
11
+ const results = await Promise.allSettled([
12
+ Promise.resolve().then(() => response.close()),
13
+ Promise.resolve().then(() => iterator?.return?.())
14
+ ]);
15
+ const failure = results.find((result) => result.status === 'rejected');
16
+ if (failure?.status === 'rejected')
17
+ throw failure.reason;
18
+ };
19
+ let registration;
20
+ try {
21
+ registration = scope.effect(() => close);
22
+ await registration.ready;
23
+ iterator = response.body[Symbol.asyncIterator]();
24
+ await hooks.emit('network.completed', { status: response.status, redirected: response.redirected }, effective);
25
+ }
26
+ catch (error) {
27
+ try {
28
+ await close();
29
+ }
30
+ catch {
31
+ diagnose();
32
+ }
33
+ throw error;
34
+ }
35
+ const resource = registration;
36
+ let done = false;
37
+ let nextTail = Promise.resolve();
38
+ const body = {
39
+ [Symbol.asyncIterator]() {
40
+ return this;
41
+ },
42
+ next() {
43
+ const pending = nextTail.then(pull);
44
+ nextTail = pending.catch(() => undefined);
45
+ return pending;
46
+ },
47
+ async return() {
48
+ done = true;
49
+ await resource.dispose();
50
+ return { done: true, value: undefined };
51
+ }
52
+ };
53
+ async function pull() {
54
+ if (done)
55
+ return { done: true, value: undefined };
56
+ try {
57
+ const next = await scope.run(async (signal) => {
58
+ signal.throwIfAborted();
59
+ const next = await iterator.next();
60
+ signal.throwIfAborted();
61
+ return next;
62
+ }, effective.signal);
63
+ if (next.done) {
64
+ done = true;
65
+ await resource.dispose();
66
+ return { done: true, value: undefined };
67
+ }
68
+ if (!(next.value instanceof Uint8Array))
69
+ throw new MarAgentError('MAR_AGENT_NETWORK_RESPONSE_INVALID', 'HTTP body must yield raw bytes.');
70
+ return { done: false, value: new Uint8Array(next.value) };
71
+ }
72
+ catch (error) {
73
+ done = true;
74
+ try {
75
+ await resource.dispose();
76
+ }
77
+ catch {
78
+ diagnose();
79
+ }
80
+ throw error;
81
+ }
82
+ }
83
+ return {
84
+ url: response.url,
85
+ status: response.status,
86
+ statusText: response.statusText,
87
+ redirected: response.redirected,
88
+ headers: Object.freeze(response.headers.map((pair) => Object.freeze([...pair]))),
89
+ body,
90
+ close: async () => {
91
+ done = true;
92
+ await resource.dispose();
93
+ }
94
+ };
95
+ }), input.signal)
96
+ };
97
+ }
@@ -0,0 +1,29 @@
1
+ export interface CoreOperationContext {
2
+ readonly operationId: string;
3
+ readonly sessionId: string;
4
+ readonly sessionEpoch: number;
5
+ readonly ownerInstanceId?: string;
6
+ readonly extensionId?: string;
7
+ readonly parentOperationId?: string;
8
+ readonly executionId?: string;
9
+ readonly turnId?: string;
10
+ /** Correlation with the actual enclosing tool call; not an authority token. */
11
+ readonly toolCallId?: string;
12
+ readonly actor: 'model' | 'sdk' | 'extension' | 'code-mode';
13
+ readonly entry: 'direct' | 'programmatic' | 'native-api';
14
+ readonly signal: AbortSignal;
15
+ }
16
+ /** Internal callback binding shared by the typed hooks and contribution handlers. */
17
+ export type CoreCallbackRunner = <Value>(call: CoreOperationContext, callback: (call: CoreOperationContext) => Value | Promise<Value>, settled?: boolean) => Promise<Value>;
18
+ /** Internal identity propagation. Caller-controlled payloads never select a framework identity. */
19
+ export declare class ExtensionOperations {
20
+ #private;
21
+ current(): CoreOperationContext | undefined;
22
+ /** Bind the effective owner signal before author code can call another facade. */
23
+ callback<Value>(call: CoreOperationContext, callback: (call: CoreOperationContext) => Value | Promise<Value>, settled?: boolean): Promise<Value>;
24
+ /** Physical transport ingress starts a new ancestry; native plugin calls cannot choose it. */
25
+ continue<T>(context: CoreOperationContext, operation: () => Promise<T>, settled?: boolean): Promise<T>;
26
+ /** Physical transport ingress starts a new ancestry; native plugin calls cannot choose it. */
27
+ enter<T>(identity: Omit<CoreOperationContext, 'operationId' | 'parentOperationId'>, operation: (context: CoreOperationContext) => T): T;
28
+ run<T>(identity: Omit<CoreOperationContext, 'operationId' | 'parentOperationId'>, operation: (context: CoreOperationContext) => T): T;
29
+ }
@@ -0,0 +1,98 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { randomUUID } from 'node:crypto';
3
+ /** Internal identity propagation. Caller-controlled payloads never select a framework identity. */
4
+ export class ExtensionOperations {
5
+ #current = new AsyncLocalStorage();
6
+ current() {
7
+ const frame = this.#current.getStore();
8
+ return frame?.active ? frame.context : undefined;
9
+ }
10
+ /** Bind the effective owner signal before author code can call another facade. */
11
+ callback(call, callback, settled = false) {
12
+ const controller = new AbortController();
13
+ const effective = Object.freeze({
14
+ ...call,
15
+ signal: AbortSignal.any([call.signal, controller.signal])
16
+ });
17
+ return this.continue(effective, async () => {
18
+ try {
19
+ return await callback(effective);
20
+ }
21
+ catch (error) {
22
+ // Cancel descendants before continue joins them; retain the original callback error.
23
+ controller.abort(error);
24
+ throw error;
25
+ }
26
+ }, settled);
27
+ }
28
+ /** Physical transport ingress starts a new ancestry; native plugin calls cannot choose it. */
29
+ async continue(context, operation, settled = false) {
30
+ const frame = { context, active: true, children: new Set() };
31
+ return this.#current.run(frame, async () => {
32
+ try {
33
+ if (!settled)
34
+ context.signal.throwIfAborted();
35
+ return await operation();
36
+ }
37
+ finally {
38
+ while (frame.children.size)
39
+ await Promise.all([...frame.children]);
40
+ frame.active = false;
41
+ }
42
+ });
43
+ }
44
+ /** Physical transport ingress starts a new ancestry; native plugin calls cannot choose it. */
45
+ enter(identity, operation) {
46
+ return this.#current.run(undefined, () => this.run(identity, operation));
47
+ }
48
+ run(identity, operation) {
49
+ const parent = this.current();
50
+ const context = Object.freeze({
51
+ ...identity,
52
+ operationId: randomUUID(),
53
+ ...(parent
54
+ ? {
55
+ parentOperationId: parent.operationId,
56
+ ...((identity.toolCallId ?? parent.toolCallId) === undefined
57
+ ? {}
58
+ : { toolCallId: identity.toolCallId ?? parent.toolCallId }),
59
+ entry: parent.entry,
60
+ signal: AbortSignal.any([identity.signal, parent.signal])
61
+ }
62
+ : {})
63
+ });
64
+ const ancestor = this.#current.getStore();
65
+ const frame = { context, active: true, children: new Set() };
66
+ let value;
67
+ try {
68
+ value = this.#current.run(frame, () => {
69
+ context.signal.throwIfAborted();
70
+ return operation(context);
71
+ });
72
+ }
73
+ catch (error) {
74
+ frame.active = false;
75
+ throw error;
76
+ }
77
+ if (!value || typeof value.then !== 'function') {
78
+ frame.active = false;
79
+ return value;
80
+ }
81
+ const result = (async () => {
82
+ try {
83
+ return await value;
84
+ }
85
+ finally {
86
+ while (frame.children.size)
87
+ await Promise.all([...frame.children]);
88
+ frame.active = false;
89
+ }
90
+ })();
91
+ if (ancestor?.active) {
92
+ const settled = result.then(() => undefined, () => undefined);
93
+ ancestor.children.add(settled);
94
+ void settled.then(() => ancestor.children.delete(settled));
95
+ }
96
+ return result;
97
+ }
98
+ }
@@ -0,0 +1,52 @@
1
+ import type { CoreDomainFacts, CoreDomainOperations } from './contracts.js';
2
+ import type { ExtensionHooks } from './hooks.js';
3
+ import type { CoreOperationContext } from './operation.js';
4
+ import type { ExtensionResourceScope } from './resources.js';
5
+ export interface CoreProcessInput {
6
+ readonly executable: string;
7
+ readonly argv?: readonly string[];
8
+ readonly cwd?: string;
9
+ readonly env?: Readonly<Record<string, string>>;
10
+ readonly input?: string | Uint8Array;
11
+ readonly signal?: AbortSignal;
12
+ }
13
+ export interface CoreProcessRunInput extends CoreProcessInput {
14
+ readonly timeoutMs?: number;
15
+ readonly outputLimitBytes?: number;
16
+ }
17
+ export interface CoreProcessExit {
18
+ readonly code: number | null;
19
+ readonly signal: string | null;
20
+ }
21
+ export interface CoreProcessHandle {
22
+ readonly processId: string;
23
+ readonly stdout: AsyncIterable<Uint8Array>;
24
+ readonly stderr: AsyncIterable<Uint8Array>;
25
+ wait(): Promise<CoreProcessExit>;
26
+ cancel(): Promise<void>;
27
+ }
28
+ export interface CoreProcessResult extends CoreProcessExit {
29
+ readonly processId: string;
30
+ readonly stdout: Uint8Array;
31
+ readonly stderr: Uint8Array;
32
+ readonly stdoutBytes: number;
33
+ readonly stderrBytes: number;
34
+ readonly truncated: boolean;
35
+ readonly timedOut: boolean;
36
+ }
37
+ export interface CoreProcessesApi {
38
+ spawn(input: CoreProcessInput): Promise<CoreProcessHandle>;
39
+ run(input: CoreProcessRunInput): Promise<CoreProcessResult>;
40
+ }
41
+ export interface CoreProcessesBackend {
42
+ spawn(input: CoreProcessInput, call: CoreOperationContext): Promise<CoreProcessHandle>;
43
+ }
44
+ export interface CoreProcessCompletion extends CoreProcessExit {
45
+ readonly processId: string;
46
+ readonly stdoutBytes?: number;
47
+ readonly stderrBytes?: number;
48
+ readonly truncated?: boolean;
49
+ readonly timedOut?: boolean;
50
+ }
51
+ export declare function validateCoreProcessInput(input: CoreProcessInput): void;
52
+ export declare function bindCoreProcesses(backend: CoreProcessesBackend, run: <Value>(operation: (call: CoreOperationContext) => Promise<Value>, signal?: AbortSignal) => Promise<Value>, scope: ExtensionResourceScope, hooks: ExtensionHooks<CoreDomainOperations, CoreDomainFacts>, diagnose: () => void): CoreProcessesApi;