Руководство по разработке агента и шаблонов сообщений

Дата последней модификации документа: 19 июня 2024.

В данном документе описываются этапы разработки агента и шаблона сообщений на платформе IACPaaS. Считается, что приступая к их разработке, пользователь (разработчик) уже зарегистрирован на сайте проекта и ознакомлен со статьёй Базовая технология разработки сервисов.

Содержание

ВАЖНО:
1. В настоящее время разработка новых шаблонов сообщений отделена от разработки агента, поэтому при использовании пользовательских шаблонов в разработке некоторого агента необходимо наличие как исходного так и исполняемого кода у таких шаблонов.
2. Сокращением ШС в данном документе обозначается словосочетание "шаблон сообщений" или "шаблоны сообщений".

Этап 1. Проектирование

  1. Сформулировать решаемую агентом (или ШС) задачу (описание назначения агента или ШС) и убедиться в отсутствии в фонде агентов (ШС), уже решающих её (путём изучения описаний присутсвующих там инфоресурсов агентов и ШС, в частности, в разделе Проблемно-независимая предметная область).
  2. Разработать требования к программной единице (на основе задачи).
  3. Разработать на основе требований проектную документацию [1], включающую:
Примечания.
  1. Этап проектирования выполняется без использования сервисов платформы.
  2. Проектируя инициализирующий агент (корневой агент), необходимо иметь ввиду, что у него должен быть блок продукций, выполнение которого инициируется системным сообщением, формируемым платформой в момент запуска сервиса по Шаблон Инициализирующее сообщение.
  3. Если агент должен завершать работу решателя, то у него должен быть блок продукций, в процессе выполнения которого должно быть создано системное сообщение по шаблону Финализирующее сообщение (указывать адресат не требуется).
  4. Агент Интерфейсный контроллер должен иметь блок продукций, выполнение которого инициируется системным сообщением, формируемум по "Шаблон Запрос от агента Вид".
  5. Для ответа агенту Вид (с целью отрисовки интерфейса в решателях с пользовательским интерфейсом) некоторый агент должен содержать блок продукций, в процессе выполнения которого должны создаваться сообщения по одному из подходящих для этого системных шаблонов — "Отобразить окно", "Вернуть инфоресурс в окно", "Вернуть JSON в окно", "Вернуть строку в окно".

Этап 2. Формирование декларативного описания агента и шаблона сообщений

Инфоресурс нового шаблона сообщений и агента создаётся в некоторой папке в фонде пользователя и служит для хранения как декларативной (правила его наполнения описаны в данном разделе) так и процедурной (см. раздел Этап 3) частей программной единицы. В процессе его наполнения и использования его можно перемещать - адресация выполняется по внутреннему имени и коду инфоресурса (местоположение используется для адресации лишь системных агентов и ШС, хранящизхся в общем фонде). После реализации агены или ШС помимо группового использования пользователями, получившими к ним доступ от владельца, могут быть опубликованы в некоторый раздел общего фонда (см. общую документацию по работе с сайтом платформы).

2.1. Формирование инфоресурса шаблона сообщений

Для формирования инфоресурса, описывающего шаблон сообщений, необходимо разработанную на этапе проектирования информацию о нём внести в инфоресурс, выполнив следующие шаги:
  1. создать в фонде пользователя единицу хранения (инфоресурс) типа шаблон сообщений (название инфоресура есть название шаблона сообщения в формате "Шаблон <ХХХ>", где <ХХХ> - название шаблона, присвоенное ему на этапе проектирования), выполнив следующие действия по созданию ЕХ;
  2. открыть на редактирование созданный на предыдущем шаге инфоресурс шаблона сообщений и сформировать его содержимое (см. статью) следующим образом:

2.2. Формирование инфоресурса агента

Для формирования инфоресурса, описывающего собственно сам агент, необходимо разработанную на этапе проектирования информацию о нём внести в содержимое инфоресурса, выполнив следующие шаги:
  1. создать в фонде пользователя единицу хранения (инфоресурс) типа агент (название инфоресура есть название агента, присвоенное ему на этапе проектирования), выполнив следующие действия по созданию ЕХ;
  2. открыть на редактирование созданный на предыдущем шаге инфоресурс агента и сформировать его содержимое (см. статью) следующим образом:
Примечания.

Этап 3. Формирование процедурного кода агента и шаблона сообщений

Этап 3.1. Генерация версии и заготовки исходного кода агента и шаблона сообщений

Исходной код агента (ШС) хранится в инфоресурсе агента в виде последовательности версий. Исходная версия имеет имя 1, затем - 2 и т.д. Каждая версия агента также включает описание, системный и собственный код. (В случае ШС - только описание и собственный код.)
Для получения новой версии исходного кода агента или шаблона сообщений необходимо, открыв инфоресурс, представляющий эту программную единицу, выполнить в редакторе следующие шаги: Примечание.

Этап 3.2. Написание исходного кода агента и шаблона сообщений

3.2.1. Общие сведения

3.2.2. Локальная разработка

Для локальнй разработки исходного кода необходимо использовать:
  1. Java Development Kit (JDK) для Java версии 17 (например, этот);
  2. API платформы, включающий:
  3. для агента, использующего пользовательские ШС — архив их классов, который можно скачать в Редакторе агента.
При этом необходимо в исходниках проекта (располагаемых, например в каталоге src) создать структуру подкаталогов, соответствующую пакету, в котором должнен(ы) располагаться класс(ы) программной единицы: Библиотеку API платформы (iacpaas-api-<1.0>.jar) и, возможно, jar-архив, содержащий байт-код повторноиспользуемых пользовательских шаблонов сообщений (при наличии таковых у разрабатываемого агента) (<внутреннее имя агента>_ReusedMessageTemplates.jar) рекомендуется полмещать в подкаталог — lib.
(Распаковка соответствующих jar-архивов не требуется - их необходимо подключить к проекту в виде зависимостей.)

3.2.3. Написание кода шаблона сообщений

Сгенерированный класс-заготовку кода шаблона сообщений можно дополнить вспомогательными методами, внутренними классами и т.п. Обычно это методы чтения/модификации инфоресурса сообщения типа set/get, которые могут быть использованы: О формировании и чтении инфоресурса соощения — см. ниже, в описании разработки исходного кода агента.

3.2.4. Написание кода блоков продукций агента

Общие правила
Код блоков продукций агента делится на системный и собственный (суффикс имени класса — Impl). Рекомендуется вручную не менять системный код, а использовать лишь предоставляемую редактором заготовку. Собственный код необходимо разработать на основе заготовки, в нём присутсвуют:
Работа с инфоресурсами
Доступ к содержимому инфоресурсов может выполняться в нескольких режимах. Возможность использования того или иного режима обуславливается тем, как формируется решатель, использующих агент, и сервис, использующих этот решатель.

Режим 1 - по порядковому номеру. НЕ РЕКОМЕНДУЕТСЯ К ИСПОЛЬЗОВАНИЮ! УПРАЗДНЁН!
В данном режиме используемые инфоресурсы указываются ТОЛЬКО в инфоресурсах решателя (2 группы собственных и группа временных) и сервисов (2 группы обрабатываемых — входные и выходные). В каждой группе инфоресурсы указываются единым списком и порядок указания становится определяющим для получения этих инфоресурсов в коде агентов решателя. Доступ осуществляется путём указания порядкового номера (начиная с 0). Такой режим указания обрабатываемых инфоресурсов и их использования ведёт к затруднению повторого использования агентов. Это происходит ввиду того, что разные агенты (в особенности, разработанные разными коллективами) могут под одними и теми же номерами обращаться не к единообразным (созданным по одной онтологии), а к разным инфоресурсам — такие агенты объединить весьма сложно.
Для доступа к инфоресурсам, организованным в сервисах/решателях таким способом, API предоставляет следующие методы: Режим 2 - по имени, задаваемому в решателе (и транслируемом в сервис). НЕ РЕКОМЕНДУЕТСЯ К ИСПОЛЬЗОВАНИЮ!
Данный режим аналогичен режиму 1, но здесь в решателе (и затем в сервисе — для входных и выходных) не просто указыватся список инфоресурсов, а указывается список именованых параметров, каждый из которых содержит указание на информационный ресурс. Это позволяет повторно использовать агент в разных решателях и объединять агенты в единые решатели без необходимости их перекодирования. Условием является необходимость соблюдения правила "имена разных по сути параметров в различных агентах различны, а для одинаковых агентов — одинаковы". Недостатком этого метода является то, что имена параметров всё ещё декларируются в решателе/сервисе, так что разработчику агента необходимо "подстроиться" под первый решатель, который будет использовать этот агент (внести в код назначенные имена параметров).
Для доступа к инфоресурсам, организованным в сервисах/решателях таким способом, API предоставляет следующие методы: Напоминание: В случае использования последних двух методов для осуществления полного доступа к содержимому инфоресурса необходимо использовать следующие методы: Режим 3 - по имени, задаваемом в декларативном описании самого агента (и транслируемом в решатели/сервисы). РЕКОМЕНДУЕМЫЙ СПОСОБ ДОСТУПА!
При данном режиме разработчик агента самостоятельно определяет и задаёт имена параметров, используя которые он будет получать в процедурном коде блоков продукций доступ к обрабатываемым инфоресурсам. Для каждого такого ресурса в декларации агента необходимо под вершиной "описание параметров для обрабатываемых инфоресурсов" указывать в требуемом подмножестве ("только чтение", "полный доступ", "временные" - в соответствии с планируемым режимом доступа и жизненным циклом обрабатываемого ресурса) имя параметра, по которому затем станет доступен инфоресурс, и ниже установить ссылку на корень его метаинформации. О семантике используемых инфоресурсов (и поставленных им в соответствие имён параметров) необхдоимо написать в вершине, формируемой по мета-вершине "описание" (здесь же). Эта информация затем поможет создателям решателей и сервисов правильно оформить декларативные описания таких программных единиц (см. далее в этом разделе).
Для доступа к инфоресу, описанному в агенте таким способом, API предоставляет следующий метод: При формировании решателя с использованием таких агентов (имеющих описание имён параметров) разработчику решателя необходимо во-первых, под вершиной "агенты решателя" сформировать по мета-вершине "имя агента" вершины путём зависимого клонирования имени от корневых вершин инфоресурсов, представляющих агенты, а также принять несколько типов решений, в соответствии с которыми задать обрабатываемые ресурсы в декларативном описании решателя (и далее в сервисах - при их формировании): Режим 4 - обрабатываемые инфоресурсы можно получать через входящие сообщения (ссылки на них в таких сообщениях должны быть установлены агентом отправителем).
Пользовательский интерфейс
Для создания решателей с пользовательским интерфейсом (программирования пользовательского интерфейса) необходимо иметь понимание общей схемы работы интерфейса на платформе - изучить раздел "1.2. Интерфейс" в документе "Руководство по разработке решателя". Согласно схеме, приведённой в этом докумение, работа агента (интерфейсного контроллера, и возможно, адресуемых им агентов, однако, для простоты будем говорить о единственном агенте) выполняется между взаимодействием 4 и 5. Она (работа) состоит из следующих шагов:
  1. принять сообщение от агента ВИД (формируемое им при некотором "интерфейсном" событии, происходящем в браузере, отображающем сайт платформы), сформированное по шаблону "Запрос от агента ВИД", — для этого в декларации агента интерфейсный-контроллер должен быть специфицирован блок продукций с таким входным шаблоном сообщений, а в его процедурном коде (в классе-реализации) должен быть метод runProduction(UiParamsMessage msg, ...)
  2. в рамках кода упомянутого выше блока продукций сформировать некий ответ агенту ВИД, в частности, при необходимости отослать пользовательский интерфейс (для его отображения) — выполнить построение его модели, используя методы класса UiBuildHelper, объект которого извлекается из входного сообщения следующим образом: UiBuildHelper ui = new UiBuildHelper(msg.getUIAbstractModel())
  3. отправить агенту ВИД (в ответ) сообщение, сформированное по одному из допустимых шаблонов, причём в это сообщение поместить сформированные данные (строку, JSON, а в случае построения пользовательского интерфейса для отображения — сформированную модель, а точнее — её корень, так как модель есть дерево).
Далее будем говорить только о формировании и работе с пользовательским интерфейсом.

Рассматривая первый шаг, стоит выделить три случая формирования такого сообщения агентом ВИД и направление его агенту решателя, играющему роль интерфейсного контроллера: Выполнение второго шага может выпоняться как на основе данных, хранимых в обрабатываемых информационных ресурсах, так и на основе данных, получаемых из интерфейса, к которым относятся: Все поступающие данные извлекаются из входящего сообщения (составленного по шаблону Запрос от агента ВИД) с помощью вызова у представляющего его объектра класса UiParamsMessage (это первый параметр метода runProduction(...)) следующих методов: При реализации агента, выполняющего построение пользовательского интерфейса исключительно в рамках своего процедурного Java кода (то есть без JS кода, работающего вне платформы - на стороне браузера) необходимо иметь ввиду, что каждый раз при поступлении ответа в агент ВИД пользовательский интерфейс (построенный по полученной от агента модели) будет полностью переотображён, то есть заменит весь отображённый ранее интенфейс в месте нахождения ui-тэга. (Фрагментированное перестроение отображённого ранее интерфейса возможно лишь при реализации агента интерфейсный контроллер как связки из JS кода, отвечающего за интерфейс, и Java кода, выпоняющего обработку поступающих данных и выдачу данных в JS часть.) Поэтому для реализации второго шага рекомендуемой схемой работы блока продукций, обрабатывающего сообщение, сформированное по шаблону Запрос от агента ВИД, является следующая:
  1. если из интерфейса поступили данные, то обработать эти данные:
  2. построить (полную) модель интерфейса для ответного сообщения агенту ВИД (сформировать полную модель интерфейса с учётом поступивших или непоступивших данных).
При таком подходе следует иметь ввиду, что условие в первом шаге (наличие данных во входящем сообщении) выполняется при некотором (единственном) нажатии пользователем на некоторый командный интерфейсный элемент - кнопку (button) или кнопку-иконку (iconButton) или гиперссылку (link - однако этот случай здесь не рассматривается), которые при их формировании (в модели интерфейса) снабжаются параметром action с заданным программистом значением (см. методы UI API). В связи с этим рекомендуется в качестве условия ветвления использовать данный параметр:
//шаг 1 - обработка поступивших данных с выяснением, какая команда поступила
String action = msg.getParam("action");
if ("my_action1".equals(action)) {...}
else if ("my_action2".equals(action)) {...}
...
Формирование нужного фрагмента пользовательского Web-интерфейса, состоящего из множества простых и/или составных интерфейсных элементов (контейнеров), выполняется посредством вызова функций API пользовательского интерфейса. Вызов каждой такой функции с требуемыми аргументами приводит к формированию декларативного описания соответствующего интерфейсного элемента или его атрибута (во временном инфоресурсе, формируемом агентом ВИД при поступлении UI-запроса от пользователя). Таким образом, формирование описания нужного фрагмента интерфейса состоит в построении композиции (суперпозиции) вызовов функций API пользовательского интерфейса, его обеспечивающей. В конечном итоге по сформированному инфоресурсу, содержащему (полное) описание интерфейса, агент ВИД выполнит формирование html-кода, который будет отображён на экране в ответ на поступивший запрос. Все методы формирования интерфейса предоставляются классом UiBuildHelper. В блоке продукций, который будет выполнять построение интерфейса, необходимо создать единственный объект такого класса, передав в конструктор инфоресурс с абстрактной моделью интерфейса. Данный инфоресурс поступает в работающем сервисе от агента ВИД к агену интерфейсный контроллер вместе с сообщением, сформированным по шалблону Запрос от агента ВИД (UiParamsMessage), и извлекается с помощью метода getUIAbstractModel().

Если разрабатывается агент, подключаемый к редактору инфоресурсов по технологии расширяемых графовых крамматик, и такой агент выполняет построение интерфейса, то извлечь инфоресурс интерфейса он должен из входящего сообщения, сформированного по шаблонам Сформировать подсеть (Модифицировать подсеть).

Полученное в результате работы блока продукций описание (фрагмента) интерфейса необходимо поместить в сообщение, созданное по шаблону UiShowWindow. Отметим (повторно), что ответ агенту ВИД может содержать не только модель пользовательского интерфейса (по которой будет сформирован html код и отображён в браузере), но и (альтернативно) json или (альтернативно) строку - которые обычно предназначены для перехвата созданным разработчиком агенте JS-кодом (также являющимся частью агента интерфейсный контроллер), работающим в браузере, с целью выполнения над этими данными некоторых манипуляций.

Вообще в ответ на запрос от агента ВИД можно отправлять не только описание интерфейса, но и строку, json (для работы используется класс Json из пакета mjson), а также инфоресурс. Для этого формируется единственное сообщение по одному из шаблонов: В перечисленные методы (у классов шаблонов сообщений) сформированный результат (описание фрагмента интерфейса, строка, json, инфоресурс) должен быть передан в качестве аргумента, как указано выше. При этом в любом случае при создании сообщения по любому из перечисленных шаблонов исходный инфоресурс (полученный пустым в сообщение от агента ВИД) с абстрактной моделью инфтерфейса должен быть передан как второй параметр в метод create.

Примеры построения фрагмента интерфейса (считается, что в коде блока продукций уже заведена переменная UiBuildHelper ui = new UiBuildHelper(msg.getUIAbstractModel()), где msg - объект, представляющий входящее сообщение и относящийся к классу UiParamsMessage):
  1. создание текстовой надписи "Комментарий:" и справа от неё — однострочного поля ввода, в которое будет помещён комментарий понятия concept, доступный для редактирования:
    IConcept commentEdit = ui.sec(ui.text("Комментарий:"), ui.textfield("concept_comment", concept.getComment()));
  2. создание двух кнопок (первая над второй): первая с надписью "Сохранить" и всплывающей подсказкой "сохранить после редактирования" (появляется при наведении указателя на данную кнопку), вторая с надписью "Отменить" и всплывающей подсказкой "отменить редактирование":
    IConcept twoButtons = ui.blocks(button("Сохранить", "сохранить после редактирования"), button("Отменить", "отменить редактирование"));
  3. создание фрагмента интерфейса отправки (в ответ) агенту ВИД (в класс-заготовку агента TestAgent при генерации исходного кода был автоматически помещён объект uiShowWindowMessage), представляющий ответное сообщение, формируемое по шаблону Шаблон Отобразить окно (класс UiShowWindowMessage) для отправки агенту ВИД, в котором размещён интерфейс, состоящий из надписи "Простой интерфейс":

public void runProduction(UiParamsMessage msg, TestAgentImpl.UiParamsMessageResultCreator rc)
    throws
    PlatformException
{
    //...
    //шаг 2 - построение UI модели с полным интерфейсом для ui-тэга из web-страницы
    IInforesource uiIr = msg.getUIAbstractModel();
    UiBuildHelper ui = new UiBuildHelper(uiIr);
    //... вызов методов для формирования дочерних элементов в иерархии UI элементов - при необходимости их формирования ...
    IConcept iFace = ui.xxx(...); // вызов метода для формирования верхнего элемента в иерархии UI элементов, с указанием дочерних элементов в качестве параметров вызова
    //формирование и отправка ответного сообщения агенту ВИД с указанием построенной модели интерфейса
    rc.uiShowWindowMessage.create(getUiView(), uiIr).setInterface(iFace);
}
Работа с локальной структурой данных агента
Локальная структура данных - один из механизмов (помимо сообщений, выходных, собственных и временных инфоресурсов), предназначенных для хранения данных агента во время работы его блоков продукций и в промежутках между ними (во время работы других агентов решателя). Технология позволяет не передавать такой набор данных через сообщения (что может быть чересчур громоздким) и не хранить его в указанных инфоресурсах (в их содержимое может вмешаться другой агент в рамках работы этого или даже другого решателя). Таким образом, Локальная структура данных является удобным и защищённым от доступа извне хранилищем - аналог сериализованных полей объекта. В рамках работы решателя можно создать несколько агентов одного типа (класса) Х, каждый со своей локальной структурой данных. Такие сущности называются экземплярами агента Х.
Локальная структура данных агента Х представляет собой отдельный инфоресурс, формируемый платформой когда некоторый блок продукций (некоторого другого агента У, или, в особо интересных случаях, самого агента Х) создаёт сообщение для отправки новому экземпляру агента Х. Данный инфоресурс удаляется платформой автоматически при завершении работы сервиса. Доступ к корневому понятию инфоресурса (это понятие, для которого понятием-прототипом является понятие "локальная структура данных" в инфоресурсе агента) осуществляется через поле local класса агента. Метаинформацией, в соответствии с которой формируется (порождается/редактируется) данный инфоресурс, является поддерево, корневое понятие которого - "локальная структура данных", находящееся в инфоресурсе агента.

Пример.
Пусть в инфоресурсе агента присутствует следующий фрагмент, описывающий локальную структуру данных:
локальная структура данных
{
    история
    {
        ~set состояние
        {
          ...
        }
    }
}

Тогда код агента на Java, создающий новое состояние в истории состояний, может иметь следующий вид:
IConceptGenerator history = (IConceptGenerator)local.generateFromRoot().getDirectSuccessor("история");
if (history == null)
    history = local.generateFromRoot().generateCopy("история");

history.generateCopy("состояние");
Протоколирование (логирование) процесса исполнения кода блоков продукций агента
Используется для получения информации о ходе выполнения блоков продукций агента, о том, какие события и в какой последовательности происходят в момент во время выполнения блоков продукций. Задача логирования состоит, также, в том, чтобы очертить место поиска ошибки и дать достаточно информации для её воспроизведения.
Выделяется шесть уровней логирования. Уровень логирования указывает степень важности информационно-отладочных сообщений. Этим уровням соответствуют следующие методы агента, используемые для записи информационного-отладочных сообщений в журнал логов (в перечисленные ниже методы в качестве аргумента должен быть передан текст сообщений — строка символов конечной длины): Некоторые записи в лог выполняются системой самостоятельно (не кодом БП агента) - запись о начале работы БПР некоторого агента и запись об окончании этой работы с указанием времени работы и количества подготовленных сообщений.

Просмотр логов осуществляется с помощью Редактора решателей задач, запускаемого для инфоресурса решателя, в рамках работы которого агент выполняет логирование. В данном редакторе необходимо раскрыть вершину "Логи" и перейти к просмотру определенного лога в новом состоянии (сделать корневое понятие лога текущим). Для каждого решателя система сохраняет не более 10 логов. Каждый лог соответствует отдельному запуску решателя. Каждый лог имеет название (имя корневой вершины) формата "Лог ДАТА ЗАПУСКА - ФИО ПОЛЬЗОВАТЕЛЯ - ИМЯ СЕРВИСА". В самом логе также хранится ссылка на пользователя, запустившего сервис, в рамках которого исследуемый агент сохранял в лог информацию, сервис и момент запуска. При наличии логирующих сообщений, каждое из них является поддеревом в инфоресурсе лога и: Логирование выполняется в рамках работы сервиса с некоторым решателем и только в том случае, когда в этом решателе по метавершине "вести лог" порождено значение "истина".
Логирование при указанных условиях выполняется единожды (ведётся до окончания работы сервиса), а в момент старта такого сервиса значение вершины в решателе, сформированной по метавершине "вести лог", устанавливается системой в "ложь". Это сделано с целью предотвратить дальшейшее логирование, так как пользователи решателя, не являющиеся программистами, при логировании имеют замедленную работу этого решателя.
Формирование и отправка сообщений
Генератор исходного кода агентов для каждого блока продукций создает специальный класс ("создатель результатов") с именем <внутреннее имя шаблона сообщения>MessageResultCreator (является типом второго параметра метода runProduction(...)), описывающий шаблоны сообщений, которые могут быть отправлены агентом из соответствующего блока продукций (шаблоны выходных сообщений блока продукций).
Описание каждого шаблона сообщений представляется в виде инициализированного поля класса (в терминах объектно-ориентированной парадигмы) следующим образом:
public final <XXX>Message.Creator <xXX>ResultMessage = new <XXX>Message.Creator(this);

где: Код создания сообщения выглядит следующим образом:
<XXX>Message msg = rc.<xXX>.create(<агент-адресат>);

где: При этом <агент-адресат> может быть идентифицирован одним из следующим способов: Примечания:
При создании сообщения оно добавляется в список ожидающих отправки из сообщений.
После создания сообщения можно, при необходимости, задать его параметры, используя методы чтения/модификации инфоресурса сообщения.
После окончания работы блока продукций (соответствующего метода runProduction(...)) коммуникационная система извлекает все созданные в нём сообщения и отправляет их агентам-адресатам.
Ограничения
На написании кода агента (и шаблона сообщений) разрашается использовать:

Пример класса-заготовки и класса-реализации агента

Пусть есть агент Мой агент с внутренним именем MyAgent, который принимает сообщение SomeMessage, в ответ на которое высылает себе же сообщение AnotherMessage и наоборот. На этапе генерации будет создан абстрактный класс-заготовка с именем MyAgent, где каждому блоку продукций будет соответствовать метод runProduction:
package ru.dvo.iacp.is.iacpaas.mas.agents;

import java.util.Date;
import ru.dvo.iacp.is.iacpaas.mas.Message;
import ru.dvo.iacp.is.iacpaas.mas.Agent;
import ru.dvo.iacp.is.iacpaas.mas.ResultCreator;
import ru.dvo.iacp.is.iacpaas.mas.MasFacet;
import ru.dvo.iacp.is.iacpaas.mas.exceptions.MasException;
import ru.dvo.iacp.is.iacpaas.common.exceptions.PlatformException;
import ru.dvo.iacp.is.iacpaas.storage.exceptions.StorageException;
import ru.dvo.iacp.is.iacpaas.storage.IInforesource;
import ru.dvo.iacp.is.iacpaas.mas.IRunningService;
import ru.dvo.iacp.is.iacpaas.mas.messages.*;
import ru.dvo.iacp.is.iacpaas.mas.messages.system.*;

public abstract class MyAgent extends Agent
{
  //Сгенерированный конструктор
  public MyAgent(IRunningService runningService, IInforesource agentInforesource)
  {
    super(runningService, agentInforesource);
  }

  //Сгенерированное описание продукций для диспетчера сообщений
  static
  {
    try
    {
      describeProduction(
        ru.dvo.iacp.is.iacpaas.mas.messages.SomeMessage.class,
        SomeMessageResultCreator.class,
        MyAgent.class);
      describeProduction(
        ru.dvo.iacp.is.iacpaas.mas.messages.AnotherMessage.class,
        AnotherMessageResultCreator.class,
        MyAgent.class);
    }
    catch(NoSuchMethodException ex)
    {
      throw new RuntimeException(ex);
    }
  }

  //создатель результатов для блока обработчика сообщений по шаблону "SomeMessage")
  public static final class SomeMessageResultCreator extends ResultCreator
  {
    public final ExternalRequestDataMessage.Creator anotherMessage;
    public SomeMessageResultCreator(MasFacet mas, IRunningService runningService)
      throws
      MasException
    {
      super(mas, runningService);
      anotherMessage = new AnotherMessage.Creator(this);
    }
  }


  //создатель результатов для блока обработчика сообщений по шаблону "AnotherMessage")
  public static final class ExternalRequestDataMessageResultCreator extends ResultCreator
  {
    public final SomeMessage.Creator someMessage;
    public AnotherMessageResultCreator(MasFacet mas, IRunningService runningService)
      throws
      MasException
    {
      super(mas, runningService);
      someMessage = new SomeMessage.Creator(this);
    }
  }

  //Сгенерированная заглушка метода runProduction для обработки сообщений по шаблону "SomeMessage"
  public void runProduction(SomeMessage message, SomeMessageResultCreator rc)
    throws
    PlatformException
  {
    throw new UnsupportedOperationException();
  }

  //Сгенерированная заглушка метода runProduction для обработки сообщений по шаблону "AnotherMessage"
  public void runProduction(AnotherMessage message, AnotherMessageResultCreator rc)
    throws
    PlatformException
  {
    throw new UnsupportedOperationException();
  }
}

Исходный код класса-реализации агента должен наследовать от MyAgent и называться MyAgentImpl:
package ru.dvo.iacp.is.iacpaas.mas.agents;

import java.util.Date;
import ru.dvo.iacp.is.iacpaas.mas.Message;
import ru.dvo.iacp.is.iacpaas.mas.Agent;
import ru.dvo.iacp.is.iacpaas.mas.ResultCreator;
import ru.dvo.iacp.is.iacpaas.mas.MasFacet;
import ru.dvo.iacp.is.iacpaas.mas.exceptions.MasException;
import ru.dvo.iacp.is.iacpaas.common.exceptions.PlatformException;
import ru.dvo.iacp.is.iacpaas.storage.exceptions.StorageException;
import ru.dvo.iacp.is.iacpaas.storage.IInforesource;
import ru.dvo.iacp.is.iacpaas.mas.IRunningService;
import ru.dvo.iacp.is.iacpaas.mas.messages.*;
import ru.dvo.iacp.is.iacpaas.mas.messages.system.*;

public final class MyAgentImpl extends MyAgent
{
  public MyAgentImpl(IRunningService runningService, IInforesource agentInforesource)
  {
    super(runningService, agentInforesource);
  }

  //Метод runProduction для обработки сообщений по шаблону "SomeMessage"
  public void runProduction(SomeMessage message, SomeMessageResultCreator rc)
    throws
    PlatformException
  {
    //логика блока продукций - обработка SomeMessage 
    //...
    //отправка сообщения AnotherMessage без каких-либо данных агенту (самому себе) по заданному адресу (в фонде)
    rc.anotherMessageResultCreator.create("<Логин пользователя>/ Мой фонд / Тестовый раздел / Мой агент");
  }

  //Метод runProduction для обработки сообщений по шаблону "AnotherMessage"
  public void runProduction(AnotherMessage message, AnotherMessageResultCreator rc)
    throws
    PlatformException
  {
    //логика блока продукций - обработка AnotherMessage 
    //...
    //отправка сообщения SomeMessage без каких-либо данных исходному агенту (самому себе)
    rc.someMessageResultCreator.create(rc.getSender());
  } 
}

3.2.5. Сохранение исходного кода агента и шаблона сообщений и выбор текущей версии

Написанный исходный код программной единицы должен быть сохранён в представляющий её инфоресурс. Это выполняется с помощью соответствующего редактора при редактировании вершин с метавершиной "код" - по окончании ввода кода необходимо использовать кнопку "сохранить в инфоресурс".

Затем, для того чтобы некоторая версия исходного кода была испльзована в качестве рабочей (исполняемой) на платформе, необходимо в рамках подграфа "исходный код" сформировать или отредактировать вершину с метапонятием "текущая версия". При этом в качестве текущей может быть выбрана только версия, которая содержит весь необходимый код программной единицы - собственный и, возможно, системный.

Примечание.
В случае локальной разработки написанный исходный код необходимо скопировать из файла и вставить в форму редактирования из буфера обмена, либо использовать кнопку "загрузить" (для собственного и отдельно для системного кода у агента).

3.3. Создание исполняемого кода агента и шаблонов сообщений и выбор текущей версии

Скомпилировать текущую версию разработанного исходного кода агента или шаблонов сообщений необходимо выполнить в Редакторе соответствующей программной единицы путём создания вершины исполняемый код. Если выполнены все необходимые условия: то исполняемый код будет успешно получен. В противном случае будет выведено сообщение об ошибке, которую необходимо устранить.

При наличии исполняемого кода у шаблона сообщений - его можно скачать (в виде jar файла) для подключению к проекту локальной разработки агента (если агент использует этот ШС).

Этап 4 (необязательный). Публикация агента и шаблона сообщений в фонд

Окончательным этапом разработки агента и шаблона сообщений может стать их публикация в общий фонд (для повторного использования другими разработчиками). При публикации в общем фонде необходимо учитывать, что:

Примечания

  1. При разработке проектной документации необходимо проанализировать содержимое фонда на предмет наличия в нем агентов, шаблонов сообщений, используя которые, можно решить определенные подзадачи в рамках решаемой агентом задачи. В случае обнаружения таких сущностей их необходимо задействовать при реализации.
  2. Может отсутствовать, если не требуется хранить такого рода информацию (все нужные данные доступны через сообщения).
  3. агент-экземпляр.
  4. Если для данного блока продукций проектируется новый шаблон, а не используется уже существующий в фонде.
  5. Может отсутствовать, если при выполнении данного блока продукций агента не должны создаваться и посылаться какие-либо сообщения или используются уже существующие в фонде шаблоны.
  6. Согласно разработанному проекту здесь могут/должны быть также сделаны ссылки на шаблоны системных сообщений — "Платформа IACPaaS / Ядро платформы / Шаблон Финализирующее сообщение", "Платформа IACPaaS / Интерфейс / Шаблон Отобразить окно", "Платформа IACPaaS / Интерфейс / Шаблон Вернуть инфоресурс в окно", "Платформа IACPaaS / Интерфейс / Шаблон Вернуть строку в окно"
  7. Это можно сделать автоматически в соответствующей IDE (например, IntelliJ IDEA, Eclipse или NetBeans)