@adobe/data 0.9.29 → 0.9.30

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,22 +1,24 @@
1
1
  import { Observe } from "../../observe/index.js";
2
2
  import { Schema } from "../../schema/index.js";
3
3
  import { AgenticService } from "./agentic-service.js";
4
- import type { AgenticServiceLinks } from "./agentic-service-links.js";
5
- /** State declaration: has top-level `type` (JSON Schema) + `description` */
6
- type StateDeclaration<S extends Schema & {
7
- type: string;
8
- } = Schema & {
9
- type: string;
10
- }> = S & {
4
+ /** State declaration: kind + schema for value + description */
5
+ type StateDeclaration<S extends Schema = Schema> = {
6
+ type: "state";
7
+ schema: S;
11
8
  description: string;
12
9
  };
13
- /** Action declaration: `description`, optional `input` schema, no `type` */
10
+ /** Action declaration: kind + description + optional input schema */
14
11
  type ActionDeclaration<I extends Schema | false | undefined = undefined> = {
12
+ type: "action";
15
13
  description: string;
16
14
  input?: I;
17
- type?: never;
18
15
  };
19
- type DeclarationEntry = StateDeclaration | ActionDeclaration<Schema | false | undefined>;
16
+ /** Link declaration: kind + optional description */
17
+ type LinkDeclaration = {
18
+ type: "link";
19
+ description?: string;
20
+ };
21
+ type DeclarationEntry = StateDeclaration | ActionDeclaration<Schema | false | undefined> | LinkDeclaration;
20
22
  type Declarations = Record<string, DeclarationEntry>;
21
23
  type ConditionalFromDeclarations<D extends Declarations> = Partial<{
22
24
  [K in keyof D]: Observe<boolean>;
@@ -24,25 +26,29 @@ type ConditionalFromDeclarations<D extends Declarations> = Partial<{
24
26
  /**
25
27
  * Creates an AgenticService from a config with interface, implementation, and optional conditional.
26
28
  *
27
- * Interface: flat map of states (have `type`) and actions (have `description`, optional `input`).
28
- * Implementation: same keys, states Observe<...>, actions (input?) => ...
29
- * Conditional: optional per-key Observe<boolean> for enablement.
29
+ * Interface: flat map of declarations. Each entry has type "state" | "action" | "link":
30
+ * - state: { type: "state", schema, description }implementation: Observe<value>
31
+ * - action: { type: "action", description, input? } → implementation: (input?) => ...
32
+ * - link: { type: "link", description? } → implementation: AgenticService | Observe<AgenticService>
33
+ * Conditional: optional per-key Observe<boolean> for enablement (applies to states, actions, and links).
30
34
  */
31
35
  export declare function create<const D extends Declarations>(config: {
32
36
  description: string;
33
37
  interface: D;
34
38
  implementation: ImplementationFromDeclarations<D>;
35
39
  conditional?: ConditionalFromDeclarations<D>;
36
- /** Optional map of links to other agentic services; fixed Record or Observe for conditional links. */
37
- links?: AgenticServiceLinks | Observe<AgenticServiceLinks>;
38
40
  }): AgenticService;
39
- /** Implementation map derived from interface: states → Observe, actions → execute fn */
41
+ /** Implementation map derived from interface: state → Observe, action → execute fn, link → AgenticService | Observe<AgenticService> */
40
42
  export type ImplementationFromDeclarations<D extends Declarations> = {
41
43
  [K in keyof D]: D[K] extends {
42
- type: string;
43
- } ? Observe<Schema.ToType<D[K]>> : D[K] extends {
44
- input: infer I extends Schema | false;
45
- } ? ExecuteFromSchema<I> : ExecuteFromSchema<false>;
44
+ type: "state";
45
+ schema: infer S extends Schema;
46
+ } ? Observe<Schema.ToType<S>> : D[K] extends {
47
+ type: "action";
48
+ input?: infer I extends Schema | false | undefined;
49
+ } ? ExecuteFromSchema<I extends undefined ? false : I> : D[K] extends {
50
+ type: "link";
51
+ } ? AgenticService | Observe<AgenticService> : never;
46
52
  };
47
53
  type ExecuteFromSchema<S extends Schema | false> = S extends false ? (() => Promise<void | AgenticService.ActionError> | void) : ((input: Schema.ToType<S>) => Promise<void | AgenticService.ActionError> | void);
48
54
  export {};
@@ -1,42 +1,41 @@
1
1
  // © 2026 Adobe. MIT License. See /LICENSE for details.
2
2
  import { Observe } from "../../observe/index.js";
3
- function isStateDeclaration(entry) {
4
- return "type" in entry && typeof entry.type === "string";
5
- }
6
3
  function getActionSchema(entry) {
7
- if (isStateDeclaration(entry))
8
- return false;
9
- const actionEntry = entry;
10
- return actionEntry.input ?? false;
4
+ return entry.input ?? false;
11
5
  }
12
6
  /**
13
7
  * Creates an AgenticService from a config with interface, implementation, and optional conditional.
14
8
  *
15
- * Interface: flat map of states (have `type`) and actions (have `description`, optional `input`).
16
- * Implementation: same keys, states Observe<...>, actions (input?) => ...
17
- * Conditional: optional per-key Observe<boolean> for enablement.
9
+ * Interface: flat map of declarations. Each entry has type "state" | "action" | "link":
10
+ * - state: { type: "state", schema, description }implementation: Observe<value>
11
+ * - action: { type: "action", description, input? } → implementation: (input?) => ...
12
+ * - link: { type: "link", description? } → implementation: AgenticService | Observe<AgenticService>
13
+ * Conditional: optional per-key Observe<boolean> for enablement (applies to states, actions, and links).
18
14
  */
19
15
  export function create(config) {
20
- const { interface: iface, implementation, conditional, links: linksConfig } = config;
16
+ const { interface: iface, implementation, conditional } = config;
21
17
  const alwaysEnabled = Observe.fromConstant(true);
22
18
  const stateKeys = [];
23
19
  const actionKeys = [];
20
+ const linkKeys = [];
24
21
  const stateSchemas = {};
25
22
  const actionMeta = {};
26
23
  for (const [key, entry] of Object.entries(iface)) {
27
- if (isStateDeclaration(entry)) {
24
+ if (entry.type === "state") {
28
25
  stateKeys.push(key);
29
- stateSchemas[key] = entry;
26
+ stateSchemas[key] = entry.schema;
30
27
  }
31
- else {
28
+ else if (entry.type === "action") {
32
29
  actionKeys.push(key);
33
- const a = entry;
34
30
  actionMeta[key] = {
35
- description: a.description,
31
+ description: entry.description,
36
32
  schema: getActionSchema(entry),
37
33
  execute: implementation[key],
38
34
  };
39
35
  }
36
+ else if (entry.type === "link") {
37
+ linkKeys.push(key);
38
+ }
40
39
  }
41
40
  const perStateObservables = {};
42
41
  for (const key of stateKeys) {
@@ -51,6 +50,14 @@ export function create(config) {
51
50
  for (const key of actionKeys) {
52
51
  enabledObservables[key] = conditional?.[key] ?? alwaysEnabled;
53
52
  }
53
+ const implRecord = implementation;
54
+ const perLinkObservables = {};
55
+ for (const key of linkKeys) {
56
+ const raw = implRecord[key];
57
+ const linkObs = typeof raw === "function" ? raw : Observe.fromConstant(raw);
58
+ const enabledObs = conditional?.[key] ?? alwaysEnabled;
59
+ perLinkObservables[key] = Observe.withMap(Observe.fromProperties({ enabled: enabledObs, value: linkObs }), (x) => x);
60
+ }
54
61
  const states = Observe.withMap(Observe.fromProperties(perStateObservables), (raw) => {
55
62
  const result = {};
56
63
  for (const [key, entry] of Object.entries(raw)) {
@@ -80,10 +87,16 @@ export function create(config) {
80
87
  return `Action "${actionName}" is not available`;
81
88
  return entry.execute(input);
82
89
  };
83
- const links = linksConfig !== undefined
84
- ? typeof linksConfig === "function"
85
- ? linksConfig
86
- : Observe.fromConstant(linksConfig)
90
+ const links = linkKeys.length > 0
91
+ ? Observe.withMap(Observe.fromProperties(perLinkObservables), (raw) => {
92
+ const result = {};
93
+ for (const [key, entry] of Object.entries(raw)) {
94
+ const { enabled, value } = entry;
95
+ if (enabled && value)
96
+ result[key] = value;
97
+ }
98
+ return result;
99
+ })
87
100
  : undefined;
88
101
  return {
89
102
  serviceName: "agentic-service",
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/service/agentic-service/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/service/agentic-service/create.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ describe("AgenticService.create", () => {
19
19
  create({
20
20
  description: "Test",
21
21
  interface: {
22
- currentHealth: { type: "number", description: "Health" },
22
+ currentHealth: { type: "state", schema: { type: "number" }, description: "Health" },
23
23
  },
24
24
  implementation: {
25
25
  currentHealth: db.observe.resources.health,
@@ -32,7 +32,7 @@ describe("AgenticService.create", () => {
32
32
  create({
33
33
  description: "Test",
34
34
  interface: {
35
- playerName: { type: "string", description: "Name" },
35
+ playerName: { type: "state", schema: { type: "string" }, description: "Name" },
36
36
  },
37
37
  implementation: {
38
38
  playerName: db.observe.resources.name,
@@ -45,8 +45,8 @@ describe("AgenticService.create", () => {
45
45
  create({
46
46
  description: "Test",
47
47
  interface: {
48
- currentHealth: { type: "number", description: "Health" },
49
- playerName: { type: "string", description: "Name" },
48
+ currentHealth: { type: "state", schema: { type: "number" }, description: "Health" },
49
+ playerName: { type: "state", schema: { type: "string" }, description: "Name" },
50
50
  },
51
51
  implementation: {
52
52
  currentHealth: db.observe.resources.health,
@@ -58,7 +58,7 @@ describe("AgenticService.create", () => {
58
58
  create({
59
59
  description: "Test",
60
60
  interface: {
61
- setHealth: { description: "Set health", input: { type: "number" } },
61
+ setHealth: { type: "action", description: "Set health", input: { type: "number" } },
62
62
  },
63
63
  implementation: {
64
64
  setHealth: async (_input) => { },
@@ -69,7 +69,7 @@ describe("AgenticService.create", () => {
69
69
  create({
70
70
  description: "Test",
71
71
  interface: {
72
- reset: { description: "Reset to defaults" },
72
+ reset: { type: "action", description: "Reset to defaults" },
73
73
  },
74
74
  implementation: {
75
75
  reset: async () => { },
@@ -81,14 +81,17 @@ describe("AgenticService.create", () => {
81
81
  description: "Test",
82
82
  interface: {
83
83
  stats: {
84
- type: "object",
85
- description: "Stats",
86
- properties: {
87
- hp: { type: "number" },
88
- label: { type: "string" },
84
+ type: "state",
85
+ schema: {
86
+ type: "object",
87
+ properties: {
88
+ hp: { type: "number" },
89
+ label: { type: "string" },
90
+ },
91
+ required: ["hp"],
92
+ additionalProperties: false,
89
93
  },
90
- required: ["hp"],
91
- additionalProperties: false,
94
+ description: "Stats",
92
95
  },
93
96
  },
94
97
  implementation: {
@@ -101,6 +104,7 @@ describe("AgenticService.create", () => {
101
104
  description: "Test",
102
105
  interface: {
103
106
  configure: {
107
+ type: "action",
104
108
  description: "Configure",
105
109
  input: {
106
110
  type: "object",
@@ -122,8 +126,8 @@ describe("AgenticService.create", () => {
122
126
  create({
123
127
  description: "Test",
124
128
  interface: {
125
- heal: { description: "Heal", input: { type: "number" } },
126
- reset: { description: "Reset" },
129
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
130
+ reset: { type: "action", description: "Reset" },
127
131
  },
128
132
  implementation: {
129
133
  heal: async (_amount) => { },
@@ -135,8 +139,8 @@ describe("AgenticService.create", () => {
135
139
  create({
136
140
  description: "Test",
137
141
  interface: {
138
- sync: { description: "Sync" },
139
- syncWithInput: { description: "Sync with input", input: { type: "number" } },
142
+ sync: { type: "action", description: "Sync" },
143
+ syncWithInput: { type: "action", description: "Sync with input", input: { type: "number" } },
140
144
  },
141
145
  implementation: {
142
146
  sync: () => { },
@@ -149,8 +153,8 @@ describe("AgenticService.create", () => {
149
153
  create({
150
154
  description: "Test",
151
155
  interface: {
152
- health: { type: "number", description: "Health" },
153
- heal: { description: "Heal", input: { type: "number" } },
156
+ health: { type: "state", schema: { type: "number" }, description: "Health" },
157
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
154
158
  },
155
159
  implementation: {
156
160
  health: db.observe.resources.health,
@@ -170,7 +174,7 @@ describe("AgenticService.create", () => {
170
174
  });
171
175
  });
172
176
  describe("links", () => {
173
- it("should expose links observable when links config is provided", () => {
177
+ it("should expose links observable when link is declared in interface", () => {
174
178
  const child = create({
175
179
  description: "Child",
176
180
  interface: {},
@@ -178,9 +182,8 @@ describe("AgenticService.create", () => {
178
182
  });
179
183
  const service = create({
180
184
  description: "Parent",
181
- interface: {},
182
- implementation: {},
183
- links: { child },
185
+ interface: { child: { type: "link", description: "Child service" } },
186
+ implementation: { child },
184
187
  });
185
188
  expect(service.links).toBeDefined();
186
189
  const received = [];
@@ -196,18 +199,16 @@ describe("AgenticService.create", () => {
196
199
  });
197
200
  expect(service.links).toBeUndefined();
198
201
  });
199
- it("should support Observe<AgenticServiceLinks> for conditional links", () => {
202
+ it("should support Observe<AgenticService> per link for dynamic link target", () => {
200
203
  const child = create({
201
204
  description: "Child",
202
205
  interface: {},
203
206
  implementation: {},
204
207
  });
205
- const linksObs = Observe.fromConstant({ child });
206
208
  const service = create({
207
209
  description: "Parent",
208
- interface: {},
209
- implementation: {},
210
- links: linksObs,
210
+ interface: { child: { type: "link" } },
211
+ implementation: { child: Observe.fromConstant(child) },
211
212
  });
212
213
  expect(service.links).toBeDefined();
213
214
  const received = [];
@@ -215,40 +216,55 @@ describe("AgenticService.create", () => {
215
216
  expect(received).toHaveLength(1);
216
217
  expect(received[0]).toEqual({ child });
217
218
  });
218
- it("should pass through Observe so links update when observable emits", () => {
219
+ it("should omit link when conditional is false", () => {
219
220
  const child = create({
220
221
  description: "Child",
221
222
  interface: {},
222
223
  implementation: {},
223
224
  });
224
- const [linksObs, setLinks] = Observe.createState({ child });
225
225
  const service = create({
226
226
  description: "Parent",
227
+ interface: { child: { type: "link" } },
228
+ implementation: { child },
229
+ conditional: { child: Observe.fromConstant(false) },
230
+ });
231
+ expect(service.links).toBeDefined();
232
+ const received = [];
233
+ service.links((l) => received.push({ ...l }));
234
+ expect(received).toHaveLength(1);
235
+ expect(received[0]).toEqual({});
236
+ });
237
+ it("should update links when conditional changes", () => {
238
+ const child = create({
239
+ description: "Child",
227
240
  interface: {},
228
241
  implementation: {},
229
- links: linksObs,
242
+ });
243
+ const [enabledObs, setEnabled] = Observe.createState(true);
244
+ const service = create({
245
+ description: "Parent",
246
+ interface: { child: { type: "link" } },
247
+ implementation: { child },
248
+ conditional: { child: enabledObs },
230
249
  });
231
250
  const received = [];
232
- const unobserve = service.links((l) => received.push({ ...l }));
251
+ service.links((l) => received.push({ ...l }));
233
252
  expect(received).toHaveLength(1);
234
253
  expect(received[0]).toEqual({ child });
235
- setLinks({});
254
+ setEnabled(false);
236
255
  expect(received).toHaveLength(2);
237
256
  expect(received[1]).toEqual({});
238
- unobserve();
257
+ setEnabled(true);
258
+ expect(received).toHaveLength(3);
259
+ expect(received[2]).toEqual({ child });
239
260
  });
240
- it("should support empty links record", () => {
261
+ it("should have links undefined when no link keys in interface", () => {
241
262
  const service = create({
242
263
  description: "Test",
243
264
  interface: {},
244
265
  implementation: {},
245
- links: {},
246
266
  });
247
- expect(service.links).toBeDefined();
248
- const received = [];
249
- service.links((l) => received.push({ ...l }));
250
- expect(received).toHaveLength(1);
251
- expect(received[0]).toEqual({});
267
+ expect(service.links).toBeUndefined();
252
268
  });
253
269
  });
254
270
  describe("conditional defaults", () => {
@@ -257,7 +273,7 @@ describe("AgenticService.create", () => {
257
273
  const service = create({
258
274
  description: "Test",
259
275
  interface: {
260
- health: { type: "number", description: "Health" },
276
+ health: { type: "state", schema: { type: "number" }, description: "Health" },
261
277
  },
262
278
  implementation: {
263
279
  health: db.observe.resources.health,
@@ -271,7 +287,7 @@ describe("AgenticService.create", () => {
271
287
  const service = create({
272
288
  description: "Test",
273
289
  interface: {
274
- heal: { description: "Heal", input: { type: "number" } },
290
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
275
291
  },
276
292
  implementation: {
277
293
  heal: async () => { },
@@ -287,7 +303,7 @@ describe("AgenticService.create", () => {
287
303
  const service = create({
288
304
  description: "Test",
289
305
  interface: {
290
- currentHealth: { type: "number", description: "Health" },
306
+ currentHealth: { type: "state", schema: { type: "number" }, description: "Health" },
291
307
  },
292
308
  implementation: {
293
309
  currentHealth: db.observe.resources.health,
@@ -295,7 +311,7 @@ describe("AgenticService.create", () => {
295
311
  });
296
312
  const states = await Observe.toPromise(service.states);
297
313
  expect(states).toHaveProperty("currentHealth");
298
- expect(states.currentHealth.schema).toEqual({ type: "number", description: "Health" });
314
+ expect(states.currentHealth.schema).toEqual({ type: "number" });
299
315
  expect(states.currentHealth.value).toBe(100);
300
316
  });
301
317
  it("should omit disabled states", async () => {
@@ -303,8 +319,8 @@ describe("AgenticService.create", () => {
303
319
  const service = create({
304
320
  description: "Test",
305
321
  interface: {
306
- visible: { type: "number", description: "Visible" },
307
- hidden: { type: "string", description: "Hidden" },
322
+ visible: { type: "state", schema: { type: "number" }, description: "Visible" },
323
+ hidden: { type: "state", schema: { type: "string" }, description: "Hidden" },
308
324
  },
309
325
  implementation: {
310
326
  visible: db.observe.resources.health,
@@ -325,7 +341,7 @@ describe("AgenticService.create", () => {
325
341
  const service = create({
326
342
  description: "Test",
327
343
  interface: {
328
- health: { type: "number", description: "Health" },
344
+ health: { type: "state", schema: { type: "number" }, description: "Health" },
329
345
  },
330
346
  implementation: {
331
347
  health: db.observe.resources.health,
@@ -345,7 +361,7 @@ describe("AgenticService.create", () => {
345
361
  const service = create({
346
362
  description: "Test",
347
363
  interface: {
348
- health: { type: "number", description: "Health" },
364
+ health: { type: "state", schema: { type: "number" }, description: "Health" },
349
365
  },
350
366
  implementation: {
351
367
  health: healthObserve,
@@ -363,7 +379,7 @@ describe("AgenticService.create", () => {
363
379
  const service = create({
364
380
  description: "Test",
365
381
  interface: {
366
- heal: { description: "Heal player", input: { type: "number" } },
382
+ heal: { type: "action", description: "Heal player", input: { type: "number" } },
367
383
  },
368
384
  implementation: {
369
385
  heal: async (_amount) => { },
@@ -379,8 +395,8 @@ describe("AgenticService.create", () => {
379
395
  const service = create({
380
396
  description: "Test",
381
397
  interface: {
382
- available: { description: "Available", input: { type: "number" } },
383
- unavailable: { description: "Unavailable" },
398
+ available: { type: "action", description: "Available", input: { type: "number" } },
399
+ unavailable: { type: "action", description: "Unavailable" },
384
400
  },
385
401
  implementation: {
386
402
  available: async () => { },
@@ -400,7 +416,7 @@ describe("AgenticService.create", () => {
400
416
  const service = create({
401
417
  description: "Test",
402
418
  interface: {
403
- heal: { description: "Heal", input: { type: "number" } },
419
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
404
420
  },
405
421
  implementation: {
406
422
  heal: async () => { },
@@ -420,7 +436,7 @@ describe("AgenticService.create", () => {
420
436
  const service = create({
421
437
  description: "Test",
422
438
  interface: {
423
- setHealth: { description: "Set health", input: { type: "number" } },
439
+ setHealth: { type: "action", description: "Set health", input: { type: "number" } },
424
440
  },
425
441
  implementation: {
426
442
  setHealth: async (input) => { received = input; },
@@ -435,7 +451,7 @@ describe("AgenticService.create", () => {
435
451
  const service = create({
436
452
  description: "Test",
437
453
  interface: {
438
- reset: { description: "Reset" },
454
+ reset: { type: "action", description: "Reset" },
439
455
  },
440
456
  implementation: {
441
457
  reset: async () => { called = true; },
@@ -449,7 +465,7 @@ describe("AgenticService.create", () => {
449
465
  const service = create({
450
466
  description: "Test",
451
467
  interface: {
452
- sync: { description: "Sync" },
468
+ sync: { type: "action", description: "Sync" },
453
469
  },
454
470
  implementation: {
455
471
  sync: () => { called = true; },
@@ -462,7 +478,7 @@ describe("AgenticService.create", () => {
462
478
  const service = create({
463
479
  description: "Test",
464
480
  interface: {
465
- heal: { description: "Heal", input: { type: "number" } },
481
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
466
482
  },
467
483
  implementation: {
468
484
  heal: async () => { },
@@ -485,7 +501,7 @@ describe("AgenticService.create", () => {
485
501
  const service = create({
486
502
  description: "Test",
487
503
  interface: {
488
- fail: { description: "Fail" },
504
+ fail: { type: "action", description: "Fail" },
489
505
  },
490
506
  implementation: {
491
507
  fail: async () => "something went wrong",
@@ -500,7 +516,7 @@ describe("AgenticService.create", () => {
500
516
  const service = create({
501
517
  description: "Test",
502
518
  interface: {
503
- heal: { description: "Heal", input: { type: "number" } },
519
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
504
520
  },
505
521
  implementation: {
506
522
  heal: async () => { called = true; },
@@ -525,8 +541,8 @@ describe("AgenticService.create", () => {
525
541
  const service = create({
526
542
  description: "Test",
527
543
  interface: {
528
- health: { type: "number", description: "Health" },
529
- name: { type: "string", description: "Name" },
544
+ health: { type: "state", schema: { type: "number" }, description: "Health" },
545
+ name: { type: "state", schema: { type: "string" }, description: "Name" },
530
546
  },
531
547
  implementation: {
532
548
  health: db.observe.resources.health,
@@ -552,8 +568,8 @@ describe("AgenticService.create", () => {
552
568
  const service = create({
553
569
  description: "Test",
554
570
  interface: {
555
- heal: { description: "Heal", input: { type: "number" } },
556
- reset: { description: "Reset" },
571
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
572
+ reset: { type: "action", description: "Reset" },
557
573
  },
558
574
  implementation: {
559
575
  heal: async () => { },
@@ -580,7 +596,7 @@ describe("AgenticService.create", () => {
580
596
  const service = create({
581
597
  description: "Test",
582
598
  interface: {
583
- heal: { description: "Heal", input: { type: "number" } },
599
+ heal: { type: "action", description: "Heal", input: { type: "number" } },
584
600
  },
585
601
  implementation: {
586
602
  heal: async (input) => { received = input; },
@@ -595,7 +611,7 @@ describe("AgenticService.create", () => {
595
611
  const service = create({
596
612
  description: "Test",
597
613
  interface: {
598
- reset: { description: "Reset" },
614
+ reset: { type: "action", description: "Reset" },
599
615
  },
600
616
  implementation: {
601
617
  reset: async () => { called = true; },
@@ -609,7 +625,7 @@ describe("AgenticService.create", () => {
609
625
  const service = create({
610
626
  description: "Test",
611
627
  interface: {
612
- fail: { description: "Fail" },
628
+ fail: { type: "action", description: "Fail" },
613
629
  },
614
630
  implementation: {
615
631
  fail: async () => "bound error",