@agen-ai/agent-orchestration 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +413 -2
  3. package/dist/catalog/parse.d.ts +3 -0
  4. package/dist/catalog/parse.js +13 -0
  5. package/dist/catalog/schemas.d.ts +8 -0
  6. package/dist/catalog/schemas.js +78 -0
  7. package/dist/catalog/types.d.ts +53 -0
  8. package/dist/catalog/types.js +0 -0
  9. package/dist/coordinator/admission.d.ts +7 -0
  10. package/dist/coordinator/admission.js +189 -0
  11. package/dist/coordinator/cancel.d.ts +7 -0
  12. package/dist/coordinator/cancel.js +111 -0
  13. package/dist/coordinator/create.d.ts +3 -0
  14. package/dist/coordinator/create.js +87 -0
  15. package/dist/coordinator/parse.d.ts +10 -0
  16. package/dist/coordinator/parse.js +60 -0
  17. package/dist/coordinator/read.d.ts +4 -0
  18. package/dist/coordinator/read.js +267 -0
  19. package/dist/coordinator/recovery.d.ts +4 -0
  20. package/dist/coordinator/recovery.js +24 -0
  21. package/dist/coordinator/shutdown.d.ts +7 -0
  22. package/dist/coordinator/shutdown.js +66 -0
  23. package/dist/coordinator/types.d.ts +154 -0
  24. package/dist/coordinator/types.js +0 -0
  25. package/dist/delivery/calls.d.ts +4 -0
  26. package/dist/delivery/calls.js +34 -0
  27. package/dist/delivery/journal.d.ts +7 -0
  28. package/dist/delivery/journal.js +57 -0
  29. package/dist/delivery/parse.d.ts +4 -0
  30. package/dist/delivery/parse.js +31 -0
  31. package/dist/delivery/recovery.d.ts +3 -0
  32. package/dist/delivery/recovery.js +18 -0
  33. package/dist/delivery/scheduler.d.ts +3 -0
  34. package/dist/delivery/scheduler.js +123 -0
  35. package/dist/delivery/setup.d.ts +7 -0
  36. package/dist/delivery/setup.js +37 -0
  37. package/dist/delivery/types.d.ts +36 -0
  38. package/dist/delivery/types.js +0 -0
  39. package/dist/execution/authority.d.ts +16 -0
  40. package/dist/execution/authority.js +86 -0
  41. package/dist/execution/cleanup.d.ts +3 -0
  42. package/dist/execution/cleanup.js +75 -0
  43. package/dist/execution/control.d.ts +6 -0
  44. package/dist/execution/control.js +231 -0
  45. package/dist/execution/finish.d.ts +6 -0
  46. package/dist/execution/finish.js +49 -0
  47. package/dist/execution/journal.d.ts +19 -0
  48. package/dist/execution/journal.js +28 -0
  49. package/dist/execution/prepare.d.ts +3 -0
  50. package/dist/execution/prepare.js +153 -0
  51. package/dist/execution/scheduler.d.ts +4 -0
  52. package/dist/execution/scheduler.js +136 -0
  53. package/dist/execution/state.d.ts +107 -0
  54. package/dist/execution/state.js +120 -0
  55. package/dist/execution/stream.d.ts +9 -0
  56. package/dist/execution/stream.js +108 -0
  57. package/dist/host/types.d.ts +95 -0
  58. package/dist/host/types.js +0 -0
  59. package/dist/index.d.ts +20 -0
  60. package/dist/index.js +58 -0
  61. package/dist/mcp/bridge.d.ts +4 -0
  62. package/dist/mcp/bridge.js +222 -0
  63. package/dist/mcp/http.d.ts +11 -0
  64. package/dist/mcp/http.js +74 -0
  65. package/dist/mcp/index.d.ts +3 -0
  66. package/dist/mcp/index.js +4 -0
  67. package/dist/mcp/limits.d.ts +10 -0
  68. package/dist/mcp/limits.js +30 -0
  69. package/dist/mcp/protocol.d.ts +50 -0
  70. package/dist/mcp/protocol.js +81 -0
  71. package/dist/mcp/types.d.ts +22 -0
  72. package/dist/mcp/types.js +0 -0
  73. package/dist/policy/matching.d.ts +4 -0
  74. package/dist/policy/matching.js +18 -0
  75. package/dist/policy/parse.d.ts +3 -0
  76. package/dist/policy/parse.js +13 -0
  77. package/dist/policy/resolve.d.ts +7 -0
  78. package/dist/policy/resolve.js +67 -0
  79. package/dist/policy/schemas.d.ts +5 -0
  80. package/dist/policy/schemas.js +59 -0
  81. package/dist/policy/types.d.ts +60 -0
  82. package/dist/policy/types.js +0 -0
  83. package/dist/shared/bounds.d.ts +6 -0
  84. package/dist/shared/bounds.js +88 -0
  85. package/dist/shared/errors.d.ts +9 -0
  86. package/dist/shared/errors.js +27 -0
  87. package/dist/shared/identity.d.ts +6 -0
  88. package/dist/shared/identity.js +32 -0
  89. package/dist/shared/immutable.d.ts +2 -0
  90. package/dist/shared/immutable.js +10 -0
  91. package/dist/shared/limits.d.ts +32 -0
  92. package/dist/shared/limits.js +69 -0
  93. package/dist/shared/operational-errors.d.ts +7 -0
  94. package/dist/shared/operational-errors.js +15 -0
  95. package/dist/shared/schemas.d.ts +11 -0
  96. package/dist/shared/schemas.js +23 -0
  97. package/dist/shared/text.d.ts +2 -0
  98. package/dist/shared/text.js +15 -0
  99. package/dist/store/memory.d.ts +7 -0
  100. package/dist/store/memory.js +215 -0
  101. package/dist/store/pages.d.ts +16 -0
  102. package/dist/store/pages.js +46 -0
  103. package/dist/store/parse.d.ts +5 -0
  104. package/dist/store/parse.js +137 -0
  105. package/dist/store/types.d.ts +219 -0
  106. package/dist/store/types.js +0 -0
  107. package/dist/store-adapter/admission.d.ts +6 -0
  108. package/dist/store-adapter/admission.js +90 -0
  109. package/dist/store-adapter/context.d.ts +20 -0
  110. package/dist/store-adapter/context.js +107 -0
  111. package/dist/store-adapter/delivery.d.ts +15 -0
  112. package/dist/store-adapter/delivery.js +81 -0
  113. package/dist/store-adapter/execution.d.ts +12 -0
  114. package/dist/store-adapter/execution.js +151 -0
  115. package/dist/store-adapter/index.d.ts +7 -0
  116. package/dist/store-adapter/index.js +27 -0
  117. package/dist/store-adapter/lifecycle.d.ts +15 -0
  118. package/dist/store-adapter/lifecycle.js +80 -0
  119. package/dist/store-adapter/plan.d.ts +7 -0
  120. package/dist/store-adapter/plan.js +168 -0
  121. package/dist/store-adapter/types.d.ts +45 -0
  122. package/dist/store-adapter/types.js +0 -0
  123. package/dist/tasks/failure.d.ts +4 -0
  124. package/dist/tasks/failure.js +24 -0
  125. package/dist/tasks/parse.d.ts +18 -0
  126. package/dist/tasks/parse.js +66 -0
  127. package/dist/tasks/schemas.d.ts +47 -0
  128. package/dist/tasks/schemas.js +215 -0
  129. package/dist/tasks/types.d.ts +192 -0
  130. package/dist/tasks/types.js +0 -0
  131. package/dist/tools/create.d.ts +4 -0
  132. package/dist/tools/create.js +69 -0
  133. package/dist/tools/errors.d.ts +4 -0
  134. package/dist/tools/errors.js +35 -0
  135. package/dist/tools/guidance.d.ts +4 -0
  136. package/dist/tools/guidance.js +28 -0
  137. package/dist/tools/handlers.d.ts +4 -0
  138. package/dist/tools/handlers.js +84 -0
  139. package/dist/tools/projection.d.ts +13 -0
  140. package/dist/tools/projection.js +72 -0
  141. package/dist/tools/schemas.d.ts +6 -0
  142. package/dist/tools/schemas.js +93 -0
  143. package/dist/tools/types.d.ts +28 -0
  144. package/dist/tools/types.js +0 -0
  145. package/package.json +64 -3
@@ -0,0 +1,192 @@
1
+ import type { AgentFailureCategory, AgentRecoveryHint, AgentTurnInputContent } from "@agen-ai/agent-protocol";
2
+ import type { DelegationTargetReference } from "../catalog/types.js";
3
+ import type { DelegationCommitReceipt } from "../store/types.js";
4
+ export type DelegationPersistence = "volatile" | "durable";
5
+ export type DelegationTaskState = "active" | "settled" | "recovery_required" | "retired";
6
+ export type DelegationRunPhase = "queued" | "preparing" | "running" | "waiting" | "settled";
7
+ export type DelegationCompletionPolicy = "collect" | "next_turn" | "automatic";
8
+ export interface DelegationParentScope {
9
+ readonly parentId: string;
10
+ readonly scopeId: string;
11
+ readonly revision: number;
12
+ }
13
+ export interface DelegationOwnerToken {
14
+ readonly storeId: string;
15
+ readonly epoch: number;
16
+ readonly nonce: string;
17
+ }
18
+ export interface DelegationPolicyCeiling {
19
+ readonly ceilingId: string;
20
+ readonly origin: DelegationParentScope;
21
+ readonly targets: readonly DelegationTargetReference[];
22
+ }
23
+ export interface DelegationTaskRecord {
24
+ readonly storeId: string;
25
+ readonly taskId: string;
26
+ readonly parent: DelegationParentScope;
27
+ readonly ancestorTaskId?: string;
28
+ readonly depth: number;
29
+ readonly policyCeilingRef: string;
30
+ readonly completionPolicy: DelegationCompletionPolicy;
31
+ readonly state: DelegationTaskState;
32
+ readonly revision: number;
33
+ readonly latestRunId: string;
34
+ readonly runCount: number;
35
+ readonly createdAt: string;
36
+ readonly retiredAt?: string;
37
+ readonly retirement?: Readonly<{
38
+ operationId: string;
39
+ inputDigest: string;
40
+ reason: string;
41
+ }>;
42
+ }
43
+ export interface DelegationHistoricalRequest {
44
+ readonly requestId: string;
45
+ readonly requestKind: "approval" | "elicitation";
46
+ readonly openedAt: string;
47
+ readonly expiresAt?: string;
48
+ readonly state: "waiting" | "resolution_intended" | "resolved" | "unavailable";
49
+ }
50
+ export interface DelegationResultReference {
51
+ readonly id: string;
52
+ readonly kind: "artifact" | "host_result";
53
+ readonly digest?: string;
54
+ }
55
+ export interface DelegationResultSummary {
56
+ readonly text: string;
57
+ readonly truncated: boolean;
58
+ readonly references: readonly DelegationResultReference[];
59
+ }
60
+ export interface DelegationPublicFailure {
61
+ readonly category: AgentFailureCategory;
62
+ readonly code: string;
63
+ readonly message: string;
64
+ readonly recovery: Exclude<AgentRecoveryHint, {
65
+ kind: "wait_for_quota";
66
+ }> | Readonly<{
67
+ kind: "wait_for_quota";
68
+ }>;
69
+ }
70
+ export type DelegationRunOutcome = Readonly<{
71
+ kind: "succeeded";
72
+ result: DelegationResultSummary;
73
+ }> | Readonly<{
74
+ kind: "failed";
75
+ error: DelegationPublicFailure;
76
+ }> | Readonly<{
77
+ kind: "canceled";
78
+ confirmation: "not_dispatched" | "provider_terminal";
79
+ }> | Readonly<{
80
+ kind: "recovery_required";
81
+ reason: "executor_lost" | "dispatch_uncertain" | "request_executor_lost" | "steering_uncertain" | "cancellation_uncertain" | "storage_failed";
82
+ }>;
83
+ export interface DelegationRunRecord {
84
+ readonly taskId: string;
85
+ readonly runId: string;
86
+ readonly ordinal: number;
87
+ readonly previousRunId?: string;
88
+ readonly continuationMode?: "next_turn" | "follow_up";
89
+ readonly admissionOperationId: string;
90
+ readonly admittedTarget: DelegationTargetReference;
91
+ readonly appliedTarget?: DelegationTargetReference;
92
+ readonly admittedPolicyRevision: number;
93
+ readonly admittedOriginPolicyRevision: number;
94
+ readonly input: AgentTurnInputContent;
95
+ readonly ownerEpoch: number;
96
+ readonly phase: DelegationRunPhase;
97
+ readonly revision: number;
98
+ readonly createdAt: string;
99
+ readonly deadlineAt: string;
100
+ readonly queuedStartDeadlineAt: string;
101
+ readonly dispatch: "none" | "intended" | "delegated";
102
+ readonly preparation: "none" | "intended" | "completed" | "uncertain";
103
+ readonly cancelRequested: boolean;
104
+ readonly pendingRequest?: DelegationHistoricalRequest;
105
+ readonly outcome?: DelegationRunOutcome;
106
+ readonly settledAt?: string;
107
+ readonly observationIndex: number;
108
+ readonly observationCount: number;
109
+ readonly observationBytes: number;
110
+ readonly omittedObservations: number;
111
+ readonly lastObservationDigest?: string;
112
+ readonly ordinaryOperationCount: number;
113
+ readonly recoveryReason?: Extract<DelegationRunOutcome, {
114
+ kind: "recovery_required";
115
+ }>["reason"];
116
+ readonly finalization?: Readonly<{
117
+ operationId: string;
118
+ inputDigest: string;
119
+ taskRevision: number;
120
+ runRevision: number;
121
+ }>;
122
+ }
123
+ export interface DelegationTaskObservation {
124
+ readonly storeId: string;
125
+ readonly taskId: string;
126
+ readonly runId: string;
127
+ readonly index: number;
128
+ readonly at: string;
129
+ readonly kind: "state" | "text" | "request" | "omitted";
130
+ readonly phase?: DelegationRunPhase;
131
+ readonly text?: string;
132
+ readonly request?: DelegationHistoricalRequest;
133
+ readonly omitted?: number;
134
+ }
135
+ export interface DelegationObservationGap {
136
+ readonly kind: "gap";
137
+ readonly storeId: string;
138
+ readonly taskId: string;
139
+ readonly runId: string;
140
+ readonly cursor: string;
141
+ }
142
+ export type DelegationObservedTaskObservation = DelegationTaskObservation & Readonly<{
143
+ cursor: string;
144
+ }>;
145
+ export interface DelegationCompletionEnvelope {
146
+ readonly storeId: string;
147
+ readonly notificationId: string;
148
+ readonly taskId: string;
149
+ readonly runId: string;
150
+ readonly parent: DelegationParentScope;
151
+ readonly policy: DelegationCompletionPolicy;
152
+ readonly settledAt: string;
153
+ readonly expiresAt: string;
154
+ readonly outcome: DelegationRunOutcome;
155
+ }
156
+ export interface DelegationDeliveryCommitRecord {
157
+ readonly operationId: string;
158
+ readonly inputDigest: string;
159
+ readonly commandDigest: string;
160
+ readonly attemptId: string;
161
+ readonly attempt: number;
162
+ readonly ownerEpoch: number;
163
+ readonly receipt: DelegationCommitReceipt;
164
+ }
165
+ export interface DelegationNotificationRecord {
166
+ readonly envelope: DelegationCompletionEnvelope;
167
+ readonly revision: number;
168
+ readonly state: "collectible" | "pending" | "claimed" | "accepted" | "rejected" | "expired" | "dismissed";
169
+ readonly claim?: Readonly<{
170
+ ownerEpoch: number;
171
+ attemptId: string;
172
+ }>;
173
+ readonly attempts: number;
174
+ readonly retryAt?: string;
175
+ readonly inboxId?: string;
176
+ readonly acceptedAt?: string;
177
+ readonly reason?: string;
178
+ readonly delivery?: Readonly<{
179
+ claim?: DelegationDeliveryCommitRecord;
180
+ receipt?: DelegationDeliveryCommitRecord;
181
+ }>;
182
+ }
183
+ export interface DelegationPage<Value> {
184
+ readonly items: readonly Value[];
185
+ readonly cursor?: string;
186
+ }
187
+ export interface DelegationTaskView {
188
+ readonly task: DelegationTaskRecord;
189
+ readonly runs: DelegationPage<DelegationRunSummary>;
190
+ }
191
+ export type DelegationRunSummary = Omit<DelegationRunRecord, "input">;
192
+ //# sourceMappingURL=types.d.ts.map
File without changes
@@ -0,0 +1,4 @@
1
+ import { type AgentSessionHostBinding } from "@agen-ai/agent-runtime";
2
+ import type { CreateDelegationHostBindingOptions } from "./types.js";
3
+ export declare function createDelegationHostBinding(options: CreateDelegationHostBindingOptions): Promise<AgentSessionHostBinding | undefined>;
4
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1,69 @@
1
+ import {
2
+ validateAgentHostToolInvocation,
3
+ validateAgentHostToolResult,
4
+ validateAgentSessionHostBinding
5
+ } from "@agen-ai/agent-runtime";
6
+ import { createDelegationId } from "../shared/identity.js";
7
+ import { delegationToolError, sanitizeDelegationToolError } from "./errors.js";
8
+ import { delegationGuidance, validateNativeToolNames } from "./guidance.js";
9
+ import { handleDelegationTool } from "./handlers.js";
10
+ import { delegationToolDefinitions } from "./schemas.js";
11
+ async function createDelegationHostBinding(options) {
12
+ const client = options.client;
13
+ const snapshot = await client.bindingSnapshot();
14
+ if (!snapshot.enabled) return void 0;
15
+ const nativeTools = validateNativeToolNames(options.nativeToolNames);
16
+ const lifetime = new AbortController();
17
+ const active = /* @__PURE__ */ new Map();
18
+ let releasePromise;
19
+ const invoke = (raw) => {
20
+ if (lifetime.signal.aborted) return Promise.resolve(delegationToolError("tool_unavailable", "This managed tool binding has been released."));
21
+ let invocation;
22
+ try {
23
+ invocation = validateAgentHostToolInvocation({ binding, invocation: raw });
24
+ } catch {
25
+ return Promise.resolve(delegationToolError("invalid_tool_input", "The managed tool invocation or arguments are invalid."));
26
+ }
27
+ if (invocation.signal?.aborted) return Promise.resolve(delegationToolError("operation_aborted", "The tool invocation was canceled before dispatch."));
28
+ if (active.has(invocation.invocationId)) return Promise.resolve(delegationToolError("invalid_tool_input", "This tool invocation ID is already active."));
29
+ if (active.size >= 16) return Promise.resolve(delegationToolError("capacity_exceeded", "This managed binding has reached its callback limit."));
30
+ const signal = invocation.signal === void 0 ? lifetime.signal : AbortSignal.any([lifetime.signal, invocation.signal]);
31
+ const work = Promise.resolve().then(async () => {
32
+ let value;
33
+ try {
34
+ value = await handleDelegationTool(client, snapshot, { ...invocation, signal });
35
+ } catch (error) {
36
+ if (signal.aborted && error === signal.reason) {
37
+ return delegationToolError("operation_aborted", "The tool invocation was canceled. Any admitted child work remains independent.");
38
+ }
39
+ return sanitizeDelegationToolError(error);
40
+ }
41
+ try {
42
+ return validateAgentHostToolResult({ kind: "success", value });
43
+ } catch {
44
+ return delegationToolError("internal_error", "The managed action did not produce a portable result. Inspect retained state before retrying.");
45
+ }
46
+ }).finally(() => {
47
+ active.delete(invocation.invocationId);
48
+ });
49
+ active.set(invocation.invocationId, work);
50
+ return work;
51
+ };
52
+ const binding = validateAgentSessionHostBinding({ binding: {
53
+ bindingId: options.bindingId ?? createDelegationId(),
54
+ tools: delegationToolDefinitions(snapshot),
55
+ instructions: { placement: options.instructionPlacement ?? "tool_context", text: delegationGuidance(snapshot, nativeTools) },
56
+ invoke,
57
+ release() {
58
+ if (!releasePromise) {
59
+ lifetime.abort(new DOMException("The managed tool binding was released.", "AbortError"));
60
+ releasePromise = Promise.allSettled(active.values()).then(() => void 0);
61
+ }
62
+ return releasePromise;
63
+ }
64
+ }, support: { kind: "supported", toolTransport: "callback", instructionPlacements: ["system", "developer", "tool_context"] } });
65
+ return binding;
66
+ }
67
+ export {
68
+ createDelegationHostBinding
69
+ };
@@ -0,0 +1,4 @@
1
+ import type { AgentHostToolResult } from "@agen-ai/agent-runtime";
2
+ export declare function delegationToolError(code: string, message: string): AgentHostToolResult;
3
+ export declare function sanitizeDelegationToolError(error: unknown): AgentHostToolResult;
4
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1,35 @@
1
+ import { AgentProtocolValidationError } from "@agen-ai/agent-protocol";
2
+ import { DelegationValidationError } from "../shared/errors.js";
3
+ import { DelegationOperationError } from "../shared/operational-errors.js";
4
+ const messages = {
5
+ delegation_disabled: "Managed delegation is currently disabled.",
6
+ policy_denied: "Current authority does not permit this managed action.",
7
+ target_unavailable: "The selected managed target is unavailable.",
8
+ stale_target: "The exact target or source revision is stale. Refresh delegation_targets.",
9
+ unsupported_operation: "This managed operation or completion policy is unsupported.",
10
+ capacity_exceeded: "This managed action exceeds a configured capacity or content limit.",
11
+ operation_conflict: "The operation ID conflicts with retained work. Retry only the canonical accepted ID with identical arguments.",
12
+ stale_revision: "The policy, scope, or page revision changed. Refresh the relevant managed view.",
13
+ owner_lost: "The managed executor is unavailable. Inspect retained task history.",
14
+ request_unavailable: "The requested managed task or request is unavailable to this parent.",
15
+ delivery_uncertain: "Delivery is uncertain. Inspect retained task state and do not automatically replay.",
16
+ recovery_required: "The managed task requires host recovery. Do not replay uncertain work.",
17
+ store_failed: "Managed storage is unavailable. Retained work may require host recovery."
18
+ };
19
+ function delegationToolError(code, message) {
20
+ return Object.freeze({ kind: "error", error: Object.freeze({ code, message, category: "unknown", recovery: Object.freeze({ kind: "unknown" }) }) });
21
+ }
22
+ function sanitizeDelegationToolError(error) {
23
+ if (error instanceof DelegationOperationError) return delegationToolError(error.code, messages[error.code]);
24
+ if (error instanceof DelegationValidationError || error instanceof AgentProtocolValidationError) {
25
+ return delegationToolError("invalid_tool_input", "The managed tool arguments are invalid.");
26
+ }
27
+ if (error instanceof DOMException && error.name === "AbortError") {
28
+ return delegationToolError("operation_aborted", "The tool invocation was canceled. Any admitted child work remains independent.");
29
+ }
30
+ return delegationToolError("internal_error", "The managed tool could not return a result. Inspect retained state before retrying an action.");
31
+ }
32
+ export {
33
+ delegationToolError,
34
+ sanitizeDelegationToolError
35
+ };
@@ -0,0 +1,4 @@
1
+ import type { DelegationBindingSnapshot } from "../coordinator/types.js";
2
+ export declare function validateNativeToolNames(input: readonly string[] | undefined): readonly string[];
3
+ export declare function delegationGuidance(snapshot: DelegationBindingSnapshot, nativeTools: readonly string[]): string;
4
+ //# sourceMappingURL=guidance.d.ts.map
@@ -0,0 +1,28 @@
1
+ import { DELEGATION_TOOL_NAMES } from "./schemas.js";
2
+ function validateNativeToolNames(input) {
3
+ if (input === void 0) return [];
4
+ if (!Array.isArray(input) || input.length > 32) throw new TypeError("Native tool names require a bounded array.");
5
+ const names = [...input];
6
+ if (new Set(names).size !== names.length || names.some((name) => typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_]{0,63}$/u.test(name) || DELEGATION_TOOL_NAMES.includes(name))) {
7
+ throw new TypeError("Native tool names must be bounded, unique, and distinct from managed tool names.");
8
+ }
9
+ return names;
10
+ }
11
+ function delegationGuidance(snapshot, nativeTools) {
12
+ return [
13
+ "Managed delegation is optional and governed by current host and user policy. These instructions do not grant execution or approval authority.",
14
+ "Use delegation_targets to obtain currently permitted exact target references and policyRevision. An emptyReason of delegation_disabled means delegation is disabled; no_permitted_targets means it is enabled but current policy permits no targets. Unknown semantics remain unknown; do not infer capability from a label. Fast execution requires explicit selection.",
15
+ "Use delegate_task for independent child work. Required operationId is a caller-chosen UUID: choose it once for an action, retain it, and reuse it only with identical arguments for an exact retry. Never invent a fresh operation ID to retry an uncertain result.",
16
+ `Task text is bounded to ${snapshot.limits.maxInputBytes} serialized input bytes and ${snapshot.limits.maxInputTextCharacters} characters in total; prompt, message, and context each allow at most 16 KiB UTF-8. Context is ordinary task input.`,
17
+ `Completion defaults to collect. Available completion policies: ${snapshot.completionPolicies.join(", ")}. Collect results with task_status; next_turn and automatic, when available, only enqueue through the host inbox and do not prove parent consumption or start a parent model turn.`,
18
+ `task_status may wait at most ${snapshot.limits.maxWaitMs} ms. A timeout or canceled tool invocation does not cancel the child. Follow returned cursors for complete target and run history; a truncated result summary is explicitly marked and references remain available.`,
19
+ "task_send steer applies only to a supported active turn and never falls back to a queue. next_turn reserves a later run; follow_up requires a definitive settled, safely resumable conversation. delivered, queued, rejected, and delivery_uncertain have distinct meanings. Inspect delivery_uncertain or recovery_required; do not replay uncertain work.",
20
+ "A waiting approval or elicitation requires the host's live request channel. These tools cannot approve, authenticate, choose executable commands, change policy, or resolve a request handle.",
21
+ "task_cancel requests interruption. requested does not mean stopped; confirmed requires terminal evidence, and recovery_required means stop is unproven. Retain the canonical accepted cancellation operation ID for retries. Existing status and cancellation access can remain available after delegation is disabled.",
22
+ nativeTools.length === 0 ? "No native collaboration tool names were certified for this binding. These managed tools make no claim about native tool availability." : `The host certifies these independent native tools in this session: ${nativeTools.join(", ")}. Use their native descriptions for native collaboration; managed tools do not replace or alter them.`
23
+ ].join("\n\n");
24
+ }
25
+ export {
26
+ delegationGuidance,
27
+ validateNativeToolNames
28
+ };
@@ -0,0 +1,4 @@
1
+ import type { AgentHostToolInvocation } from "@agen-ai/agent-runtime";
2
+ import type { DelegationBindingSnapshot, DelegationClient } from "../coordinator/types.js";
3
+ export declare function handleDelegationTool(client: DelegationClient, snapshot: DelegationBindingSnapshot, invocation: AgentHostToolInvocation): Promise<unknown>;
4
+ //# sourceMappingURL=handlers.d.ts.map
@@ -0,0 +1,84 @@
1
+ import { AGENT_PROTOCOL_TEXT_MAX_LENGTH } from "@agen-ai/agent-protocol";
2
+ import { failDelegation } from "../shared/operational-errors.js";
3
+ import { projectTargetPage, projectTaskPage } from "./projection.js";
4
+ function taskContent(text, context) {
5
+ for (const field of [text, ...context === void 0 ? [] : [context]]) {
6
+ if (new TextEncoder().encode(field).byteLength > 16384) {
7
+ failDelegation("capacity_exceeded", "A task text field exceeds its UTF-8 byte limit.");
8
+ }
9
+ }
10
+ const contents = context === void 0 ? text : `${text}
11
+
12
+ Context:
13
+ ${context}`;
14
+ const parts = [];
15
+ let position = 0;
16
+ while (position < contents.length) {
17
+ let end = Math.min(position + AGENT_PROTOCOL_TEXT_MAX_LENGTH, contents.length);
18
+ if (end < contents.length && /[\uD800-\uDBFF]/u.test(contents[end - 1])) end--;
19
+ parts.push({ type: "text", text: contents.slice(position, end) });
20
+ position = end;
21
+ }
22
+ return { parts };
23
+ }
24
+ async function handleDelegationTool(client, snapshot, invocation) {
25
+ const args = invocation.arguments;
26
+ invocation.signal?.throwIfAborted();
27
+ switch (invocation.toolName) {
28
+ case "delegation_targets": {
29
+ const input = args;
30
+ return projectTargetPage(client, {
31
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor },
32
+ limit: input.limit ?? Math.min(20, snapshot.limits.maxPageRecords)
33
+ });
34
+ }
35
+ case "delegate_task": {
36
+ const input = args;
37
+ return client.spawn({
38
+ operationId: input.operationId,
39
+ target: input.target,
40
+ expectedPolicyRevision: input.expectedPolicyRevision,
41
+ input: taskContent(input.prompt, input.context),
42
+ ...input.completionPolicy === void 0 ? {} : { completionPolicy: input.completionPolicy },
43
+ ...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs }
44
+ });
45
+ }
46
+ case "task_status": {
47
+ const input = args;
48
+ let waitStatus;
49
+ if (input.waitMs !== void 0 && input.waitMs > 0) {
50
+ waitStatus = (await client.wait({
51
+ taskId: input.taskId,
52
+ timeoutMs: input.waitMs,
53
+ ...invocation.signal === void 0 ? {} : { signal: invocation.signal }
54
+ })).status;
55
+ invocation.signal?.throwIfAborted();
56
+ }
57
+ return projectTaskPage(client, {
58
+ taskId: input.taskId,
59
+ ...input.runsCursor === void 0 ? {} : { runsCursor: input.runsCursor },
60
+ limit: input.limit ?? Math.min(20, snapshot.limits.maxPageRecords)
61
+ }, waitStatus);
62
+ }
63
+ case "task_send": {
64
+ const input = args;
65
+ return client.send({
66
+ operationId: input.operationId,
67
+ taskId: input.taskId,
68
+ mode: input.mode,
69
+ target: input.target,
70
+ expectedPolicyRevision: input.expectedPolicyRevision,
71
+ input: taskContent(input.message, input.context)
72
+ });
73
+ }
74
+ case "task_cancel": {
75
+ const input = args;
76
+ return client.cancel({ operationId: input.operationId, taskId: input.taskId });
77
+ }
78
+ default:
79
+ return failDelegation("unsupported_operation", "The managed tool is unavailable.");
80
+ }
81
+ }
82
+ export {
83
+ handleDelegationTool
84
+ };
@@ -0,0 +1,13 @@
1
+ import type { DelegationClient } from "../coordinator/types.js";
2
+ import type { DelegationToolTargetPage, DelegationToolTaskStatus } from "./types.js";
3
+ export declare const DELEGATION_TOOL_PAGE_BYTES = 24576;
4
+ export declare function projectTargetPage(client: DelegationClient, input: Readonly<{
5
+ cursor?: string;
6
+ limit: number;
7
+ }>): Promise<DelegationToolTargetPage>;
8
+ export declare function projectTaskPage(client: DelegationClient, input: Readonly<{
9
+ taskId: string;
10
+ runsCursor?: string;
11
+ limit: number;
12
+ }>, waitStatus?: "settled" | "timeout"): Promise<DelegationToolTaskStatus>;
13
+ //# sourceMappingURL=projection.d.ts.map
@@ -0,0 +1,72 @@
1
+ import { agentProtocolSerializedJsonBytes } from "@agen-ai/agent-protocol";
2
+ import { failDelegation } from "../shared/operational-errors.js";
3
+ const DELEGATION_TOOL_PAGE_BYTES = 24576;
4
+ function targetProjection(target) {
5
+ const { reference, providerKey, modelId, label, options, reasoning, executionMode, limitations } = target;
6
+ return { reference, providerKey, modelId, label, options, reasoning, executionMode, limitations };
7
+ }
8
+ function runProjection(run) {
9
+ const { runId, ordinal, phase, revision, dispatch, cancelRequested, createdAt, deadlineAt } = run;
10
+ const pending = run.pendingRequest;
11
+ return {
12
+ runId,
13
+ ordinal,
14
+ phase,
15
+ revision,
16
+ dispatch,
17
+ cancelRequested,
18
+ createdAt,
19
+ deadlineAt,
20
+ target: run.admittedTarget,
21
+ ...run.previousRunId === void 0 ? {} : { previousRunId: run.previousRunId },
22
+ ...run.continuationMode === void 0 ? {} : { continuationMode: run.continuationMode },
23
+ ...run.outcome === void 0 ? {} : { outcome: run.outcome },
24
+ ...run.settledAt === void 0 ? {} : { settledAt: run.settledAt },
25
+ ...pending === void 0 ? {} : { pendingRequest: {
26
+ requestKind: pending.requestKind,
27
+ state: pending.state,
28
+ openedAt: pending.openedAt,
29
+ ...pending.expiresAt === void 0 ? {} : { expiresAt: pending.expiresAt }
30
+ } }
31
+ };
32
+ }
33
+ function taskProjection(view, waitStatus) {
34
+ const { storeId, taskId, state, revision, latestRunId, runCount, completionPolicy } = view.task;
35
+ return {
36
+ task: { storeId, taskId, state, revision, latestRunId, runCount, completionPolicy },
37
+ runs: { items: view.runs.items.map(runProjection), ...view.runs.cursor === void 0 ? {} : { cursor: view.runs.cursor } },
38
+ ...waitStatus === void 0 ? {} : { waitStatus }
39
+ };
40
+ }
41
+ async function boundedPage(limit, read) {
42
+ let requested = limit;
43
+ for (; ; ) {
44
+ const page = await read(requested);
45
+ if (agentProtocolSerializedJsonBytes(page) <= DELEGATION_TOOL_PAGE_BYTES) return page;
46
+ if (requested === 1) return failDelegation("capacity_exceeded", "One projected record exceeds the tool result limit.");
47
+ requested = Math.max(1, Math.floor(requested / 2));
48
+ }
49
+ }
50
+ function projectTargetPage(client, input) {
51
+ return boundedPage(input.limit, async (limit) => {
52
+ const page = await client.targets({ ...input.cursor === void 0 ? {} : { cursor: input.cursor }, limit });
53
+ return {
54
+ policyRevision: page.policyRevision,
55
+ targets: page.targets.map(targetProjection),
56
+ ...page.cursor === void 0 ? {} : { cursor: page.cursor },
57
+ ...page.emptyReason === void 0 ? {} : { emptyReason: page.emptyReason }
58
+ };
59
+ });
60
+ }
61
+ function projectTaskPage(client, input, waitStatus) {
62
+ return boundedPage(input.limit, async (limit) => taskProjection(await client.inspect({
63
+ taskId: input.taskId,
64
+ ...input.runsCursor === void 0 ? {} : { runsCursor: input.runsCursor },
65
+ limit
66
+ }), waitStatus));
67
+ }
68
+ export {
69
+ DELEGATION_TOOL_PAGE_BYTES,
70
+ projectTargetPage,
71
+ projectTaskPage
72
+ };
@@ -0,0 +1,6 @@
1
+ import type { AgentHostToolDefinition } from "@agen-ai/agent-runtime";
2
+ import type { DelegationBindingSnapshot } from "../coordinator/types.js";
3
+ export declare const DELEGATION_TOOL_NAMES: readonly ["delegation_targets", "delegate_task", "task_status", "task_send", "task_cancel"];
4
+ export type DelegationToolName = typeof DELEGATION_TOOL_NAMES[number];
5
+ export declare function delegationToolDefinitions(snapshot: DelegationBindingSnapshot): readonly AgentHostToolDefinition[];
6
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1,93 @@
1
+ const DELEGATION_TOOL_NAMES = ["delegation_targets", "delegate_task", "task_status", "task_send", "task_cancel"];
2
+ const uuid = {
3
+ type: "string",
4
+ minLength: 36,
5
+ maxLength: 36,
6
+ description: "A UUID. For operations, choose it once and reuse it only for the exact same action and arguments."
7
+ };
8
+ const revision = { type: "integer", minimum: 1, maximum: Number.MAX_SAFE_INTEGER };
9
+ const identifier = { type: "string", minLength: 1, maxLength: 256 };
10
+ const cursor = { type: "string", minLength: 1, maxLength: 512 };
11
+ const target = {
12
+ type: "object",
13
+ additionalProperties: false,
14
+ properties: {
15
+ catalogId: identifier,
16
+ catalogRevision: revision,
17
+ targetId: identifier,
18
+ targetRevision: revision,
19
+ sourceId: identifier,
20
+ sourceRevision: revision
21
+ },
22
+ required: ["catalogId", "catalogRevision", "targetId", "targetRevision", "sourceId", "sourceRevision"]
23
+ };
24
+ function schema(properties, required = []) {
25
+ return { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required, additionalProperties: false };
26
+ }
27
+ function delegationToolDefinitions(snapshot) {
28
+ const text = {
29
+ type: "string",
30
+ minLength: 1,
31
+ maxLength: snapshot.limits.maxInputTextCharacters,
32
+ description: "Plain text, at most 16 KiB UTF-8 per field. Combined task content must fit the configured input byte and character limits."
33
+ };
34
+ const limit = { type: "integer", minimum: 1, maximum: snapshot.limits.maxPageRecords };
35
+ return [
36
+ {
37
+ name: "delegation_targets",
38
+ description: "List currently permitted managed targets and the policy revision. An emptyReason distinguishes delegation_disabled from no_permitted_targets. Follow the returned cursor for more choices; preserve the exact target reference for admission.",
39
+ inputSchema: schema({ cursor, limit })
40
+ },
41
+ {
42
+ name: "delegate_task",
43
+ description: "Admit one managed child task using an exact listed target and current policy revision. A queued receipt is admission only. Supply a stable UUID operationId; identical retries never create another task.",
44
+ inputSchema: schema(
45
+ {
46
+ operationId: uuid,
47
+ target,
48
+ expectedPolicyRevision: revision,
49
+ prompt: text,
50
+ context: text,
51
+ completionPolicy: { type: "string", enum: snapshot.completionPolicies, maxLength: 9 },
52
+ timeoutMs: { type: "integer", minimum: 1, maximum: snapshot.limits.runTimeoutMs }
53
+ },
54
+ ["operationId", "target", "expectedPolicyRevision", "prompt"]
55
+ )
56
+ },
57
+ {
58
+ name: "task_status",
59
+ description: "Inspect bounded managed run history and results. Optionally wait for a bounded interval; a wait timeout does not cancel work. Follow runs.cursor without discarding earlier run outcomes. Waiting approval or elicitation belongs to the host.",
60
+ inputSchema: schema({
61
+ taskId: uuid,
62
+ runsCursor: cursor,
63
+ limit,
64
+ waitMs: { type: "integer", minimum: 0, maximum: snapshot.limits.maxWaitMs }
65
+ }, ["taskId"])
66
+ },
67
+ {
68
+ name: "task_send",
69
+ description: "Send explicit steer, next_turn, or follow_up input with a stable UUID operationId. Steer never falls back to a queue. next_turn reserves a later run; follow_up requires a safe settled continuation. delivery_uncertain requires inspection, not automatic replay.",
70
+ inputSchema: schema(
71
+ {
72
+ operationId: uuid,
73
+ taskId: uuid,
74
+ mode: { type: "string", enum: ["steer", "next_turn", "follow_up"], maxLength: 9 },
75
+ target,
76
+ expectedPolicyRevision: revision,
77
+ message: text,
78
+ context: text
79
+ },
80
+ ["operationId", "taskId", "mode", "target", "expectedPolicyRevision", "message"]
81
+ )
82
+ },
83
+ {
84
+ name: "task_cancel",
85
+ description: "Request cancellation using a stable UUID operationId. requested does not mean stopped; inspect until confirmed or recovery_required. Retry the canonical accepted operation ID. Cancellation remains available after managed delegation is disabled.",
86
+ inputSchema: schema({ operationId: uuid, taskId: uuid }, ["operationId", "taskId"])
87
+ }
88
+ ];
89
+ }
90
+ export {
91
+ DELEGATION_TOOL_NAMES,
92
+ delegationToolDefinitions
93
+ };
@@ -0,0 +1,28 @@
1
+ import type { AgentHostInstructionPlacement } from "@agen-ai/agent-runtime";
2
+ import type { DelegationClient } from "../coordinator/types.js";
3
+ import type { DelegationTarget } from "../catalog/types.js";
4
+ import type { DelegationHistoricalRequest, DelegationPage, DelegationRunSummary, DelegationTaskRecord } from "../tasks/types.js";
5
+ export interface CreateDelegationHostBindingOptions {
6
+ readonly client: DelegationClient;
7
+ readonly bindingId?: string;
8
+ readonly instructionPlacement?: AgentHostInstructionPlacement;
9
+ /** The host certifies that these native tools exist in this exact session. */
10
+ readonly nativeToolNames?: readonly string[];
11
+ }
12
+ export type DelegationToolTarget = Pick<DelegationTarget, "reference" | "providerKey" | "modelId" | "label" | "options" | "reasoning" | "executionMode" | "limitations">;
13
+ export interface DelegationToolTargetPage {
14
+ readonly policyRevision: number;
15
+ readonly targets: readonly DelegationToolTarget[];
16
+ readonly cursor?: string;
17
+ readonly emptyReason?: "delegation_disabled" | "no_permitted_targets";
18
+ }
19
+ export type DelegationToolRunSummary = Pick<DelegationRunSummary, "runId" | "ordinal" | "previousRunId" | "continuationMode" | "phase" | "revision" | "dispatch" | "cancelRequested" | "outcome" | "createdAt" | "deadlineAt" | "settledAt"> & Readonly<{
20
+ target: DelegationTarget["reference"];
21
+ pendingRequest?: Omit<DelegationHistoricalRequest, "requestId">;
22
+ }>;
23
+ export interface DelegationToolTaskStatus {
24
+ readonly task: Pick<DelegationTaskRecord, "storeId" | "taskId" | "state" | "revision" | "latestRunId" | "runCount" | "completionPolicy">;
25
+ readonly runs: DelegationPage<DelegationToolRunSummary>;
26
+ readonly waitStatus?: "settled" | "timeout";
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
File without changes