@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.
Files changed (170) hide show
  1. package/lib/cjs/assistant/generate-output.js +101 -0
  2. package/lib/cjs/assistant/select-agent.js +76 -0
  3. package/lib/cjs/assistant/type.js +11 -0
  4. package/lib/cjs/common/aid.js +42 -0
  5. package/lib/cjs/common/index.js +238 -0
  6. package/lib/cjs/common/resource-manager.js +199 -0
  7. package/lib/cjs/constants.js +9 -0
  8. package/lib/cjs/executor/agent.js +10 -0
  9. package/lib/cjs/executor/aigc.js +28 -0
  10. package/lib/cjs/executor/api.js +64 -0
  11. package/lib/cjs/executor/base.js +676 -0
  12. package/lib/cjs/executor/blocklet.js +25 -0
  13. package/lib/cjs/executor/call-agent.js +105 -0
  14. package/lib/cjs/executor/decision.js +478 -0
  15. package/lib/cjs/executor/image-blender.js +32 -0
  16. package/lib/cjs/executor/index.js +81 -0
  17. package/lib/cjs/executor/llm.js +379 -0
  18. package/lib/cjs/executor/logic.js +167 -0
  19. package/lib/cjs/index.js +17 -0
  20. package/lib/cjs/libs/blocklet/vc.js +92 -0
  21. package/lib/cjs/libs/openapi/request/index.js +24 -0
  22. package/lib/cjs/libs/openapi/request/util.js +146 -0
  23. package/lib/cjs/libs/openapi/types/index.js +17 -0
  24. package/lib/cjs/libs/openapi/util/call.js +15 -0
  25. package/lib/cjs/libs/openapi/util/check-schema.js +67 -0
  26. package/lib/cjs/libs/openapi/util/convert-schema.js +44 -0
  27. package/lib/cjs/libs/openapi/util/flatten-open-api.js +21 -0
  28. package/lib/cjs/libs/openapi/util/get-open-api-i18n-text.js +7 -0
  29. package/lib/cjs/logger.js +4 -0
  30. package/lib/cjs/runtime/resource-blocklet.js +5 -0
  31. package/lib/cjs/runtime/runtime.js +143 -0
  32. package/lib/cjs/types/assistant/index.js +31 -0
  33. package/lib/cjs/types/assistant/mustache/ReadableMustache.js +69 -0
  34. package/lib/cjs/types/assistant/mustache/directive.js +35 -0
  35. package/lib/cjs/types/assistant/mustache/mustache.js +688 -0
  36. package/lib/cjs/types/common/index.js +2 -0
  37. package/lib/cjs/types/index.js +20 -0
  38. package/lib/cjs/types/resource/index.js +47 -0
  39. package/lib/cjs/types/resource/project.js +35 -0
  40. package/lib/cjs/types/runtime/agent.js +2 -0
  41. package/lib/cjs/types/runtime/error.js +18 -0
  42. package/lib/cjs/types/runtime/index.js +37 -0
  43. package/lib/cjs/types/runtime/runtime-resource-blocklet-state.js +4 -0
  44. package/lib/cjs/types/runtime/schema.js +259 -0
  45. package/lib/cjs/utils/cron-job.js +48 -0
  46. package/lib/cjs/utils/extract-metadata-transform.js +58 -0
  47. package/lib/cjs/utils/extract-metadata-transform.test.js +61 -0
  48. package/lib/cjs/utils/fs.js +49 -0
  49. package/lib/cjs/utils/get-blocklet-agent.js +351 -0
  50. package/lib/cjs/utils/geti.js +37 -0
  51. package/lib/cjs/utils/is-non-nullable.js +20 -0
  52. package/lib/cjs/utils/render-message.js +23 -0
  53. package/lib/cjs/utils/resolve-secret-inputs.js +49 -0
  54. package/lib/cjs/utils/retry.js +19 -0
  55. package/lib/cjs/utils/task-id.js +7 -0
  56. package/lib/cjs/utils/tool-calls-transform.js +18 -0
  57. package/lib/esm/assistant/generate-output.js +91 -0
  58. package/lib/esm/assistant/select-agent.js +71 -0
  59. package/lib/esm/assistant/type.js +7 -0
  60. package/lib/esm/common/aid.js +38 -0
  61. package/lib/esm/common/index.js +232 -0
  62. package/lib/esm/common/resource-manager.js +192 -0
  63. package/lib/esm/constants.js +6 -0
  64. package/lib/esm/executor/agent.js +6 -0
  65. package/lib/esm/executor/aigc.js +24 -0
  66. package/lib/esm/executor/api.js +34 -0
  67. package/lib/esm/executor/base.js +668 -0
  68. package/lib/esm/executor/blocklet.js +21 -0
  69. package/lib/esm/executor/call-agent.js +98 -0
  70. package/lib/esm/executor/decision.js +471 -0
  71. package/lib/esm/executor/image-blender.js +25 -0
  72. package/lib/esm/executor/index.js +74 -0
  73. package/lib/esm/executor/llm.js +372 -0
  74. package/lib/esm/executor/logic.js +160 -0
  75. package/lib/esm/index.js +1 -0
  76. package/lib/esm/libs/blocklet/vc.js +85 -0
  77. package/lib/esm/libs/openapi/request/index.js +20 -0
  78. package/lib/esm/libs/openapi/request/util.js +136 -0
  79. package/lib/esm/libs/openapi/types/index.js +1 -0
  80. package/lib/esm/libs/openapi/util/call.js +8 -0
  81. package/lib/esm/libs/openapi/util/check-schema.js +62 -0
  82. package/lib/esm/libs/openapi/util/convert-schema.js +42 -0
  83. package/lib/esm/libs/openapi/util/flatten-open-api.js +19 -0
  84. package/lib/esm/libs/openapi/util/get-open-api-i18n-text.js +5 -0
  85. package/lib/esm/logger.js +2 -0
  86. package/lib/esm/runtime/resource-blocklet.js +2 -0
  87. package/lib/esm/runtime/runtime.js +136 -0
  88. package/lib/esm/types/assistant/index.js +9 -0
  89. package/lib/esm/types/assistant/mustache/ReadableMustache.js +63 -0
  90. package/lib/esm/types/assistant/mustache/directive.js +29 -0
  91. package/lib/esm/types/assistant/mustache/mustache.js +686 -0
  92. package/lib/esm/types/common/index.js +1 -0
  93. package/lib/esm/types/index.js +4 -0
  94. package/lib/esm/types/resource/index.js +26 -0
  95. package/lib/esm/types/resource/project.js +29 -0
  96. package/lib/esm/types/runtime/agent.js +1 -0
  97. package/lib/esm/types/runtime/error.js +14 -0
  98. package/lib/esm/types/runtime/index.js +20 -0
  99. package/lib/esm/types/runtime/runtime-resource-blocklet-state.js +1 -0
  100. package/lib/esm/types/runtime/schema.js +249 -0
  101. package/lib/esm/utils/cron-job.js +44 -0
  102. package/lib/esm/utils/extract-metadata-transform.js +54 -0
  103. package/lib/esm/utils/extract-metadata-transform.test.js +59 -0
  104. package/lib/esm/utils/fs.js +41 -0
  105. package/lib/esm/utils/get-blocklet-agent.js +344 -0
  106. package/lib/esm/utils/geti.js +30 -0
  107. package/lib/esm/utils/is-non-nullable.js +13 -0
  108. package/lib/esm/utils/render-message.js +20 -0
  109. package/lib/esm/utils/resolve-secret-inputs.js +46 -0
  110. package/lib/esm/utils/retry.js +16 -0
  111. package/lib/esm/utils/task-id.js +3 -0
  112. package/lib/esm/utils/tool-calls-transform.js +15 -0
  113. package/lib/types/assistant/generate-output.d.ts +29 -0
  114. package/lib/types/assistant/select-agent.d.ts +14 -0
  115. package/lib/types/assistant/type.d.ts +61 -0
  116. package/lib/types/common/aid.d.ts +18 -0
  117. package/lib/types/common/index.d.ts +7 -0
  118. package/lib/types/common/resource-manager.d.ts +88 -0
  119. package/lib/types/constants.d.ts +6 -0
  120. package/lib/types/executor/agent.d.ts +5 -0
  121. package/lib/types/executor/aigc.d.ts +9 -0
  122. package/lib/types/executor/api.d.ts +9 -0
  123. package/lib/types/executor/base.d.ts +209 -0
  124. package/lib/types/executor/blocklet.d.ts +9 -0
  125. package/lib/types/executor/call-agent.d.ts +12 -0
  126. package/lib/types/executor/decision.d.ts +20 -0
  127. package/lib/types/executor/image-blender.d.ts +9 -0
  128. package/lib/types/executor/index.d.ts +8 -0
  129. package/lib/types/executor/llm.d.ts +38 -0
  130. package/lib/types/executor/logic.d.ts +9 -0
  131. package/lib/types/index.d.ts +1 -0
  132. package/lib/types/libs/blocklet/vc.d.ts +17 -0
  133. package/lib/types/libs/openapi/request/index.d.ts +17 -0
  134. package/lib/types/libs/openapi/request/util.d.ts +40 -0
  135. package/lib/types/libs/openapi/types/index.d.ts +20 -0
  136. package/lib/types/libs/openapi/util/call.d.ts +2 -0
  137. package/lib/types/libs/openapi/util/check-schema.d.ts +3 -0
  138. package/lib/types/libs/openapi/util/convert-schema.d.ts +8 -0
  139. package/lib/types/libs/openapi/util/flatten-open-api.d.ts +3 -0
  140. package/lib/types/libs/openapi/util/get-open-api-i18n-text.d.ts +2 -0
  141. package/lib/types/logger.d.ts +2 -0
  142. package/lib/types/runtime/resource-blocklet.d.ts +2 -0
  143. package/lib/types/runtime/runtime.d.ts +20 -0
  144. package/lib/types/types/assistant/index.d.ts +405 -0
  145. package/lib/types/types/assistant/mustache/ReadableMustache.d.ts +2 -0
  146. package/lib/types/types/assistant/mustache/directive.d.ts +6 -0
  147. package/lib/types/types/assistant/mustache/mustache.d.ts +2 -0
  148. package/lib/types/types/common/index.d.ts +45 -0
  149. package/lib/types/types/index.d.ts +4 -0
  150. package/lib/types/types/resource/index.d.ts +17 -0
  151. package/lib/types/types/resource/project.d.ts +41 -0
  152. package/lib/types/types/runtime/agent.d.ts +33 -0
  153. package/lib/types/types/runtime/error.d.ts +10 -0
  154. package/lib/types/types/runtime/index.d.ts +116 -0
  155. package/lib/types/types/runtime/runtime-resource-blocklet-state.d.ts +5 -0
  156. package/lib/types/types/runtime/schema.d.ts +110 -0
  157. package/lib/types/utils/cron-job.d.ts +22 -0
  158. package/lib/types/utils/extract-metadata-transform.d.ts +16 -0
  159. package/lib/types/utils/extract-metadata-transform.test.d.ts +1 -0
  160. package/lib/types/utils/fs.d.ts +9 -0
  161. package/lib/types/utils/get-blocklet-agent.d.ts +219 -0
  162. package/lib/types/utils/geti.d.ts +1 -0
  163. package/lib/types/utils/is-non-nullable.d.ts +2 -0
  164. package/lib/types/utils/render-message.d.ts +6 -0
  165. package/lib/types/utils/resolve-secret-inputs.d.ts +11 -0
  166. package/lib/types/utils/retry.d.ts +1 -0
  167. package/lib/types/utils/task-id.d.ts +1 -0
  168. package/lib/types/utils/tool-calls-transform.d.ts +2 -0
  169. package/package.json +67 -0
  170. 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
+ }