@aigne/core 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.
Files changed (168) hide show
  1. package/lib/cjs/index.js +1 -1
  2. package/lib/cjs/types/index.js +2 -4
  3. package/lib/esm/index.js +1 -1
  4. package/lib/esm/types/index.js +2 -4
  5. package/lib/types/index.d.ts +1 -1
  6. package/lib/types/types/agent.d.ts +5 -0
  7. package/lib/types/types/index.d.ts +2 -4
  8. package/lib/types/types/runnable.d.ts +20 -0
  9. package/package.json +6 -7
  10. package/lib/cjs/assistant/generate-output.js +0 -101
  11. package/lib/cjs/assistant/select-agent.js +0 -76
  12. package/lib/cjs/assistant/type.js +0 -11
  13. package/lib/cjs/common/aid.js +0 -42
  14. package/lib/cjs/common/index.js +0 -238
  15. package/lib/cjs/common/resource-manager.js +0 -199
  16. package/lib/cjs/constants.js +0 -9
  17. package/lib/cjs/executor/agent.js +0 -10
  18. package/lib/cjs/executor/aigc.js +0 -28
  19. package/lib/cjs/executor/api.js +0 -64
  20. package/lib/cjs/executor/base.js +0 -676
  21. package/lib/cjs/executor/blocklet.js +0 -25
  22. package/lib/cjs/executor/call-agent.js +0 -105
  23. package/lib/cjs/executor/decision.js +0 -478
  24. package/lib/cjs/executor/image-blender.js +0 -32
  25. package/lib/cjs/executor/index.js +0 -81
  26. package/lib/cjs/executor/llm.js +0 -379
  27. package/lib/cjs/executor/logic.js +0 -167
  28. package/lib/cjs/libs/blocklet/vc.js +0 -92
  29. package/lib/cjs/libs/openapi/request/index.js +0 -24
  30. package/lib/cjs/libs/openapi/request/util.js +0 -146
  31. package/lib/cjs/libs/openapi/types/index.js +0 -17
  32. package/lib/cjs/libs/openapi/util/call.js +0 -15
  33. package/lib/cjs/libs/openapi/util/check-schema.js +0 -67
  34. package/lib/cjs/libs/openapi/util/convert-schema.js +0 -44
  35. package/lib/cjs/libs/openapi/util/flatten-open-api.js +0 -21
  36. package/lib/cjs/libs/openapi/util/get-open-api-i18n-text.js +0 -7
  37. package/lib/cjs/runtime/resource-blocklet.js +0 -5
  38. package/lib/cjs/runtime/runtime.js +0 -143
  39. package/lib/cjs/types/assistant/index.js +0 -31
  40. package/lib/cjs/types/assistant/mustache/ReadableMustache.js +0 -69
  41. package/lib/cjs/types/assistant/mustache/directive.js +0 -35
  42. package/lib/cjs/types/assistant/mustache/mustache.js +0 -688
  43. package/lib/cjs/types/resource/index.js +0 -47
  44. package/lib/cjs/types/resource/project.js +0 -35
  45. package/lib/cjs/types/runtime/error.js +0 -18
  46. package/lib/cjs/types/runtime/index.js +0 -37
  47. package/lib/cjs/types/runtime/runtime-resource-blocklet-state.js +0 -4
  48. package/lib/cjs/types/runtime/schema.js +0 -259
  49. package/lib/cjs/utils/cron-job.js +0 -48
  50. package/lib/cjs/utils/extract-metadata-transform.js +0 -58
  51. package/lib/cjs/utils/extract-metadata-transform.test.js +0 -61
  52. package/lib/cjs/utils/fs.js +0 -49
  53. package/lib/cjs/utils/get-blocklet-agent.js +0 -351
  54. package/lib/cjs/utils/geti.js +0 -37
  55. package/lib/cjs/utils/is-non-nullable.js +0 -20
  56. package/lib/cjs/utils/render-message.js +0 -23
  57. package/lib/cjs/utils/resolve-secret-inputs.js +0 -49
  58. package/lib/cjs/utils/retry.js +0 -19
  59. package/lib/cjs/utils/task-id.js +0 -7
  60. package/lib/cjs/utils/tool-calls-transform.js +0 -18
  61. package/lib/esm/assistant/generate-output.js +0 -91
  62. package/lib/esm/assistant/select-agent.js +0 -71
  63. package/lib/esm/assistant/type.js +0 -7
  64. package/lib/esm/common/aid.js +0 -38
  65. package/lib/esm/common/index.js +0 -232
  66. package/lib/esm/common/resource-manager.js +0 -192
  67. package/lib/esm/constants.js +0 -6
  68. package/lib/esm/executor/agent.js +0 -6
  69. package/lib/esm/executor/aigc.js +0 -24
  70. package/lib/esm/executor/api.js +0 -34
  71. package/lib/esm/executor/base.js +0 -668
  72. package/lib/esm/executor/blocklet.js +0 -21
  73. package/lib/esm/executor/call-agent.js +0 -98
  74. package/lib/esm/executor/decision.js +0 -471
  75. package/lib/esm/executor/image-blender.js +0 -25
  76. package/lib/esm/executor/index.js +0 -74
  77. package/lib/esm/executor/llm.js +0 -372
  78. package/lib/esm/executor/logic.js +0 -160
  79. package/lib/esm/libs/blocklet/vc.js +0 -85
  80. package/lib/esm/libs/openapi/request/index.js +0 -20
  81. package/lib/esm/libs/openapi/request/util.js +0 -136
  82. package/lib/esm/libs/openapi/types/index.js +0 -1
  83. package/lib/esm/libs/openapi/util/call.js +0 -8
  84. package/lib/esm/libs/openapi/util/check-schema.js +0 -62
  85. package/lib/esm/libs/openapi/util/convert-schema.js +0 -42
  86. package/lib/esm/libs/openapi/util/flatten-open-api.js +0 -19
  87. package/lib/esm/libs/openapi/util/get-open-api-i18n-text.js +0 -5
  88. package/lib/esm/runtime/resource-blocklet.js +0 -2
  89. package/lib/esm/runtime/runtime.js +0 -136
  90. package/lib/esm/types/assistant/index.js +0 -9
  91. package/lib/esm/types/assistant/mustache/ReadableMustache.js +0 -63
  92. package/lib/esm/types/assistant/mustache/directive.js +0 -29
  93. package/lib/esm/types/assistant/mustache/mustache.js +0 -686
  94. package/lib/esm/types/resource/index.js +0 -26
  95. package/lib/esm/types/resource/project.js +0 -29
  96. package/lib/esm/types/runtime/error.js +0 -14
  97. package/lib/esm/types/runtime/index.js +0 -20
  98. package/lib/esm/types/runtime/runtime-resource-blocklet-state.js +0 -1
  99. package/lib/esm/types/runtime/schema.js +0 -249
  100. package/lib/esm/utils/cron-job.js +0 -44
  101. package/lib/esm/utils/extract-metadata-transform.js +0 -54
  102. package/lib/esm/utils/extract-metadata-transform.test.js +0 -59
  103. package/lib/esm/utils/fs.js +0 -41
  104. package/lib/esm/utils/get-blocklet-agent.js +0 -344
  105. package/lib/esm/utils/geti.js +0 -30
  106. package/lib/esm/utils/is-non-nullable.js +0 -13
  107. package/lib/esm/utils/render-message.js +0 -20
  108. package/lib/esm/utils/resolve-secret-inputs.js +0 -46
  109. package/lib/esm/utils/retry.js +0 -16
  110. package/lib/esm/utils/task-id.js +0 -3
  111. package/lib/esm/utils/tool-calls-transform.js +0 -15
  112. package/lib/types/assistant/generate-output.d.ts +0 -29
  113. package/lib/types/assistant/select-agent.d.ts +0 -14
  114. package/lib/types/assistant/type.d.ts +0 -61
  115. package/lib/types/common/aid.d.ts +0 -18
  116. package/lib/types/common/index.d.ts +0 -7
  117. package/lib/types/common/resource-manager.d.ts +0 -88
  118. package/lib/types/constants.d.ts +0 -6
  119. package/lib/types/executor/agent.d.ts +0 -5
  120. package/lib/types/executor/aigc.d.ts +0 -9
  121. package/lib/types/executor/api.d.ts +0 -9
  122. package/lib/types/executor/base.d.ts +0 -209
  123. package/lib/types/executor/blocklet.d.ts +0 -9
  124. package/lib/types/executor/call-agent.d.ts +0 -12
  125. package/lib/types/executor/decision.d.ts +0 -20
  126. package/lib/types/executor/image-blender.d.ts +0 -9
  127. package/lib/types/executor/index.d.ts +0 -8
  128. package/lib/types/executor/llm.d.ts +0 -38
  129. package/lib/types/executor/logic.d.ts +0 -9
  130. package/lib/types/libs/blocklet/vc.d.ts +0 -17
  131. package/lib/types/libs/openapi/request/index.d.ts +0 -17
  132. package/lib/types/libs/openapi/request/util.d.ts +0 -40
  133. package/lib/types/libs/openapi/types/index.d.ts +0 -20
  134. package/lib/types/libs/openapi/util/call.d.ts +0 -2
  135. package/lib/types/libs/openapi/util/check-schema.d.ts +0 -3
  136. package/lib/types/libs/openapi/util/convert-schema.d.ts +0 -8
  137. package/lib/types/libs/openapi/util/flatten-open-api.d.ts +0 -3
  138. package/lib/types/libs/openapi/util/get-open-api-i18n-text.d.ts +0 -2
  139. package/lib/types/runtime/resource-blocklet.d.ts +0 -2
  140. package/lib/types/runtime/runtime.d.ts +0 -20
  141. package/lib/types/types/assistant/index.d.ts +0 -405
  142. package/lib/types/types/assistant/mustache/ReadableMustache.d.ts +0 -2
  143. package/lib/types/types/assistant/mustache/directive.d.ts +0 -6
  144. package/lib/types/types/assistant/mustache/mustache.d.ts +0 -2
  145. package/lib/types/types/common/index.d.ts +0 -45
  146. package/lib/types/types/resource/index.d.ts +0 -17
  147. package/lib/types/types/resource/project.d.ts +0 -41
  148. package/lib/types/types/runtime/agent.d.ts +0 -33
  149. package/lib/types/types/runtime/error.d.ts +0 -10
  150. package/lib/types/types/runtime/index.d.ts +0 -116
  151. package/lib/types/types/runtime/runtime-resource-blocklet-state.d.ts +0 -5
  152. package/lib/types/types/runtime/schema.d.ts +0 -110
  153. package/lib/types/utils/cron-job.d.ts +0 -22
  154. package/lib/types/utils/extract-metadata-transform.d.ts +0 -16
  155. package/lib/types/utils/extract-metadata-transform.test.d.ts +0 -1
  156. package/lib/types/utils/fs.d.ts +0 -9
  157. package/lib/types/utils/get-blocklet-agent.d.ts +0 -219
  158. package/lib/types/utils/geti.d.ts +0 -1
  159. package/lib/types/utils/is-non-nullable.d.ts +0 -2
  160. package/lib/types/utils/render-message.d.ts +0 -6
  161. package/lib/types/utils/resolve-secret-inputs.d.ts +0 -11
  162. package/lib/types/utils/retry.d.ts +0 -1
  163. package/lib/types/utils/task-id.d.ts +0 -1
  164. package/lib/types/utils/tool-calls-transform.d.ts +0 -2
  165. /package/lib/cjs/types/{runtime/agent.js → agent.js} +0 -0
  166. /package/lib/cjs/types/{common/index.js → runnable.js} +0 -0
  167. /package/lib/esm/types/{runtime/agent.js → agent.js} +0 -0
  168. /package/lib/esm/types/{common/index.js → runnable.js} +0 -0
@@ -1,372 +0,0 @@
1
- import { TransformStream } from 'stream/web';
2
- import { isChatCompletionChunk, isChatCompletionUsage } from '@blocklet/ai-kit/api/types/index';
3
- import { logger } from '@blocklet/sdk/lib/config';
4
- import { extractMetadataFromStream, metadataOutputFormatPrompt, metadataStreamOutputFormatPrompt, } from '../assistant/generate-output';
5
- import { defaultTextModel, supportJsonSchemaModels } from '../common';
6
- import { parseIdentity, stringifyIdentity } from '../common/aid';
7
- import { AssistantResponseType, RuntimeOutputVariable, jsonSchemaToOpenAIJsonSchema, outputVariablesToJsonSchema, } from '../types';
8
- import { parseDirectives } from '../types/assistant/mustache/directive';
9
- import retry from '../utils/retry';
10
- import { nextId } from '../utils/task-id';
11
- import { AgentExecutorBase } from './base';
12
- export class LLMAgentExecutor extends AgentExecutorBase {
13
- retryTimes = 0;
14
- get modelInfo() {
15
- const { agent } = this;
16
- const model = agent.model || agent.project.model || defaultTextModel;
17
- const defaultModelInfo = model === agent.project.model ? agent.project : undefined;
18
- return {
19
- model,
20
- temperature: agent.temperature ?? defaultModelInfo?.temperature,
21
- topP: agent.topP ?? defaultModelInfo?.topP,
22
- presencePenalty: agent.presencePenalty ?? defaultModelInfo?.presencePenalty,
23
- frequencyPenalty: agent.frequencyPenalty ?? defaultModelInfo?.frequencyPenalty,
24
- };
25
- }
26
- _executor;
27
- get executor() {
28
- this._executor ??= (async () => {
29
- const { agent } = this;
30
- const identity = parseIdentity(agent.identity.aid, { rejectWhenError: true });
31
- return agent.executor?.agent?.id
32
- ? {
33
- executor: await this.context.getAgent({
34
- aid: stringifyIdentity({
35
- blockletDid: agent.executor.agent.blockletDid || identity.blockletDid,
36
- projectId: agent.executor.agent.projectId || identity.projectId,
37
- projectRef: identity.projectRef,
38
- agentId: agent.executor.agent.id,
39
- }),
40
- working: agent.identity.working,
41
- rejectOnEmpty: true,
42
- }),
43
- inputValues: agent.executor.inputValues,
44
- }
45
- : agent.project.executor?.agent?.id
46
- ? {
47
- executor: await this.context.getAgent({
48
- aid: stringifyIdentity({
49
- blockletDid: agent.project.executor.agent.blockletDid || identity.blockletDid,
50
- projectId: agent.project.executor.agent.projectId || identity.projectId,
51
- projectRef: identity.projectRef,
52
- agentId: agent.project.executor.agent.id,
53
- }),
54
- working: agent.identity.working,
55
- rejectOnEmpty: true,
56
- }),
57
- inputValues: agent.project.executor.inputValues,
58
- }
59
- : undefined;
60
- })();
61
- return this._executor;
62
- }
63
- _outputsInfo;
64
- get outputsInfo() {
65
- this._outputsInfo ??= (async () => {
66
- const { agent } = this;
67
- const outputVariables = (agent.outputVariables ?? []).filter((i) => !!i.name && !i.hidden && i.from?.type !== 'callAgent') ?? [];
68
- const schema = outputVariablesToJsonSchema(agent, {
69
- variables: await this.context.getMemoryVariables({
70
- ...parseIdentity(agent.identity.aid, { rejectWhenError: true }),
71
- working: agent.identity.working,
72
- }),
73
- });
74
- const hasStreamingTextOutput = outputVariables.some((i) => i.name === RuntimeOutputVariable.text);
75
- const hasJsonOutputs = !!schema && Object.values(schema.properties).length > 0;
76
- return { outputs: outputVariables, schema, hasStreamingTextOutput, hasJsonOutputs };
77
- })();
78
- return this._outputsInfo;
79
- }
80
- getMessages({ inputs }) {
81
- const { agent } = this;
82
- const createContentStructure = async (content, variables, agent, prompt) => {
83
- const parameters = agent.parameters ?? [];
84
- // 没有特殊变量
85
- if (!variables.length) {
86
- const renderedContent = await this.renderMessage(content, { ...inputs, ...this.globalContext });
87
- return renderedContent;
88
- }
89
- // 没有图片变量
90
- const haveImageParameter = parameters.filter((i) => i.type === 'image').some((i) => variables.includes(i.key));
91
- if (!haveImageParameter) {
92
- const renderedContent = await this.renderMessage(content, { ...inputs, ...this.globalContext });
93
- return renderedContent;
94
- }
95
- // 创建图片变量标记
96
- const createImageMarker = (variable) => `__IMAGE_${variable}__`;
97
- const imageVariablesMap = {};
98
- const imageVariables = [];
99
- // 当前参数有图片变量
100
- parameters
101
- .filter((i) => i.type === 'image' && i.key && variables.includes(i.key))
102
- .forEach((param) => {
103
- if (param.type === 'image' && param.key && inputs[param.key]) {
104
- const marker = createImageMarker(param.key);
105
- imageVariablesMap[param.key] = marker;
106
- imageVariables.push({ marker, value: inputs[param.key] });
107
- }
108
- });
109
- const renderedContent = await this.renderMessage(content, {
110
- ...inputs,
111
- ...this.globalContext,
112
- ...imageVariablesMap,
113
- });
114
- const contentParts = [];
115
- if (imageVariables.length === 0) {
116
- return renderedContent;
117
- }
118
- let remainingContent = renderedContent;
119
- for (const { marker, value } of imageVariables) {
120
- const parts = remainingContent.split(marker);
121
- if (parts[0]) {
122
- contentParts.push({ type: 'text', text: parts[0] });
123
- }
124
- // 只有是 user 时,才处理
125
- if (prompt.data.role === 'user') {
126
- const list = Array.isArray(value) ? value : [value];
127
- list.forEach((item) => contentParts.push({ type: 'image_url', imageUrl: { url: item } }));
128
- }
129
- remainingContent = parts[1] || '';
130
- }
131
- if (remainingContent) {
132
- contentParts.push({ type: 'text', text: remainingContent });
133
- }
134
- logger.info('have image messages', contentParts);
135
- return contentParts;
136
- };
137
- return (async () => (await Promise.all((agent.prompts ?? [])
138
- .filter((i) => i.visibility !== 'hidden')
139
- .map(async (prompt) => {
140
- if (prompt.type === 'message') {
141
- const content = prompt.data.content
142
- ?.split('\n')
143
- .filter((i) => !i.startsWith('//'))
144
- .join('\n') || '';
145
- const variables = parseDirectives(content)
146
- .filter((i) => i.type === 'variable')
147
- .map((i) => i.name);
148
- const contentStructure = await createContentStructure(content, variables, agent, prompt);
149
- return {
150
- role: prompt.data.role,
151
- content: contentStructure,
152
- };
153
- }
154
- console.warn('Unsupported prompt type', prompt);
155
- return undefined;
156
- })))
157
- .flat()
158
- .filter((i) => !!i?.content))();
159
- }
160
- async process({ inputs }) {
161
- const { hasJsonOutputs } = await this.outputsInfo;
162
- const messages = await this.getMessages({ inputs });
163
- const { modelInfo } = this;
164
- const e = await this.executor;
165
- // NOTE: use json_schema output for models that support it
166
- if (supportJsonSchemaModels.includes(modelInfo.model) &&
167
- hasJsonOutputs &&
168
- // check the llm executor is support json schema output
169
- (!e || e.executor.parameters?.some((i) => i.type === 'llmInputResponseFormat'))) {
170
- return this.processWithJsonSchemaFormat({ messages, inputs });
171
- }
172
- return this.processWithOutJsonSchemaFormatSupport({ inputs, messages });
173
- }
174
- async processWithOutJsonSchemaFormatSupport({ inputs, messages, }) {
175
- const { agent, options: { taskId, parentTaskId }, } = this;
176
- const { hasStreamingTextOutput, hasJsonOutputs, schema } = await this.outputsInfo;
177
- const outputSchema = JSON.stringify(schema);
178
- const messagesWithSystemPrompt = [...messages];
179
- const lastSystemIndex = messagesWithSystemPrompt.findLastIndex((i) => i.role === 'system');
180
- if (hasJsonOutputs) {
181
- if (hasStreamingTextOutput) {
182
- messagesWithSystemPrompt.splice(lastSystemIndex + 1, 0, {
183
- role: 'system',
184
- content: metadataStreamOutputFormatPrompt(outputSchema),
185
- });
186
- }
187
- else {
188
- messagesWithSystemPrompt.splice(lastSystemIndex + 1, 0, {
189
- role: 'system',
190
- content: metadataOutputFormatPrompt(outputSchema),
191
- });
192
- }
193
- }
194
- if (!messagesWithSystemPrompt.length)
195
- return undefined;
196
- this.context.callback?.({
197
- type: AssistantResponseType.INPUT,
198
- assistantId: agent.id,
199
- parentTaskId,
200
- taskId,
201
- assistantName: agent.name,
202
- inputParameters: this.hideSecretInputs(inputs, agent),
203
- promptMessages: messagesWithSystemPrompt,
204
- });
205
- const run = async () => {
206
- this.retryTimes += 1;
207
- let result = '';
208
- const metadataStrings = [];
209
- const chatCompletionChunk = await this.callAIOrExecutor({ messages: messagesWithSystemPrompt, inputs });
210
- const stream = extractMetadataFromStream(chatCompletionChunk.pipeThrough(new TransformStream({
211
- transform: (chunk, controller) => {
212
- if (isChatCompletionUsage(chunk)) {
213
- this.context.callback?.({
214
- type: AssistantResponseType.USAGE,
215
- taskId,
216
- assistantId: agent.id,
217
- usage: chunk.usage,
218
- });
219
- }
220
- controller.enqueue(chunk);
221
- },
222
- })), hasJsonOutputs);
223
- for await (const chunk of stream) {
224
- if (chunk.type === 'text') {
225
- const { text } = chunk;
226
- result += text;
227
- if (hasStreamingTextOutput && this.retryTimes === 1) {
228
- this.context.callback?.({
229
- type: AssistantResponseType.CHUNK,
230
- taskId,
231
- assistantId: agent.id,
232
- delta: { content: text },
233
- });
234
- }
235
- }
236
- else if (chunk.type === 'match') {
237
- metadataStrings.push(chunk.text);
238
- }
239
- }
240
- const json = {};
241
- for (const i of metadataStrings) {
242
- try {
243
- const obj = JSON.parse(i);
244
- Object.assign(json, obj);
245
- }
246
- catch {
247
- // ignore
248
- }
249
- }
250
- // try to parse all text content as a json
251
- try {
252
- Object.assign(json, JSON.parse(result));
253
- }
254
- catch {
255
- // ignore
256
- }
257
- try {
258
- return await super.validateOutputs({
259
- inputs,
260
- outputs: { ...json, $text: result },
261
- });
262
- }
263
- catch (error) {
264
- logger.error('validate LLM outputs error', error);
265
- throw new Error('Unexpected response format from AI');
266
- }
267
- };
268
- return await retry(run, this.context.maxRetries);
269
- }
270
- async processWithJsonSchemaFormat({ messages, inputs, }) {
271
- const { agent, options: { parentTaskId, taskId }, } = this;
272
- this.context.callback?.({
273
- type: AssistantResponseType.INPUT,
274
- assistantId: agent.id,
275
- parentTaskId,
276
- taskId,
277
- assistantName: agent.name,
278
- inputParameters: this.hideSecretInputs(inputs, agent),
279
- promptMessages: messages,
280
- });
281
- const { hasStreamingTextOutput, schema } = await this.outputsInfo;
282
- const [json, { text }] = await Promise.all([
283
- this.callAIGetJsonOutput({ messages, schema }),
284
- hasStreamingTextOutput ? this.callAIGetTextStreamOutput({ messages, inputs }) : { text: undefined },
285
- ]);
286
- try {
287
- return await super.validateOutputs({
288
- inputs,
289
- outputs: { ...json, $text: text },
290
- });
291
- }
292
- catch (error) {
293
- logger.error('validate LLM outputs error', error);
294
- throw new Error('Unexpected response format from AI');
295
- }
296
- }
297
- async callAIGetJsonOutput({ messages, schema }) {
298
- const { modelInfo } = this;
299
- const result = await this.context.callAI({
300
- assistant: this.agent,
301
- input: {
302
- messages,
303
- ...modelInfo,
304
- responseFormat: {
305
- type: 'json_schema',
306
- jsonSchema: {
307
- name: 'output',
308
- schema: jsonSchemaToOpenAIJsonSchema(schema),
309
- strict: true,
310
- },
311
- },
312
- },
313
- });
314
- let json = '';
315
- for await (const i of result) {
316
- if (isChatCompletionChunk(i)) {
317
- json += i.delta.content || '';
318
- }
319
- }
320
- try {
321
- return JSON.parse(json);
322
- }
323
- catch (error) {
324
- logger.error(json, error);
325
- throw new Error('parse ai json schema output error');
326
- }
327
- }
328
- async callAIGetTextStreamOutput({ messages, inputs, }) {
329
- const { agent, options: { taskId }, } = this;
330
- const stream = await this.callAIOrExecutor({
331
- messages,
332
- inputs,
333
- });
334
- let text = '';
335
- for await (const chunk of stream) {
336
- if (isChatCompletionChunk(chunk)) {
337
- text += chunk.delta.content || '';
338
- this.context.callback?.({
339
- type: AssistantResponseType.CHUNK,
340
- taskId,
341
- assistantId: agent.id,
342
- delta: { content: chunk.delta.content },
343
- });
344
- }
345
- }
346
- return { text };
347
- }
348
- async callAIOrExecutor({ messages, inputs, }) {
349
- const { agent, modelInfo, options: { taskId }, } = this;
350
- const e = await this.executor;
351
- return e
352
- ? (await this.context
353
- .executor(e.executor, {
354
- inputs: {
355
- ...inputs,
356
- ...e.inputValues,
357
- [e.executor.parameters?.find((i) => i.type === 'llmInputMessages' && !i.hidden)?.key]: messages,
358
- },
359
- taskId: nextId(),
360
- parentTaskId: taskId,
361
- })
362
- .execute())[RuntimeOutputVariable.llmResponseStream]
363
- : await this.context.callAI({
364
- assistant: agent,
365
- input: {
366
- stream: true,
367
- messages,
368
- ...modelInfo,
369
- },
370
- });
371
- }
372
- }
@@ -1,160 +0,0 @@
1
- import crypto from 'crypto';
2
- import { Sandbox } from '@blocklet/quickjs';
3
- import { call, getComponentMountPoint } from '@blocklet/sdk/lib/component';
4
- import config from '@blocklet/sdk/lib/config';
5
- import equal from 'fast-deep-equal';
6
- import Joi from 'joi';
7
- import pick from 'lodash/pick';
8
- import { parseIdentity, stringifyIdentity } from '../common/aid';
9
- import logger from '../logger';
10
- import { AssistantResponseType } from '../types';
11
- import { renderMustacheStream } from '../types/assistant/mustache/ReadableMustache';
12
- import { geti } from '../utils/geti';
13
- import { nextId } from '../utils/task-id';
14
- import { AgentExecutorBase } from './base';
15
- async function parseJSONInVM(str) {
16
- return Sandbox.callFunction({
17
- code: `\
18
- function parse(json) {
19
- return eval(\`const j = \${json}; j\`)
20
- }
21
- `,
22
- filename: 'parserJSONInVm.js',
23
- functionName: 'parse',
24
- args: [str.trim()],
25
- });
26
- }
27
- export class LogicAgentExecutor extends AgentExecutorBase {
28
- async process({ inputs }) {
29
- const { agent, options: { taskId }, } = this;
30
- if (!agent.code)
31
- throw new Error(`Assistant ${agent.id}'s code is empty`);
32
- const args = Object.fromEntries(await Promise.all((agent.parameters ?? [])
33
- .filter((i) => !!i.key && !i.hidden)
34
- .map(async (i) => [i.key, inputs?.[i.key] ?? i.defaultValue])));
35
- const $json = (variables, ...rest) => {
36
- const taggedFn = async (t, ...rest) => {
37
- const template = t.map((s, i) => `${s}${i === t.length - 1 ? '' : rest[i]}`).join('');
38
- const renderCtx = {
39
- ...args,
40
- ...variables,
41
- ...this.globalContext,
42
- get: () => async (template, render) => {
43
- const s = await render(template);
44
- return geti(renderCtx, s);
45
- },
46
- runAgent: () => async (template, render) => {
47
- const t = (await parseJSONInVM(template))?.template;
48
- const s = await render(template);
49
- const j = await parseJSONInVM(s);
50
- const { agentId, inputs } = await Joi.object({
51
- agentId: Joi.string().required(),
52
- inputs: Joi.object().pattern(Joi.string(), Joi.any()).required(),
53
- }).validateAsync(j, { stripUnknown: true });
54
- const a = await this.context.getAgent({
55
- aid: stringifyIdentity({ ...parseIdentity(agent.identity.aid, { rejectWhenError: true }), agentId }),
56
- working: agent.identity.working,
57
- rejectOnEmpty: true,
58
- });
59
- const result = await this.context.execute(a, { taskId: nextId(), parentTaskId: taskId, inputs });
60
- return this.renderMessage(t, { ...renderCtx, $result: result }, { escapeJsonSymbols: true });
61
- },
62
- };
63
- const result = renderMustacheStream(template, (enqueue) => ({
64
- ...renderCtx,
65
- runAgent: () => enqueue(renderCtx.runAgent()),
66
- }));
67
- let object;
68
- for await (const chunk of result) {
69
- const newObj = await parseJSONInVM(chunk);
70
- // skip if the object is equal
71
- // TODO: throttle the output
72
- if (equal(object, newObj)) {
73
- continue;
74
- }
75
- object = newObj;
76
- try {
77
- const obj = await this.validateOutputs({ outputs: object, partial: true });
78
- this.context.callback?.({
79
- type: AssistantResponseType.CHUNK,
80
- taskId,
81
- assistantId: agent.id,
82
- delta: { object: obj },
83
- });
84
- }
85
- catch (error) {
86
- logger.error('validate LLM outputs error', error, object);
87
- }
88
- }
89
- return object;
90
- };
91
- // 支持 $json({foo:"xxx"})`` 和 $json`` 两种调用方式
92
- if (Array.isArray(variables)) {
93
- return taggedFn(variables, ...rest);
94
- }
95
- return taggedFn;
96
- };
97
- const log = (...args) => this.context.callback({
98
- type: AssistantResponseType.LOG,
99
- log: JSON.stringify(args),
100
- timestamp: Date.now(),
101
- taskId,
102
- assistantId: agent.id,
103
- });
104
- const global = {
105
- console: {
106
- // NOTE: do not return logger.xxx result, it will cause memory leak
107
- log: (...args) => log(...args),
108
- info: (...args) => log(...args),
109
- debug: (...args) => log(...args),
110
- warn: (...args) => log(...args),
111
- error: (...args) => log(...args),
112
- },
113
- getComponentMountPoint,
114
- call: (...args) => call(...args).then((res) => ({ data: res.data })),
115
- crypto: { randomInt: crypto.randomInt },
116
- config: { env: pick(config.env, 'appId', 'appName', 'appDescription', 'appUrl') },
117
- };
118
- const allArgs = {
119
- $json,
120
- runAgent: async ({ agentId, inputs, streaming, }) => {
121
- const a = await this.context.getAgent({
122
- aid: stringifyIdentity({ ...parseIdentity(agent.identity.aid, { rejectWhenError: true }), agentId }),
123
- working: agent.identity.working,
124
- rejectOnEmpty: true,
125
- });
126
- const { callback } = this.context;
127
- const currentTaskId = nextId();
128
- return this.context
129
- .copy(streaming
130
- ? {
131
- callback: function hello(args) {
132
- callback(args);
133
- if (args.type === AssistantResponseType.CHUNK &&
134
- args.delta.content &&
135
- args.taskId === currentTaskId) {
136
- callback({ ...args, taskId });
137
- }
138
- },
139
- }
140
- : {})
141
- .execute(a, { taskId: currentTaskId, parentTaskId: taskId, inputs });
142
- },
143
- ...this.globalContext,
144
- ...args,
145
- };
146
- const argKeys = Object.keys(allArgs);
147
- const resultPromise = await Sandbox.callFunction({
148
- code: `\
149
- async function main({${argKeys.join(', ')}) {
150
- ${agent.code}
151
- }
152
- `,
153
- filename: `${agent.name || agent.id}.js`,
154
- global,
155
- functionName: 'main',
156
- args: [allArgs],
157
- });
158
- return resultPromise;
159
- }
160
- }
@@ -1,85 +0,0 @@
1
- import AuthService from '@blocklet/sdk/lib/service/auth';
2
- import { AIGNE_ISSUE_VC_PREFIX } from '../../constants';
3
- export const authService = new AuthService();
4
- export async function issueVC({ context: { entry }, userDid, name, title, description, reissue = false, displayUrl, notify = true, }) {
5
- // NOTE: ensure name starts with AIGNE_ISSUE_VC_PREFIX to avoid conflict with internal passports such as admin/owner
6
- if (!name.startsWith(AIGNE_ISSUE_VC_PREFIX))
7
- name = `${AIGNE_ISSUE_VC_PREFIX}${name}`;
8
- await createPassportIfNotExist({ name, title, description });
9
- const userResult = await authService.getUser(userDid, { includeTags: true });
10
- if (!userResult.user)
11
- throw new Error(`User not found ${userDid}`);
12
- if (!reissue) {
13
- const vc = userResult.user.passports.find((p) => p.role === name);
14
- if (vc)
15
- return { user: userResult.user, vc };
16
- }
17
- const issueResult = await authService.issuePassportToUser({
18
- userDid,
19
- role: name,
20
- display: displayUrl ? { type: 'url', content: displayUrl } : undefined,
21
- notify,
22
- notification: JSON.stringify({
23
- title: `You just received a VC ${title}`,
24
- body: description,
25
- attachments: [
26
- {
27
- type: 'image',
28
- data: {
29
- url: displayUrl,
30
- alt: title,
31
- },
32
- },
33
- ],
34
- appInfo: {
35
- title: entry.project.name,
36
- // logo: getProjectIconUrl(entry.project.id, {
37
- // blockletDid: entry.blockletDid,
38
- // working: entry.working,
39
- // updatedAt: entry.project.updatedAt,
40
- // }),
41
- url: entry.appUrl,
42
- description: entry.project.description,
43
- },
44
- poweredBy: {
45
- name: 'AIGNE',
46
- url: 'https://www.aigne.io',
47
- },
48
- severity: 'success',
49
- }),
50
- });
51
- if (issueResult.code !== 'ok')
52
- throw new Error(`Issue VC failed got ${issueResult.code}`);
53
- const vc = issueResult.user.passports.findLast((p) => p.role === name);
54
- if (!vc)
55
- throw new Error('Issue VC got empty result');
56
- return { user: issueResult.user, vc };
57
- }
58
- const CREATE_PASSPORT_TASKS = {};
59
- async function createPassportIfNotExist({ name, title, description, }) {
60
- CREATE_PASSPORT_TASKS[name] ??= (async () => {
61
- try {
62
- let result = await authService.getRole(name);
63
- if (!result.role) {
64
- // Create a role for custom display
65
- result = await authService.createRole({
66
- title,
67
- name,
68
- description,
69
- permissions: [],
70
- extra: JSON.stringify({
71
- display: 'custom',
72
- types: [name],
73
- }),
74
- });
75
- }
76
- return result;
77
- }
78
- catch (error) {
79
- // NOTE: reset task if failed
80
- delete CREATE_PASSPORT_TASKS[name];
81
- throw error;
82
- }
83
- })();
84
- return CREATE_PASSPORT_TASKS[name];
85
- }
@@ -1,20 +0,0 @@
1
- import { call } from '@blocklet/sdk/lib/component';
2
- import { getRequestConfig } from './util';
3
- export const callBlockletApi = (pathItem, data, options) => {
4
- const requestConfig = getRequestConfig(pathItem, data, {
5
- params: options?.params || {},
6
- data: options?.data || {},
7
- });
8
- const { headers, method, url, params, ...config } = requestConfig;
9
- const did = options?.user?.did || '';
10
- if (!pathItem.name)
11
- throw new Error('Blocklet name is required to call blocklet api');
12
- return call({
13
- ...config,
14
- method: method,
15
- name: pathItem.name,
16
- path: url,
17
- headers,
18
- params: { ...params, userId: did },
19
- });
20
- };