@aigne/core 0.0.1
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/lib/cjs/assistant/generate-output.js +101 -0
- package/lib/cjs/assistant/select-agent.js +76 -0
- package/lib/cjs/assistant/type.js +11 -0
- package/lib/cjs/common/aid.js +42 -0
- package/lib/cjs/common/index.js +238 -0
- package/lib/cjs/common/resource-manager.js +199 -0
- package/lib/cjs/constants.js +9 -0
- package/lib/cjs/executor/agent.js +10 -0
- package/lib/cjs/executor/aigc.js +28 -0
- package/lib/cjs/executor/api.js +64 -0
- package/lib/cjs/executor/base.js +676 -0
- package/lib/cjs/executor/blocklet.js +25 -0
- package/lib/cjs/executor/call-agent.js +105 -0
- package/lib/cjs/executor/decision.js +478 -0
- package/lib/cjs/executor/image-blender.js +32 -0
- package/lib/cjs/executor/index.js +81 -0
- package/lib/cjs/executor/llm.js +379 -0
- package/lib/cjs/executor/logic.js +167 -0
- package/lib/cjs/index.js +17 -0
- package/lib/cjs/libs/blocklet/vc.js +92 -0
- package/lib/cjs/libs/openapi/request/index.js +24 -0
- package/lib/cjs/libs/openapi/request/util.js +146 -0
- package/lib/cjs/libs/openapi/types/index.js +17 -0
- package/lib/cjs/libs/openapi/util/call.js +15 -0
- package/lib/cjs/libs/openapi/util/check-schema.js +67 -0
- package/lib/cjs/libs/openapi/util/convert-schema.js +44 -0
- package/lib/cjs/libs/openapi/util/flatten-open-api.js +21 -0
- package/lib/cjs/libs/openapi/util/get-open-api-i18n-text.js +7 -0
- package/lib/cjs/logger.js +4 -0
- package/lib/cjs/runtime/resource-blocklet.js +5 -0
- package/lib/cjs/runtime/runtime.js +143 -0
- package/lib/cjs/types/assistant/index.js +31 -0
- package/lib/cjs/types/assistant/mustache/ReadableMustache.js +69 -0
- package/lib/cjs/types/assistant/mustache/directive.js +35 -0
- package/lib/cjs/types/assistant/mustache/mustache.js +688 -0
- package/lib/cjs/types/common/index.js +2 -0
- package/lib/cjs/types/index.js +20 -0
- package/lib/cjs/types/resource/index.js +47 -0
- package/lib/cjs/types/resource/project.js +35 -0
- package/lib/cjs/types/runtime/agent.js +2 -0
- package/lib/cjs/types/runtime/error.js +18 -0
- package/lib/cjs/types/runtime/index.js +37 -0
- package/lib/cjs/types/runtime/runtime-resource-blocklet-state.js +4 -0
- package/lib/cjs/types/runtime/schema.js +259 -0
- package/lib/cjs/utils/cron-job.js +48 -0
- package/lib/cjs/utils/extract-metadata-transform.js +58 -0
- package/lib/cjs/utils/extract-metadata-transform.test.js +61 -0
- package/lib/cjs/utils/fs.js +49 -0
- package/lib/cjs/utils/get-blocklet-agent.js +351 -0
- package/lib/cjs/utils/geti.js +37 -0
- package/lib/cjs/utils/is-non-nullable.js +20 -0
- package/lib/cjs/utils/render-message.js +23 -0
- package/lib/cjs/utils/resolve-secret-inputs.js +49 -0
- package/lib/cjs/utils/retry.js +19 -0
- package/lib/cjs/utils/task-id.js +7 -0
- package/lib/cjs/utils/tool-calls-transform.js +18 -0
- package/lib/esm/assistant/generate-output.js +91 -0
- package/lib/esm/assistant/select-agent.js +71 -0
- package/lib/esm/assistant/type.js +7 -0
- package/lib/esm/common/aid.js +38 -0
- package/lib/esm/common/index.js +232 -0
- package/lib/esm/common/resource-manager.js +192 -0
- package/lib/esm/constants.js +6 -0
- package/lib/esm/executor/agent.js +6 -0
- package/lib/esm/executor/aigc.js +24 -0
- package/lib/esm/executor/api.js +34 -0
- package/lib/esm/executor/base.js +668 -0
- package/lib/esm/executor/blocklet.js +21 -0
- package/lib/esm/executor/call-agent.js +98 -0
- package/lib/esm/executor/decision.js +471 -0
- package/lib/esm/executor/image-blender.js +25 -0
- package/lib/esm/executor/index.js +74 -0
- package/lib/esm/executor/llm.js +372 -0
- package/lib/esm/executor/logic.js +160 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/libs/blocklet/vc.js +85 -0
- package/lib/esm/libs/openapi/request/index.js +20 -0
- package/lib/esm/libs/openapi/request/util.js +136 -0
- package/lib/esm/libs/openapi/types/index.js +1 -0
- package/lib/esm/libs/openapi/util/call.js +8 -0
- package/lib/esm/libs/openapi/util/check-schema.js +62 -0
- package/lib/esm/libs/openapi/util/convert-schema.js +42 -0
- package/lib/esm/libs/openapi/util/flatten-open-api.js +19 -0
- package/lib/esm/libs/openapi/util/get-open-api-i18n-text.js +5 -0
- package/lib/esm/logger.js +2 -0
- package/lib/esm/runtime/resource-blocklet.js +2 -0
- package/lib/esm/runtime/runtime.js +136 -0
- package/lib/esm/types/assistant/index.js +9 -0
- package/lib/esm/types/assistant/mustache/ReadableMustache.js +63 -0
- package/lib/esm/types/assistant/mustache/directive.js +29 -0
- package/lib/esm/types/assistant/mustache/mustache.js +686 -0
- package/lib/esm/types/common/index.js +1 -0
- package/lib/esm/types/index.js +4 -0
- package/lib/esm/types/resource/index.js +26 -0
- package/lib/esm/types/resource/project.js +29 -0
- package/lib/esm/types/runtime/agent.js +1 -0
- package/lib/esm/types/runtime/error.js +14 -0
- package/lib/esm/types/runtime/index.js +20 -0
- package/lib/esm/types/runtime/runtime-resource-blocklet-state.js +1 -0
- package/lib/esm/types/runtime/schema.js +249 -0
- package/lib/esm/utils/cron-job.js +44 -0
- package/lib/esm/utils/extract-metadata-transform.js +54 -0
- package/lib/esm/utils/extract-metadata-transform.test.js +59 -0
- package/lib/esm/utils/fs.js +41 -0
- package/lib/esm/utils/get-blocklet-agent.js +344 -0
- package/lib/esm/utils/geti.js +30 -0
- package/lib/esm/utils/is-non-nullable.js +13 -0
- package/lib/esm/utils/render-message.js +20 -0
- package/lib/esm/utils/resolve-secret-inputs.js +46 -0
- package/lib/esm/utils/retry.js +16 -0
- package/lib/esm/utils/task-id.js +3 -0
- package/lib/esm/utils/tool-calls-transform.js +15 -0
- package/lib/types/assistant/generate-output.d.ts +29 -0
- package/lib/types/assistant/select-agent.d.ts +14 -0
- package/lib/types/assistant/type.d.ts +61 -0
- package/lib/types/common/aid.d.ts +18 -0
- package/lib/types/common/index.d.ts +7 -0
- package/lib/types/common/resource-manager.d.ts +88 -0
- package/lib/types/constants.d.ts +6 -0
- package/lib/types/executor/agent.d.ts +5 -0
- package/lib/types/executor/aigc.d.ts +9 -0
- package/lib/types/executor/api.d.ts +9 -0
- package/lib/types/executor/base.d.ts +209 -0
- package/lib/types/executor/blocklet.d.ts +9 -0
- package/lib/types/executor/call-agent.d.ts +12 -0
- package/lib/types/executor/decision.d.ts +20 -0
- package/lib/types/executor/image-blender.d.ts +9 -0
- package/lib/types/executor/index.d.ts +8 -0
- package/lib/types/executor/llm.d.ts +38 -0
- package/lib/types/executor/logic.d.ts +9 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/libs/blocklet/vc.d.ts +17 -0
- package/lib/types/libs/openapi/request/index.d.ts +17 -0
- package/lib/types/libs/openapi/request/util.d.ts +40 -0
- package/lib/types/libs/openapi/types/index.d.ts +20 -0
- package/lib/types/libs/openapi/util/call.d.ts +2 -0
- package/lib/types/libs/openapi/util/check-schema.d.ts +3 -0
- package/lib/types/libs/openapi/util/convert-schema.d.ts +8 -0
- package/lib/types/libs/openapi/util/flatten-open-api.d.ts +3 -0
- package/lib/types/libs/openapi/util/get-open-api-i18n-text.d.ts +2 -0
- package/lib/types/logger.d.ts +2 -0
- package/lib/types/runtime/resource-blocklet.d.ts +2 -0
- package/lib/types/runtime/runtime.d.ts +20 -0
- package/lib/types/types/assistant/index.d.ts +405 -0
- package/lib/types/types/assistant/mustache/ReadableMustache.d.ts +2 -0
- package/lib/types/types/assistant/mustache/directive.d.ts +6 -0
- package/lib/types/types/assistant/mustache/mustache.d.ts +2 -0
- package/lib/types/types/common/index.d.ts +45 -0
- package/lib/types/types/index.d.ts +4 -0
- package/lib/types/types/resource/index.d.ts +17 -0
- package/lib/types/types/resource/project.d.ts +41 -0
- package/lib/types/types/runtime/agent.d.ts +33 -0
- package/lib/types/types/runtime/error.d.ts +10 -0
- package/lib/types/types/runtime/index.d.ts +116 -0
- package/lib/types/types/runtime/runtime-resource-blocklet-state.d.ts +5 -0
- package/lib/types/types/runtime/schema.d.ts +110 -0
- package/lib/types/utils/cron-job.d.ts +22 -0
- package/lib/types/utils/extract-metadata-transform.d.ts +16 -0
- package/lib/types/utils/extract-metadata-transform.test.d.ts +1 -0
- package/lib/types/utils/fs.d.ts +9 -0
- package/lib/types/utils/get-blocklet-agent.d.ts +219 -0
- package/lib/types/utils/geti.d.ts +1 -0
- package/lib/types/utils/is-non-nullable.d.ts +2 -0
- package/lib/types/utils/render-message.d.ts +6 -0
- package/lib/types/utils/resolve-secret-inputs.d.ts +11 -0
- package/lib/types/utils/retry.d.ts +1 -0
- package/lib/types/utils/task-id.d.ts +1 -0
- package/lib/types/utils/tool-calls-transform.d.ts +2 -0
- package/package.json +67 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
import { projectSettingsSchema } from './project';
|
|
3
|
+
export * from './project';
|
|
4
|
+
export const ResourceTypes = [
|
|
5
|
+
'application',
|
|
6
|
+
'tool',
|
|
7
|
+
'llm-adapter',
|
|
8
|
+
'aigc-adapter',
|
|
9
|
+
'knowledge',
|
|
10
|
+
'template',
|
|
11
|
+
'example',
|
|
12
|
+
];
|
|
13
|
+
const resourceProjectSchema = Joi.object({
|
|
14
|
+
project: projectSettingsSchema.required(),
|
|
15
|
+
agents: Joi.array().items(Joi.object()).required(),
|
|
16
|
+
config: Joi.object().default({}),
|
|
17
|
+
cron: Joi.object().default({}),
|
|
18
|
+
memory: Joi.object().default({}),
|
|
19
|
+
}).options({ stripUnknown: true });
|
|
20
|
+
export async function validateResourceProject(value) {
|
|
21
|
+
return resourceProjectSchema.validateAsync({
|
|
22
|
+
...value,
|
|
23
|
+
agents: value.agents || value.assistants,
|
|
24
|
+
cron: value.cron || value.cronConfig,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
export const projectSettingsSchema = Joi.object({
|
|
3
|
+
id: Joi.string().required(),
|
|
4
|
+
name: Joi.string().empty(['', null]),
|
|
5
|
+
description: Joi.string().empty(['', null]),
|
|
6
|
+
model: Joi.string().empty(['', null]),
|
|
7
|
+
temperature: Joi.number().empty(['', null]),
|
|
8
|
+
topP: Joi.number().empty(['', null]),
|
|
9
|
+
presencePenalty: Joi.number().empty(['', null]),
|
|
10
|
+
frequencyPenalty: Joi.number().empty(['', null]),
|
|
11
|
+
maxTokens: Joi.number().empty(['', null]),
|
|
12
|
+
createdAt: Joi.alternatives(Joi.string().isoDate(), Joi.date().cast('string')).empty(['', null]),
|
|
13
|
+
updatedAt: Joi.alternatives(Joi.string().isoDate(), Joi.date().cast('string')).empty(['', null]),
|
|
14
|
+
createdBy: Joi.string().empty(['', null]),
|
|
15
|
+
updatedBy: Joi.string().empty(['', null]),
|
|
16
|
+
appearance: Joi.object({
|
|
17
|
+
primaryColor: Joi.string().empty(['', null]),
|
|
18
|
+
typography: Joi.object({
|
|
19
|
+
fontFamily: Joi.string().empty(['', null]),
|
|
20
|
+
heading: Joi.object({
|
|
21
|
+
fontFamily: Joi.string().empty(['', null]),
|
|
22
|
+
}).empty(['', null]),
|
|
23
|
+
}).empty(['', null]),
|
|
24
|
+
}).empty(['', null]),
|
|
25
|
+
readme: Joi.string().empty(['', null]).optional(),
|
|
26
|
+
executor: Joi.object().empty(['', null]).optional(),
|
|
27
|
+
})
|
|
28
|
+
.rename('_id', 'id', { override: true, ignoreUndefined: true })
|
|
29
|
+
.options({ stripUnknown: true });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export var RuntimeErrorType;
|
|
2
|
+
(function (RuntimeErrorType) {
|
|
3
|
+
RuntimeErrorType["MissingSecretError"] = "MissingSecretError";
|
|
4
|
+
RuntimeErrorType["RequestExceededError"] = "RequestExceededError";
|
|
5
|
+
RuntimeErrorType["ProjectOwnerRequestExceededError"] = "ProjectOwnerRequestExceededError";
|
|
6
|
+
RuntimeErrorType["ProjectLimitExceededError"] = "ProjectLimitExceededError";
|
|
7
|
+
})(RuntimeErrorType || (RuntimeErrorType = {}));
|
|
8
|
+
export class RuntimeError extends Error {
|
|
9
|
+
type;
|
|
10
|
+
constructor(type, message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.type = type;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './schema';
|
|
2
|
+
export * from './error';
|
|
3
|
+
export var ExecutionPhase;
|
|
4
|
+
(function (ExecutionPhase) {
|
|
5
|
+
ExecutionPhase["EXECUTE_BLOCK_START"] = "EXECUTE_BLOCK_START";
|
|
6
|
+
ExecutionPhase["EXECUTE_SELECT_STOP"] = "EXECUTE_SELECT_STOP";
|
|
7
|
+
ExecutionPhase["EXECUTE_ASSISTANT_START"] = "EXECUTE_ASSISTANT_START";
|
|
8
|
+
ExecutionPhase["EXECUTE_ASSISTANT_RUNNING"] = "EXECUTE_BLOCK_RUNNING";
|
|
9
|
+
ExecutionPhase["EXECUTE_ASSISTANT_END"] = "EXECUTE_ASSISTANT_END";
|
|
10
|
+
})(ExecutionPhase || (ExecutionPhase = {}));
|
|
11
|
+
export var AssistantResponseType;
|
|
12
|
+
(function (AssistantResponseType) {
|
|
13
|
+
AssistantResponseType["ERROR"] = "ERROR";
|
|
14
|
+
AssistantResponseType["LOG"] = "LOG";
|
|
15
|
+
AssistantResponseType["INPUT"] = "INPUT";
|
|
16
|
+
AssistantResponseType["CHUNK"] = "CHUNK";
|
|
17
|
+
AssistantResponseType["USAGE"] = "USAGE";
|
|
18
|
+
AssistantResponseType["EXECUTE"] = "EXECUTE";
|
|
19
|
+
AssistantResponseType["INPUT_PARAMETER"] = "INPUT_PARAMETER";
|
|
20
|
+
})(AssistantResponseType || (AssistantResponseType = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const RUNTIME_RESOURCE_BLOCKLET_STATE_GLOBAL_VARIABLE = '__AI_RUNTIME_RESOURCE_BLOCKLET_STATE__';
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
import omitBy from 'lodash/omitBy';
|
|
3
|
+
import toLower from 'lodash/toLower';
|
|
4
|
+
export const variableBlockListForAgent = {
|
|
5
|
+
prompt: {
|
|
6
|
+
// block: new Set(['$images']),
|
|
7
|
+
},
|
|
8
|
+
image: {
|
|
9
|
+
// allow: new Set(['$images']),
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export const runtimeVariablesSchema = {
|
|
13
|
+
$text: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
description: 'Text Stream',
|
|
16
|
+
faker: 'lorem.paragraph',
|
|
17
|
+
},
|
|
18
|
+
$images: {
|
|
19
|
+
type: 'array',
|
|
20
|
+
description: 'Generated Images',
|
|
21
|
+
element: {
|
|
22
|
+
id: '',
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: [
|
|
25
|
+
{
|
|
26
|
+
id: '',
|
|
27
|
+
type: 'string',
|
|
28
|
+
name: 'url',
|
|
29
|
+
description: 'Image Url',
|
|
30
|
+
required: true,
|
|
31
|
+
faker: 'image.url',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
'$suggested.questions': {
|
|
37
|
+
type: 'array',
|
|
38
|
+
description: 'Generate 3 questions for users to ask you based on answers and context',
|
|
39
|
+
element: {
|
|
40
|
+
id: '',
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: [
|
|
43
|
+
{
|
|
44
|
+
id: '',
|
|
45
|
+
type: 'string',
|
|
46
|
+
name: 'question',
|
|
47
|
+
required: true,
|
|
48
|
+
faker: 'lorem.sentence',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
required: true,
|
|
53
|
+
},
|
|
54
|
+
'$reference.links': {
|
|
55
|
+
type: 'array',
|
|
56
|
+
description: 'List all referenced links in the generated text',
|
|
57
|
+
element: {
|
|
58
|
+
id: '',
|
|
59
|
+
type: 'object',
|
|
60
|
+
properties: [
|
|
61
|
+
{
|
|
62
|
+
id: '',
|
|
63
|
+
type: 'string',
|
|
64
|
+
name: 'title',
|
|
65
|
+
required: true,
|
|
66
|
+
faker: 'lorem.sentence',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: '',
|
|
70
|
+
type: 'string',
|
|
71
|
+
name: 'url',
|
|
72
|
+
required: true,
|
|
73
|
+
faker: 'internet.url',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
required: true,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
export function outputVariablesToJsonSchema(assistant, { variables, includeRuntimeOutputVariables, includeFaker, }) {
|
|
81
|
+
const variableToSchema = (variable) => {
|
|
82
|
+
if (variable.from?.type === 'input')
|
|
83
|
+
return undefined;
|
|
84
|
+
if (!includeRuntimeOutputVariables && ignoreJsonSchemaOutputs.has(variable.name))
|
|
85
|
+
return undefined;
|
|
86
|
+
if (variable.name && isRuntimeOutputVariable(variable.name)) {
|
|
87
|
+
const runtimeVariable = runtimeVariablesSchema[variable.name];
|
|
88
|
+
if (!runtimeVariable)
|
|
89
|
+
return undefined;
|
|
90
|
+
return variableToSchema({
|
|
91
|
+
...runtimeVariable,
|
|
92
|
+
description: [runtimeVariable.description, variable.description].filter((i) => !!i).join('\n'),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
if (variable.variable) {
|
|
96
|
+
const { key, scope } = variable.variable;
|
|
97
|
+
const v = variables.find((i) => toLower(i.key) === toLower(key) && i.scope === scope);
|
|
98
|
+
if (!v?.type)
|
|
99
|
+
throw new Error(`Variable ${key} not found from ${scope}`);
|
|
100
|
+
return variableToSchema(v.type);
|
|
101
|
+
}
|
|
102
|
+
return omitBy({
|
|
103
|
+
type: variable.type || 'string',
|
|
104
|
+
description: variable.description,
|
|
105
|
+
properties: variable.type === 'object' && variable.properties
|
|
106
|
+
? Object.fromEntries(variable.properties
|
|
107
|
+
.map((property) => [property.name, variableToSchema(property)])
|
|
108
|
+
.filter((i) => i[0] && i[1]))
|
|
109
|
+
: undefined,
|
|
110
|
+
items: variable.type === 'array' && variable.element ? variableToSchema(variable.element) : undefined,
|
|
111
|
+
additionalProperties: variable.type === 'object' ? false : undefined,
|
|
112
|
+
required: variable.type === 'object' && variable.properties?.length
|
|
113
|
+
? variable.properties
|
|
114
|
+
.filter((i) => i.name &&
|
|
115
|
+
(i.required ||
|
|
116
|
+
(runtimeOutputVariableSet.has(i.name) &&
|
|
117
|
+
runtimeVariablesSchema[i.name] &&
|
|
118
|
+
!ignoreJsonSchemaOutputs.has(i.name))))
|
|
119
|
+
.map((i) => i.name)
|
|
120
|
+
: undefined,
|
|
121
|
+
faker: includeFaker ? variable.faker : undefined,
|
|
122
|
+
}, (v) => v === undefined);
|
|
123
|
+
};
|
|
124
|
+
const outputVariables = (assistant.outputVariables ?? []).filter((i) => !i.hidden && i.from?.type !== 'callAgent' && !i.valueTemplate?.trim());
|
|
125
|
+
return variableToSchema({ type: 'object', properties: outputVariables });
|
|
126
|
+
}
|
|
127
|
+
export function outputVariablesToJoiSchema(assistant, { partial, variables }) {
|
|
128
|
+
const variableToSchema = (variable) => {
|
|
129
|
+
let schema;
|
|
130
|
+
if (variable.from?.type === 'input') {
|
|
131
|
+
const fromId = variable.from.id;
|
|
132
|
+
const input = assistant.parameters?.find((i) => i.id === fromId && !i.hidden);
|
|
133
|
+
if (input) {
|
|
134
|
+
return Joi.any();
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
if (variable.from?.type === 'output') {
|
|
139
|
+
return Joi.any();
|
|
140
|
+
}
|
|
141
|
+
if (variable.name && isRuntimeOutputVariable(variable.name)) {
|
|
142
|
+
if (variable.name === RuntimeOutputVariable.llmResponseStream) {
|
|
143
|
+
schema = Joi.any();
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const runtimeVariable = runtimeVariablesSchema[variable.name];
|
|
147
|
+
if (!runtimeVariable)
|
|
148
|
+
return undefined;
|
|
149
|
+
schema = variableToSchema({ ...runtimeVariable });
|
|
150
|
+
if (schema) {
|
|
151
|
+
schema = Joi.alternatives().try(schema, Joi.any().empty(Joi.any()));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return schema;
|
|
155
|
+
}
|
|
156
|
+
if (variable.variable) {
|
|
157
|
+
const { key, scope } = variable.variable;
|
|
158
|
+
const v = variables.find((i) => toLower(i.key) === toLower(key) && i.scope === scope);
|
|
159
|
+
if (!v?.type)
|
|
160
|
+
return undefined;
|
|
161
|
+
schema = variableToSchema(v.type);
|
|
162
|
+
}
|
|
163
|
+
else if (!variable.type || variable.type === 'string') {
|
|
164
|
+
schema = Joi.string().empty(['', null]);
|
|
165
|
+
}
|
|
166
|
+
else if (variable.type === 'number') {
|
|
167
|
+
schema = Joi.number().empty([null, '']);
|
|
168
|
+
}
|
|
169
|
+
else if (variable.type === 'boolean') {
|
|
170
|
+
schema = Joi.boolean().empty([null, '']);
|
|
171
|
+
}
|
|
172
|
+
else if (variable.type === 'object') {
|
|
173
|
+
if (variable.properties?.length) {
|
|
174
|
+
schema = Joi.object(Object.fromEntries((variable.properties ?? [])
|
|
175
|
+
.map((property) => [property.name, variableToSchema(property)])
|
|
176
|
+
.filter((i) => i[0] && i[1])))
|
|
177
|
+
.empty([null, ''])
|
|
178
|
+
.options({ stripUnknown: true });
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
schema = Joi.any().empty(['', null]);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (variable.type === 'array') {
|
|
185
|
+
schema = Joi.array()
|
|
186
|
+
.empty([null, ''])
|
|
187
|
+
.items((variable.element && variableToSchema(variable.element)) || Joi.string().empty([null, '']));
|
|
188
|
+
}
|
|
189
|
+
if (!schema)
|
|
190
|
+
return undefined;
|
|
191
|
+
if ('defaultValue' in variable) {
|
|
192
|
+
schema = schema.default(variable.defaultValue);
|
|
193
|
+
}
|
|
194
|
+
if (variable.required) {
|
|
195
|
+
schema = schema.required();
|
|
196
|
+
}
|
|
197
|
+
return schema;
|
|
198
|
+
};
|
|
199
|
+
const outputVariables = (assistant.outputVariables ?? []).filter((i) => !i.hidden && i.from?.type !== 'callAgent' && !i.valueTemplate);
|
|
200
|
+
return variableToSchema({
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: partial ? outputVariables.map((i) => ({ ...i, required: false })) : outputVariables,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
export var RuntimeOutputVariable;
|
|
206
|
+
(function (RuntimeOutputVariable) {
|
|
207
|
+
RuntimeOutputVariable["llmResponseStream"] = "$llmResponseStream";
|
|
208
|
+
RuntimeOutputVariable["text"] = "$text";
|
|
209
|
+
RuntimeOutputVariable["images"] = "$images";
|
|
210
|
+
RuntimeOutputVariable["suggestedQuestions"] = "$suggested.questions";
|
|
211
|
+
RuntimeOutputVariable["referenceLinks"] = "$reference.links";
|
|
212
|
+
RuntimeOutputVariable["appearancePage"] = "$appearance.page";
|
|
213
|
+
RuntimeOutputVariable["appearanceInput"] = "$appearance.input";
|
|
214
|
+
RuntimeOutputVariable["appearanceOutput"] = "$appearance.output";
|
|
215
|
+
RuntimeOutputVariable["children"] = "$children";
|
|
216
|
+
RuntimeOutputVariable["share"] = "$share";
|
|
217
|
+
RuntimeOutputVariable["openingQuestions"] = "$openingQuestions";
|
|
218
|
+
RuntimeOutputVariable["openingMessage"] = "$openingMessage";
|
|
219
|
+
RuntimeOutputVariable["profile"] = "$profile";
|
|
220
|
+
})(RuntimeOutputVariable || (RuntimeOutputVariable = {}));
|
|
221
|
+
const runtimeOutputVariableSet = new Set(Object.values(RuntimeOutputVariable));
|
|
222
|
+
const ignoreJsonSchemaOutputs = new Set([
|
|
223
|
+
RuntimeOutputVariable.text,
|
|
224
|
+
RuntimeOutputVariable.images,
|
|
225
|
+
]);
|
|
226
|
+
export function isRuntimeOutputVariable(variable) {
|
|
227
|
+
return Object.values(RuntimeOutputVariable).includes(variable);
|
|
228
|
+
}
|
|
229
|
+
export function jsonSchemaToOpenAIJsonSchema(schema) {
|
|
230
|
+
if (schema?.type === 'object') {
|
|
231
|
+
const { required, properties } = schema;
|
|
232
|
+
return {
|
|
233
|
+
...schema,
|
|
234
|
+
properties: Object.fromEntries(Object.entries(properties).map(([key, value]) => {
|
|
235
|
+
const valueSchema = jsonSchemaToOpenAIJsonSchema(value);
|
|
236
|
+
// NOTE: All fields must be required https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required
|
|
237
|
+
return [key, required?.includes(key) ? valueSchema : { anyOf: [valueSchema, { type: ['null'] }] }];
|
|
238
|
+
})),
|
|
239
|
+
required: Object.keys(properties),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (schema?.type === 'array') {
|
|
243
|
+
return {
|
|
244
|
+
...schema,
|
|
245
|
+
items: jsonSchemaToOpenAIJsonSchema(schema.items),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
return schema;
|
|
249
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CronJob } from 'cron';
|
|
2
|
+
export const CronJobDefaultGroup = 'default';
|
|
3
|
+
export class CronJobManager {
|
|
4
|
+
groups = {};
|
|
5
|
+
resetJobs(jobs, { groupId = CronJobDefaultGroup } = {}) {
|
|
6
|
+
this.destroyGroup({ groupId });
|
|
7
|
+
for (const job of jobs) {
|
|
8
|
+
this.resetJob(job, { groupId });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
resetJob(job, { groupId = CronJobDefaultGroup } = {}) {
|
|
12
|
+
if (!job.cronTime)
|
|
13
|
+
throw new Error('cronTime is required');
|
|
14
|
+
this.groups[groupId] ??= { jobs: {} };
|
|
15
|
+
const group = this.groups[groupId];
|
|
16
|
+
this.stopJob(job.id, { groupId });
|
|
17
|
+
const cronJob = CronJob.from({ cronTime: job.cronTime, onTick: job.onTick, utcOffset: 0, start: true });
|
|
18
|
+
group.jobs[job.id] = { cronJob, job };
|
|
19
|
+
}
|
|
20
|
+
stopJob(jobId, { groupId = CronJobDefaultGroup } = {}) {
|
|
21
|
+
const group = this.groups[groupId];
|
|
22
|
+
if (!group)
|
|
23
|
+
return;
|
|
24
|
+
const item = group.jobs[jobId];
|
|
25
|
+
if (!item)
|
|
26
|
+
return;
|
|
27
|
+
item.cronJob.stop();
|
|
28
|
+
delete group.jobs[jobId];
|
|
29
|
+
}
|
|
30
|
+
destroyGroup({ groupId }) {
|
|
31
|
+
const group = this.groups[groupId];
|
|
32
|
+
if (!group)
|
|
33
|
+
return;
|
|
34
|
+
for (const item of Object.values(group.jobs)) {
|
|
35
|
+
this.stopJob(item.job.id, { groupId });
|
|
36
|
+
}
|
|
37
|
+
delete this.groups[groupId];
|
|
38
|
+
}
|
|
39
|
+
destroy() {
|
|
40
|
+
for (const groupId of Object.keys(this.groups)) {
|
|
41
|
+
this.destroyGroup({ groupId });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { TransformStream } from 'stream/web';
|
|
2
|
+
export class ExtractMetadataTransform extends TransformStream {
|
|
3
|
+
buffer = '';
|
|
4
|
+
cursor = 0;
|
|
5
|
+
state = 'none';
|
|
6
|
+
constructor({ start, end }) {
|
|
7
|
+
super({
|
|
8
|
+
transform: async (chunk, controller) => {
|
|
9
|
+
if (!start || !end) {
|
|
10
|
+
controller.enqueue({ type: 'text', text: chunk });
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
this.buffer += chunk;
|
|
14
|
+
for (;;) {
|
|
15
|
+
if (this.state === 'none') {
|
|
16
|
+
const found = findMatchIndex(this.buffer, this.cursor, start);
|
|
17
|
+
if (found.start > this.cursor) {
|
|
18
|
+
const text = this.buffer.slice(this.cursor, found.start);
|
|
19
|
+
this.cursor = found.start;
|
|
20
|
+
controller.enqueue({ type: 'text', text });
|
|
21
|
+
}
|
|
22
|
+
if (found.end) {
|
|
23
|
+
this.state = 'start';
|
|
24
|
+
this.cursor = found.end;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (this.state === 'start') {
|
|
28
|
+
const found = findMatchIndex(this.buffer, this.cursor, end);
|
|
29
|
+
if (found.end) {
|
|
30
|
+
const match = this.buffer.slice(this.cursor, found.start);
|
|
31
|
+
controller.enqueue({ type: 'match', text: match });
|
|
32
|
+
this.state = 'none';
|
|
33
|
+
this.cursor = found.end;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function findMatchIndex(str, position, match) {
|
|
44
|
+
const i = str.indexOf(match, position);
|
|
45
|
+
if (i >= 0)
|
|
46
|
+
return { start: i, end: i + match.length };
|
|
47
|
+
for (let i = match.length - 1; i > 0; i--) {
|
|
48
|
+
const m = match.slice(0, i);
|
|
49
|
+
if (str.endsWith(m)) {
|
|
50
|
+
return { start: str.length - m.length };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { start: str.length };
|
|
54
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ReadableStream } from 'stream/web';
|
|
2
|
+
import { describe, expect, test } from '@jest/globals';
|
|
3
|
+
import { ExtractMetadataTransform } from './extract-metadata-transform';
|
|
4
|
+
describe('ExtractMetadataTransform', () => {
|
|
5
|
+
async function run(str, start, end, step = 1) {
|
|
6
|
+
const s = new ReadableStream({
|
|
7
|
+
start(controller) {
|
|
8
|
+
let t = '';
|
|
9
|
+
for (const i of str) {
|
|
10
|
+
t += i;
|
|
11
|
+
if (t.length === step) {
|
|
12
|
+
controller.enqueue(t);
|
|
13
|
+
t = '';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
controller.enqueue(t);
|
|
17
|
+
controller.close();
|
|
18
|
+
},
|
|
19
|
+
}).pipeThrough(new ExtractMetadataTransform({ start, end }));
|
|
20
|
+
let text = '';
|
|
21
|
+
const matched = [];
|
|
22
|
+
for await (const i of s) {
|
|
23
|
+
if (i.type === 'text') {
|
|
24
|
+
text += i.text;
|
|
25
|
+
}
|
|
26
|
+
else if (i.type === 'match') {
|
|
27
|
+
matched.push(i.text);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { text, matched };
|
|
31
|
+
}
|
|
32
|
+
const cases = [
|
|
33
|
+
{
|
|
34
|
+
input: 'hello<metadata>{"name":"foo","age":120}</metadata>world how<metadata>{"name":"bar","age":130}</metadata> to',
|
|
35
|
+
start: '<metadata>',
|
|
36
|
+
end: '</metadata>',
|
|
37
|
+
expected: { text: 'helloworld how to', matched: ['{"name":"foo","age":120}', '{"name":"bar","age":130}'] },
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
input: '```metadata{"name":"foo","age":120}```',
|
|
41
|
+
start: '```metadata',
|
|
42
|
+
end: '```',
|
|
43
|
+
expected: { text: '', matched: ['{"name":"foo","age":120}'] },
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
input: '```metadata{"name":"foo","age":120}``````metadata{"name":"bar","age":130}```',
|
|
47
|
+
start: '```metadata',
|
|
48
|
+
end: '```',
|
|
49
|
+
expected: { text: '', matched: ['{"name":"foo","age":120}', '{"name":"bar","age":130}'] },
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
test('extract metadata transform', async () => {
|
|
53
|
+
for (const c of cases) {
|
|
54
|
+
for (let i = 1; i < c.input.length; i++) {
|
|
55
|
+
expect([await run(c.input, c.start, c.end, i), i]).toEqual([c.expected, i]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function copyFile(src, dest, { skip } = {}) {
|
|
4
|
+
if (skip?.(src))
|
|
5
|
+
return;
|
|
6
|
+
await new Promise((resolve, reject) => {
|
|
7
|
+
const readStream = fs.createReadStream(src);
|
|
8
|
+
const writeStream = fs.createWriteStream(dest);
|
|
9
|
+
readStream.on('error', reject);
|
|
10
|
+
writeStream.on('error', reject);
|
|
11
|
+
writeStream.on('finish', resolve);
|
|
12
|
+
readStream.pipe(writeStream);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function copyDirectory(src, dest, { skip } = {}) {
|
|
16
|
+
if (skip?.(src))
|
|
17
|
+
return;
|
|
18
|
+
await fs.promises.mkdir(dest, { recursive: true });
|
|
19
|
+
const entries = await fs.promises.readdir(src, { withFileTypes: true });
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const srcPath = path.join(src, entry.name);
|
|
22
|
+
const destPath = path.join(dest, entry.name);
|
|
23
|
+
if (entry.isDirectory()) {
|
|
24
|
+
await copyDirectory(srcPath, destPath, { skip });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
await copyFile(srcPath, destPath, { skip });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function copyRecursive(src, dest, { skip } = {}) {
|
|
32
|
+
if (skip?.(src))
|
|
33
|
+
return;
|
|
34
|
+
const srcStats = await fs.promises.stat(src);
|
|
35
|
+
if (srcStats.isDirectory()) {
|
|
36
|
+
await copyDirectory(src, dest, { skip });
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
await copyFile(src, dest, { skip });
|
|
40
|
+
}
|
|
41
|
+
}
|