@adobe/data 0.9.28 → 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.
- package/dist/service/agentic-service/agentic-service-links.d.ts +5 -0
- package/dist/service/agentic-service/agentic-service-links.js +3 -0
- package/dist/service/agentic-service/agentic-service-links.js.map +1 -0
- package/dist/service/agentic-service/agentic-service.d.ts +6 -3
- package/dist/service/agentic-service/agentic-service.js.map +1 -1
- package/dist/service/agentic-service/create.d.ts +26 -17
- package/dist/service/agentic-service/create.js +40 -16
- package/dist/service/agentic-service/create.js.map +1 -1
- package/dist/service/agentic-service/create.test.js +142 -44
- package/dist/service/agentic-service/create.test.js.map +1 -1
- package/dist/service/agentic-service/create.type-test.js +32 -10
- package/dist/service/agentic-service/create.type-test.js.map +1 -1
- package/dist/service/agentic-service/link.d.ts +15 -0
- package/dist/service/agentic-service/link.js +3 -0
- package/dist/service/agentic-service/link.js.map +1 -0
- package/dist/service/agentic-service/public.d.ts +1 -0
- package/dist/service/agentic-service/public.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentic-service-links.js","sourceRoot":"","sources":["../../../src/service/agentic-service/agentic-service-links.ts"],"names":[],"mappings":"AAAA,uDAAuD"}
|
|
@@ -2,15 +2,16 @@ import { Observe } from "../../observe/index.js";
|
|
|
2
2
|
import type { Service } from "../index.js";
|
|
3
3
|
import type { Action } from "./action.js";
|
|
4
4
|
import type { ActionError } from "./action-error.js";
|
|
5
|
+
import type { AgenticServiceLinks } from "./agentic-service-links.js";
|
|
5
6
|
import type { State } from "./state.js";
|
|
6
7
|
/**
|
|
7
8
|
* An agentic service provides a set of valid states and actions
|
|
8
9
|
* which are conditionally available based upon the current state.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Optional links expose other agentic services (e.g. parent, children)
|
|
11
|
+
* for navigation or delegation. Designed as a foundation for agentic
|
|
12
|
+
* systems; MCP or other agentic protocols can be built on this interface.
|
|
11
13
|
*/
|
|
12
14
|
export interface AgenticService extends Service {
|
|
13
|
-
description: Observe<string>;
|
|
14
15
|
states: Observe<{
|
|
15
16
|
[key: string]: State;
|
|
16
17
|
}>;
|
|
@@ -18,5 +19,7 @@ export interface AgenticService extends Service {
|
|
|
18
19
|
[key: string]: Action;
|
|
19
20
|
}>;
|
|
20
21
|
execute: (action: string, input: unknown) => Promise<void | ActionError>;
|
|
22
|
+
/** When set, observable map of links to other agentic services (key → AgenticService). */
|
|
23
|
+
links?: Observe<AgenticServiceLinks>;
|
|
21
24
|
}
|
|
22
25
|
export * as AgenticService from "./public.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentic-service.js","sourceRoot":"","sources":["../../../src/service/agentic-service/agentic-service.ts"],"names":[],"mappings":"AAAA,uDAAuD;
|
|
1
|
+
{"version":3,"file":"agentic-service.js","sourceRoot":"","sources":["../../../src/service/agentic-service/agentic-service.ts"],"names":[],"mappings":"AAAA,uDAAuD;AA2BvD,OAAO,KAAK,cAAc,MAAM,aAAa,CAAC"}
|
|
@@ -1,21 +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
|
-
/** State declaration:
|
|
5
|
-
type StateDeclaration<S extends Schema
|
|
6
|
-
type:
|
|
7
|
-
|
|
8
|
-
type: string;
|
|
9
|
-
}> = S & {
|
|
4
|
+
/** State declaration: kind + schema for value + description */
|
|
5
|
+
type StateDeclaration<S extends Schema = Schema> = {
|
|
6
|
+
type: "state";
|
|
7
|
+
schema: S;
|
|
10
8
|
description: string;
|
|
11
9
|
};
|
|
12
|
-
/** Action declaration:
|
|
10
|
+
/** Action declaration: kind + description + optional input schema */
|
|
13
11
|
type ActionDeclaration<I extends Schema | false | undefined = undefined> = {
|
|
12
|
+
type: "action";
|
|
14
13
|
description: string;
|
|
15
14
|
input?: I;
|
|
16
|
-
type?: never;
|
|
17
15
|
};
|
|
18
|
-
|
|
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;
|
|
19
22
|
type Declarations = Record<string, DeclarationEntry>;
|
|
20
23
|
type ConditionalFromDeclarations<D extends Declarations> = Partial<{
|
|
21
24
|
[K in keyof D]: Observe<boolean>;
|
|
@@ -23,9 +26,11 @@ type ConditionalFromDeclarations<D extends Declarations> = Partial<{
|
|
|
23
26
|
/**
|
|
24
27
|
* Creates an AgenticService from a config with interface, implementation, and optional conditional.
|
|
25
28
|
*
|
|
26
|
-
* Interface: flat map of
|
|
27
|
-
*
|
|
28
|
-
*
|
|
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).
|
|
29
34
|
*/
|
|
30
35
|
export declare function create<const D extends Declarations>(config: {
|
|
31
36
|
description: string;
|
|
@@ -33,13 +38,17 @@ export declare function create<const D extends Declarations>(config: {
|
|
|
33
38
|
implementation: ImplementationFromDeclarations<D>;
|
|
34
39
|
conditional?: ConditionalFromDeclarations<D>;
|
|
35
40
|
}): AgenticService;
|
|
36
|
-
/** Implementation map derived from interface:
|
|
41
|
+
/** Implementation map derived from interface: state → Observe, action → execute fn, link → AgenticService | Observe<AgenticService> */
|
|
37
42
|
export type ImplementationFromDeclarations<D extends Declarations> = {
|
|
38
43
|
[K in keyof D]: D[K] extends {
|
|
39
|
-
type:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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;
|
|
43
52
|
};
|
|
44
53
|
type ExecuteFromSchema<S extends Schema | false> = S extends false ? (() => Promise<void | AgenticService.ActionError> | void) : ((input: Schema.ToType<S>) => Promise<void | AgenticService.ActionError> | void);
|
|
45
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
|
-
|
|
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
|
|
16
|
-
*
|
|
17
|
-
*
|
|
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
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 (
|
|
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:
|
|
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,6 +87,23 @@ export function create(config) {
|
|
|
80
87
|
return `Action "${actionName}" is not available`;
|
|
81
88
|
return entry.execute(input);
|
|
82
89
|
};
|
|
83
|
-
|
|
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
|
+
})
|
|
100
|
+
: undefined;
|
|
101
|
+
return {
|
|
102
|
+
serviceName: "agentic-service",
|
|
103
|
+
states,
|
|
104
|
+
actions,
|
|
105
|
+
execute,
|
|
106
|
+
...(links !== undefined && { links }),
|
|
107
|
+
};
|
|
84
108
|
}
|
|
85
109
|
//# sourceMappingURL=create.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/service/agentic-service/create.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
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: "
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
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,
|
|
@@ -169,13 +173,107 @@ describe("AgenticService.create", () => {
|
|
|
169
173
|
expect(service.serviceName).toBe("agentic-service");
|
|
170
174
|
});
|
|
171
175
|
});
|
|
176
|
+
describe("links", () => {
|
|
177
|
+
it("should expose links observable when link is declared in interface", () => {
|
|
178
|
+
const child = create({
|
|
179
|
+
description: "Child",
|
|
180
|
+
interface: {},
|
|
181
|
+
implementation: {},
|
|
182
|
+
});
|
|
183
|
+
const service = create({
|
|
184
|
+
description: "Parent",
|
|
185
|
+
interface: { child: { type: "link", description: "Child service" } },
|
|
186
|
+
implementation: { child },
|
|
187
|
+
});
|
|
188
|
+
expect(service.links).toBeDefined();
|
|
189
|
+
const received = [];
|
|
190
|
+
service.links((l) => received.push({ ...l }));
|
|
191
|
+
expect(received).toHaveLength(1);
|
|
192
|
+
expect(received[0]).toEqual({ child });
|
|
193
|
+
});
|
|
194
|
+
it("should omit links when links config is omitted", () => {
|
|
195
|
+
const service = create({
|
|
196
|
+
description: "Test",
|
|
197
|
+
interface: {},
|
|
198
|
+
implementation: {},
|
|
199
|
+
});
|
|
200
|
+
expect(service.links).toBeUndefined();
|
|
201
|
+
});
|
|
202
|
+
it("should support Observe<AgenticService> per link for dynamic link target", () => {
|
|
203
|
+
const child = create({
|
|
204
|
+
description: "Child",
|
|
205
|
+
interface: {},
|
|
206
|
+
implementation: {},
|
|
207
|
+
});
|
|
208
|
+
const service = create({
|
|
209
|
+
description: "Parent",
|
|
210
|
+
interface: { child: { type: "link" } },
|
|
211
|
+
implementation: { child: Observe.fromConstant(child) },
|
|
212
|
+
});
|
|
213
|
+
expect(service.links).toBeDefined();
|
|
214
|
+
const received = [];
|
|
215
|
+
service.links((l) => received.push({ ...l }));
|
|
216
|
+
expect(received).toHaveLength(1);
|
|
217
|
+
expect(received[0]).toEqual({ child });
|
|
218
|
+
});
|
|
219
|
+
it("should omit link when conditional is false", () => {
|
|
220
|
+
const child = create({
|
|
221
|
+
description: "Child",
|
|
222
|
+
interface: {},
|
|
223
|
+
implementation: {},
|
|
224
|
+
});
|
|
225
|
+
const service = create({
|
|
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",
|
|
240
|
+
interface: {},
|
|
241
|
+
implementation: {},
|
|
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 },
|
|
249
|
+
});
|
|
250
|
+
const received = [];
|
|
251
|
+
service.links((l) => received.push({ ...l }));
|
|
252
|
+
expect(received).toHaveLength(1);
|
|
253
|
+
expect(received[0]).toEqual({ child });
|
|
254
|
+
setEnabled(false);
|
|
255
|
+
expect(received).toHaveLength(2);
|
|
256
|
+
expect(received[1]).toEqual({});
|
|
257
|
+
setEnabled(true);
|
|
258
|
+
expect(received).toHaveLength(3);
|
|
259
|
+
expect(received[2]).toEqual({ child });
|
|
260
|
+
});
|
|
261
|
+
it("should have links undefined when no link keys in interface", () => {
|
|
262
|
+
const service = create({
|
|
263
|
+
description: "Test",
|
|
264
|
+
interface: {},
|
|
265
|
+
implementation: {},
|
|
266
|
+
});
|
|
267
|
+
expect(service.links).toBeUndefined();
|
|
268
|
+
});
|
|
269
|
+
});
|
|
172
270
|
describe("conditional defaults", () => {
|
|
173
271
|
it("should default state enabled to always true when omitted", async () => {
|
|
174
272
|
const db = createTestDb();
|
|
175
273
|
const service = create({
|
|
176
274
|
description: "Test",
|
|
177
275
|
interface: {
|
|
178
|
-
health: { type: "number", description: "Health" },
|
|
276
|
+
health: { type: "state", schema: { type: "number" }, description: "Health" },
|
|
179
277
|
},
|
|
180
278
|
implementation: {
|
|
181
279
|
health: db.observe.resources.health,
|
|
@@ -189,7 +287,7 @@ describe("AgenticService.create", () => {
|
|
|
189
287
|
const service = create({
|
|
190
288
|
description: "Test",
|
|
191
289
|
interface: {
|
|
192
|
-
heal: { description: "Heal", input: { type: "number" } },
|
|
290
|
+
heal: { type: "action", description: "Heal", input: { type: "number" } },
|
|
193
291
|
},
|
|
194
292
|
implementation: {
|
|
195
293
|
heal: async () => { },
|
|
@@ -205,7 +303,7 @@ describe("AgenticService.create", () => {
|
|
|
205
303
|
const service = create({
|
|
206
304
|
description: "Test",
|
|
207
305
|
interface: {
|
|
208
|
-
currentHealth: { type: "number", description: "Health" },
|
|
306
|
+
currentHealth: { type: "state", schema: { type: "number" }, description: "Health" },
|
|
209
307
|
},
|
|
210
308
|
implementation: {
|
|
211
309
|
currentHealth: db.observe.resources.health,
|
|
@@ -213,7 +311,7 @@ describe("AgenticService.create", () => {
|
|
|
213
311
|
});
|
|
214
312
|
const states = await Observe.toPromise(service.states);
|
|
215
313
|
expect(states).toHaveProperty("currentHealth");
|
|
216
|
-
expect(states.currentHealth.schema).toEqual({ type: "number"
|
|
314
|
+
expect(states.currentHealth.schema).toEqual({ type: "number" });
|
|
217
315
|
expect(states.currentHealth.value).toBe(100);
|
|
218
316
|
});
|
|
219
317
|
it("should omit disabled states", async () => {
|
|
@@ -221,8 +319,8 @@ describe("AgenticService.create", () => {
|
|
|
221
319
|
const service = create({
|
|
222
320
|
description: "Test",
|
|
223
321
|
interface: {
|
|
224
|
-
visible: { type: "number", description: "Visible" },
|
|
225
|
-
hidden: { type: "string", description: "Hidden" },
|
|
322
|
+
visible: { type: "state", schema: { type: "number" }, description: "Visible" },
|
|
323
|
+
hidden: { type: "state", schema: { type: "string" }, description: "Hidden" },
|
|
226
324
|
},
|
|
227
325
|
implementation: {
|
|
228
326
|
visible: db.observe.resources.health,
|
|
@@ -243,7 +341,7 @@ describe("AgenticService.create", () => {
|
|
|
243
341
|
const service = create({
|
|
244
342
|
description: "Test",
|
|
245
343
|
interface: {
|
|
246
|
-
health: { type: "number", description: "Health" },
|
|
344
|
+
health: { type: "state", schema: { type: "number" }, description: "Health" },
|
|
247
345
|
},
|
|
248
346
|
implementation: {
|
|
249
347
|
health: db.observe.resources.health,
|
|
@@ -263,7 +361,7 @@ describe("AgenticService.create", () => {
|
|
|
263
361
|
const service = create({
|
|
264
362
|
description: "Test",
|
|
265
363
|
interface: {
|
|
266
|
-
health: { type: "number", description: "Health" },
|
|
364
|
+
health: { type: "state", schema: { type: "number" }, description: "Health" },
|
|
267
365
|
},
|
|
268
366
|
implementation: {
|
|
269
367
|
health: healthObserve,
|
|
@@ -281,7 +379,7 @@ describe("AgenticService.create", () => {
|
|
|
281
379
|
const service = create({
|
|
282
380
|
description: "Test",
|
|
283
381
|
interface: {
|
|
284
|
-
heal: { description: "Heal player", input: { type: "number" } },
|
|
382
|
+
heal: { type: "action", description: "Heal player", input: { type: "number" } },
|
|
285
383
|
},
|
|
286
384
|
implementation: {
|
|
287
385
|
heal: async (_amount) => { },
|
|
@@ -297,8 +395,8 @@ describe("AgenticService.create", () => {
|
|
|
297
395
|
const service = create({
|
|
298
396
|
description: "Test",
|
|
299
397
|
interface: {
|
|
300
|
-
available: { description: "Available", input: { type: "number" } },
|
|
301
|
-
unavailable: { description: "Unavailable" },
|
|
398
|
+
available: { type: "action", description: "Available", input: { type: "number" } },
|
|
399
|
+
unavailable: { type: "action", description: "Unavailable" },
|
|
302
400
|
},
|
|
303
401
|
implementation: {
|
|
304
402
|
available: async () => { },
|
|
@@ -318,7 +416,7 @@ describe("AgenticService.create", () => {
|
|
|
318
416
|
const service = create({
|
|
319
417
|
description: "Test",
|
|
320
418
|
interface: {
|
|
321
|
-
heal: { description: "Heal", input: { type: "number" } },
|
|
419
|
+
heal: { type: "action", description: "Heal", input: { type: "number" } },
|
|
322
420
|
},
|
|
323
421
|
implementation: {
|
|
324
422
|
heal: async () => { },
|
|
@@ -338,7 +436,7 @@ describe("AgenticService.create", () => {
|
|
|
338
436
|
const service = create({
|
|
339
437
|
description: "Test",
|
|
340
438
|
interface: {
|
|
341
|
-
setHealth: { description: "Set health", input: { type: "number" } },
|
|
439
|
+
setHealth: { type: "action", description: "Set health", input: { type: "number" } },
|
|
342
440
|
},
|
|
343
441
|
implementation: {
|
|
344
442
|
setHealth: async (input) => { received = input; },
|
|
@@ -353,7 +451,7 @@ describe("AgenticService.create", () => {
|
|
|
353
451
|
const service = create({
|
|
354
452
|
description: "Test",
|
|
355
453
|
interface: {
|
|
356
|
-
reset: { description: "Reset" },
|
|
454
|
+
reset: { type: "action", description: "Reset" },
|
|
357
455
|
},
|
|
358
456
|
implementation: {
|
|
359
457
|
reset: async () => { called = true; },
|
|
@@ -367,7 +465,7 @@ describe("AgenticService.create", () => {
|
|
|
367
465
|
const service = create({
|
|
368
466
|
description: "Test",
|
|
369
467
|
interface: {
|
|
370
|
-
sync: { description: "Sync" },
|
|
468
|
+
sync: { type: "action", description: "Sync" },
|
|
371
469
|
},
|
|
372
470
|
implementation: {
|
|
373
471
|
sync: () => { called = true; },
|
|
@@ -380,7 +478,7 @@ describe("AgenticService.create", () => {
|
|
|
380
478
|
const service = create({
|
|
381
479
|
description: "Test",
|
|
382
480
|
interface: {
|
|
383
|
-
heal: { description: "Heal", input: { type: "number" } },
|
|
481
|
+
heal: { type: "action", description: "Heal", input: { type: "number" } },
|
|
384
482
|
},
|
|
385
483
|
implementation: {
|
|
386
484
|
heal: async () => { },
|
|
@@ -403,7 +501,7 @@ describe("AgenticService.create", () => {
|
|
|
403
501
|
const service = create({
|
|
404
502
|
description: "Test",
|
|
405
503
|
interface: {
|
|
406
|
-
fail: { description: "Fail" },
|
|
504
|
+
fail: { type: "action", description: "Fail" },
|
|
407
505
|
},
|
|
408
506
|
implementation: {
|
|
409
507
|
fail: async () => "something went wrong",
|
|
@@ -418,7 +516,7 @@ describe("AgenticService.create", () => {
|
|
|
418
516
|
const service = create({
|
|
419
517
|
description: "Test",
|
|
420
518
|
interface: {
|
|
421
|
-
heal: { description: "Heal", input: { type: "number" } },
|
|
519
|
+
heal: { type: "action", description: "Heal", input: { type: "number" } },
|
|
422
520
|
},
|
|
423
521
|
implementation: {
|
|
424
522
|
heal: async () => { called = true; },
|
|
@@ -443,8 +541,8 @@ describe("AgenticService.create", () => {
|
|
|
443
541
|
const service = create({
|
|
444
542
|
description: "Test",
|
|
445
543
|
interface: {
|
|
446
|
-
health: { type: "number", description: "Health" },
|
|
447
|
-
name: { type: "string", description: "Name" },
|
|
544
|
+
health: { type: "state", schema: { type: "number" }, description: "Health" },
|
|
545
|
+
name: { type: "state", schema: { type: "string" }, description: "Name" },
|
|
448
546
|
},
|
|
449
547
|
implementation: {
|
|
450
548
|
health: db.observe.resources.health,
|
|
@@ -470,8 +568,8 @@ describe("AgenticService.create", () => {
|
|
|
470
568
|
const service = create({
|
|
471
569
|
description: "Test",
|
|
472
570
|
interface: {
|
|
473
|
-
heal: { description: "Heal", input: { type: "number" } },
|
|
474
|
-
reset: { description: "Reset" },
|
|
571
|
+
heal: { type: "action", description: "Heal", input: { type: "number" } },
|
|
572
|
+
reset: { type: "action", description: "Reset" },
|
|
475
573
|
},
|
|
476
574
|
implementation: {
|
|
477
575
|
heal: async () => { },
|
|
@@ -498,7 +596,7 @@ describe("AgenticService.create", () => {
|
|
|
498
596
|
const service = create({
|
|
499
597
|
description: "Test",
|
|
500
598
|
interface: {
|
|
501
|
-
heal: { description: "Heal", input: { type: "number" } },
|
|
599
|
+
heal: { type: "action", description: "Heal", input: { type: "number" } },
|
|
502
600
|
},
|
|
503
601
|
implementation: {
|
|
504
602
|
heal: async (input) => { received = input; },
|
|
@@ -513,7 +611,7 @@ describe("AgenticService.create", () => {
|
|
|
513
611
|
const service = create({
|
|
514
612
|
description: "Test",
|
|
515
613
|
interface: {
|
|
516
|
-
reset: { description: "Reset" },
|
|
614
|
+
reset: { type: "action", description: "Reset" },
|
|
517
615
|
},
|
|
518
616
|
implementation: {
|
|
519
617
|
reset: async () => { called = true; },
|
|
@@ -527,7 +625,7 @@ describe("AgenticService.create", () => {
|
|
|
527
625
|
const service = create({
|
|
528
626
|
description: "Test",
|
|
529
627
|
interface: {
|
|
530
|
-
fail: { description: "Fail" },
|
|
628
|
+
fail: { type: "action", description: "Fail" },
|
|
531
629
|
},
|
|
532
630
|
implementation: {
|
|
533
631
|
fail: async () => "bound error",
|