@statelyai/agent 0.0.2 → 0.0.4
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/.changeset/config.json +1 -1
- package/.env.template +6 -0
- package/.github/actions/ci-setup/action.yml +24 -0
- package/.github/workflows/release.yml +35 -0
- package/CHANGELOG.md +14 -0
- package/dist/index.d.ts +38 -44
- package/dist/index.js +64 -39
- package/examples/helpers/helpers.ts +17 -0
- package/examples/helpers/loader.ts +32 -0
- package/examples/helpers/runner.ts +27 -0
- package/examples/joke.ts +121 -56
- package/examples/multiAgentCollaboration.ts +0 -0
- package/examples/ticTacToe.ts +41 -66
- package/examples/weather.ts +160 -0
- package/package.json +14 -6
- package/readme.md +41 -0
- package/src/{openai.ts → adapters/openai.ts} +68 -58
- package/src/agent.ts +8 -0
- package/src/index.ts +3 -6
- package/src/schemas.ts +38 -0
- package/dist/index.d.mts +0 -3
- package/dist/index.mjs +0 -7
package/.changeset/config.json
CHANGED
package/.env.template
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Setup Workflow
|
|
2
|
+
description: Composite action that sets up pnpm
|
|
3
|
+
runs:
|
|
4
|
+
using: 'composite'
|
|
5
|
+
steps:
|
|
6
|
+
- uses: pnpm/action-setup@v2
|
|
7
|
+
- uses: actions/setup-node@v4
|
|
8
|
+
with:
|
|
9
|
+
node-version: 20.x
|
|
10
|
+
|
|
11
|
+
- name: Get pnpm store directory
|
|
12
|
+
shell: bash
|
|
13
|
+
id: pnpm-cache
|
|
14
|
+
run: |
|
|
15
|
+
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
16
|
+
- uses: actions/cache@v4
|
|
17
|
+
name: Setup pnpm cache
|
|
18
|
+
with:
|
|
19
|
+
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
|
|
20
|
+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
|
21
|
+
restore-keys: |
|
|
22
|
+
${{ runner.os }}-pnpm-store-
|
|
23
|
+
- run: pnpm install
|
|
24
|
+
shell: bash
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
9
|
+
|
|
10
|
+
permissions: {}
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
permissions:
|
|
14
|
+
contents: write # to create release (changesets/action)
|
|
15
|
+
issues: write # to post issue comments (changesets/action)
|
|
16
|
+
pull-requests: write # to create pull request (changesets/action)
|
|
17
|
+
|
|
18
|
+
if: github.repository == 'statelyai/agent'
|
|
19
|
+
|
|
20
|
+
timeout-minutes: 20
|
|
21
|
+
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v3
|
|
26
|
+
- uses: ./.github/actions/ci-setup
|
|
27
|
+
|
|
28
|
+
- name: Create Release Pull Request or Publish to npm
|
|
29
|
+
uses: changesets/action@v1
|
|
30
|
+
with:
|
|
31
|
+
publish: pnpm run release
|
|
32
|
+
version: pnpm run version
|
|
33
|
+
env:
|
|
34
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
35
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @statelyai/agent
|
|
2
2
|
|
|
3
|
+
## 0.0.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#5](https://github.com/statelyai/agent/pull/5) [`ae473d7`](https://github.com/statelyai/agent/commit/ae473d73399a15ac3199d77d00eb44a0ea5626db) Thanks [@davidkpiano](https://github.com/davidkpiano)! - Simplify API (WIP)
|
|
8
|
+
|
|
9
|
+
- [#5](https://github.com/statelyai/agent/pull/5) [`687bed8`](https://github.com/statelyai/agent/commit/687bed87f29bd1d13447cc53b5154da0fe6fdcab) Thanks [@davidkpiano](https://github.com/davidkpiano)! - Add `createSchemas`, `createOpenAIAdapter`, and change `createAgent`
|
|
10
|
+
|
|
11
|
+
## 0.0.3
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#1](https://github.com/statelyai/agent/pull/1) [`3dc2880`](https://github.com/statelyai/agent/commit/3dc28809a7ffd915a69d9f3374531c31fc1ee357) Thanks [@mellson](https://github.com/mellson)! - Adds a convenient way to run the examples with `pnpm example ${exampleName}`. If no example name is provided, the script will print the available examples. Also, adds a fun little loading animation to the joke example.
|
|
16
|
+
|
|
3
17
|
## 0.0.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Prop,
|
|
1
|
+
import * as xstate from 'xstate';
|
|
2
|
+
import { Prop, Values, AnyStateMachine, createActor, PromiseActorLogic, AnyEventObject, ObservableActorLogic } from 'xstate';
|
|
3
3
|
import { JSONSchema7 } from 'json-schema-to-ts/lib/types/definitions';
|
|
4
4
|
import { FromSchema } from 'json-schema-to-ts';
|
|
5
|
+
import OpenAI from 'openai';
|
|
5
6
|
import { ChatCompletionCreateParamsNonStreaming } from 'openai/resources';
|
|
6
7
|
import { ChatCompletionCreateParamsBase, ChatCompletionCreateParamsStreaming } from 'openai/resources/chat/completions';
|
|
7
8
|
|
|
@@ -35,52 +36,45 @@ type ConvertContextToJSONSchema<T extends ContextSchema> = {
|
|
|
35
36
|
additionalProperties: false;
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* Creates [observable actor logic](https://stately.ai/docs/observable-actors) that uses the OpenAI API to generate a completion stream.
|
|
48
|
-
*
|
|
49
|
-
* @param openai The OpenAI instance to use.
|
|
50
|
-
* @param inputFn A function that maps arbitrary input to OpenAI chat completion input.
|
|
51
|
-
*/
|
|
52
|
-
declare function fromChatCompletionStream<TInput>(openai: OpenAI, inputFn: (input: TInput) => string | OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming): ObservableActorLogic<OpenAI.Chat.Completions.ChatCompletionChunk, TInput>;
|
|
53
|
-
/**
|
|
54
|
-
* Creates [promise actor logic](https://stately.ai/docs/promise-actors) that passes the next possible transitions as functions to [OpenAI tool calls](https://platform.openai.com/docs/guides/function-calling) and returns an array of potential next events.
|
|
55
|
-
*
|
|
56
|
-
* @param openai The OpenAI instance to use.
|
|
57
|
-
* @param inputFn A function that maps arbitrary input to OpenAI chat completion input.
|
|
58
|
-
*/
|
|
59
|
-
declare function fromEventChoice<TInput>(openai: OpenAI, machineTypes: {
|
|
60
|
-
schemas: {
|
|
61
|
-
context: ContextSchema;
|
|
62
|
-
events: EventSchemas;
|
|
39
|
+
declare function createSchemas<TContextSchema extends ContextSchema, TEventSchemas extends EventSchemas>({ context, events, }: {
|
|
40
|
+
context: TContextSchema;
|
|
41
|
+
events: TEventSchemas;
|
|
42
|
+
}): {
|
|
43
|
+
context: ConvertContextToJSONSchema<TContextSchema>;
|
|
44
|
+
events: ConvertToJSONSchemas<TEventSchemas>;
|
|
45
|
+
types: {
|
|
46
|
+
context: FromSchema<ConvertContextToJSONSchema<TContextSchema>>;
|
|
47
|
+
events: FromSchema<Values<ConvertToJSONSchemas<TEventSchemas>>>;
|
|
63
48
|
};
|
|
64
|
-
}
|
|
65
|
-
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
declare function createAgent<T extends AnyStateMachine>(...args: Parameters<typeof createActor<T>>): xstate.Actor<T>;
|
|
52
|
+
|
|
53
|
+
interface OpenAIAdapterOutput<T extends {
|
|
66
54
|
model: ChatCompletionCreateParamsBase['model'];
|
|
67
|
-
context: ContextSchema;
|
|
68
|
-
events: EventSchemas;
|
|
69
55
|
}> {
|
|
70
56
|
model: T['model'];
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Determines which event to send to the parent state machine actor based on the prompt.
|
|
59
|
+
*/
|
|
60
|
+
fromEventChoice: <TInput>(inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming, options?: {
|
|
61
|
+
/**
|
|
62
|
+
* Immediately execute sending the event to the parent actor.
|
|
63
|
+
* @default true
|
|
64
|
+
*/
|
|
65
|
+
execute?: boolean;
|
|
66
|
+
}) => PromiseActorLogic<AnyEventObject[] | undefined, TInput>;
|
|
67
|
+
/**
|
|
68
|
+
* Creates promise actor logic that resolves with a chat completion.
|
|
69
|
+
*/
|
|
70
|
+
fromChat: <TInput>(inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming) => PromiseActorLogic<OpenAI.Chat.Completions.ChatCompletion, TInput>;
|
|
71
|
+
/**
|
|
72
|
+
* Creates observable actor logic that emits a chat completion stream.
|
|
73
|
+
*/
|
|
74
|
+
fromChatStream: <TInput>(inputFn: (input: TInput) => string | ChatCompletionCreateParamsStreaming) => ObservableActorLogic<OpenAI.Chat.Completions.ChatCompletionChunk, TInput>;
|
|
79
75
|
}
|
|
80
|
-
declare function
|
|
76
|
+
declare function createOpenAIAdapter<T extends {
|
|
81
77
|
model: ChatCompletionCreateParamsBase['model'];
|
|
82
|
-
|
|
83
|
-
events: EventSchemas;
|
|
84
|
-
}>(openai: OpenAI, settings: T): CreateAgentOutput<T>;
|
|
78
|
+
}>(openai: OpenAI, settings: T): OpenAIAdapterOutput<T>;
|
|
85
79
|
|
|
86
|
-
export { createAgent,
|
|
80
|
+
export { createAgent, createOpenAIAdapter, createSchemas };
|
package/dist/index.js
CHANGED
|
@@ -21,15 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
createAgent: () => createAgent,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
fromEventChoice: () => fromEventChoice
|
|
24
|
+
createOpenAIAdapter: () => createOpenAIAdapter,
|
|
25
|
+
createSchemas: () => createSchemas
|
|
27
26
|
});
|
|
28
27
|
module.exports = __toCommonJS(src_exports);
|
|
29
28
|
|
|
30
|
-
// src/openai.ts
|
|
31
|
-
var import_xstate = require("xstate");
|
|
32
|
-
|
|
33
29
|
// src/utils.ts
|
|
34
30
|
function getAllTransitions(state) {
|
|
35
31
|
const nodes = state._nodes;
|
|
@@ -55,13 +51,38 @@ function createEventSchemas(eventSchemaMap) {
|
|
|
55
51
|
return resolvedEventSchemaMap;
|
|
56
52
|
}
|
|
57
53
|
|
|
58
|
-
// src/
|
|
59
|
-
function
|
|
60
|
-
|
|
54
|
+
// src/schemas.ts
|
|
55
|
+
function createSchemas({
|
|
56
|
+
context,
|
|
57
|
+
events
|
|
58
|
+
}) {
|
|
59
|
+
return {
|
|
60
|
+
context: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: context,
|
|
63
|
+
additionalProperties: false,
|
|
64
|
+
required: Object.keys(context)
|
|
65
|
+
},
|
|
66
|
+
events: createEventSchemas(events),
|
|
67
|
+
types: {}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/agent.ts
|
|
72
|
+
var import_xstate = require("xstate");
|
|
73
|
+
function createAgent(...args) {
|
|
74
|
+
const [machine, options] = args;
|
|
75
|
+
return (0, import_xstate.createActor)(machine, options);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/adapters/openai.ts
|
|
79
|
+
var import_xstate2 = require("xstate");
|
|
80
|
+
function fromChatCompletion(openai, agentSettings, inputFn) {
|
|
81
|
+
return (0, import_xstate2.fromPromise)(
|
|
61
82
|
async ({ input }) => {
|
|
62
83
|
const openAiInput = inputFn(input);
|
|
63
84
|
const params = typeof openAiInput === "string" ? {
|
|
64
|
-
model:
|
|
85
|
+
model: agentSettings.model,
|
|
65
86
|
messages: [
|
|
66
87
|
{
|
|
67
88
|
role: "user",
|
|
@@ -74,14 +95,14 @@ function fromChatCompletion(openai, inputFn) {
|
|
|
74
95
|
}
|
|
75
96
|
);
|
|
76
97
|
}
|
|
77
|
-
function
|
|
78
|
-
return (0,
|
|
98
|
+
function fromChatStream(openai, agentSettings, inputFn) {
|
|
99
|
+
return (0, import_xstate2.fromObservable)(
|
|
79
100
|
({ input }) => {
|
|
80
101
|
const observers = /* @__PURE__ */ new Set();
|
|
81
102
|
(async () => {
|
|
82
103
|
const openAiInput = inputFn(input);
|
|
83
104
|
const resolvedParams = typeof openAiInput === "string" ? {
|
|
84
|
-
model:
|
|
105
|
+
model: agentSettings.model,
|
|
85
106
|
messages: [
|
|
86
107
|
{
|
|
87
108
|
role: "user",
|
|
@@ -101,7 +122,7 @@ function fromChatCompletionStream(openai, inputFn) {
|
|
|
101
122
|
})();
|
|
102
123
|
return {
|
|
103
124
|
subscribe: (...args) => {
|
|
104
|
-
const observer = (0,
|
|
125
|
+
const observer = (0, import_xstate2.toObserver)(...args);
|
|
105
126
|
observers.add(observer);
|
|
106
127
|
return {
|
|
107
128
|
unsubscribe: () => {
|
|
@@ -113,9 +134,15 @@ function fromChatCompletionStream(openai, inputFn) {
|
|
|
113
134
|
}
|
|
114
135
|
);
|
|
115
136
|
}
|
|
116
|
-
function fromEventChoice(openai,
|
|
117
|
-
return (0,
|
|
118
|
-
async ({ input, self }) => {
|
|
137
|
+
function fromEventChoice(openai, agentSettings, inputFn, options) {
|
|
138
|
+
return (0, import_xstate2.fromPromise)(
|
|
139
|
+
async ({ input, self, system }) => {
|
|
140
|
+
const parentSnapshot = self._parent?.getSnapshot();
|
|
141
|
+
if (!parentSnapshot || !(0, import_xstate2.isMachineSnapshot)(parentSnapshot)) {
|
|
142
|
+
return void 0;
|
|
143
|
+
}
|
|
144
|
+
const schemas = parentSnapshot.machine.schemas;
|
|
145
|
+
const eventSchemaMap = schemas.events ?? {};
|
|
119
146
|
const transitions = getAllTransitions(self._parent.getSnapshot());
|
|
120
147
|
const functionNameMapping = {};
|
|
121
148
|
const tools = transitions.filter((t) => {
|
|
@@ -127,17 +154,17 @@ function fromEventChoice(openai, machineTypes, inputFn) {
|
|
|
127
154
|
type: "function",
|
|
128
155
|
function: {
|
|
129
156
|
name,
|
|
130
|
-
description: t.description ??
|
|
157
|
+
description: t.description ?? eventSchemaMap[t.eventType]?.description,
|
|
131
158
|
parameters: {
|
|
132
159
|
type: "object",
|
|
133
|
-
properties:
|
|
160
|
+
properties: eventSchemaMap[t.eventType]?.properties ?? {}
|
|
134
161
|
}
|
|
135
162
|
}
|
|
136
163
|
};
|
|
137
164
|
});
|
|
138
165
|
const openAiInput = inputFn(input);
|
|
139
166
|
const completionParams = typeof openAiInput === "string" ? {
|
|
140
|
-
model:
|
|
167
|
+
model: agentSettings.model,
|
|
141
168
|
messages: [
|
|
142
169
|
{
|
|
143
170
|
role: "user",
|
|
@@ -151,39 +178,37 @@ function fromEventChoice(openai, machineTypes, inputFn) {
|
|
|
151
178
|
});
|
|
152
179
|
const toolCalls = completion.choices[0]?.message.tool_calls;
|
|
153
180
|
if (toolCalls) {
|
|
154
|
-
|
|
181
|
+
const events = toolCalls.map((tc) => {
|
|
155
182
|
return {
|
|
156
183
|
type: functionNameMapping[tc.function.name],
|
|
157
184
|
...JSON.parse(tc.function.arguments)
|
|
158
185
|
};
|
|
159
186
|
});
|
|
187
|
+
if (options?.execute) {
|
|
188
|
+
events.forEach((event) => {
|
|
189
|
+
system._relay(self, self._parent, event);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
160
192
|
}
|
|
161
193
|
return void 0;
|
|
162
194
|
}
|
|
163
195
|
);
|
|
164
196
|
}
|
|
165
|
-
function
|
|
166
|
-
const
|
|
197
|
+
function createOpenAIAdapter(openai, settings) {
|
|
198
|
+
const agentSettings = {
|
|
167
199
|
model: settings.model,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
events: createEventSchemas(settings.events)
|
|
175
|
-
},
|
|
176
|
-
types: {},
|
|
177
|
-
fromEventChoice: (input) => fromEventChoice(openai, obj, input),
|
|
178
|
-
fromChatCompletion: (input) => fromChatCompletion(openai, input),
|
|
179
|
-
fromChatCompletionStream: (input) => fromChatCompletionStream(openai, input)
|
|
200
|
+
fromEventChoice: (input) => (
|
|
201
|
+
// @ts-ignore infinitely deep
|
|
202
|
+
fromEventChoice(openai, agentSettings, input, { execute: true })
|
|
203
|
+
),
|
|
204
|
+
fromChat: (input) => fromChatCompletion(openai, agentSettings, input),
|
|
205
|
+
fromChatStream: (input) => fromChatStream(openai, agentSettings, input)
|
|
180
206
|
};
|
|
181
|
-
return
|
|
207
|
+
return agentSettings;
|
|
182
208
|
}
|
|
183
209
|
// Annotate the CommonJS export names for ESM import in node:
|
|
184
210
|
0 && (module.exports = {
|
|
185
211
|
createAgent,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
fromEventChoice
|
|
212
|
+
createOpenAIAdapter,
|
|
213
|
+
createSchemas
|
|
189
214
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { fromPromise } from 'xstate';
|
|
2
|
+
|
|
3
|
+
export const getFromTerminal = fromPromise<string, string>(
|
|
4
|
+
async ({ input }) => {
|
|
5
|
+
const topic = await new Promise<string>((res) => {
|
|
6
|
+
console.log(input + '\n');
|
|
7
|
+
const listener = (data: Buffer) => {
|
|
8
|
+
const result = data.toString().trim();
|
|
9
|
+
process.stdin.off('data', listener);
|
|
10
|
+
res(result);
|
|
11
|
+
};
|
|
12
|
+
process.stdin.on('data', listener);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return topic;
|
|
16
|
+
}
|
|
17
|
+
);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Adapted from https://stackoverflow.com/questions/34848505/how-to-make-a-loading-animation-in-console-application-written-in-javascript-or
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create and display a loader in the console.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} [text=""] Text to display after loader
|
|
7
|
+
* @param {array.<string>} [chars=["⠙", "⠘", "⠰", "⠴", "⠤", "⠦", "⠆", "⠃", "⠋", "⠉"]]
|
|
8
|
+
* Array of characters representing loader steps
|
|
9
|
+
* @param {number} [delay=100] Delay in ms between loader steps
|
|
10
|
+
* @example
|
|
11
|
+
* let loader = loadingAnimation("Loading…");
|
|
12
|
+
*
|
|
13
|
+
* // Stop loader after 1 second
|
|
14
|
+
* setTimeout(() => clearInterval(loader), 1000);
|
|
15
|
+
* @returns {number} An interval that can be cleared to stop the animation
|
|
16
|
+
*/
|
|
17
|
+
export function loadingAnimation(
|
|
18
|
+
text: string = '',
|
|
19
|
+
chars: Array<string> = ['⠙', '⠘', '⠰', '⠴', '⠤', '⠦', '⠆', '⠃', '⠋', '⠉'],
|
|
20
|
+
delay: number = 100
|
|
21
|
+
) {
|
|
22
|
+
let x = 0;
|
|
23
|
+
|
|
24
|
+
const i = setInterval(function () {
|
|
25
|
+
process.stdout.write('\r' + chars[x++] + ' ' + text);
|
|
26
|
+
x = x % chars.length;
|
|
27
|
+
}, delay);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
stop: () => clearInterval(i),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
import { existsSync, readdirSync } from 'fs';
|
|
3
|
+
dotenv.config();
|
|
4
|
+
|
|
5
|
+
function showExamples() {
|
|
6
|
+
const exampleFiles = readdirSync('./examples', { withFileTypes: true });
|
|
7
|
+
exampleFiles.forEach((file) => {
|
|
8
|
+
if (file.isDirectory()) return;
|
|
9
|
+
const exampleName = file.name.split('.')[0];
|
|
10
|
+
console.log(`- ${exampleName}`);
|
|
11
|
+
});
|
|
12
|
+
process.exit();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const exampleParams = process.argv.slice(2);
|
|
16
|
+
if (exampleParams.length === 0) {
|
|
17
|
+
console.error('No example specified, you can choose from:');
|
|
18
|
+
showExamples();
|
|
19
|
+
}
|
|
20
|
+
const exampleName = exampleParams[0];
|
|
21
|
+
const filePath = `./examples/${exampleName}.ts`;
|
|
22
|
+
if (existsSync(filePath)) {
|
|
23
|
+
require(`../${exampleName}.ts`);
|
|
24
|
+
} else {
|
|
25
|
+
console.error(`Example ${exampleName} does not exist, you can choose from:`);
|
|
26
|
+
showExamples();
|
|
27
|
+
}
|