@scfloworg/actions 0.0.0-stage → 0.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.
@@ -0,0 +1,31 @@
1
+ import type { ValidateFunction } from "ajv/dist/2020.js";
2
+ import type { ActionDefinition, JsonSchema, RefResolver } from "./types.js";
3
+ /**
4
+ * The parameters of a definition as a JSON Schema object: its JSON text read,
5
+ * or an empty object schema when it declares none. Text that is not JSON, or a
6
+ * schema whose `type` is not `object`, is refused with `constraint_violation`.
7
+ */
8
+ export declare function parametersSchema(definition: ActionDefinition): JsonSchema;
9
+ /**
10
+ * The validator of a parameters schema, compiled once per schema object. A
11
+ * schema that is not a valid JSON Schema, or uses an unknown keyword, is
12
+ * refused with `constraint_violation`.
13
+ */
14
+ export declare function compileParameters(id: string, schema: JsonSchema): ValidateFunction;
15
+ /**
16
+ * Checks parameters against the JSON Schema of an action and gives the
17
+ * parameters its body receives: a copy, with the `default` of each absent
18
+ * property, and each `ref` value replaced by the key of the instance it names.
19
+ *
20
+ * `undefined` stands for no parameters, an empty object. Parameters that break
21
+ * the schema are refused with `invalid_parameters`. A `ref` value is resolved
22
+ * by `resolveRef` under the rule of the specification: the instance whose id
23
+ * is the value wins; otherwise the one instance whose `display_name` is the
24
+ * value; no instance or several are refused with `invalid_parameters`. Without
25
+ * `resolveRef`, a `ref` value is kept as it is.
26
+ *
27
+ * `validate` is the compiled validator, which a registry keeps; it is compiled
28
+ * from the definition when absent.
29
+ */
30
+ export declare function validateParameters(definition: ActionDefinition, params: unknown, resolveRef?: RefResolver, validate?: ValidateFunction): Promise<unknown>;
31
+ //# sourceMappingURL=parameters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../src/parameters.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA4D5E;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,gBAAgB,GAAG,UAAU,CA0BzE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,gBAAgB,CAclF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EAAE,OAAO,EACf,UAAU,CAAC,EAAE,WAAW,EACxB,QAAQ,GAAE,gBAAiF,GAC1F,OAAO,CAAC,OAAO,CAAC,CA4BlB"}
@@ -0,0 +1,141 @@
1
+ import { Ajv2020 } from "ajv/dist/2020.js";
2
+ import { actionError } from "./errors.js";
3
+ import { copyJson } from "./json.js";
4
+ /** The sites of the validation running now; validation is synchronous, so one list is enough. */
5
+ let collecting = null;
6
+ /**
7
+ * The validator of every action: JSON Schema draft 2020-12, the version of MCP
8
+ * tools. Unknown keywords are refused, `default` fills absent properties, and
9
+ * `format` is an annotation only, since no format vocabulary is loaded.
10
+ */
11
+ const ajv = new Ajv2020({
12
+ allErrors: true,
13
+ useDefaults: true,
14
+ strictSchema: true,
15
+ strictTypes: false,
16
+ strictTuples: false,
17
+ strictRequired: false,
18
+ validateFormats: false,
19
+ });
20
+ /**
21
+ * `ref` names a schema of the model: the value is the id or the display name
22
+ * of one of its instances. The validator only notes where each value sits;
23
+ * `validateParameters` resolves them once the parameters are valid.
24
+ */
25
+ ajv.addKeyword({
26
+ keyword: "ref",
27
+ schemaType: "string",
28
+ errors: false,
29
+ validate(schema, data, _parentSchema, context) {
30
+ if (collecting && typeof data === "string" && context && context.parentData !== undefined) {
31
+ collecting.push({
32
+ schema,
33
+ value: data,
34
+ parent: context.parentData,
35
+ property: context.parentDataProperty,
36
+ });
37
+ }
38
+ return true;
39
+ },
40
+ });
41
+ const compiled = new WeakMap();
42
+ /** The parameters of an action that declares none. */
43
+ const NO_PARAMETERS = Object.freeze({ type: "object", properties: Object.freeze({}) });
44
+ /**
45
+ * The parameters of a definition as a JSON Schema object: its JSON text read,
46
+ * or an empty object schema when it declares none. Text that is not JSON, or a
47
+ * schema whose `type` is not `object`, is refused with `constraint_violation`.
48
+ */
49
+ export function parametersSchema(definition) {
50
+ const { parameters } = definition;
51
+ if (parameters === undefined)
52
+ return NO_PARAMETERS;
53
+ let schema = parameters;
54
+ if (typeof parameters === "string") {
55
+ try {
56
+ schema = JSON.parse(parameters);
57
+ }
58
+ catch (error) {
59
+ throw actionError("constraint_violation", `${definition.id}: parameters are not JSON: ${error.message}`);
60
+ }
61
+ }
62
+ if (schema === null ||
63
+ typeof schema !== "object" ||
64
+ Array.isArray(schema) ||
65
+ schema.type !== "object") {
66
+ throw actionError("constraint_violation", `${definition.id}: parameters must be a JSON Schema of type object`);
67
+ }
68
+ return schema;
69
+ }
70
+ /**
71
+ * The validator of a parameters schema, compiled once per schema object. A
72
+ * schema that is not a valid JSON Schema, or uses an unknown keyword, is
73
+ * refused with `constraint_violation`.
74
+ */
75
+ export function compileParameters(id, schema) {
76
+ const known = compiled.get(schema);
77
+ if (known)
78
+ return known;
79
+ let validate;
80
+ try {
81
+ validate = ajv.compile(schema);
82
+ }
83
+ catch (error) {
84
+ throw actionError("constraint_violation", `${id}: parameters are not a valid JSON Schema: ${error.message}`);
85
+ }
86
+ compiled.set(schema, validate);
87
+ return validate;
88
+ }
89
+ /**
90
+ * Checks parameters against the JSON Schema of an action and gives the
91
+ * parameters its body receives: a copy, with the `default` of each absent
92
+ * property, and each `ref` value replaced by the key of the instance it names.
93
+ *
94
+ * `undefined` stands for no parameters, an empty object. Parameters that break
95
+ * the schema are refused with `invalid_parameters`. A `ref` value is resolved
96
+ * by `resolveRef` under the rule of the specification: the instance whose id
97
+ * is the value wins; otherwise the one instance whose `display_name` is the
98
+ * value; no instance or several are refused with `invalid_parameters`. Without
99
+ * `resolveRef`, a `ref` value is kept as it is.
100
+ *
101
+ * `validate` is the compiled validator, which a registry keeps; it is compiled
102
+ * from the definition when absent.
103
+ */
104
+ export async function validateParameters(definition, params, resolveRef, validate = compileParameters(definition.id, parametersSchema(definition))) {
105
+ const data = params === undefined ? {} : copyJson(params);
106
+ const sites = [];
107
+ collecting = sites;
108
+ let valid;
109
+ try {
110
+ valid = validate(data);
111
+ }
112
+ finally {
113
+ collecting = null;
114
+ }
115
+ if (!valid) {
116
+ throw actionError("invalid_parameters", `${definition.id}: ${ajv.errorsText(validate.errors, { dataVar: "parameters" })}`);
117
+ }
118
+ if (resolveRef) {
119
+ // A value under several subschemas (allOf, anyOf) is met more than once: resolve it once.
120
+ const done = new Map();
121
+ for (const site of sites) {
122
+ const properties = done.get(site.parent) ?? new Set();
123
+ if (properties.has(site.property))
124
+ continue;
125
+ properties.add(site.property);
126
+ done.set(site.parent, properties);
127
+ site.parent[site.property] = await resolveKey(definition.id, site, resolveRef);
128
+ }
129
+ }
130
+ return data;
131
+ }
132
+ async function resolveKey(id, site, resolveRef) {
133
+ const matches = await resolveRef(site.schema, site.value);
134
+ if (matches.id !== null)
135
+ return matches.id;
136
+ if (matches.names.length === 1)
137
+ return matches.names[0];
138
+ const count = matches.names.length === 0 ? "no" : "several";
139
+ throw actionError("invalid_parameters", `${id}: "${site.value}" names ${count} instance of ${site.schema}`);
140
+ }
141
+ //# sourceMappingURL=parameters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameters.js","sourceRoot":"","sources":["../src/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAWrC,iGAAiG;AACjG,IAAI,UAAU,GAAqB,IAAI,CAAC;AAExC;;;;GAIG;AACH,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC;IACtB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,KAAK;IAClB,YAAY,EAAE,KAAK;IACnB,cAAc,EAAE,KAAK;IACrB,eAAe,EAAE,KAAK;CACvB,CAAC,CAAC;AAEH;;;;GAIG;AACH,GAAG,CAAC,UAAU,CAAC;IACb,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,QAAQ;IACpB,MAAM,EAAE,KAAK;IACb,QAAQ,CACN,MAAc,EACd,IAAa,EACb,aAAuB,EACvB,OAAsE;QAEtE,IAAI,UAAU,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAC1F,UAAU,CAAC,IAAI,CAAC;gBACd,MAAM;gBACN,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,OAAO,CAAC,UAA+B;gBAC/C,QAAQ,EAAE,OAAO,CAAC,kBAAkB;aACrC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA4B,CAAC;AAEzD,sDAAsD;AACtD,MAAM,aAAa,GAAe,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAEnG;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA4B;IAC3D,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC;IAClC,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IACnD,IAAI,MAAM,GAAY,UAAU,CAAC;IACjC,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,CACf,sBAAsB,EACtB,GAAG,UAAU,CAAC,EAAE,8BAA+B,KAAe,CAAC,OAAO,EAAE,CACzE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IACE,MAAM,KAAK,IAAI;QACf,OAAO,MAAM,KAAK,QAAQ;QAC1B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACpB,MAAqB,CAAC,IAAI,KAAK,QAAQ,EACxC,CAAC;QACD,MAAM,WAAW,CACf,sBAAsB,EACtB,GAAG,UAAU,CAAC,EAAE,mDAAmD,CACpE,CAAC;IACJ,CAAC;IACD,OAAO,MAAoB,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAU,EAAE,MAAkB;IAC9D,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,QAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,WAAW,CACf,sBAAsB,EACtB,GAAG,EAAE,6CAA8C,KAAe,CAAC,OAAO,EAAE,CAC7E,CAAC;IACJ,CAAC;IACD,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAA4B,EAC5B,MAAe,EACf,UAAwB,EACxB,WAA6B,iBAAiB,CAAC,UAAU,CAAC,EAAE,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAE3F,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,UAAU,GAAG,KAAK,CAAC;IACnB,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAY,CAAC;IACpC,CAAC;YAAS,CAAC;QACT,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,WAAW,CACf,oBAAoB,EACpB,GAAG,UAAU,CAAC,EAAE,KAAK,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,CAClF,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,0FAA0F;QAC1F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAgC,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;YACtD,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC5C,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,EAAU,EAAE,IAAa,EAAE,UAAuB;IAC1E,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,EAAE,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC,EAAE,CAAC;IAC3C,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,MAAM,WAAW,CACf,oBAAoB,EACpB,GAAG,EAAE,MAAM,IAAI,CAAC,KAAK,WAAW,KAAK,gBAAgB,IAAI,CAAC,MAAM,EAAE,CACnE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { Action, RunEntry, RunHost, RunOutcome, RunTrace } from "./types.js";
2
+ /** A registry of actions, each known by its id. */
3
+ export interface ActionRegistry<C = RunTrace> {
4
+ /**
5
+ * Adds an action. Its id must be a namespace, a slash and a name, and its
6
+ * parameters a valid JSON Schema object, or it is refused with
7
+ * `constraint_violation`; an id already registered is refused with
8
+ * `duplicate_name`.
9
+ */
10
+ register(action: Action<C>): void;
11
+ /** The action with this id, or `undefined`. */
12
+ get(id: string): Action<C> | undefined;
13
+ /** Every action, in the order of registration. */
14
+ list(): readonly Action<C>[];
15
+ /**
16
+ * Runs one action: checks its parameters (see `validateParameters`), runs its
17
+ * body with the context the host builds, and records the call as a run
18
+ * entry, which `host.onEntry` receives, done or refused. An id that names no
19
+ * action is refused with `unknown_action`, and no entry is recorded.
20
+ *
21
+ * It opens no transaction: the host runs it inside the transaction of the
22
+ * action.
23
+ */
24
+ run(id: string, params?: unknown, host?: RunHost<C>): Promise<RunOutcome>;
25
+ }
26
+ /** The run entry recorded for an exception a run threw, if any. */
27
+ export declare function entryOfRefusal(error: unknown): RunEntry | undefined;
28
+ /** Creates an empty registry. `C` is the context a host gives the bodies, the trace by default. */
29
+ export declare function createActionRegistry<C = RunTrace>(): ActionRegistry<C>;
30
+ /** A run log: the entries of the runs it is given to, in order. */
31
+ export interface RunLog {
32
+ readonly entries: readonly RunEntry[];
33
+ /** Adds an entry; pass it as `RunHost.onEntry`. */
34
+ readonly record: (entry: RunEntry) => void;
35
+ }
36
+ /** Creates an empty run log, kept in memory. */
37
+ export declare function createRunLog(): RunLog;
38
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAW,QAAQ,EAAE,MAAM,YAAY,CAAC;AAK3F,mDAAmD;AACnD,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,QAAQ;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACvC,kDAAkD;IAClD,IAAI,IAAI,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7B;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3E;AAUD,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAEnE;AAWD,mGAAmG;AACnG,wBAAgB,oBAAoB,CAAC,CAAC,GAAG,QAAQ,KAAK,cAAc,CAAC,CAAC,CAAC,CAyFtE;AAED,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IACtC,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC5C;AAED,gDAAgD;AAChD,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
@@ -0,0 +1,113 @@
1
+ import { actionError, errorCodeOf } from "./errors.js";
2
+ import { canonicalJson, copyJson } from "./json.js";
3
+ import { compileParameters, parametersSchema, validateParameters } from "./parameters.js";
4
+ /** An action id: the namespace of its module, a slash and a name, both identifiers. */
5
+ const ACTION_ID = /^[A-Za-z_][A-Za-z0-9_]*\/[A-Za-z_][A-Za-z0-9_]*$/;
6
+ /** The entry of each refused run, by its exception, so a caller records it as a step. */
7
+ const refusedEntries = new WeakMap();
8
+ /** The run entry recorded for an exception a run threw, if any. */
9
+ export function entryOfRefusal(error) {
10
+ return error !== null && typeof error === "object" ? refusedEntries.get(error) : undefined;
11
+ }
12
+ /** The parameters as given, in canonical form, or their text when they are not JSON. */
13
+ function givenParameters(params) {
14
+ try {
15
+ return canonicalJson(params === undefined ? {} : params);
16
+ }
17
+ catch {
18
+ return JSON.stringify(String(params));
19
+ }
20
+ }
21
+ /** Creates an empty registry. `C` is the context a host gives the bodies, the trace by default. */
22
+ export function createActionRegistry() {
23
+ const actions = new Map();
24
+ function refuse(error, action, parameters, steps) {
25
+ const entry = {
26
+ action,
27
+ parameters,
28
+ steps,
29
+ outcome: "refused",
30
+ error: errorCodeOf(error),
31
+ };
32
+ if (error !== null && typeof error === "object")
33
+ refusedEntries.set(error, entry);
34
+ throw error;
35
+ }
36
+ async function execute(id, params, host) {
37
+ const registered = actions.get(id);
38
+ if (!registered)
39
+ throw actionError("unknown_action", `no action ${id}`);
40
+ const steps = [];
41
+ let checked;
42
+ try {
43
+ checked = await validateParameters(registered.action, params, host.resolveRef, registered.validate);
44
+ }
45
+ catch (error) {
46
+ refuse(error, id, givenParameters(params), steps);
47
+ }
48
+ const parameters = canonicalJson(checked);
49
+ const trace = {
50
+ action: id,
51
+ command(command, result) {
52
+ steps.push({ command: copyJson(command), result: canonicalJson(result) });
53
+ },
54
+ async call(calledId, calledParams) {
55
+ try {
56
+ const outcome = await execute(calledId, calledParams, host);
57
+ steps.push({ call: outcome.entry });
58
+ return outcome.result;
59
+ }
60
+ catch (error) {
61
+ const entry = entryOfRefusal(error);
62
+ if (entry)
63
+ steps.push({ call: entry });
64
+ throw error;
65
+ }
66
+ },
67
+ };
68
+ const context = host.context ? host.context(trace) : trace;
69
+ let result;
70
+ try {
71
+ result = await registered.action.run(checked, context);
72
+ }
73
+ catch (error) {
74
+ refuse(error, id, parameters, steps);
75
+ }
76
+ const entry = result === undefined
77
+ ? { action: id, parameters, steps, outcome: "done" }
78
+ : { action: id, parameters, steps, outcome: "done", result: canonicalJson(result) };
79
+ return { result, entry };
80
+ }
81
+ return {
82
+ register(action) {
83
+ if (typeof action.id !== "string" || !ACTION_ID.test(action.id)) {
84
+ throw actionError("constraint_violation", `"${action.id}" is not a namespace, a slash and a name`);
85
+ }
86
+ if (actions.has(action.id))
87
+ throw actionError("duplicate_name", `action ${action.id} is already registered`);
88
+ const validate = compileParameters(action.id, parametersSchema(action));
89
+ actions.set(action.id, { action, validate });
90
+ },
91
+ get: (id) => actions.get(id)?.action,
92
+ list: () => [...actions.values()].map((registered) => registered.action),
93
+ async run(id, params, host = {}) {
94
+ try {
95
+ const outcome = await execute(id, params, host);
96
+ host.onEntry?.(outcome.entry);
97
+ return outcome;
98
+ }
99
+ catch (error) {
100
+ const entry = entryOfRefusal(error);
101
+ if (entry)
102
+ host.onEntry?.(entry);
103
+ throw error;
104
+ }
105
+ },
106
+ };
107
+ }
108
+ /** Creates an empty run log, kept in memory. */
109
+ export function createRunLog() {
110
+ const entries = [];
111
+ return { entries, record: (entry) => void entries.push(entry) };
112
+ }
113
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { ActionDefinition, JsonSchema } from "./types.js";
2
+ /** An AI tool, in the shape of an MCP tool definition. */
3
+ export interface AiTool {
4
+ /** The id of the action with its slash replaced by a hyphen (see `toolName`). */
5
+ readonly name: string;
6
+ readonly title?: string;
7
+ readonly description?: string;
8
+ /** The parameters of the action, a JSON Schema object, `ref` keywords included, in the shape providers accept. */
9
+ readonly inputSchema: JsonSchema;
10
+ readonly annotations: {
11
+ readonly title?: string;
12
+ /** `true` for an action of kind `read`. */
13
+ readonly readOnlyHint: boolean;
14
+ /** `true` for a `destructive` action. */
15
+ readonly destructiveHint: boolean;
16
+ };
17
+ }
18
+ /**
19
+ * The tool name of an action id: the slash replaced by a hyphen, because AI
20
+ * clients accept only letters, digits, `_` and `-` in a tool name. A hyphen
21
+ * never appears in an identifier, so `actionIdOfTool` gives the id back.
22
+ */
23
+ export declare function toolName(id: string): string;
24
+ /** The action id of a tool name made by `toolName`, or `undefined` when the name has no hyphen. */
25
+ export declare function actionIdOfTool(name: string): string | undefined;
26
+ /** What the tools of a project are told about it. */
27
+ export interface ToolOptions {
28
+ /**
29
+ * The ordered `languages` of the dataset, the first being the source
30
+ * language. The description of each localized text parameter then names them.
31
+ * Left out or empty (not stated), the descriptions are not changed.
32
+ */
33
+ readonly languages?: readonly string[] | undefined;
34
+ }
35
+ /** The sentence added to a localized parameter: the languages of the project and its source language. */
36
+ export declare function languagesNote(languages: readonly string[]): string;
37
+ /**
38
+ * The parameters of an action as `parametersSchema` gives them, with the
39
+ * languages of the project named in the description of each localized text.
40
+ * Gives the schema itself when `languages` is absent or empty.
41
+ */
42
+ export declare function parametersWithLanguages(action: ActionDefinition, languages: readonly string[] | undefined): JsonSchema;
43
+ /** The AI tool of one action, whatever its exposure. */
44
+ export declare function toAiTool(action: ActionDefinition, options?: ToolOptions): AiTool;
45
+ /**
46
+ * Exports actions to AI tools: the `visible` actions, in
47
+ * order, each by `toAiTool`. An action whose `exposure` is `hidden` is left
48
+ * out, because the author of the model says what an AI should use.
49
+ */
50
+ export declare function toAiTools(actions: Iterable<ActionDefinition>, options?: ToolOptions): AiTool[];
51
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE/D,0DAA0D;AAC1D,MAAM,WAAW,MAAM;IACrB,iFAAiF;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kHAAkH;IAClH,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE;QACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,2CAA2C;QAC3C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;QAC/B,yCAAyC;QACzC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;KACnC,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG/D;AAiBD,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACpD;AAgBD,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAElE;AAiBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,UAAU,CAMtH;AAED,wDAAwD;AACxD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAkBpF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,EAAE,CAElG"}
package/dist/tools.js ADDED
@@ -0,0 +1,106 @@
1
+ import { copyJson } from "./json.js";
2
+ import { parametersSchema } from "./parameters.js";
3
+ /**
4
+ * The tool name of an action id: the slash replaced by a hyphen, because AI
5
+ * clients accept only letters, digits, `_` and `-` in a tool name. A hyphen
6
+ * never appears in an identifier, so `actionIdOfTool` gives the id back.
7
+ */
8
+ export function toolName(id) {
9
+ return id.replace("/", "-");
10
+ }
11
+ /** The action id of a tool name made by `toolName`, or `undefined` when the name has no hyphen. */
12
+ export function actionIdOfTool(name) {
13
+ const at = name.indexOf("-");
14
+ return at < 0 ? undefined : `${name.slice(0, at)}/${name.slice(at + 1)}`;
15
+ }
16
+ /** What AI providers refuse at the top level of the schema of a tool. */
17
+ const TOP_LEVEL_REFUSED = ["anyOf", "oneOf", "allOf"];
18
+ /** The properties of an `anyOf` whose branches each require one property, else `undefined`. */
19
+ function atLeastOneOf(anyOf) {
20
+ if (!Array.isArray(anyOf) || anyOf.length === 0)
21
+ return undefined;
22
+ const names = [];
23
+ for (const branch of anyOf) {
24
+ const required = branch?.required;
25
+ if (Object.keys(branch ?? {}).length !== 1 || !Array.isArray(required) || required.length !== 1)
26
+ return undefined;
27
+ names.push(String(required[0]));
28
+ }
29
+ return names;
30
+ }
31
+ /** Whether a parameter schema is a localized text: a string, or a map of language to string, in an `anyOf`. */
32
+ function isLocalizedText(node) {
33
+ const branches = node.anyOf;
34
+ if (!Array.isArray(branches))
35
+ return false;
36
+ const isMapOfStrings = (branch) => {
37
+ const values = branch.additionalProperties;
38
+ return branch.type === "object" && typeof values === "object" && values !== null && values.type === "string";
39
+ };
40
+ return (branches.some((branch) => branch?.type === "string") &&
41
+ branches.some((branch) => branch !== null && typeof branch === "object" && isMapOfStrings(branch)));
42
+ }
43
+ /** The sentence added to a localized parameter: the languages of the project and its source language. */
44
+ export function languagesNote(languages) {
45
+ return `Write this text only in the languages of the project: ${languages.join(", ")}. The source language is ${languages[0]}. Give an object keyed by language code.`;
46
+ }
47
+ /** Appends `languagesNote` to every localized text found in `node`, in place. */
48
+ function nameLanguages(node, note) {
49
+ if (Array.isArray(node)) {
50
+ for (const entry of node)
51
+ nameLanguages(entry, note);
52
+ return;
53
+ }
54
+ if (node === null || typeof node !== "object")
55
+ return;
56
+ const object = node;
57
+ if (isLocalizedText(object)) {
58
+ object.description = [object.description, note].filter((part) => typeof part === "string" && part !== "").join(" ");
59
+ return;
60
+ }
61
+ for (const value of Object.values(object))
62
+ nameLanguages(value, note);
63
+ }
64
+ /**
65
+ * The parameters of an action as `parametersSchema` gives them, with the
66
+ * languages of the project named in the description of each localized text.
67
+ * Gives the schema itself when `languages` is absent or empty.
68
+ */
69
+ export function parametersWithLanguages(action, languages) {
70
+ const schema = parametersSchema(action);
71
+ if (!languages || languages.length === 0)
72
+ return schema;
73
+ const copy = copyJson(schema);
74
+ nameLanguages(copy, languagesNote(languages));
75
+ return copy;
76
+ }
77
+ /** The AI tool of one action, whatever its exposure. */
78
+ export function toAiTool(action, options = {}) {
79
+ const { title } = action;
80
+ const inputSchema = copyJson(parametersWithLanguages(action, options.languages));
81
+ const required = atLeastOneOf(inputSchema.anyOf);
82
+ for (const keyword of TOP_LEVEL_REFUSED)
83
+ delete inputSchema[keyword];
84
+ const rule = required ? `Give at least one of: ${required.join(", ")}.` : undefined;
85
+ const description = rule ? [action.description, rule].filter(Boolean).join(" ") : action.description;
86
+ return {
87
+ name: toolName(action.id),
88
+ ...(title === undefined ? {} : { title }),
89
+ ...(description === undefined ? {} : { description }),
90
+ inputSchema: inputSchema,
91
+ annotations: {
92
+ ...(title === undefined ? {} : { title }),
93
+ readOnlyHint: action.kind === "read",
94
+ destructiveHint: action.destructive === true,
95
+ },
96
+ };
97
+ }
98
+ /**
99
+ * Exports actions to AI tools: the `visible` actions, in
100
+ * order, each by `toAiTool`. An action whose `exposure` is `hidden` is left
101
+ * out, because the author of the model says what an AI should use.
102
+ */
103
+ export function toAiTools(actions, options = {}) {
104
+ return [...actions].filter((action) => action.exposure !== "hidden").map((action) => toAiTool(action, options));
105
+ }
106
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * The types of the action contract (`packages/core/docs/spec/meta-model.md`,
3
+ * section Action). They hold no model: an action is an id, a description for
4
+ * people and AI, its parameters as JSON Schema and a body.
5
+ */
6
+ /** A JSON Schema, as plain data. */
7
+ export type JsonSchema = {
8
+ readonly [keyword: string]: unknown;
9
+ };
10
+ /**
11
+ * The declaration of an action, apart from its body. It matches an MCP tool
12
+ * definition: `id` gives the tool name, `description` and `parameters` the
13
+ * description and input schema, `kind: "read"` the read-only hint and
14
+ * `destructive` the destructive hint.
15
+ */
16
+ export interface ActionDefinition {
17
+ /** The namespace of the module, a slash and a name, for example `scflow/create_actor`. */
18
+ readonly id: string;
19
+ /** A short label for people, used in a user interface and an undo history. */
20
+ readonly title?: string;
21
+ /** What the action does, for people and AI assistants. */
22
+ readonly description?: string;
23
+ /** `read` writes nothing; `action`, the default, writes. */
24
+ readonly kind?: "read" | "action";
25
+ /** Whether the action may destroy data. */
26
+ readonly destructive?: boolean;
27
+ /** Whether an AI sees the action: `visible`, the default, or `hidden`. */
28
+ readonly exposure?: "visible" | "hidden";
29
+ /**
30
+ * The parameters, a JSON Schema object (draft 2020-12), or its JSON text as a
31
+ * manifest holds it. It may use the keyword `ref`, which names a schema of
32
+ * the model: see `RefResolver`. Absent, the action takes an empty object.
33
+ */
34
+ readonly parameters?: JsonSchema | string;
35
+ /** The schemas the action writes. Kept for the engine, which enforces it. */
36
+ readonly writes?: readonly string[];
37
+ }
38
+ /**
39
+ * The trace of one run: a body records through it each command it emits, with
40
+ * its result, and calls other actions. A host builds the context of the body
41
+ * from it (`RunHost.context`); without a host context, the body receives the
42
+ * trace itself.
43
+ */
44
+ export interface RunTrace {
45
+ /** The id of the running action. */
46
+ readonly action: string;
47
+ /**
48
+ * Records a command as the body emitted it, before its placeholders are
49
+ * resolved, with the result the engine gave.
50
+ */
51
+ command(command: unknown, result: unknown): void;
52
+ /**
53
+ * Runs another action of the registry with the same host, and records the
54
+ * call as a step of this run. It resolves to the result of the called action,
55
+ * and rejects with its exception.
56
+ */
57
+ call(id: string, params?: unknown): Promise<unknown>;
58
+ }
59
+ /**
60
+ * An action: its declaration and its body. The body is `run(params, context)`;
61
+ * it receives the parameters after their check, with each `ref` resolved to a
62
+ * key, and the context the host builds. Following the contract of a body, its
63
+ * only effect is to emit commands and calls through that context.
64
+ */
65
+ export interface Action<C = RunTrace> extends ActionDefinition {
66
+ run(params: any, context: C): unknown;
67
+ }
68
+ /**
69
+ * The instances a `ref` value names, as the engine finds them: the key of the
70
+ * instance whose id is the value, if any, and the keys of the instances whose
71
+ * `display_name` is the value, in any language.
72
+ */
73
+ export interface RefMatches {
74
+ readonly id: string | null;
75
+ readonly names: readonly string[];
76
+ }
77
+ /**
78
+ * Finds the instances of `schema` a `ref` value names. The engine gives it,
79
+ * since this package reads no instance; the package applies the rule of
80
+ * resolution (see `validateParameters`).
81
+ */
82
+ export type RefResolver = (schema: string, value: string) => RefMatches | Promise<RefMatches>;
83
+ /** What a host gives a run: the context of bodies, the resolver of `ref` and the run log. */
84
+ export interface RunHost<C = RunTrace> {
85
+ /** Builds the context a body receives from the trace of its run. Absent, the body receives the trace. */
86
+ context?(trace: RunTrace): C;
87
+ /** Resolves the `ref` values of parameters. Absent, a `ref` value is given to the body as it is. */
88
+ resolveRef?: RefResolver;
89
+ /** Receives the entry of each top-level call, done or refused. A nested call is a step of its caller. */
90
+ onEntry?(entry: RunEntry): void;
91
+ }
92
+ /** One call of an action, as it ran (`run_entry` of the specification). */
93
+ export interface RunEntry {
94
+ /** The id of the action. */
95
+ readonly action: string;
96
+ /** The parameters in canonical JSON, after their check with each ref resolved; as given when they were refused. */
97
+ readonly parameters: string;
98
+ /** What the body emitted, in order. */
99
+ readonly steps: readonly RunStep[];
100
+ readonly outcome: "done" | "refused";
101
+ /** The code of the exception of a refused call, or its message when it has no code. */
102
+ readonly error?: string;
103
+ /** The result of the action in canonical JSON; absent when the action returned none. */
104
+ readonly result?: string;
105
+ }
106
+ /** One effect of a body (`run_step`): a command with its result, or a call. */
107
+ export type RunStep = {
108
+ readonly command: unknown;
109
+ readonly result: string;
110
+ } | {
111
+ readonly call: RunEntry;
112
+ };
113
+ /** What a run gives: the result of the body and the entry of the call. */
114
+ export interface RunOutcome {
115
+ readonly result: unknown;
116
+ readonly entry: RunEntry;
117
+ }
118
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}