@project-ajax/sdk 0.0.28
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 +22 -0
- package/dist/block.d.ts +321 -0
- package/dist/block.d.ts.map +1 -0
- package/dist/block.js +0 -0
- package/dist/builder.d.ts +12 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +22 -0
- package/dist/capabilities/slashCommand.d.ts +56 -0
- package/dist/capabilities/slashCommand.d.ts.map +1 -0
- package/dist/capabilities/slashCommand.js +32 -0
- package/dist/capabilities/sync.d.ts +58 -0
- package/dist/capabilities/sync.d.ts.map +1 -0
- package/dist/capabilities/sync.js +26 -0
- package/dist/capabilities/tool.d.ts +69 -0
- package/dist/capabilities/tool.d.ts.map +1 -0
- package/dist/capabilities/tool.js +75 -0
- package/dist/capabilities/tool.test.d.ts +2 -0
- package/dist/capabilities/tool.test.d.ts.map +1 -0
- package/dist/cli/api/client.d.ts +185 -0
- package/dist/cli/api/client.d.ts.map +1 -0
- package/dist/cli/api/client.js +315 -0
- package/dist/cli/api/result.d.ts +43 -0
- package/dist/cli/api/result.d.ts.map +1 -0
- package/dist/cli/api/result.js +43 -0
- package/dist/cli/bin/cli.d.ts +3 -0
- package/dist/cli/bin/cli.d.ts.map +1 -0
- package/dist/cli/bin/cli.js +5 -0
- package/dist/cli/commands/auth.d.ts +2 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.impl.d.ts +10 -0
- package/dist/cli/commands/auth.impl.d.ts.map +1 -0
- package/dist/cli/commands/auth.impl.js +68 -0
- package/dist/cli/commands/auth.js +71 -0
- package/dist/cli/commands/bundle.d.ts +2 -0
- package/dist/cli/commands/bundle.d.ts.map +1 -0
- package/dist/cli/commands/bundle.impl.d.ts +2 -0
- package/dist/cli/commands/bundle.impl.d.ts.map +1 -0
- package/dist/cli/commands/bundle.impl.js +21 -0
- package/dist/cli/commands/bundle.js +23 -0
- package/dist/cli/commands/capabilities.d.ts +2 -0
- package/dist/cli/commands/capabilities.d.ts.map +1 -0
- package/dist/cli/commands/capabilities.impl.d.ts +3 -0
- package/dist/cli/commands/capabilities.impl.d.ts.map +1 -0
- package/dist/cli/commands/capabilities.impl.js +40 -0
- package/dist/cli/commands/capabilities.js +24 -0
- package/dist/cli/commands/deploy.d.ts +3 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.impl.d.ts +2 -0
- package/dist/cli/commands/deploy.impl.d.ts.map +1 -0
- package/dist/cli/commands/deploy.impl.js +31 -0
- package/dist/cli/commands/deploy.js +16 -0
- package/dist/cli/commands/exec.d.ts +3 -0
- package/dist/cli/commands/exec.d.ts.map +1 -0
- package/dist/cli/commands/exec.impl.d.ts +7 -0
- package/dist/cli/commands/exec.impl.d.ts.map +1 -0
- package/dist/cli/commands/exec.impl.js +122 -0
- package/dist/cli/commands/exec.js +30 -0
- package/dist/cli/commands/runs.d.ts +2 -0
- package/dist/cli/commands/runs.d.ts.map +1 -0
- package/dist/cli/commands/runs.impl.d.ts +4 -0
- package/dist/cli/commands/runs.impl.d.ts.map +1 -0
- package/dist/cli/commands/runs.impl.js +71 -0
- package/dist/cli/commands/runs.js +45 -0
- package/dist/cli/commands/secrets.d.ts +2 -0
- package/dist/cli/commands/secrets.d.ts.map +1 -0
- package/dist/cli/commands/secrets.impl.d.ts +5 -0
- package/dist/cli/commands/secrets.impl.d.ts.map +1 -0
- package/dist/cli/commands/secrets.impl.js +93 -0
- package/dist/cli/commands/secrets.js +64 -0
- package/dist/cli/config.d.ts +38 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/context.d.ts +15 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +16 -0
- package/dist/cli/deploy.d.ts +25 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +101 -0
- package/dist/cli/flags.d.ts +16 -0
- package/dist/cli/flags.d.ts.map +1 -0
- package/dist/cli/flags.js +24 -0
- package/dist/cli/handler.d.ts +14 -0
- package/dist/cli/handler.d.ts.map +1 -0
- package/dist/cli/handler.js +30 -0
- package/dist/cli/routes.d.ts +2 -0
- package/dist/cli/routes.d.ts.map +1 -0
- package/dist/cli/routes.js +44 -0
- package/dist/cli/utils/array.d.ts +2 -0
- package/dist/cli/utils/array.d.ts.map +1 -0
- package/dist/cli/utils/array.js +10 -0
- package/dist/cli/utils/string.d.ts +2 -0
- package/dist/cli/utils/string.d.ts.map +1 -0
- package/dist/cli/utils/string.js +12 -0
- package/dist/cli/writer.d.ts +48 -0
- package/dist/cli/writer.d.ts.map +1 -0
- package/dist/cli/writer.js +73 -0
- package/dist/error.d.ts +8 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +11 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/schema.d.ts +45 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +14 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/package.json +79 -0
- package/src/block.ts +529 -0
- package/src/builder.ts +26 -0
- package/src/capabilities/slashCommand.ts +71 -0
- package/src/capabilities/sync.ts +76 -0
- package/src/capabilities/tool.test.ts +181 -0
- package/src/capabilities/tool.ts +145 -0
- package/src/cli/api/client.ts +588 -0
- package/src/cli/api/result.ts +71 -0
- package/src/cli/bin/cli.ts +7 -0
- package/src/cli/commands/auth.impl.ts +92 -0
- package/src/cli/commands/auth.ts +77 -0
- package/src/cli/commands/bundle.impl.ts +21 -0
- package/src/cli/commands/bundle.ts +23 -0
- package/src/cli/commands/capabilities.impl.ts +47 -0
- package/src/cli/commands/capabilities.ts +25 -0
- package/src/cli/commands/deploy.impl.ts +34 -0
- package/src/cli/commands/deploy.ts +16 -0
- package/src/cli/commands/exec.impl.ts +169 -0
- package/src/cli/commands/exec.ts +32 -0
- package/src/cli/commands/runs.impl.ts +87 -0
- package/src/cli/commands/runs.ts +49 -0
- package/src/cli/commands/secrets.impl.ts +124 -0
- package/src/cli/commands/secrets.ts +73 -0
- package/src/cli/config.ts +175 -0
- package/src/cli/context.ts +26 -0
- package/src/cli/deploy.ts +175 -0
- package/src/cli/flags.ts +43 -0
- package/src/cli/handler.ts +62 -0
- package/src/cli/routes.ts +43 -0
- package/src/cli/utils/array.ts +7 -0
- package/src/cli/utils/string.ts +9 -0
- package/src/cli/writer.ts +97 -0
- package/src/error.ts +12 -0
- package/src/index.ts +3 -0
- package/src/schema.ts +54 -0
- package/src/types.ts +10 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
InvalidToolInputError,
|
|
4
|
+
InvalidToolOutputError,
|
|
5
|
+
ToolExecutionError,
|
|
6
|
+
tool,
|
|
7
|
+
} from "./tool.js";
|
|
8
|
+
|
|
9
|
+
describe("tool", () => {
|
|
10
|
+
it("sync execution", async () => {
|
|
11
|
+
const myTool = tool<{ name: string }, string>({
|
|
12
|
+
description: "Greet a user",
|
|
13
|
+
schema: {
|
|
14
|
+
type: "object",
|
|
15
|
+
properties: {
|
|
16
|
+
name: { type: "string" },
|
|
17
|
+
},
|
|
18
|
+
required: ["name"],
|
|
19
|
+
additionalProperties: false,
|
|
20
|
+
},
|
|
21
|
+
execute: (input) => {
|
|
22
|
+
return `Hello, ${input.name}!`;
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const result = await myTool.handler({ name: "Alice" });
|
|
27
|
+
|
|
28
|
+
expect(result._tag).toBe("success");
|
|
29
|
+
if (result._tag === "success") {
|
|
30
|
+
expect(result.value).toBe("Hello, Alice!");
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("async execution", async () => {
|
|
35
|
+
const myTool = tool<{ id: number }, { data: string }>({
|
|
36
|
+
description: "Fetch data asynchronously",
|
|
37
|
+
schema: {
|
|
38
|
+
type: "object",
|
|
39
|
+
properties: {
|
|
40
|
+
id: { type: "number" },
|
|
41
|
+
},
|
|
42
|
+
required: ["id"],
|
|
43
|
+
additionalProperties: false,
|
|
44
|
+
},
|
|
45
|
+
execute: async (input) => {
|
|
46
|
+
// Simulate async operation
|
|
47
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
48
|
+
return { data: `Data for ID ${input.id}` };
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const result = await myTool.handler({ id: 42 });
|
|
53
|
+
|
|
54
|
+
expect(result._tag).toBe("success");
|
|
55
|
+
if (result._tag === "success") {
|
|
56
|
+
expect(result.value).toEqual({ data: "Data for ID 42" });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("execution error", async () => {
|
|
61
|
+
const myTool = tool<Record<string, never>, string>({
|
|
62
|
+
description: "Throws an error",
|
|
63
|
+
schema: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {},
|
|
66
|
+
required: [],
|
|
67
|
+
additionalProperties: false,
|
|
68
|
+
},
|
|
69
|
+
execute: () => {
|
|
70
|
+
throw new Error("Something went wrong");
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const result = await myTool.handler({});
|
|
75
|
+
|
|
76
|
+
expect(result._tag).toBe("error");
|
|
77
|
+
if (result._tag === "error") {
|
|
78
|
+
expect(result.error).toBeInstanceOf(ToolExecutionError);
|
|
79
|
+
expect(result.error.message).toBe("Something went wrong");
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("invalid input", async () => {
|
|
84
|
+
const myTool = tool<{ name: string }, string>({
|
|
85
|
+
description: "Requires a name property",
|
|
86
|
+
schema: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
name: { type: "string" },
|
|
90
|
+
},
|
|
91
|
+
required: ["name"],
|
|
92
|
+
additionalProperties: false,
|
|
93
|
+
},
|
|
94
|
+
execute: (input) => {
|
|
95
|
+
return `Hello, ${input.name}!`;
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const result = await myTool.handler({ age: 25 });
|
|
100
|
+
|
|
101
|
+
expect(result._tag).toBe("error");
|
|
102
|
+
if (result._tag === "error") {
|
|
103
|
+
expect(result.error).toBeInstanceOf(InvalidToolInputError);
|
|
104
|
+
expect(result.error.message).toContain("name");
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("invalid output", async () => {
|
|
109
|
+
const myTool = tool<Record<string, never>, { result: string }>({
|
|
110
|
+
name: "returnInvalidOutput",
|
|
111
|
+
description: "Returns output that doesn't match schema",
|
|
112
|
+
schema: {
|
|
113
|
+
type: "object",
|
|
114
|
+
properties: {},
|
|
115
|
+
required: [],
|
|
116
|
+
additionalProperties: false,
|
|
117
|
+
},
|
|
118
|
+
outputSchema: {
|
|
119
|
+
type: "object",
|
|
120
|
+
properties: {
|
|
121
|
+
result: { type: "string" },
|
|
122
|
+
},
|
|
123
|
+
required: ["result"],
|
|
124
|
+
additionalProperties: false,
|
|
125
|
+
},
|
|
126
|
+
// @ts-expect-error Testing invalid output - intentionally returning number instead of string
|
|
127
|
+
execute: () => {
|
|
128
|
+
return { result: 123 };
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const result = await myTool.handler({});
|
|
133
|
+
|
|
134
|
+
expect(result._tag).toBe("error");
|
|
135
|
+
if (result._tag === "error") {
|
|
136
|
+
expect(result.error).toBeInstanceOf(InvalidToolOutputError);
|
|
137
|
+
expect(result.error.message).toContain("result");
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("invalid output with custom output schema", async () => {
|
|
142
|
+
const myTool = tool<
|
|
143
|
+
{ value: number },
|
|
144
|
+
{ doubled: number; message: string }
|
|
145
|
+
>({
|
|
146
|
+
name: "customOutput",
|
|
147
|
+
description: "Has custom output schema",
|
|
148
|
+
schema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
value: { type: "number" },
|
|
152
|
+
},
|
|
153
|
+
required: ["value"],
|
|
154
|
+
additionalProperties: false,
|
|
155
|
+
},
|
|
156
|
+
outputSchema: {
|
|
157
|
+
type: "object",
|
|
158
|
+
properties: {
|
|
159
|
+
doubled: { type: "number" },
|
|
160
|
+
message: { type: "string" },
|
|
161
|
+
},
|
|
162
|
+
required: ["doubled", "message"],
|
|
163
|
+
additionalProperties: false,
|
|
164
|
+
},
|
|
165
|
+
// @ts-expect-error Testing invalid output - intentionally missing message property
|
|
166
|
+
execute: (input) => {
|
|
167
|
+
return {
|
|
168
|
+
doubled: input.value * 2,
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const result = await myTool.handler({ value: 5 });
|
|
174
|
+
|
|
175
|
+
expect(result._tag).toBe("error");
|
|
176
|
+
if (result._tag === "error") {
|
|
177
|
+
expect(result.error).toBeInstanceOf(InvalidToolOutputError);
|
|
178
|
+
expect(result.error.message).toContain("message");
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Ajv, type JSONSchemaType } from "ajv";
|
|
2
|
+
|
|
3
|
+
type JSONValue =
|
|
4
|
+
| string
|
|
5
|
+
| number
|
|
6
|
+
| boolean
|
|
7
|
+
| null
|
|
8
|
+
| JSONValue[]
|
|
9
|
+
| { [key: string]: JSONValue };
|
|
10
|
+
|
|
11
|
+
export interface ToolConfiguration<
|
|
12
|
+
I extends JSONValue,
|
|
13
|
+
O extends JSONValue = JSONValue,
|
|
14
|
+
> {
|
|
15
|
+
description: string;
|
|
16
|
+
schema: JSONSchemaType<I>;
|
|
17
|
+
outputSchema?: JSONSchemaType<O>;
|
|
18
|
+
execute: (input: I) => O | Promise<O>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* An error returned when the input to a tool doesn't match the input schema.
|
|
23
|
+
*/
|
|
24
|
+
export class InvalidToolInputError extends Error {
|
|
25
|
+
constructor(message: string) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "InvalidToolInputError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* An error returned when the output from a tool doesn't match the output schema.
|
|
33
|
+
*/
|
|
34
|
+
export class InvalidToolOutputError extends Error {
|
|
35
|
+
constructor(message: string) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = "InvalidToolOutputError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* An error returned when the tool execution fails.
|
|
43
|
+
*/
|
|
44
|
+
export class ToolExecutionError extends Error {
|
|
45
|
+
constructor(message: string) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.name = "ToolExecutionError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Creates a capability definition for a tool to be used by an agent.
|
|
53
|
+
*
|
|
54
|
+
* Example:
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* tool<{ name: string }>({
|
|
58
|
+
* description: "Say hello to the user",
|
|
59
|
+
* schema: {
|
|
60
|
+
* type: "object",
|
|
61
|
+
* properties: {
|
|
62
|
+
* name: { type: "string" },
|
|
63
|
+
* },
|
|
64
|
+
* required: ["name"],
|
|
65
|
+
* },
|
|
66
|
+
* execute: ({ name }) => {
|
|
67
|
+
* return `Hello, ${name}!`;
|
|
68
|
+
* },
|
|
69
|
+
* })
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @param config - The configuration for the tool.
|
|
73
|
+
* @returns A capability definition for the tool.
|
|
74
|
+
*/
|
|
75
|
+
export function tool<I extends JSONValue, O extends JSONValue = JSONValue>(
|
|
76
|
+
config: ToolConfiguration<I, O>,
|
|
77
|
+
) {
|
|
78
|
+
const ajv = new Ajv();
|
|
79
|
+
const validateInput = ajv.compile(config.schema);
|
|
80
|
+
const validateOutput = config.outputSchema
|
|
81
|
+
? ajv.compile(config.outputSchema)
|
|
82
|
+
: null;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
_tag: "tool",
|
|
86
|
+
config: {
|
|
87
|
+
description: config.description,
|
|
88
|
+
schema: config.schema,
|
|
89
|
+
outputSchema: config.outputSchema,
|
|
90
|
+
},
|
|
91
|
+
async handler(input: JSONValue): Promise<
|
|
92
|
+
| {
|
|
93
|
+
_tag: "success";
|
|
94
|
+
value: O;
|
|
95
|
+
}
|
|
96
|
+
| {
|
|
97
|
+
_tag: "error";
|
|
98
|
+
error:
|
|
99
|
+
| InvalidToolInputError
|
|
100
|
+
| InvalidToolOutputError
|
|
101
|
+
| ToolExecutionError;
|
|
102
|
+
}
|
|
103
|
+
> {
|
|
104
|
+
if (!validateInput(input)) {
|
|
105
|
+
// ajv resets the "errors" property on each validation call.
|
|
106
|
+
if (validateInput.errors == null) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"Unexpected: No validation errors after failed validation",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
_tag: "error" as const,
|
|
114
|
+
error: new InvalidToolInputError(
|
|
115
|
+
JSON.stringify(validateInput.errors, null, 2),
|
|
116
|
+
),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const result = await config.execute(input);
|
|
122
|
+
if (validateOutput && !validateOutput(result)) {
|
|
123
|
+
return {
|
|
124
|
+
_tag: "error" as const,
|
|
125
|
+
error: new InvalidToolOutputError(
|
|
126
|
+
JSON.stringify(validateOutput.errors, null, 2),
|
|
127
|
+
),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
_tag: "success" as const,
|
|
133
|
+
value: result,
|
|
134
|
+
};
|
|
135
|
+
} catch (err) {
|
|
136
|
+
return {
|
|
137
|
+
_tag: "error" as const,
|
|
138
|
+
error: new ToolExecutionError(
|
|
139
|
+
err instanceof Error ? err.message : String(err),
|
|
140
|
+
),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|