@tangle-network/agent-interface 1.0.1 → 1.1.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.
package/README.md CHANGED
@@ -1,10 +1,34 @@
1
1
  # @tangle-network/agent-interface
2
2
 
3
- Shared TypeScript types and zod schemas that define the contract between Tangle
3
+ Shared TypeScript types and Zod schemas that define the contract between Tangle
4
4
  agents, the sidecar, and provider adapters: capabilities, agent profiles,
5
5
  message parts, and harness descriptors. This is the canonical home for those
6
6
  shapes; higher-level packages import from here rather than redefining them.
7
7
 
8
+ ## Agent instances
9
+
10
+ `AgentProfile` describes behavior. `AgentInstanceSpec` describes one optional managed Agent inside an existing execution environment. The environment remains the computer and security boundary, so it may host zero, one, or many Agent instances.
11
+
12
+ ```ts
13
+ import type { AgentInstanceSpec } from "@tangle-network/agent-interface/agent-instance";
14
+
15
+ const planner = {
16
+ id: "planner",
17
+ profile: {
18
+ name: "planner",
19
+ harness: "opencode",
20
+ prompt: { systemPrompt: "Plan before editing." },
21
+ },
22
+ workspace: { mode: "shared" },
23
+ } satisfies AgentInstanceSpec;
24
+ ```
25
+
26
+ The portable contract owns only inline profile and harness selection, shared or isolated workspace intent, public lifecycle state, a provider-sanitized failure summary, and idempotent stop shapes. Credentials, HTTP routes, process identifiers, placement, billing, snapshots, local resource controls, grants, and fencing remain provider-private.
27
+
28
+ `shared` means ordinary same-computer file visibility. It is not automatic merge behavior or tenant isolation. `isolated` asks the provider for a private writable view and explicit inspect or commit behavior. Providers must reject unsatisfied machine requirements rather than silently replacing or migrating a live environment.
29
+
30
+ The public `AgentInstanceRecord` contains a credential-free profile identity, not the full profile or provider request. Existing session APIs can implement this contract without a new service: one instance maps to one managed session, compatible sessions may reuse a backend process, and stop maps to idempotent session deletion or process release.
31
+
8
32
  ## Durable runs, interactions, and context
9
33
 
10
34
  `AgentRunControlRef` identifies a retained run without depending on a live JavaScript object and may carry the provider's admission digest so reconstruction can reject changed-input reuse.
@@ -66,8 +90,6 @@ Omitting `interactions` and `nativeContinuation`, or leaving the three durable b
66
90
  `replace` means the provider deletes the harness's own system prompt and installs `prompt.systemPrompt`; `append` means it keeps that prompt and adds `prompt.appendSystemPrompt` to it.
67
91
  A provider that can only append must declare `replace: false` and refuse a profile carrying `systemPrompt`, because quietly appending a requested replacement leaves the instructions the caller asked to delete in force.
68
92
 
69
-
70
-
71
93
  ## Install
72
94
 
73
95
  ```bash
@@ -0,0 +1,98 @@
1
+ import { z } from "zod";
2
+ import type { Sha256Digest } from "./agent-candidate.js";
3
+ import type { AgentProfile } from "./agent-profile.js";
4
+ import type { HarnessType } from "./harness.js";
5
+ /** Lifecycle state of one managed Agent inside an execution environment. */
6
+ export declare const AGENT_INSTANCE_STATUSES: readonly ["starting", "ready", "busy", "failed", "stopped"];
7
+ export type AgentInstanceStatus = (typeof AGENT_INSTANCE_STATUSES)[number];
8
+ /**
9
+ * How one Agent sees the provider-owned workspace.
10
+ *
11
+ * `shared` is ordinary same-computer visibility. `isolated` requests a private
12
+ * writable view with provider-defined inspect or commit behavior. Neither mode
13
+ * is a security boundary between mutually untrusted Agents.
14
+ */
15
+ export declare const AGENT_INSTANCE_WORKSPACE_MODES: readonly ["shared", "isolated"];
16
+ export type AgentInstanceWorkspaceMode = (typeof AGENT_INSTANCE_WORKSPACE_MODES)[number];
17
+ export interface AgentInstanceWorkspace {
18
+ mode: AgentInstanceWorkspaceMode;
19
+ }
20
+ /**
21
+ * Provider-neutral request to start one managed Agent inside an existing
22
+ * execution environment.
23
+ *
24
+ * Omitting `profile` asks the provider for its default Agent configuration.
25
+ * Omitting `workspace` selects the provider's documented default. A profile
26
+ * never implies another VM.
27
+ */
28
+ export interface AgentInstanceSpec {
29
+ /** Stable caller-selected id or idempotency key, when supported. */
30
+ id?: string;
31
+ /** Human-readable label; not immutable identity. */
32
+ name?: string;
33
+ /** Exact portable profile for this Agent. */
34
+ profile?: AgentProfile;
35
+ /** Optional execution override; otherwise the profile or provider decides. */
36
+ harness?: HarnessType;
37
+ workspace?: AgentInstanceWorkspace;
38
+ }
39
+ /** Credential-free identity of the profile bound to an Agent instance. */
40
+ export interface AgentInstanceProfileIdentity {
41
+ name?: string;
42
+ digest: Sha256Digest;
43
+ }
44
+ /**
45
+ * Public failure summary. Providers must remove credentials and private
46
+ * implementation details before publishing this value.
47
+ */
48
+ export interface AgentInstanceFailure {
49
+ code?: string;
50
+ message: string;
51
+ }
52
+ /**
53
+ * Portable snapshot of one managed Agent.
54
+ *
55
+ * The record deliberately excludes the full profile, provider request,
56
+ * credentials, grants, process ids, placement, and fencing state.
57
+ */
58
+ export interface AgentInstanceRecord {
59
+ kind: "agent-instance";
60
+ schemaVersion: 1;
61
+ id: string;
62
+ name?: string;
63
+ profile?: AgentInstanceProfileIdentity;
64
+ /** Effective harness after profile and caller override resolution. */
65
+ harness?: HarnessType;
66
+ workspace: AgentInstanceWorkspace;
67
+ status: AgentInstanceStatus;
68
+ failure?: AgentInstanceFailure;
69
+ createdAtMs: number;
70
+ updatedAtMs: number;
71
+ }
72
+ export interface AgentInstanceStopRequest {
73
+ agentId: string;
74
+ /** Provider-defined hard termination after graceful stop cannot complete. */
75
+ force?: boolean;
76
+ }
77
+ export interface AgentInstanceStopAcknowledgement {
78
+ agentId: string;
79
+ outcome: "stopped" | "already-stopped" | "not-found";
80
+ }
81
+ export declare const agentInstanceStatusSchema: z.ZodEnum<{
82
+ failed: "failed";
83
+ starting: "starting";
84
+ ready: "ready";
85
+ busy: "busy";
86
+ stopped: "stopped";
87
+ }>;
88
+ export declare const agentInstanceWorkspaceModeSchema: z.ZodEnum<{
89
+ isolated: "isolated";
90
+ shared: "shared";
91
+ }>;
92
+ export declare const agentInstanceWorkspaceSchema: z.ZodType<AgentInstanceWorkspace>;
93
+ export declare const agentInstanceSpecSchema: z.ZodType<AgentInstanceSpec>;
94
+ export declare const agentInstanceProfileIdentitySchema: z.ZodType<AgentInstanceProfileIdentity>;
95
+ export declare const agentInstanceFailureSchema: z.ZodType<AgentInstanceFailure>;
96
+ export declare const agentInstanceRecordSchema: z.ZodType<AgentInstanceRecord>;
97
+ export declare const agentInstanceStopRequestSchema: z.ZodType<AgentInstanceStopRequest>;
98
+ export declare const agentInstanceStopAcknowledgementSchema: z.ZodType<AgentInstanceStopAcknowledgement>;
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ import { isWellFormedUnicode, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
3
+ import { harnessTypeSchema } from "./harness.js";
4
+ import { agentProfileSchema } from "./profile-schema.js";
5
+ /** Lifecycle state of one managed Agent inside an execution environment. */
6
+ export const AGENT_INSTANCE_STATUSES = [
7
+ "starting",
8
+ "ready",
9
+ "busy",
10
+ "failed",
11
+ "stopped",
12
+ ];
13
+ /**
14
+ * How one Agent sees the provider-owned workspace.
15
+ *
16
+ * `shared` is ordinary same-computer visibility. `isolated` requests a private
17
+ * writable view with provider-defined inspect or commit behavior. Neither mode
18
+ * is a security boundary between mutually untrusted Agents.
19
+ */
20
+ export const AGENT_INSTANCE_WORKSPACE_MODES = ["shared", "isolated"];
21
+ const identifierSchema = z
22
+ .string()
23
+ .min(1)
24
+ .max(128)
25
+ .regex(/^[A-Za-z0-9](?:[A-Za-z0-9._:-]*[A-Za-z0-9])?$/, "identifier must use visible alphanumeric, '.', '_', ':', or '-' characters");
26
+ const labelSchema = z
27
+ .string()
28
+ .min(1)
29
+ .max(256)
30
+ .refine((value) => isWellFormedUnicode(value) && !/[\u0000-\u001f\u007f]/u.test(value), "label must be valid Unicode without control characters");
31
+ const failureMessageSchema = z
32
+ .string()
33
+ .min(1)
34
+ .max(16_384)
35
+ .refine((value) => isWellFormedUnicode(value) && !value.includes("\0"), "failure message must be valid Unicode without NUL");
36
+ const timestampSchema = z
37
+ .number()
38
+ .int()
39
+ .nonnegative()
40
+ .max(Number.MAX_SAFE_INTEGER);
41
+ export const agentInstanceStatusSchema = z.enum(AGENT_INSTANCE_STATUSES);
42
+ export const agentInstanceWorkspaceModeSchema = z.enum(AGENT_INSTANCE_WORKSPACE_MODES);
43
+ export const agentInstanceWorkspaceSchema = z.strictObject({
44
+ mode: agentInstanceWorkspaceModeSchema,
45
+ });
46
+ export const agentInstanceSpecSchema = z.strictObject({
47
+ id: identifierSchema.optional(),
48
+ name: labelSchema.optional(),
49
+ profile: agentProfileSchema.optional(),
50
+ harness: harnessTypeSchema.optional(),
51
+ workspace: agentInstanceWorkspaceSchema.optional(),
52
+ });
53
+ export const agentInstanceProfileIdentitySchema = z.strictObject({
54
+ name: labelSchema.optional(),
55
+ digest: sha256DigestSchema,
56
+ });
57
+ export const agentInstanceFailureSchema = z.strictObject({
58
+ code: identifierSchema.optional(),
59
+ message: failureMessageSchema,
60
+ });
61
+ export const agentInstanceRecordSchema = z
62
+ .strictObject({
63
+ kind: z.literal("agent-instance"),
64
+ schemaVersion: z.literal(1),
65
+ id: identifierSchema,
66
+ name: labelSchema.optional(),
67
+ profile: agentInstanceProfileIdentitySchema.optional(),
68
+ harness: harnessTypeSchema.optional(),
69
+ workspace: agentInstanceWorkspaceSchema,
70
+ status: agentInstanceStatusSchema,
71
+ failure: agentInstanceFailureSchema.optional(),
72
+ createdAtMs: timestampSchema,
73
+ updatedAtMs: timestampSchema,
74
+ })
75
+ .superRefine((record, context) => {
76
+ if (record.updatedAtMs < record.createdAtMs) {
77
+ context.addIssue({
78
+ code: "custom",
79
+ path: ["updatedAtMs"],
80
+ message: "agent instance update cannot precede creation",
81
+ });
82
+ }
83
+ if (record.status === "failed" && record.failure === undefined) {
84
+ context.addIssue({
85
+ code: "custom",
86
+ path: ["failure"],
87
+ message: "failed agent instance requires a failure reason",
88
+ });
89
+ }
90
+ if (record.status !== "failed" && record.failure !== undefined) {
91
+ context.addIssue({
92
+ code: "custom",
93
+ path: ["failure"],
94
+ message: "failure reason is valid only for failed agent instances",
95
+ });
96
+ }
97
+ });
98
+ export const agentInstanceStopRequestSchema = z.strictObject({
99
+ agentId: identifierSchema,
100
+ force: z.boolean().optional(),
101
+ });
102
+ export const agentInstanceStopAcknowledgementSchema = z.strictObject({
103
+ agentId: identifierSchema,
104
+ outcome: z.enum(["stopped", "already-stopped", "not-found"]),
105
+ });
@@ -1050,8 +1050,8 @@ export declare const AgentInteractiveSessionStatusSchema: z.ZodDiscriminatedUnio
1050
1050
  }, z.core.$strict>;
1051
1051
  endedAt: z.ZodISODateTime;
1052
1052
  reason: z.ZodEnum<{
1053
- exited: "exited";
1054
1053
  stopped: "stopped";
1054
+ exited: "exited";
1055
1055
  lost: "lost";
1056
1056
  }>;
1057
1057
  exitCode: z.ZodOptional<z.ZodNumber>;
@@ -1541,8 +1541,8 @@ export declare const AgentInteractiveSessionStopAcknowledgementSchema: z.ZodObje
1541
1541
  }>;
1542
1542
  effect: z.ZodEnum<{
1543
1543
  unknown: "unknown";
1544
- not_live: "not_live";
1545
1544
  stopped: "stopped";
1545
+ not_live: "not_live";
1546
1546
  stop_requested: "stop_requested";
1547
1547
  }>;
1548
1548
  message: z.ZodOptional<z.ZodString>;
@@ -105,9 +105,9 @@ export declare const AgentEnvironmentStatusSchema: z.ZodEnum<{
105
105
  unknown: "unknown";
106
106
  failed: "failed";
107
107
  expired: "expired";
108
+ stopped: "stopped";
108
109
  pending: "pending";
109
110
  running: "running";
110
- stopped: "stopped";
111
111
  provisioning: "provisioning";
112
112
  }>;
113
113
  /** Lifecycle, cleanup, continuity, and persistence of one environment. */
@@ -116,9 +116,9 @@ export declare const EnvironmentLifecycleSchema: z.ZodObject<{
116
116
  unknown: "unknown";
117
117
  failed: "failed";
118
118
  expired: "expired";
119
+ stopped: "stopped";
119
120
  pending: "pending";
120
121
  running: "running";
121
- stopped: "stopped";
122
122
  provisioning: "provisioning";
123
123
  }>;
124
124
  cleanup: z.ZodOptional<z.ZodObject<{
@@ -441,9 +441,9 @@ export declare const AgentEnvironmentObservationSchema: z.ZodObject<{
441
441
  unknown: "unknown";
442
442
  failed: "failed";
443
443
  expired: "expired";
444
+ stopped: "stopped";
444
445
  pending: "pending";
445
446
  running: "running";
446
- stopped: "stopped";
447
447
  provisioning: "provisioning";
448
448
  }>;
449
449
  cleanup: z.ZodOptional<z.ZodObject<{
@@ -489,9 +489,9 @@ export declare const AgentEnvironmentObservationSchema: z.ZodObject<{
489
489
  unknown: "unknown";
490
490
  failed: "failed";
491
491
  expired: "expired";
492
+ stopped: "stopped";
492
493
  pending: "pending";
493
494
  running: "running";
494
- stopped: "stopped";
495
495
  provisioning: "provisioning";
496
496
  }>;
497
497
  cleanup: z.ZodOptional<z.ZodObject<{
package/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@ export * from "./agent-profile-improvement.js";
26
26
  export * from "./agent-profile-improvement-schema.js";
27
27
  export * from "./agent-execution-limits.js";
28
28
  export * from "./agent-profile.js";
29
+ export * from "./agent-instance.js";
29
30
  export * from "./agent-profile-snapshot.js";
30
31
  export * from "./agent-profile-activation.js";
31
32
  export * from "./agent-profile-materialization.js";
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ export * from "./agent-profile-improvement.js";
24
24
  export * from "./agent-profile-improvement-schema.js";
25
25
  export * from "./agent-execution-limits.js";
26
26
  export * from "./agent-profile.js";
27
+ export * from "./agent-instance.js";
27
28
  export * from "./agent-profile-snapshot.js";
28
29
  export * from "./agent-profile-activation.js";
29
30
  export * from "./agent-profile-materialization.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -22,6 +22,11 @@
22
22
  "types": "./dist/agent-profile.d.ts",
23
23
  "default": "./dist/agent-profile.js"
24
24
  },
25
+ "./agent-instance": {
26
+ "import": "./dist/agent-instance.js",
27
+ "types": "./dist/agent-instance.d.ts",
28
+ "default": "./dist/agent-instance.js"
29
+ },
25
30
  "./profile-snapshot": {
26
31
  "import": "./dist/agent-profile-snapshot.js",
27
32
  "types": "./dist/agent-profile-snapshot.d.ts",