Skip to content

Repository files navigation

MyHarness

Автономный ReAct-агент на Microsoft Agent Framework (Microsoft.Agents.AI + Microsoft.Agents.AI.Harness). Бэкенд — Ollama Cloud через OllamaSharp (авторизация Bearer-ключом). Агент работает в выбранной пользователем рабочей папке: читает и правит файлы, ищет по содержимому, выполняет команды PowerShell и Python-код в песочнице.

В решении три проекта:

Проект Что это
Harness.Core библиотека (net10.0) — весь агент: AgentHost, плагины, трассировка, настройки, а также поставляемые skills/, agents/, dotnet-scripts/, plugin-examples/
MyHarness WinForms-приложение (net10.0-windows) — чат-окно с Markdown в WebView2
HarnessCli консольное приложение (net10.0, SharpConsoleUI) — то же окно чата в терминале

Оба приложения — это только UI поверх Harness.Core: логика агента, набор инструментов, плагины, навыки и персоны у них общие.


Возможности

Окно чата: MyHarness (WinForms)

  • Тёмная тема, компоновка в стиле десктопного приложения Claude: сайдбар сессий слева, строка меню сверху, лог чата с полем ввода, строка состояния снизу.
  • Сайдбар сессий: список рабочих папок; кнопка «+» у папки создаёт в ней новую сессию. Между сессиями можно переключаться в любой момент — стенограмма каждой сессии сохраняется и восстанавливается при переключении.
  • Несколько рабочих папок одновременно: каждая папка получает собственный экземпляр агента (AgentHost) со своей песочницей, shell-исполнителем и HTTP-клиентом. Новая папка добавляется кнопкой «📁 Папка…».
  • Рендеринг Markdown: ответы ассистента отображаются как Markdown (Markdig) в тёмном WebView2. Реплики пользователя, рассуждения (reasoning), вызовы инструментов, ошибки и служебные сообщения — цветные блоки. Вывод стримится и добавляется пакетами (без мерцания); ссылки открываются в браузере по умолчанию.
  • Выбор модели: меню «Модель» заполняется списком моделей с сервера Ollama (/api/tags); есть пункт «Ввести имя модели…» для ручного ввода. Переключение действует со следующего сообщения, история диалога сохраняется. Модель из secret.json / OLLAMA_MODEL_NAME остаётся стартовой по умолчанию.
  • Динамическое контекстное окно: при выборе модели её реальный размер контекста запрашивается у сервера (/api/show, поле *.context_length), и бюджеты токенов агента подстраиваются автоматически (например, 1 000 000 токенов для glm-5.2). Если окно изменилось, агент пересоздаётся, а все сессии переносятся на него без потери истории. Для моделей, не сообщающих контекст, используется значение по умолчанию — 131 072 токена.
  • Режимы plan / execute: переключаются в меню «Режим» (по умолчанию — execute).
  • Меню «Ресурсы»: показывает всё, до чего агент дотягивается прямо сейчас — агенты (agents/*/AGENTS.md), навыки (skills/*/SKILL.md), плагины (plugins/*/plugin.cs) и dotnet-скрипты (scripts/*.cs в рабочей папке). Рядом с названием — количество, во всплывающей подсказке — краткое описание и путь. Список строится при каждом открытии, поэтому плагин или скрипт, созданный агентом в этой же сессии, появляется сразу. Клик подставляет готовый запрос в поле ввода (не отправляет — можно дописать задачу).
  • Подтверждение инструментов: перед записью файлов, запуском PowerShell или Python показывается модальный диалог с четырьмя вариантами: разрешить / всегда разрешать инструмент / всегда разрешать с этими аргументами / отклонить. Read-only-вызовы file_access одобряются автоматически.
  • Автоподтверждение («авторазрешения» в меню «Режим»): опциональный режим, в котором все запросы инструментов одобряются без диалога.
  • Строка состояния: текущая рабочая папка, использование токенов, индикатор занятости.
  • Запоминание рабочей папки: последняя папка сохраняется в %LocalAppData%\MyHarness\settings.json и подставляется при следующем запуске; если файла нет или папка удалена — показывается диалог выбора папки.

Окно чата: HarnessCli (консоль)

Консольный порт того же окна на SharpConsoleUI — структура и возможности те же: сайдбар сессий слева, строка меню сверху («Сессия», «Модель», «Режим», «Ресурсы»), стримящийся лог чата с полем ввода и строка состояния снизу. Ответы ассистента рендерятся как Markdown средствами терминала. Отличия от WinForms-версии:

  • Рабочая папка берётся из аргумента командной строки (HarnessCli <папка>), иначе из сохранённых настроек (%LocalAppData%\HarnessCli\settings.json), иначе запрашивается в диалоге выбора папки уже внутри окна.
  • Горячие клавиши: Ctrl+N — новая сессия, Ctrl+O — рабочая папка, Ctrl+P — авторазрешения, Ctrl+Q — выход.
  • HarnessCli --help печатает краткую справку и выходит.

Агент

  • Цикл ReAct: рассуждение → выбор инструмента → действие → анализ наблюдения, повторяется до выполнения запроса.
  • Контекстное окно — динамическое, по данным модели с сервера Ollama (131 072 токена, если модель его не сообщает). Бюджет вывода — до 16 384 токенов (не больше четверти контекстного окна), reasoning effort — Medium.
  • Сэмплирование зафиксировано: temperature 0, top_p 1, seed 0 — иначе бэкенд применяет свои значения по умолчанию (0.8 / 0.9) и модель выдумывает правдоподобные факты.
  • Встроенные провайдеры Harness: todo-список, режимы агента, файловая память, подтверждение инструментов, навыки (skills); дополнительно — CodeAct (Python) и сведения об окружении shell в системном промпте.
  • Hosted web-search у Ollama нет. Локальный поиск по рабочей папке — search_files; живой доступ в интернет даёт плагин web-search (инструменты web_search / web_fetch).

Инструменты агента

Инструмент Что делает Подтверждение
file_access чтение / запись / список / редактирование файлов в рабочей папке чтение — автоматически, запись — диалог
search_files рекурсивный поиск по содержимому рабочей папки (regex, без учёта регистра, до 200 совпадений, строки обрезаются до 200 символов; .git, bin, obj, node_modules и бинарные файлы пропускаются) не требуется
web_search / web_fetch поиск в интернете и загрузка текста страницы (плагин web-search) не требуется
run_shell команды PowerShell в дочернем процессе; рабочий каталог — рабочая папка; deny-list опасных команд (rm -rf, sudo, fork-бомбы, mkfs, запись в /dev/sd*, Format-Volume); таймаут 30 с диалог
execute_code Python в песочнице Hyperlight (WASM) — изолированное выполнение кода диалог

Плюс файловая память (agent-files/ рядом с exe — заметки, переживающие перезапуск) и todo-инструменты.

Dotnet-скрипты (C#)

Агент умеет решать задачи C#-скриптами — file-based программами .NET 10 (один .cs-файл с top-level statements, без csproj; NuGet-пакеты — директивой #:package Имя@Версия).

  • Все скрипты сохраняются только в папке scripts/ внутри рабочей папки.
  • Запуск через run_shell: dotnet run scripts\имя.cs -- <аргументы>.
  • При первом запуске в scripts/ копируются примеры из dotnet-scripts/ (существующие файлы никогда не перезаписываются):
    • hello.cs — минимальный скрипт (аргументы командной строки, вывод);
    • sysinfo.cs — сведения о системе и дисках (BCL, LINQ);
    • todo-report.cs — обход файлов, поиск TODO, Markdown-отчёт.
  • Для запуска скриптов на машине нужен .NET 10 SDK (dotnet в PATH).

Навыки и персоны

Лежат в Harness.Core, копируются в выходной каталог обоих приложений при сборке и обнаруживаются агентом во время работы:

  • skills/<навык>/SKILL.md — навыки, загружаемые по мере необходимости:
    • dotnet-script — сценарий работы с C#-скриптами;
    • research — сценарий исследования.
  • agents/<имя>/AGENTS.md — документы-персоны (роли), которые агент читает через run_shell, когда принимает роль:
    • coder, researcher, weather;
    • dotnet-scripter — пишет и отлаживает произвольные C#-скрипты;
    • dotnet-analyst — анализ данных (CSV/JSON/логи) только через выполняемый код;
    • dotnet-automator — повторяемые файловые автоматизации (dry-run по умолчанию, изменения только с --apply, резервные копии).

Плагины

Плагины — C#-файлы в plugins\<имя>\plugin.cs рядом с exe; приложение само компилирует их (Roslyn, без csproj). Два типа:

  • одноразовые (IOneShotPlugin) — становятся инструментами агента (Microsoft.Extensions.AI.AIFunction): CreateHandler возвращает делегат, чьи параметры с атрибутами [Description] образуют схему инструмента;
  • резидентные (IResidentPlugin) — загружаются вместе с приложением, StartAsync работает всё время, GetTools() отдаёт их инструменты агенту.

Компиляция и загрузка плагинов требуют JIT, поэтому в NativeAOT-сборке плагины недоступны: инструменты plugin_create / plugin_load не предлагаются агенту, остальное приложение работает как обычно.

Агент может сам создавать плагины инструментом plugin_create; плагин загружается сразу, без перезапуска приложения (горячая загрузка, инструменты доступны со следующего сообщения), существующую папку поднимает plugin_load. Обновление кода уже загруженного плагина требует перезапуска.

Плагины взаимодействуют с агентом через IPluginContext: AskAgentAsync(message) передаёт запрос пользователя агенту и возвращает его ответ (у каждого плагина своя постоянная сессия; tool-подтверждения в этом канале одобряются автоматически), а Log(message) пишет в plugins\<имя>\plugin.log и дублируется в окно чата (🔌).

Примеры: hello_once (одноразовый инструмент с параметром) и telegram-bot (резидентный backend Telegram-бота: входящие сообщения пересылаются агенту, ответы возвращаются в чат; инструмент telegram_send; токен — token.txt в папке плагина или переменная TELEGRAM_BOT_TOKEN). Исходники примеров — Harness.Core\plugin-examples\; контракты плагинов лежат в namespace Harness.Core.Plugins.

Трассировка

OpenTelemetry-трассы (включая HTTP-инструментирование) пишутся в файлы traces_*.log в папке traces рядом с exe. Имя источника задаёт приложение — MyHarness или HarnessCli (параметр AgentHost.CreateAsync).

Логи приложения (Serilog) — в папке logs рядом с exe: app-YYYYMMDD.log, ротация по дням, хранится 30 файлов. Все обработчики исключений пишут сюда.


Настройка: secret.json

Конфигурация бэкенда Ollama читается из secret.json. Файл создаётся рядом с csproj приложенияMyHarness\secret.json и/или HarnessCli\secret.json, у каждого свой (он в .gitignore и при сборке копируется в выходной каталог; читается из каталога exe).

Требуемая структура — вложенная секция Ollama (имена полей без учёта регистра):

{
  "Ollama": {
    "Endpoint": "https://ollama.com",
    "Model": "glm-5.2:cloud",
    "ApiKey": "<ваш ключ Ollama Cloud>"
  }
}
Поле Обязательное Значение по умолчанию Описание
Ollama.Endpoint нет https://ollama.com Базовый URL сервера Ollama (Cloud или локальный).
Ollama.Model нет glm-5.2:cloud Стартовая модель; в UI её можно сменить в любой момент.
Ollama.ApiKey да API-ключ Ollama Cloud; передаётся как Bearer-токен. Без него приложение не запустится.

Правила:

  • Файл обязателен: если secret.json не найден рядом с exe, приложение падает при создании агента с понятным сообщением об ошибке.
  • Плоские ключи (например, "OLLAMA_API_KEY": "..." на верхнем уровне) не читаются — нужна именно вложенная секция Ollama.
  • Переменные окружения имеют приоритет над secret.json: OLLAMA_ENDPOINT, OLLAMA_MODEL_NAME, OLLAMA_API_KEY.

Требования

Общее для обоих приложений:

  • .NET 10 SDK (и для сборки, и для dotnet-скриптов агента);
  • PowerShell для инструмента run_shell;
  • ключ Ollama Cloud (или локальный сервер Ollama с совместимым API).

Дополнительно для MyHarness: Windows (net10.0-windows, WinForms) и WebView2 Runtime (на Windows 11 обычно уже установлен). HarnessCli собирается под net10.0 и не зависит от WinForms.

Запуск

WinForms-версия:

dotnet run --project MyHarness
  1. При первом запуске выберите рабочую папку в диалоге (далее она запоминается).
  2. Общайтесь с агентом в чат-окне; запросы на выполнение инструментов подтверждайте в появляющихся диалогах (или включите авторазрешения в меню «Режим»).
  3. Модель и режим (plan/execute) переключаются в строке меню; новые папки — кнопкой «📁 Папка…», новые сессии — кнопкой «+» в сайдбаре.

Консольная версия (рабочую папку можно передать аргументом):

dotnet run --project HarnessCli -- C:\путь\к\рабочей\папке

Структура проекта

Вся не-UI часть вынесена в библиотеку Harness.Core; оба приложения (WinForms и консольное) — это только UI поверх неё.

Harness.Core/             — общая библиотека (net10.0), ссылаются оба приложения
├── AgentHost.cs          — сборка агента: бэкенд Ollama, инструменты, песочница, трассировка
├── AppSettings.cs        — сохранение последней рабочей папки (%LocalAppData%\<имя приложения>)
├── Plugins/              — контракты плагинов и PluginManager (компиляция Roslyn, горячая загрузка)
├── Tracing/              — OpenTelemetry: провайдер и файловый экспортёр спанов
├── agents/               — персоны (AGENTS.md), копируются к exe обоих приложений
├── skills/               — навыки (SKILL.md), копируются к exe обоих приложений
├── dotnet-scripts/       — примеры C#-скриптов, при первом запуске копируются в <рабочая папка>\scripts
└── plugin-examples/      — примеры плагинов, копируются к exe как plugins\

MyHarness/                — WinForms-приложение
├── Program.cs            — точка входа: выбор/восстановление рабочей папки, запуск окна
├── UI/
│   ├── MainForm.cs       — чат-окно: сессии, модель, режим, цикл подтверждений
│   ├── MarkdownViewer.cs — лог чата: Markdown в WebView2, цветные блоки, стриминг
│   ├── ToolApprovalDialog.cs — диалог подтверждения инструмента (4 варианта)
│   └── Theme.cs          — тёмная тема
└── secret.json           — ключ и настройки Ollama (в .gitignore)

HarnessCli/               — консольное приложение (SharpConsoleUI)
├── Program.cs            — точка входа: рабочая папка из аргумента/настроек, запуск окна
├── UI/
│   ├── MainWindow.cs     — чат-окно: сессии, модель, режим, цикл подтверждений
│   ├── AppDialogs.cs     — диалоги (подтверждение инструмента, выбор папки и модели)
│   └── TranscriptLog.cs  — лог чата
└── secret.json           — ключ и настройки Ollama (в .gitignore)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages