@tangle-network/agent-interface 0.39.0 → 0.41.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.
@@ -1,6 +1,11 @@
1
+ import { z } from "zod";
1
2
  import type { AgentProfile, AgentProfileCapabilities, AgentProfileValidationResult } from "./agent-profile.js";
2
3
  import type { AgentCandidateTermination } from "./agent-candidate.js";
3
4
  import type { InputPart, StreamEvent, TokenUsage } from "./index.js";
5
+ import { type InteractionAcknowledgement, type InteractionCapabilities, type InteractionResponseCommand } from "./interaction.js";
6
+ import type { ContextTransferReceipt, ContextTransferRequest, NativeContextBoundaryProof, NativeContextContinuationRequest } from "./portable-context.js";
7
+ import type { AgentRunControlRef } from "./runtime-control.js";
8
+ import type { AgentWorkspaceBranching } from "./workspace-branching.js";
4
9
  /** Portable profile reference: inline profile or provider catalog id. */
5
10
  export type AgentProfileRef = AgentProfile | string;
6
11
  export type AgentEnvironmentStatus = "pending" | "provisioning" | "running" | "stopped" | "failed" | "expired" | "unknown";
@@ -202,6 +207,12 @@ export interface AgentTurnInput {
202
207
  lastEventId?: string;
203
208
  turnId?: string;
204
209
  detach?: boolean;
210
+ /** Stable coordinates for a retained run when one already exists. */
211
+ controlRef?: AgentRunControlRef;
212
+ /** Approved portable history for a fresh provider session. */
213
+ contextTransfer?: ContextTransferRequest;
214
+ /** Verified same-session continuation; never carries duplicate history. */
215
+ nativeContinuation?: NativeContextContinuationRequest;
205
216
  context?: Record<string, unknown>;
206
217
  signal?: AbortSignal;
207
218
  providerOptions?: Record<string, unknown>;
@@ -214,10 +225,13 @@ export interface AgentTurnResult {
214
225
  usage?: TokenUsage;
215
226
  metadata?: Record<string, unknown>;
216
227
  events?: AgentEnvironmentEvent[];
228
+ contextTransferReceipt?: ContextTransferReceipt;
217
229
  }
218
230
  export interface AgentSessionRef {
219
231
  id: string;
220
232
  provider?: string;
233
+ controlRef?: AgentRunControlRef;
234
+ contextTransferReceipt?: ContextTransferReceipt;
221
235
  metadata?: Record<string, unknown>;
222
236
  }
223
237
  export interface AgentEnvironmentEvent {
@@ -230,13 +244,23 @@ export interface AgentEnvironmentEvent {
230
244
  }
231
245
  export interface AgentSession {
232
246
  readonly id: string;
247
+ readonly controlRef?: AgentRunControlRef;
233
248
  status(): Promise<AgentSessionStatus | null>;
234
249
  events(options?: {
250
+ /** Exclusive stable event id previously emitted by this session. */
235
251
  since?: string;
252
+ /** Provider execution selected by the durable control reference, when required. */
253
+ executionId?: string;
236
254
  signal?: AbortSignal;
237
255
  }): AsyncIterable<AgentEnvironmentEvent>;
238
256
  result(): Promise<AgentTurnResult>;
239
257
  prompt(input: AgentTurnInput): Promise<AgentTurnResult>;
258
+ respondToInteraction?(command: InteractionResponseCommand, options?: {
259
+ signal?: AbortSignal;
260
+ }): Promise<InteractionAcknowledgement>;
261
+ contextBoundary?(options?: {
262
+ signal?: AbortSignal;
263
+ }): Promise<NativeContextBoundaryProof | null>;
240
264
  cancel(): Promise<void>;
241
265
  }
242
266
  export interface AgentEnvironment {
@@ -246,7 +270,12 @@ export interface AgentEnvironment {
246
270
  status(): Promise<AgentEnvironmentStatus>;
247
271
  stream(input: AgentTurnInput): AsyncIterable<AgentEnvironmentEvent>;
248
272
  dispatch?(input: AgentTurnInput): Promise<AgentSessionRef>;
249
- session?(id: string): AgentSession;
273
+ session?(id: string, options?: {
274
+ controlRef?: AgentRunControlRef;
275
+ }): AgentSession;
276
+ respondToInteraction?(command: InteractionResponseCommand, options?: {
277
+ signal?: AbortSignal;
278
+ }): Promise<InteractionAcknowledgement>;
250
279
  read?(path: string, options?: {
251
280
  sessionId?: string;
252
281
  }): Promise<string>;
@@ -256,6 +285,8 @@ export interface AgentEnvironment {
256
285
  exec?(command: string, options?: ExecRequest): Promise<ExecResult>;
257
286
  checkpoint?(options?: CheckpointRequest): Promise<CheckpointRef>;
258
287
  fork?(checkpoint: CheckpointRef, options?: ForkRequest): Promise<AgentEnvironment>;
288
+ /** Durable, retry-safe checkpoint and environment-fork operations. */
289
+ readonly workspaceBranching?: AgentWorkspaceBranching;
259
290
  placement?(): Promise<PlacementInfo>;
260
291
  refresh?(): Promise<void>;
261
292
  destroy?(): Promise<void>;
@@ -273,6 +304,8 @@ export interface AgentEnvironmentCapabilities {
273
304
  list: boolean;
274
305
  messages: boolean;
275
306
  };
307
+ /** Absent when the provider cannot originate or answer interactions. */
308
+ interactions?: InteractionCapabilities;
276
309
  workspace: {
277
310
  read: boolean;
278
311
  write: boolean;
@@ -284,6 +317,12 @@ export interface AgentEnvironmentCapabilities {
284
317
  branching: {
285
318
  checkpoint: boolean;
286
319
  fork: boolean;
320
+ /** True only when key + canonical request digest semantics are implemented. */
321
+ retrySafe?: boolean;
322
+ /** True only when operations can be recovered by idempotency key. */
323
+ lookup?: boolean;
324
+ /** True only when checkpoints and forked environments have confirmed cleanup. */
325
+ cleanup?: boolean;
287
326
  };
288
327
  placement: boolean;
289
328
  usage: boolean;
@@ -293,6 +332,85 @@ export interface AgentEnvironmentCapabilities {
293
332
  egress: readonly AgentExactProcessEgressMode[];
294
333
  };
295
334
  }
335
+ /** Strict runtime validator for provider capability negotiation. */
336
+ export declare const AgentEnvironmentCapabilitiesSchema: z.ZodObject<{
337
+ profile: z.ZodObject<{
338
+ namedProfiles: z.ZodBoolean;
339
+ systemPrompt: z.ZodBoolean;
340
+ instructions: z.ZodBoolean;
341
+ tools: z.ZodBoolean;
342
+ permissions: z.ZodBoolean;
343
+ mcp: z.ZodBoolean;
344
+ subagents: z.ZodBoolean;
345
+ resources: z.ZodObject<{
346
+ files: z.ZodBoolean;
347
+ instructions: z.ZodBoolean;
348
+ tools: z.ZodOptional<z.ZodBoolean>;
349
+ skills: z.ZodOptional<z.ZodBoolean>;
350
+ agents: z.ZodOptional<z.ZodBoolean>;
351
+ commands: z.ZodOptional<z.ZodBoolean>;
352
+ }, z.core.$strict>;
353
+ hooks: z.ZodOptional<z.ZodBoolean>;
354
+ modes: z.ZodOptional<z.ZodBoolean>;
355
+ runtimeUpdate: z.ZodBoolean;
356
+ validation: z.ZodBoolean;
357
+ extensions: z.ZodOptional<z.ZodArray<z.ZodString>>;
358
+ }, z.core.$strict>;
359
+ streaming: z.ZodObject<{
360
+ live: z.ZodBoolean;
361
+ replay: z.ZodBoolean;
362
+ detach: z.ZodBoolean;
363
+ turnIdempotency: z.ZodBoolean;
364
+ }, z.core.$strict>;
365
+ sessions: z.ZodObject<{
366
+ continue: z.ZodBoolean;
367
+ list: z.ZodBoolean;
368
+ messages: z.ZodBoolean;
369
+ }, z.core.$strict>;
370
+ interactions: z.ZodOptional<z.ZodObject<{
371
+ kinds: z.ZodArray<z.ZodString>;
372
+ answerFieldTypes: z.ZodArray<z.ZodEnum<{
373
+ number: "number";
374
+ boolean: "boolean";
375
+ text: "text";
376
+ select: "select";
377
+ secret: "secret";
378
+ }>>;
379
+ responseScopes: z.ZodArray<z.ZodEnum<{
380
+ interaction: "interaction";
381
+ session: "session";
382
+ persistent: "persistent";
383
+ }>>;
384
+ secretAnswers: z.ZodBoolean;
385
+ concurrentRequests: z.ZodBoolean;
386
+ replay: z.ZodBoolean;
387
+ responseIdempotency: z.ZodBoolean;
388
+ }, z.core.$strict>>;
389
+ workspace: z.ZodObject<{
390
+ read: z.ZodBoolean;
391
+ write: z.ZodBoolean;
392
+ exec: z.ZodBoolean;
393
+ git: z.ZodBoolean;
394
+ upload: z.ZodBoolean;
395
+ download: z.ZodBoolean;
396
+ }, z.core.$strict>;
397
+ branching: z.ZodObject<{
398
+ checkpoint: z.ZodBoolean;
399
+ fork: z.ZodBoolean;
400
+ retrySafe: z.ZodOptional<z.ZodBoolean>;
401
+ lookup: z.ZodOptional<z.ZodBoolean>;
402
+ cleanup: z.ZodOptional<z.ZodBoolean>;
403
+ }, z.core.$strict>;
404
+ placement: z.ZodBoolean;
405
+ usage: z.ZodBoolean;
406
+ confidential: z.ZodBoolean;
407
+ exactProcess: z.ZodOptional<z.ZodObject<{
408
+ egress: z.ZodArray<z.ZodEnum<{
409
+ blocked: "blocked";
410
+ strict: "strict";
411
+ }>>;
412
+ }, z.core.$strict>>;
413
+ }, z.core.$strict>;
296
414
  export interface CreateAgentEnvironmentInput {
297
415
  profile: AgentProfileRef;
298
416
  /** Agent backend inside the provider, for example "opencode" or "codex". */
@@ -1 +1,102 @@
1
- export {};
1
+ import { z } from "zod";
2
+ import { InteractionCapabilitiesSchema, } from "./interaction.js";
3
+ /*
4
+ * Keep the provider contract runtime-validatable. Provider capability data is
5
+ * commonly read from a remote service or adapter configuration, so its static
6
+ * TypeScript type is not a trust boundary.
7
+ */
8
+ const AgentProfileCapabilitiesSchema = z.strictObject({
9
+ namedProfiles: z.boolean(),
10
+ systemPrompt: z.boolean(),
11
+ instructions: z.boolean(),
12
+ tools: z.boolean(),
13
+ permissions: z.boolean(),
14
+ mcp: z.boolean(),
15
+ subagents: z.boolean(),
16
+ resources: z.strictObject({
17
+ files: z.boolean(),
18
+ instructions: z.boolean(),
19
+ tools: z.boolean().optional(),
20
+ skills: z.boolean().optional(),
21
+ agents: z.boolean().optional(),
22
+ commands: z.boolean().optional(),
23
+ }),
24
+ hooks: z.boolean().optional(),
25
+ modes: z.boolean().optional(),
26
+ runtimeUpdate: z.boolean(),
27
+ validation: z.boolean(),
28
+ extensions: z.array(z.string().min(1)).optional(),
29
+ });
30
+ /** Strict runtime validator for provider capability negotiation. */
31
+ export const AgentEnvironmentCapabilitiesSchema = z
32
+ .strictObject({
33
+ profile: AgentProfileCapabilitiesSchema,
34
+ streaming: z.strictObject({
35
+ live: z.boolean(),
36
+ replay: z.boolean(),
37
+ detach: z.boolean(),
38
+ turnIdempotency: z.boolean(),
39
+ }),
40
+ sessions: z.strictObject({
41
+ continue: z.boolean(),
42
+ list: z.boolean(),
43
+ messages: z.boolean(),
44
+ }),
45
+ interactions: InteractionCapabilitiesSchema.optional(),
46
+ workspace: z.strictObject({
47
+ read: z.boolean(),
48
+ write: z.boolean(),
49
+ exec: z.boolean(),
50
+ git: z.boolean(),
51
+ upload: z.boolean(),
52
+ download: z.boolean(),
53
+ }),
54
+ branching: z.strictObject({
55
+ checkpoint: z.boolean(),
56
+ fork: z.boolean(),
57
+ retrySafe: z.boolean().optional(),
58
+ lookup: z.boolean().optional(),
59
+ cleanup: z.boolean().optional(),
60
+ }),
61
+ placement: z.boolean(),
62
+ usage: z.boolean(),
63
+ confidential: z.boolean(),
64
+ exactProcess: z
65
+ .strictObject({
66
+ egress: z.array(z.enum(["blocked", "strict"])).min(1),
67
+ })
68
+ .optional(),
69
+ })
70
+ .superRefine((capabilities, refinement) => {
71
+ const durableBranching = [
72
+ capabilities.branching.retrySafe ?? false,
73
+ capabilities.branching.lookup ?? false,
74
+ capabilities.branching.cleanup ?? false,
75
+ ];
76
+ if (durableBranching.some(Boolean) &&
77
+ (!durableBranching.every(Boolean) ||
78
+ !capabilities.branching.checkpoint ||
79
+ !capabilities.branching.fork)) {
80
+ refinement.addIssue({
81
+ code: "custom",
82
+ path: ["branching"],
83
+ message: "retry-safe branching requires checkpoint, fork, lookup, and cleanup together",
84
+ });
85
+ }
86
+ const egress = capabilities.exactProcess?.egress;
87
+ if (egress && new Set(egress).size !== egress.length) {
88
+ refinement.addIssue({
89
+ code: "custom",
90
+ path: ["exactProcess", "egress"],
91
+ message: "exact process egress modes must be unique",
92
+ });
93
+ }
94
+ const extensions = capabilities.profile.extensions;
95
+ if (extensions && new Set(extensions).size !== extensions.length) {
96
+ refinement.addIssue({
97
+ code: "custom",
98
+ path: ["profile", "extensions"],
99
+ message: "profile extension namespaces must be unique",
100
+ });
101
+ }
102
+ });
package/dist/harness.d.ts CHANGED
@@ -14,8 +14,10 @@ import { z } from "zod";
14
14
  * a one-shot) with no full coding-agent harness. The rest are full agentic harnesses run in a
15
15
  * sandbox or locally via the CLI bridge.
16
16
  *
17
+ * `forge` (tailcallhq/forgecode) and `cursor` (cursor-agent) are multi-provider CLI harnesses with
18
+ * no vendor lock, so they carry no entry in the capability tables and resolve as router-backed.
17
19
  */
18
- export type HarnessType = "claude-code" | "nanoclaw" | "codex" | "opencode" | "kimi-code" | "pi" | "gemini" | "hermes" | "openclaw" | "amp" | "factory-droids" | "acp" | "cli-base";
20
+ export type HarnessType = "claude-code" | "nanoclaw" | "codex" | "opencode" | "kimi-code" | "pi" | "gemini" | "hermes" | "openclaw" | "amp" | "factory-droids" | "forge" | "cursor" | "acp" | "cli-base";
19
21
  /** Runtime validator for {@link HarnessType}. Kept in lockstep with the type by the drift guard below. */
20
22
  export declare const harnessTypeSchema: z.ZodEnum<{
21
23
  "claude-code": "claude-code";
@@ -29,6 +31,8 @@ export declare const harnessTypeSchema: z.ZodEnum<{
29
31
  openclaw: "openclaw";
30
32
  amp: "amp";
31
33
  "factory-droids": "factory-droids";
34
+ forge: "forge";
35
+ cursor: "cursor";
32
36
  acp: "acp";
33
37
  "cli-base": "cli-base";
34
38
  }>;
package/dist/harness.js CHANGED
@@ -12,6 +12,8 @@ export const harnessTypeSchema = z.enum([
12
12
  "openclaw",
13
13
  "amp",
14
14
  "factory-droids",
15
+ "forge",
16
+ "cursor",
15
17
  "acp",
16
18
  "cli-base",
17
19
  ]);
package/dist/index.d.ts CHANGED
@@ -4,10 +4,14 @@
4
4
  * Shared types and interfaces for SDK provider adapters.
5
5
  * This package defines the contract between the sidecar and provider implementations.
6
6
  */
7
- import type { InteractionRequest, InteractionResponse } from "./interaction.js";
7
+ import type { InteractionAcknowledgement, InteractionRequest, InteractionResponse, InteractionResponseCommand } from "./interaction.js";
8
8
  import type { AgentExecutionOutcome, DurablePlan, PlanContinuation, SdkPlanHost } from "./plan.js";
9
9
  export type * from "./environment-provider.js";
10
+ export { AgentEnvironmentCapabilitiesSchema } from "./environment-provider.js";
10
11
  export * from "./plan.js";
12
+ export * from "./runtime-control.js";
13
+ export * from "./portable-context.js";
14
+ export * from "./workspace-branching.js";
11
15
  export type BackendCapabilities = {
12
16
  streaming: boolean;
13
17
  toolUse: boolean;
@@ -605,10 +609,16 @@ export interface SdkProviderAdapter {
605
609
  downloadArtifact?(sessionId: string, path: string): Promise<Uint8Array>;
606
610
  /**
607
611
  * Respond to an outstanding interaction (question, permission, …). The
608
- * generalized inbound channel; the adapter translates the response into the
609
- * provider's native control call to unblock the agent.
612
+ * original best-effort inbound channel. Kept source-compatible for existing
613
+ * adapters; durable callers should use `respondToInteractionCommand`.
610
614
  */
611
615
  respondToInteraction?(response: InteractionResponse): Promise<void>;
616
+ /**
617
+ * Retry-safe interaction response bound to an exact run and caller operation.
618
+ */
619
+ respondToInteractionCommand?(command: InteractionResponseCommand, options?: {
620
+ signal?: AbortSignal;
621
+ }): Promise<InteractionAcknowledgement>;
612
622
  }
613
623
  export * from "./interaction.js";
614
624
  export * from "./agent-candidate.js";
@@ -623,6 +633,7 @@ export * from "./agent-profile-improvement.js";
623
633
  export * from "./agent-profile-improvement-schema.js";
624
634
  export * from "./agent-execution-limits.js";
625
635
  export * from "./agent-profile.js";
636
+ export * from "./agent-profile-snapshot.js";
626
637
  export * from "./agent-profile-activation.js";
627
638
  export * from "./agent-profile-materialization.js";
628
639
  export * from "./agent-execution-preparation.js";
package/dist/index.js CHANGED
@@ -4,7 +4,11 @@
4
4
  * Shared types and interfaces for SDK provider adapters.
5
5
  * This package defines the contract between the sidecar and provider implementations.
6
6
  */
7
+ export { AgentEnvironmentCapabilitiesSchema } from "./environment-provider.js";
7
8
  export * from "./plan.js";
9
+ export * from "./runtime-control.js";
10
+ export * from "./portable-context.js";
11
+ export * from "./workspace-branching.js";
8
12
  /** Helper to check part type */
9
13
  export function isTextPart(part) {
10
14
  return part.type === "text";
@@ -135,6 +139,7 @@ export * from "./agent-profile-improvement.js";
135
139
  export * from "./agent-profile-improvement-schema.js";
136
140
  export * from "./agent-execution-limits.js";
137
141
  export * from "./agent-profile.js";
142
+ export * from "./agent-profile-snapshot.js";
138
143
  export * from "./agent-profile-activation.js";
139
144
  export * from "./agent-profile-materialization.js";
140
145
  export * from "./agent-execution-preparation.js";