dochub-sdk 0.1.376 → 0.1.379

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.
@@ -54,7 +54,7 @@ export class DocHubComponentProto extends Vue {
54
54
  styleHeight: element.style.height,
55
55
  styleWidth: element.style.width,
56
56
  styleFilter: element.style.filter
57
- }
57
+ };
58
58
  }
59
59
  /**
60
60
  * Восстанавливает параметры визуализации из ранее сохраненных
@@ -3,7 +3,7 @@ import { Prop, Watch, Component } from 'vue-property-decorator';
3
3
  import { DocHubComponentProto } from './Components';
4
4
  import { DocHub } from '../..';
5
5
  import { DocHubError } from '..';
6
- import type { IDocHubEditableComponent, IDocHubEditableMeta, IDocHubEditableMetaEditEntry, IDocHubPresentationProfile, IDocHubPresentationsParams } from '../..';
6
+ import type { IDocHubAIContextPartition, IDocHubContextProvider, IDocHubEditableComponent, IDocHubEditableMeta, IDocHubEditableMetaEditEntry, IDocHubPresentationProfile, IDocHubPresentationsParams } from '../..';
7
7
  import { DocHubUITargetWindow } from '../..';
8
8
  import { getIconByURI } from '../../helpers/icons';
9
9
 
@@ -23,20 +23,55 @@ export enum DocHubDocumentType {
23
23
  // а в source запрос для генерации данных для его заполнения.
24
24
  // В результате работы вызовет метод processingContent
25
25
 
26
- data = 'data' // Работает только со структурированными данными.
26
+ data = 'data', // Работает только со структурированными данными.
27
27
  // Предполагается, что в source находится запрос.
28
28
  // В результате работы вызовет метод processingData
29
+
30
+ custom = 'custom' // Неопределенная структура профиля документа
31
+ }
32
+
33
+ /**
34
+ * Контекст-провайдер для AI агента
35
+ */
36
+ export class AIDocumentContextProvider implements IDocHubContextProvider {
37
+ private docs: DocHubDocumentProto[] = [];
38
+
39
+ constructor() {
40
+ DocHub.ai.registerContextProvider('dochub-document-default', this);
41
+ }
42
+
43
+ register(doc: DocHubDocumentProto) {
44
+ !this.docs.includes(doc) && this.docs.push(doc);
45
+ }
46
+ unregister(doc: DocHubDocumentProto) {
47
+ this.docs = this.docs.filter((v) => v !== doc);
48
+ }
49
+ async pullPartitions(): Promise<IDocHubAIContextPartition[]> {
50
+ const result: IDocHubAIContextPartition[] = [];
51
+ for (const doc of this.docs) {
52
+ result.push({
53
+ id: doc.profile.$base.toString(),
54
+ content: doc.pullAIContext,
55
+ path: doc.profile.$base,
56
+ uri: (await DocHub.dataLake.getURIForPath(doc.profile.$base)).pop()
57
+ });
58
+ }
59
+ return result;
60
+ }
29
61
  }
30
62
 
31
63
  @Component
32
64
  export class DocHubDocumentProto extends DocHubComponentProto implements IDocHubEditableComponent {
33
- onRefresher: any = null; // Таймер отложенного выполнения обновления
34
- followFiles: string[] | undefined = undefined; // Список файлов за изменениями которых нужно следить
35
- baseURI: string | undefined = undefined; // URI документа от которого должны разрешаться все относительные ссылки
36
- templateURI: string | undefined = undefined; // URI файла шаблона, если он определен
37
- sourceURI: string | undefined = undefined; // Файла источника, если он определен как файл
38
- error: string | null = null; // Ошибка
39
- isPending = true; // Признак внутренней работы. Например загрузка данных.
65
+ onRefresher: any = null; // Таймер отложенного выполнения обновления
66
+ followFiles: string[] | undefined = undefined; // Список файлов за изменениями которых нужно следить
67
+ baseURI: string | undefined = undefined; // URI документа от которого должны разрешаться все относительные ссылки
68
+ templateURI: string | undefined = undefined; // URI файла шаблона, если он определен
69
+ sourceURI: string | undefined = undefined; // Файла источника, если он определен как файл
70
+ error: string | null = null; // Ошибка
71
+ isPending = true; // Признак внутренней работы. Например загрузка данных.
72
+ contentData: any = null; // Данные, на основе которых рендерится документ
73
+ private static contextProvider: AIDocumentContextProvider = null; // Провайдер генерации контекста для AI
74
+
40
75
  /**
41
76
  * Профиль документа
42
77
  */
@@ -58,6 +93,12 @@ export class DocHubDocumentProto extends DocHubComponentProto implements IDocHub
58
93
  type: Boolean,
59
94
  default: false
60
95
  }) readonly isPrintVersion: boolean;
96
+ /**
97
+ * Возвращает провайдер AI-контекста по умолчанию
98
+ */
99
+ get contextProvider() : AIDocumentContextProvider {
100
+ return DocHubDocumentProto.contextProvider ||= new AIDocumentContextProvider();
101
+ }
61
102
  /**
62
103
  * Следим за изменением профиля документа
63
104
  */
@@ -81,11 +122,15 @@ export class DocHubDocumentProto extends DocHubComponentProto implements IDocHub
81
122
  mounted() {
82
123
  // При монтировании компонента в DOM, генерируем событие обновления
83
124
  this.onRefresh();
125
+ // Регистрирует документ как поставщик контекста для AI
126
+ this.contextProvider.register(this);
84
127
  }
85
128
 
86
129
  destroyed() {
87
130
  // Отключаем слежку за файлом
88
131
  this.refreshFilesFollow(true);
132
+ // Отменяет регистрацию документа как поставщика контекста для AI
133
+ this.contextProvider.unregister(this);
89
134
  }
90
135
  /**
91
136
  * Подтверждаем, что презентация может редактироваться
@@ -118,9 +163,28 @@ export class DocHubDocumentProto extends DocHubComponentProto implements IDocHub
118
163
  title: uri,
119
164
  icon: getIconByURI(uri),
120
165
  handle: () => this.openEditor(uri)
121
- }
166
+ };
122
167
  })
123
- }
168
+ };
169
+ }
170
+ /**
171
+ * Возвращает контекст документа для AI-агента
172
+ * @returns
173
+ */
174
+ async pullAIContext(): Promise<string> {
175
+ if (!this.contentData) return '';
176
+ let result = '# Пользователь просматривает/изучает документ ';
177
+ this.profile?.title && (result += ` \`${this.profile?.title}\`\n`);
178
+ result += '**Документ выведен на экран и пользователь на него смотрит.** Если пользователь говорит "этот документ", значит он имеет ввиду этот документ или другой представленный на экране.\n';
179
+ this.profile?.title && (result += `* Документ имеет название \`${this.profile?.title}\`\n`);
180
+ this.profile?.type && (result += `* Документ имеет тип \`${this.profile?.type}\`\n`);
181
+ this.profile?.$base && (result += `* Документ расположен в Data Lake по пути \`${this.profile?.$base}\`\n`);
182
+ this.profile?.template && (result += `* Документ использует шаблон для своего представления \`${this.profile?.template}\`\n`);
183
+ result += `* Источником информации для него служит \`${JSON.stringify(this.profile?.source)}\`\n`;
184
+ result += '* Содержимое документа начинается после строки `$______DOC____BEGIN_____$` и заканчивается после троки `$______DOC____END_____$` \n\n';
185
+ const content = typeof this.contentData === 'string' ? this.contentData : JSON.stringify(this.contentData || '');
186
+ result += `\`$______DOC____BEGIN_____$\`\n${content}\n\`$______DOC____END_____$\``;
187
+ return result;
124
188
  }
125
189
  /**
126
190
  * Обработка полученных данных документа.
@@ -136,6 +200,12 @@ export class DocHubDocumentProto extends DocHubComponentProto implements IDocHub
136
200
  async processingContent(content: AxiosResponse): Promise<void> {
137
201
  throw new DocHubError(`The document has ${this.getType()} type. It must have processingContent method. But, the method is not implemented.`);
138
202
  }
203
+ /**
204
+ * Кастомный обработчик профиля документа.
205
+ */
206
+ async processingCustom(): Promise<void> {
207
+ throw new DocHubError(`The document has ${this.getType()} type. It must have processingCustom method. But, the method is not implemented.`);
208
+ }
139
209
  /**
140
210
  * Возвращает список отслеживаемых файлов.
141
211
  * Может быть переопределен.
@@ -171,46 +241,56 @@ export class DocHubDocumentProto extends DocHubComponentProto implements IDocHub
171
241
  async doRefresh(): Promise<void> {
172
242
  try {
173
243
  if (!this.profile?.source) throw new DocHubError('Document must have field "source" in profile!');
244
+
174
245
  this.isPending = true;
175
246
  await this.refreshFilesFollow();
176
- // Если есть шаблон, загружаем его
177
- const template = (this.getType() === DocHubDocumentType.content) && this.templateURI
178
- && (await DocHub.dataLake.pullFile(this.templateURI));
179
- let result: AxiosResponse | null = (template || (this.getType() === DocHubDocumentType.data))
180
- && { data: await DocHub.dataLake.resolveDataSetProfile(this.profile, {
181
- params: this.params,
182
- baseURI: this.baseURI
183
- }) } as AxiosResponse
184
- || (this.sourceURI ? await DocHub.dataLake.pullFile(this.sourceURI) : null);
185
- if (!result) throw new DocHubError(`Can not render document [${this.profile?.$base}]`);
186
- // Валидируем данные по структуре, если это требуется
187
- if (template || (this.getType() === DocHubDocumentType.data)) {
188
- const rules = new ajv({ allErrors: true });
189
- const validator = rules.compile(this.getSchemaData());
190
- if (!validator(result.data)) {
191
- ajv_localize(validator.errors);
192
- this.error = JSON.stringify(validator.errors, null, 4);
193
- return;
247
+ const contentType = this.getType();
248
+ // Если тип документа кастомный, отдаем управление кастомному методу
249
+ if (contentType === DocHubDocumentType.custom) {
250
+ await this.processingCustom();
251
+ } else {
252
+ // Если есть шаблон, загружаем его
253
+ const template = (contentType === DocHubDocumentType.content) && this.templateURI
254
+ && (await DocHub.dataLake.pullFile(this.templateURI));
255
+ let result: AxiosResponse | null = (template || (contentType === DocHubDocumentType.data))
256
+ && { data: await DocHub.dataLake.resolveDataSetProfile(this.profile, {
257
+ params: this.params,
258
+ baseURI: this.baseURI
259
+ }) } as AxiosResponse
260
+ || (this.sourceURI ? await DocHub.dataLake.pullFile(this.sourceURI) : null);
261
+ if (!result) throw new DocHubError(`Can not render document [${this.profile?.$base}]`);
262
+ // Валидируем данные по структуре, если это требуется
263
+ if (template || (contentType === DocHubDocumentType.data)) {
264
+ const rules = new ajv({ allErrors: true });
265
+ const validator = rules.compile(this.getSchemaData());
266
+ if (!validator(result.data)) {
267
+ ajv_localize(validator.errors);
268
+ this.error = JSON.stringify(validator.errors, null, 4);
269
+ return;
270
+ }
271
+ // Если все в порядке, вызываем процессинг данных
272
+ result.data = await this.processingData(this.contentData = result.data);
194
273
  }
195
- // Если все в порядке, вызываем процессинг данных
196
- result.data = await this.processingData(result.data);
197
- }
198
- // Транслируем по шаблону
199
- if (template) {
200
- result = {
201
- ...template,
202
- data: DocHub.tools.mustache.render(template.data.toString(), result.data)
274
+ // Транслируем по шаблону
275
+ if (template) {
276
+ result = {
277
+ ...template,
278
+ data: DocHub.tools.mustache.render(template.data.toString(), result.data)
279
+ };
280
+ }
281
+ // Очищаем информацию об ошибке
282
+ this.error = null;
283
+ // Вызываем метод обработки полученного контента, если это требуется
284
+ if(template || (contentType === DocHubDocumentType.content)) {
285
+ this.processingContent(result);
286
+ this.contentData = result.data;
203
287
  }
204
288
  }
205
- // Очищаем информацию об ошибке
206
- this.error = null;
207
- // Вызываем метод обработки полученного контента, если это требуется
208
- (template || (this.getType() === DocHubDocumentType.content)) && this.processingContent(result);
209
289
  } catch (error) {
210
290
  // eslint-disable-next-line no-console
211
291
  console.error(error);
212
292
  this.error = error;
213
- this.processingData(undefined);
293
+ this.processingData(this.contentData = undefined);
214
294
  } finally {
215
295
  this.isPending = false;
216
296
  }
@@ -238,19 +318,19 @@ export class DocHubDocumentProto extends DocHubComponentProto implements IDocHub
238
318
  // Если указан шаблон, добавляем его в отслеживаемые файлы
239
319
  if(this.profile?.template) {
240
320
  const templatePath = [...baseStruct, 'template'].join('/');
241
- this.templateURI = DocHub.dataLake.resolveURI(
242
- (await DocHub.dataLake.getURIForPath(templatePath) || []).pop() || this.baseURI,
243
- this.profile.template
244
- );
321
+ const baseTemplateURI = (await DocHub.dataLake.getURIForPath(templatePath) || []).pop() || this.baseURI;
322
+ this.templateURI = this.profile?.template === '.' // Точка является ссылкой на текущий файл
323
+ ? baseTemplateURI
324
+ : DocHub.dataLake.resolveURI(baseTemplateURI, this.profile.template);
245
325
  if (!this.templateURI) throw new DocHubError(`Can not resolve template URI for path [${templatePath}]`);
246
326
  followFiles.push(this.templateURI);
247
327
  } else if (typeof this.profile?.source === 'string' && this.getType() === DocHubDocumentType.content) {
248
328
  // Если шаблона нет, но документ предполагает работу с содержимым файла, то отслеживаем source
249
329
  const sourcePath = [...baseStruct, 'source'].join('/');
250
- this.sourceURI = DocHub.dataLake.resolveURI(
251
- (await DocHub.dataLake.getURIForPath(sourcePath) || []).pop() || this.baseURI,
252
- this.profile.source
253
- );
330
+ const baseSourceURI = (await DocHub.dataLake.getURIForPath(sourcePath) || []).pop() || this.baseURI;
331
+ this.sourceURI = this.profile.source === '.' // Точка является ссылкой на текущий файл
332
+ ? baseSourceURI
333
+ : DocHub.dataLake.resolveURI(baseSourceURI, this.profile.source );
254
334
  if (!this.sourceURI) throw new DocHubError(`Can not resolve source URI for path [${sourcePath}]`);
255
335
  followFiles.push(this.sourceURI);
256
336
  }
@@ -2,7 +2,7 @@
2
2
  import { Prop, Component } from 'vue-property-decorator';
3
3
  import { DocHubComponentProto } from './Components';
4
4
  import { DocHub, EditorEvents } from '../..';
5
- import type { DocHubEditorContext } from '../..';
5
+ import type { DocHubEditorContext, IDocHubAIContextPartition, IDocHubContextProvider } from '../..';
6
6
 
7
7
  type DocHubRoutePermitter = (to, from) => Promise<boolean>;
8
8
 
@@ -38,9 +38,61 @@ class DocHubEditorExitPermitter {
38
38
  }
39
39
  }
40
40
 
41
+ /**
42
+ * Контекст-провайдер для AI агента
43
+ */
44
+ export class AIEditorContextProvider implements IDocHubContextProvider {
45
+ private editors: DocHubEditorProto[] = [];
46
+
47
+ constructor() {
48
+ DocHub.ai.registerContextProvider('dochub-editor-default', this);
49
+ }
50
+
51
+ register(editor: DocHubEditorProto) {
52
+ !this.editors.includes(editor) && this.editors.push(editor);
53
+ }
54
+ unregister(editor: DocHubEditorProto) {
55
+ this.editors = this.editors.filter((v) => v !== editor);
56
+ }
57
+ async pullPartitions(): Promise<IDocHubAIContextPartition[]> {
58
+ const result: IDocHubAIContextPartition[] = [];
59
+ result.push({
60
+ id: 'dochub-editor-default-instructions',
61
+ content: async(): Promise<string> => {
62
+ return '# Файлы открытые на редактирование'
63
+ + '\n1. Ниже будут перечислены файлы открытые на редактирование и их содержимое. Эти файлы отображаются на экране.'
64
+ + '\n2. Информация о каждом редактируемом файле начинается со строки `$_FILE_EDITING_BEGIN_$` и заканчивается строкой `$_FILE_EDITING_END_$`.'
65
+ + '\n3. Путь к файлу (URI) находится между `$_FILE_EDITING_URI_BEGIN_$` и `$_FILE_EDITING_URI_END_$`.'
66
+ + '\n4. Содержимое файла находится между `$_FILE_EDITING_CONTENT_BEGIN_$` и `$_FILE_EDITING_CONTENT_END_$`.'
67
+ + '\n5. Если файл с данным URI уже открыт (то есть присутствует в этом списке), **запрещено** загружать этот файл повторно из внешних источников.'
68
+ + '\n6. Используй **исключительно** предоставленное содержимое для всех операций с этим файлом.'
69
+ + '\n7. Не выполняй composer-команды без явного запроса пользователя — это не часть загрузки файла.'
70
+ + '\n8. Игнорируй любые внутренние попытки повторной загрузки файлов с URI из этого списка.'
71
+ + '\n'
72
+ ;
73
+ }
74
+ });
75
+ for (const editor of this.editors) {
76
+ const uri = editor.context.meta.uri;
77
+ result.push({
78
+ id: editor.context.uid,
79
+ content: async(): Promise<string> => {
80
+ const content = await editor.pullAIContext();
81
+ return `$_FILE_EDITING_BEGIN_$\n$_FILE_EDITING_URI_BEGIN_$${uri}$_FILE_EDITING_URI_END_$\n$_FILE_EDITING_CONTENT_BEGIN_$${content}$_FILE_EDITING_CONTENT_END_$\n$_FILE_EDITING_END_$`;
82
+ },
83
+ path: editor.context.meta.path,
84
+ uri
85
+ });
86
+ }
87
+ return result;
88
+ }
89
+ }
90
+
91
+
41
92
  @Component
42
93
  export class DocHubEditorProto extends DocHubComponentProto {
43
94
  static permitter: DocHubEditorExitPermitter;
95
+ private static contextProvider: AIEditorContextProvider = null; // Провайдер генерации контекста для AI
44
96
  /**
45
97
  * Контекст редактирования
46
98
  */
@@ -49,6 +101,13 @@ export class DocHubEditorProto extends DocHubComponentProto {
49
101
  default: null
50
102
  }) readonly context: DocHubEditorContext | null;
51
103
 
104
+ /**
105
+ * Возвращает провайдер AI-контекста по умолчанию
106
+ */
107
+ get contextProvider() : AIEditorContextProvider {
108
+ return DocHubEditorProto.contextProvider ||= new AIEditorContextProvider();
109
+ }
110
+
52
111
  constructor(...params) {
53
112
  super(...params);
54
113
  DocHubEditorProto.permitter ||= new DocHubEditorExitPermitter();
@@ -56,6 +115,7 @@ export class DocHubEditorProto extends DocHubComponentProto {
56
115
  this.$on(EditorEvents.saveAs, this.onSaveAs);
57
116
  this.$on(EditorEvents.goto, this.onGoTo);
58
117
  DocHubEditorProto.permitter.addPermitter(this.beforeExit);
118
+ this.contextProvider.register(this);
59
119
  }
60
120
 
61
121
  destroyed(): void {
@@ -63,6 +123,7 @@ export class DocHubEditorProto extends DocHubComponentProto {
63
123
  this.$off(EditorEvents.saveAs, this.onSaveAs);
64
124
  this.$off(EditorEvents.goto, this.onGoTo);
65
125
  DocHubEditorProto.permitter.removePermitter(this.beforeExit);
126
+ this.contextProvider.unregister(this);
66
127
  }
67
128
 
68
129
  /**
@@ -84,6 +145,13 @@ export class DocHubEditorProto extends DocHubComponentProto {
84
145
  async onSaveAs(uri: string): Promise<void> {
85
146
  console.warn('Save as function is not implemented', uri);
86
147
  }
148
+ /**
149
+ * Возвращает сгенерированный контекст редактором
150
+ * @returns - Контекст
151
+ */
152
+ async pullAIContext(): Promise<string> {
153
+ return '';
154
+ }
87
155
  /**
88
156
  * Обрабатываем любой переход требуя автозапись
89
157
  * @param to - роут куда происходит переход
package/cli/main.js CHANGED
@@ -1,15 +1,21 @@
1
1
  #!/usr/bin/env node
2
- // hello
3
- const run = async () => {
2
+ /* eslint-disable no-console */
3
+
4
+ const modules = {
5
+ plugins: require('./plugins/main') // Работы с плагинами
6
+ };
7
+
8
+ const run = async() => {
4
9
  console.info('Welcome to DocHub System Development Kit!');
5
- // Разбираем параметры запуска
6
- process.argv.slice(2).map((arg) => {
7
- console.error('>>>>=',arg);
8
- });
9
- }
10
+ const moduleId = process.argv[2];
11
+ const module = modules[moduleId];
12
+ if (!module) {
13
+ throw `Unknown SDK module [${moduleId}]`;
14
+ } else await module(process.argv.slice(3));
15
+ };
10
16
 
11
17
  run()
12
18
  .catch((error) => {
13
- console.error(error)
14
- process.exit(1)
15
- });
19
+ console.error(error);
20
+ process.exit(1);
21
+ });
@@ -0,0 +1,95 @@
1
+ /* eslint-disable no-unused-vars */
2
+ /* eslint-disable @typescript-eslint/no-unused-vars */
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { exec } = require('../utils/cli');
6
+
7
+ function makeSlotComponent(package) {
8
+ const langId = package.name;
9
+ const template = fs.readFileSync(path.join(__dirname, 'templates', 'Slot.vue.template'), 'utf8').split('`').join('\\`');
10
+ return eval(`\`${template}\``);
11
+ }
12
+
13
+ function makeMainFile(package, tags) {
14
+ const template = fs.readFileSync(path.join(__dirname, 'templates', 'index.ts.template'), 'utf8').split('`').join('\\`');
15
+ const importSDK = ['DocHub'];
16
+ const langId = package.name;
17
+ const components = [];
18
+ const frontendCode = (tags || []).map((tag) => {
19
+ if (tag === '-slot') {
20
+ importSDK.push('DocHubUISlot', 'DocHubEditMode');
21
+ components.push('Slot');
22
+ return `
23
+ const lang = DocHub.lang.getConst('${langId}.strings');
24
+ DocHub.ui.register(DocHubUISlot.explorer, Slot, {
25
+ title: lang?.title,
26
+ modes: [ DocHubEditMode.editWeb, DocHubEditMode.editIDE, DocHubEditMode.view ],
27
+ uid: '${langId}-explorer',
28
+ expanded: true
29
+ });`;
30
+ }
31
+ });
32
+ return eval(`\`${template}\``);
33
+ }
34
+
35
+ module.exports = async function(params) {
36
+ const pluginID = params[0];
37
+ if (!pluginID) throw 'Plugin name is required';
38
+
39
+ // Определяем путь к создаваемому плагину
40
+ const pluginDir = path.join(process.cwd(), 'plugins', pluginID);
41
+
42
+ // Проверяем, что путь вакантный
43
+ if (fs.existsSync(pluginDir))
44
+ throw `Can not create plugin. Folder [${pluginDir}] is already found.`;
45
+
46
+ // Создаем папку плагина
47
+ fs.mkdirSync(pluginDir, { recursive: true });
48
+ // Создаем папки языковых констант
49
+ fs.mkdirSync(path.join(pluginDir, 'lang', 'ru'), { recursive: true });
50
+ fs.mkdirSync(path.join(pluginDir, 'lang', 'en'), { recursive: true });
51
+ // Создаем папку исходников
52
+ fs.mkdirSync(path.join(pluginDir, 'src', 'components'), { recursive: true });
53
+
54
+ // Выполняем первичную инициализацию проекта с использованием NPM
55
+ await exec('npm init -y', { cwd: pluginDir });
56
+
57
+ // Производим преобразования package.json
58
+ const packagePath = path.join(pluginDir, 'package.json');
59
+ const package = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
60
+
61
+ // Модифицируем манифест дефолтными параметрами для DocHubIDE
62
+ package.main = 'index.ts';
63
+ package.keywords = ['DocHub', 'AaaC', pluginID];
64
+ package.dochub = {
65
+ description: {
66
+ en: package.description || 'DocHubIDE plugin'
67
+ },
68
+ environments: {}
69
+ };
70
+
71
+ // Перезаписываем манифест
72
+ fs.writeFileSync(packagePath, JSON.stringify(package, null, 2), 'utf8');
73
+
74
+ // Генерируем main файл
75
+ fs.writeFileSync(path.join(pluginDir, 'index.ts'), makeMainFile(package, params), 'utf8');
76
+ // Генерируем пустые языковые константы
77
+ fs.writeFileSync(path.join(path.join(pluginDir, 'lang', 'ru'), 'strings.js'), `module.exports = ${JSON.stringify({
78
+ title: pluginID,
79
+ hello_world: 'Привет мир!'
80
+ }, null, 2)};\n`, 'utf8');
81
+ fs.writeFileSync(path.join(path.join(pluginDir, 'lang', 'en'), 'strings.js'), `module.exports = ${JSON.stringify({
82
+ title: pluginID,
83
+ hello_world: 'Hello world!'
84
+ }, null, 2)};\n`, 'utf8');
85
+ // Генерируем нужные файлы по тэгам
86
+ params.map((tag) => {
87
+ if (tag === '-slot') {
88
+ fs.writeFileSync(path.join(pluginDir, 'src/components/Slot.vue'), makeSlotComponent(package), 'utf8');
89
+ }
90
+ });
91
+
92
+ // eslint-disable-next-line no-console
93
+ console.info(`Plugin [${pluginID}] is created.`);
94
+ };
95
+
@@ -0,0 +1,12 @@
1
+ const commands = {
2
+ create: require('./create') // Работы с плагинами
3
+ };
4
+
5
+ module.exports = async function(params) {
6
+ const commandId = params[0];
7
+ const command = commands[commandId];
8
+ if (!command)
9
+ throw `Plugins: Undefined command [${commandId}] `;
10
+ await command(params.slice(1));
11
+ };
12
+
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div>
3
+ lang?.hello_world
4
+ <br>I am slot!
5
+ </div>
6
+ </template>
7
+
8
+ <script lang="ts">
9
+ import { Component } from 'vue-property-decorator';
10
+ import { DocHubComponentProto } from 'dochub-sdk/classes/vue2';
11
+
12
+ @Component
13
+ export default class Slot extends DocHubComponentProto {
14
+ getLangPackageID(): string {
15
+ return '${langId}.strings';
16
+ }
17
+ }
18
+
19
+ </script>
20
+
21
+ <style scoped>
22
+
23
+ </style>
@@ -0,0 +1,12 @@
1
+ import { ${importSDK.join(', ')} } from 'dochub-sdk';
2
+ ${components.map((id) => 'import ' + id + ' from \'./src/components/' + id + '.vue\';').join(';\n')}
3
+
4
+ /**
5
+ * Регистрация языкового пакета
6
+ */
7
+ DocHub.lang.registerPackage('${langId}', require.context('./lang', true, /\.js$/));
8
+
9
+ // Точка входа для инициализации фронтовых интерфейсов
10
+ export function frontend() {
11
+ ${frontendCode.join('\n')}
12
+ }
@@ -0,0 +1,15 @@
1
+ const { exec } = require('child_process');
2
+
3
+ module.exports = {
4
+ exec(command, options) {
5
+ return new Promise((resolve, reject) => {
6
+ exec(command, options, (error, stdout, stderr) => {
7
+ if (error) {
8
+ reject(error, stderr);
9
+ return;
10
+ }
11
+ resolve(stdout);
12
+ });
13
+ });
14
+ }
15
+ };
package/interfaces/ai.ts CHANGED
@@ -1,4 +1,12 @@
1
- import { DocHubEditorContext } from "./editors";
1
+ import { description } from '@front/lang/en/validators';
2
+ import { DocHubJSONSchema } from '../schemas/basetypes';
3
+ import { DataLakePath } from './datalake';
4
+ import { DocHubEditorContext } from './editors';
5
+
6
+ /**
7
+ * Фрагмент контекста
8
+ */
9
+ export interface IDocHubAIContextPortion {}
2
10
 
3
11
  /**
4
12
  * Интерфейс открытого запроса к AI
@@ -26,17 +34,44 @@ export interface IDocHubAIRequest {
26
34
  * @param error - Ошибка
27
35
  */
28
36
  onError?: (error: Error) => void;
37
+ /**
38
+ * Очищает накопившийся контекст
39
+ */
40
+ clearContext();
29
41
  /**
30
42
  * Отменяет запрос
31
43
  * @returns
32
44
  */
33
45
  cancel();
46
+ /**
47
+ * Отправляет следующий запрос в AI
48
+ * @returns
49
+ */
50
+ next(question: string): Promise<void>;
51
+ }
52
+
53
+ /**
54
+ * Опции выполнения AI запроса
55
+ */
56
+ export interface IDocHubAIAskOptions {
57
+ /**
58
+ * Драйвер AI-агента, который нужно использовать для выполнения запроса
59
+ */
60
+ driver?: string;
61
+ /**
62
+ * AI-модель, которую нужно использовать для выполнения запроса
63
+ */
64
+ model?: string;
65
+ /**
66
+ * Признак отображения внутреннего диалога IDE и AI-агента
67
+ */
68
+ trace?: boolean;
34
69
  }
35
70
 
36
71
  /**
37
72
  * Тип функции запроса к AI
38
73
  */
39
- export type DocHubAskFunction = (question: string, driver?: string, model?: string) => Promise<IDocHubAIRequest>;
74
+ export type DocHubAskFunction = (question: string, options?: IDocHubAIAskOptions) => Promise<IDocHubAIRequest>;
40
75
 
41
76
  /**
42
77
  * Интерфейс драйвера AI
@@ -55,6 +90,103 @@ export interface IDocHubAIDriver {
55
90
  ask: DocHubAskFunction;
56
91
  }
57
92
 
93
+ export interface IDocHubAITextPartition {
94
+ /**
95
+ * Уникальный идентификатор сегмента контекста
96
+ */
97
+ id: string;
98
+ /**
99
+ * URI источника контекста, если актуально
100
+ */
101
+ uri?: string;
102
+ /**
103
+ * Источник в DataLake, если актуально
104
+ */
105
+ path?: DataLakePath;
106
+ /**
107
+ * Название сегмента
108
+ */
109
+ title?: string;
110
+ /**
111
+ * Краткое описание сути сегмента
112
+ */
113
+ description?: string;
114
+ /**
115
+ * Функция генерации контента
116
+ */
117
+ content: () => Promise<string>;
118
+ }
119
+
120
+ /**
121
+ * Интерфейс сегмента AI контекста
122
+ */
123
+ export type IDocHubAIContextPartition = IDocHubAITextPartition;
124
+
125
+ /**
126
+ * Интерфейс провайдера AI контекстов
127
+ */
128
+ export interface IDocHubContextProvider {
129
+ pullPartitions(): Promise<IDocHubAIContextPartition[]>;
130
+ }
131
+
132
+ /**
133
+ * Интерфейс сегмента AI контекста
134
+ */
135
+ export type IDocHubAIKnowledgeItem = IDocHubAITextPartition;
136
+
137
+ /**
138
+ * Интерфейс провайдера AI знаний
139
+ */
140
+ export interface IDocHubKnowledgeProvider {
141
+ pullItems(): Promise<IDocHubAIKnowledgeItem[]>;
142
+ }
143
+
144
+ export type IDocHubAIComposerCommandPayload = any;
145
+
146
+ export interface IDocHubAIComposerCommandMeta {
147
+ /**
148
+ * Уникальный идентификатор команды
149
+ */
150
+ id: string;
151
+ /**
152
+ * Схема определяющая payload команды
153
+ */
154
+ schema: DocHubJSONSchema;
155
+ }
156
+
157
+ /**
158
+ * Метаинформация о доступных знаниях
159
+ */
160
+ export interface IDocHubAIComposerKnowledgeMeta {
161
+ /**
162
+ * Уникальный идентификатор знания
163
+ */
164
+ id: string;
165
+ /**
166
+ * Краткое описание сути знания
167
+ */
168
+ description: string;
169
+ }
170
+
171
+ /**
172
+ * Интерфейс декларирующий доступную команду для AI
173
+ */
174
+ export interface IDocHubAIComposerCommand extends IDocHubAIComposerCommandMeta {
175
+ /**
176
+ * Метод исполнения команды
177
+ * @param payload - Данны для выполнения команды
178
+ * @returns - Результат выполнения команды для включения в контекст
179
+ */
180
+ execute(payload: IDocHubAIComposerCommandPayload): Promise<string>;
181
+ }
182
+
183
+ /**
184
+ * Интерфейс провайдера AI composer
185
+ */
186
+ export interface IDocHubComposerProvider {
187
+ fetchCommands(): Promise<IDocHubAIComposerCommand[]>;
188
+ }
189
+
58
190
  /**
59
191
  * Интерфейс AI ассистента
60
192
  */
@@ -77,12 +209,50 @@ export interface IDocHubAI {
77
209
  * @returns - Глобальный контекст
78
210
  */
79
211
  makeGlobalContext(context?: DocHubEditorContext): Promise<string>;
212
+ /**
213
+ * Исполняет команду композера
214
+ * @param commandId - Идентификатор команды
215
+ * @param payload - Данные передающиеся для исполнения команды
216
+ * @returns - Результат исполнения команды, который станет частью контекста
217
+ */
218
+ execComposerCommand(commandId: string, payload: IDocHubAIComposerCommandPayload): Promise<string>;
219
+ /**
220
+ * Возвращает все зарегистрированные команды композера
221
+ */
222
+ fetchComposerCommands(): Promise<IDocHubAIComposerCommandMeta[]>;
223
+ /**
224
+ * Возвращает все модули знаний
225
+ */
226
+ fetchKnowledge(): Promise<IDocHubAIComposerKnowledgeMeta[]>;
80
227
  /**
81
228
  * Регистрирует драйвер AI
82
229
  * @param alias - Алиас драйвера
83
230
  * @param driver - Драйвер AI
84
231
  */
85
232
  registerDriver(alias: string, driver: IDocHubAIDriver): void;
233
+ /**
234
+ * Регистрирует провайдера AI-контекстов
235
+ * @param alias - Алиас провайдера
236
+ * @param provider - Драйвер контекста
237
+ */
238
+ registerContextProvider(alias: string, provider: IDocHubContextProvider): void;
239
+ /**
240
+ * Регистрирует провайдера AI-знаний
241
+ * @param alias - Алиас провайдера
242
+ * @param provider - Драйвер контекста
243
+ */
244
+ registerKnowledgeProvider(alias: string, provider: IDocHubKnowledgeProvider): void;
245
+ /**
246
+ * Возвращает массив запрашиваемых знаний
247
+ * @param ids - Идентификаторы знаний
248
+ */
249
+ pullKnowledge(ids: string[]): Promise<string[]>;
250
+ /**
251
+ * Регистрирует провайдера команд доступных для AI
252
+ * @param alias - Алиас провайдера
253
+ * @param provider - Драйвер контекста
254
+ */
255
+ registerComposerProvider(alias: string, provider: IDocHubComposerProvider): void;
86
256
  /**
87
257
  * Возвращает список доступных моделей AI
88
258
  */
@@ -5,5 +5,5 @@ export interface IDocHubContextEnv {
5
5
 
6
6
  // Интерфейс контекста для выполнения плагина
7
7
  export interface IDocHubContext {
8
- // Зарезервированно
9
- }
8
+ // Зарезервировано
9
+ }
@@ -6,7 +6,7 @@ import { DocHubJSONSchema } from '../schemas/basetypes';
6
6
  export enum DataLakeChange {
7
7
  update = 'update', // Обновление данных по указанному пути
8
8
  remove = 'remove', // Удаляет данные по указанному пути
9
- };
9
+ }
10
10
 
11
11
  /**
12
12
  * RegExp для указания пути в DataLake в DocHub
@@ -129,6 +129,7 @@ export type IDocHubTransactionFile = {
129
129
  */
130
130
  export enum DocHubTransactionStatus {
131
131
  open = 'open', // Открыта и готова к изменениям
132
+ restore = 'restore', // Транзакция восстановлена из локального хранилища
132
133
  committing = 'committing', // В процессе применения. Не готова к изменениям.
133
134
  canceling = 'canceling', // В процессе отмены. Не готова к изменениям.
134
135
  close = 'close' // Завершена. Не готова изменениям.
@@ -191,7 +192,7 @@ export interface IDocHubFileEditorComponent {}
191
192
  /**
192
193
  * VUE компонент редактора файлов по умолчанию
193
194
  */
194
- export interface IDocHubFileDefaultEditorComponent extends IDocHubFileEditorComponent {}
195
+ export type IDocHubFileDefaultEditorComponent = IDocHubFileEditorComponent
195
196
 
196
197
  /**
197
198
  * Метаинформация о редакторе файла
@@ -236,7 +237,7 @@ export interface IDocHubFileDifferComponent {}
236
237
  /**
237
238
  * VUE компонент визуализатора различий файлов по умолчанию
238
239
  */
239
- export interface IDocHubFileDefaultDifferComponent extends IDocHubFileDifferComponent {}
240
+ export type IDocHubFileDefaultDifferComponent = IDocHubFileDifferComponent
240
241
 
241
242
  /**
242
243
  * Метаинформация о визуализаторе различий в файлах
@@ -271,7 +272,7 @@ export interface IDocHubDiffOptions {
271
272
  /**
272
273
  * Дополнительные параметры получения файла из DataLake
273
274
  */
274
- export interface IDataLakePullFileOptions extends IProtocolResponseOptions {}
275
+ export type IDataLakePullFileOptions = IProtocolResponseOptions
275
276
 
276
277
  /**
277
278
  * Обработчик событий изменения файла
@@ -7,7 +7,7 @@ export interface IDocHubEventBus {
7
7
  * @param event - Идентификатор события
8
8
  * @param data - Данные события
9
9
  */
10
- $emit(event: string, data: any);
10
+ $emit(event: string, data?: any);
11
11
  /**
12
12
  * Монтирует слушателя в шину
13
13
  * @param event - Идентификатор события
@@ -1,5 +1,4 @@
1
1
  import { DocHubDataSetProfileSource, IDocHubDataSetProfile } from './jsonata';
2
- import { DataLakePath } from './datalake';
3
2
  import { DocHubJSONSchema } from './../schemas/basetypes';
4
3
 
5
4
  /**
@@ -57,4 +56,4 @@ export interface IDocHubPresentations {
57
56
  * @returns - Массив типов презентаций
58
57
  */
59
58
  fetch(): Promise<string[]>
60
- }
59
+ }
package/interfaces/ui.ts CHANGED
@@ -8,6 +8,7 @@ export enum DocHubUISlot {
8
8
  avatar = 'avatar', // Компонент монтируется в область аватаров
9
9
  toolbar = 'toolbar', // Компонент монтируется в область панелей инструментов
10
10
  explorer = 'explorer', // Компонент монтируется в область навигации
11
+ chat = 'chat', // Компонент используется при вызове комьюнити чата
11
12
  codeViewer = 'code-viewer', // Компонент используется при рендере кода
12
13
  transactionView = 'transaction-view' // Выводится на страницу исследования транзакции
13
14
  }
@@ -16,7 +17,7 @@ export enum DocHubUISlot {
16
17
  * События интерфейса
17
18
  */
18
19
  export enum DocHubUIEvents {
19
- mountedToSlot = 'dochub-ui-slot-mounted' // В слот смонтирован компонент
20
+ mountedToSlot = '#dochub-ui-slot-mounted' // В слот смонтирован компонент
20
21
  }
21
22
 
22
23
  export interface IDocHubUISlotOptions {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dochub-sdk",
3
- "version": "0.1.376",
3
+ "version": "0.1.379",
4
4
  "description": "The DocHub System Development Kit.",
5
5
  "private": false,
6
6
  "main": "index.ts",
@@ -105,6 +105,7 @@ export interface IDocHubJSONSchemaObject extends IDocHubJSONSchemaBase {
105
105
  patternProperties?: IDocHubJSONSchemaPatternProperties;
106
106
  regexp?: RegExp;
107
107
  dependencies?: any;
108
+ examples?: any[];
108
109
  }
109
110
 
110
111
  export type DocHubJSONSchema =