Skip to content

Commit c92ea6f

Browse files
committed
Add more info to readme
1 parent cb502a5 commit c92ea6f

1 file changed

Lines changed: 114 additions & 1 deletion

File tree

README.md

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,43 @@ It builds on top of `ChatAIze.Abstractions` and provides convenient implementati
1111

1212
If you want a working example, start with `ChatAIze.PluginApi.ExamplePlugin/MyShop.cs`.
1313

14+
## TL;DR
15+
16+
- Create a `net10.0` class library and reference `ChatAIze.PluginApi`.
17+
- Implement `IPluginLoader` (or `IAsyncPluginLoader`) and return a `ChatbotPlugin` with `Id`, `Title`, and `Version`.
18+
- Add settings/tools/actions/conditions (either via the collections or callback properties).
19+
- Build `Release` and deploy to ChatAIze.Chatbot (upload a single `.dll`, or copy the whole output folder for plugins with dependencies).
20+
1421
## What you can build
1522

1623
- **Plugin settings** (dashboard UI): Admin-configured values like API keys and feature toggles.
1724
- **Tools** (LLM function calling): Model-callable functions that run code and return structured output.
1825
- **Workflow actions**: Reusable steps that admins compose into “integration functions” in the dashboard.
1926
- **Workflow conditions**: Gates that allow/deny an integration function for the current chat/user.
2027

28+
## Contents
29+
30+
- [TL;DR](#tldr)
31+
- [Requirements](#requirements)
32+
- [Install](#install)
33+
- [Quick Start](#quick-start-minimal-plugin)
34+
- [Deploy](#deploy-to-chataizechatbot)
35+
- [Release Checklist](#plugin-release-checklist)
36+
- [Core Concepts](#core-concepts)
37+
- [Stable IDs](#stable-ids-plugins-settings-tools-actions-conditions)
38+
- [Lifetime & Concurrency](#lifetime-concurrency-and-disposal)
39+
- [Context Objects](#context-objects-what-you-can-access-at-runtime)
40+
- [Glossary](#glossary-chataizechatbot-terms)
41+
- [Tools](#tools-llm-callable-functions)
42+
- [Settings](#settings-plugin-configuration-ui)
43+
- [List Settings](#list-settings-listsetting)
44+
- [Map Settings](#map-settings-mapsetting)
45+
- [Workflow Actions](#workflow-actions-integration-function-steps)
46+
- [Workflow Conditions](#workflow-conditions-gates)
47+
- [Useful Patterns](#useful-patterns)
48+
- [Troubleshooting](#troubleshooting)
49+
- [Examples](#examples)
50+
2151
## Requirements
2252

2353
- **Target framework**: `net10.0` (matches the current `ChatAIze.Chatbot` host).
@@ -101,6 +131,8 @@ public sealed class MyPluginLoader : IAsyncPluginLoader
101131
}
102132
```
103133

134+
Tip: `ChatbotPlugin` defaults to returning its in-memory `Settings` / `Functions` / `Actions` / `Conditions` collections from the callback properties. You can either populate the collections directly or override the callback properties to return context-dependent definitions.
135+
104136
3) Build:
105137

106138
```bash
@@ -129,7 +161,19 @@ into the chatbot server’s `plugins/` directory.
129161

130162
Tip: If you have extra dependencies, the safest approach is to copy everything from `bin/Release/net10.0/` (except `.pdb` if you don’t want symbols).
131163

132-
### How plugin loading works (advanced)
164+
### Plugin release checklist
165+
166+
- Target `net10.0` (match the host).
167+
- Set `IChatbotPlugin.Id` and keep it stable (loading a plugin with the same id replaces the previous one).
168+
- Set `IChatbotPlugin.Version` (ChatAIze.Chatbot treats missing versions as invalid).
169+
- Namespace plugin-level settings (`com.mycompany.myplugin:api_key`) to avoid collisions with other plugins.
170+
- Prefer named methods for tools (`AddFunction(MyTool)`), and keep tool names unique.
171+
- Respect `IsPreview` / `IsCommunicationSandboxed` before doing side effects (HTTP calls, emails/SMS, writes to external systems).
172+
- Don’t log secrets (API keys/tokens).
173+
- If you deploy dependencies, prefer copying the whole output folder to `plugins/` (don’t rely on dashboard upload for multi-file plugins).
174+
175+
<details>
176+
<summary>How plugin loading works (advanced)</summary>
133177

134178
ChatAIze.Chatbot loads plugins with an isolated, unloadable `AssemblyLoadContext`:
135179

@@ -139,6 +183,7 @@ ChatAIze.Chatbot loads plugins with an isolated, unloadable `AssemblyLoadContext
139183
- Any other dependency must be resolvable via the plugin’s `.deps.json` (and present in the `plugins/` folder).
140184

141185
This is why dashboard upload is best for “single dll” plugins, and file-copy deployment is best for plugins with external dependencies.
186+
</details>
142187

143188
## Core Concepts
144189

@@ -176,6 +221,15 @@ Every callback can optionally accept a context parameter:
176221
- `IActionContext` (workflow actions): adds action indices/results + placeholder APIs
177222
- `IConditionContext` (workflow conditions): currently just `IChatContext`
178223

224+
### Glossary (ChatAIze.Chatbot terms)
225+
226+
- **Plugin**: a loaded `.dll` that returns settings, tools, actions and/or conditions.
227+
- **Tool / function**: an `IChatFunction` exposed to the model as a callable tool (LLM function calling).
228+
- **Integration function**: a dashboard-configured function (also an `IChatFunction`) that executes a workflow of actions/conditions.
229+
- **Workflow action**: an `IFunctionAction` step used inside an integration function (not exposed to the model directly).
230+
- **Workflow condition**: an `IFunctionCondition` gate evaluated before an integration function runs.
231+
- **Placeholder**: a named value (`{placeholder}`) produced by actions and injected into later settings as plain-text substitution (supports nested access like `{ticket.id}` when the placeholder is a JSON object).
232+
179233
## Tools (LLM-Callable Functions)
180234

181235
Tools are `IChatFunction` instances returned by `IChatbotPlugin.FunctionsCallback`. They are presented to the language model as callable tools.
@@ -238,6 +292,8 @@ public sealed class MyPluginLoader : IPluginLoader
238292
- `IFunctionContext` is injected by type,
239293
- `CancellationToken` is injected by type.
240294

295+
Tip: Prefer named methods over lambdas for tools. Some compiler-generated lambda names are not stable/public-friendly and may fail normalization. If you need full control, register a `ChatFunction` with an explicit `Name`.
296+
241297
### Tool schema generation (what the model sees)
242298

243299
In the ChatAIze stack, schema generation works like this:
@@ -274,6 +330,24 @@ If you rely on reflection-based schemas, you can improve the model-visible docum
274330
- `DescriptionAttribute` on the method and/or parameters
275331
- string data annotations such as `[Required]`, `[MinLength]`, `[MaxLength]`, `[StringLength]`
276332

333+
Example (reflection schema + runtime validation for strings):
334+
335+
```csharp
336+
using System.ComponentModel;
337+
using System.ComponentModel.DataAnnotations;
338+
using ChatAIze.Abstractions.Chat;
339+
340+
[Description("Searches the knowledge base.")]
341+
private static async Task<string> SearchAsync(
342+
IFunctionContext context,
343+
[Description("Search query.")] [Required] [MinLength(2)] string query,
344+
CancellationToken cancellationToken = default)
345+
{
346+
var result = await context.SearchKnowledgeAsync(query, cancellationToken: cancellationToken);
347+
return result.ToString();
348+
}
349+
```
350+
277351
### Error handling conventions
278352

279353
- For **recoverable** failures, prefer returning a string that starts with `"Error: "`.
@@ -297,6 +371,18 @@ In ChatAIze.Chatbot, your `SettingsCallback` is invoked while rendering the plug
297371
- Containers: `SettingsSection`, `SettingsGroup`, `SettingsParagraph` (layout-only, do not store a value).
298372
- Leaf settings: `StringSetting`, `SelectionSetting`, `IntegerSetting`, `BooleanSetting`, `DecimalSetting`, `DateTimeSetting`, `ListSetting`, `MapSetting` (store a value under `ISetting.Id`).
299373

374+
### Settings cheat sheet
375+
376+
| Setting | Stored JSON kind | Typical use |
377+
| --- | --- | --- |
378+
| `StringSetting` | string | API keys, URLs, names |
379+
| `IntegerSetting` / `DecimalSetting` | number | thresholds, limits |
380+
| `BooleanSetting` | true/false | feature toggles |
381+
| `SelectionSetting` | string | “pick one” choices |
382+
| `DateTimeSetting` | string (date/time) | schedules, reminders |
383+
| `ListSetting` | array of strings | tags, allow/deny lists |
384+
| `MapSetting` | object (string → string) | headers, simple key/value configs |
385+
300386
### Example settings UI
301387

302388
```csharp
@@ -611,6 +697,18 @@ context.SetStatus("Calling external API...", progress: 30);
611697
context.SetStatus("Done.", progress: 100);
612698
```
613699

700+
### Logging
701+
702+
All context types expose `Log(...)` (wired to the host logging pipeline):
703+
704+
```csharp
705+
using Microsoft.Extensions.Logging;
706+
707+
context.Log(LogLevel.Information, "Starting order lookup...");
708+
```
709+
710+
Tip: avoid logging secrets. In ChatAIze.Chatbot, logs can be visible to administrators.
711+
614712
### Forms and confirmations
615713

616714
Plugins can prompt the current user with built-in UI dialogs (when supported by the host):
@@ -655,6 +753,20 @@ var lastOrderId = await context.User.GetPropertyAsync("com.mycompany.myplugin:la
655753
await context.User.SetPropertyAsync("com.mycompany.myplugin:last_order_id", "12345", cancellationToken);
656754
```
657755

756+
### Optional plugin-to-plugin integration
757+
758+
If your plugin can optionally integrate with another plugin, you can ask the host for a plugin instance by type:
759+
760+
```csharp
761+
var other = context.GetPlugin<OtherPluginType>(id: "com.other.plugin");
762+
if (other is not null)
763+
{
764+
// Use the optional integration.
765+
}
766+
```
767+
768+
Avoid hard dependencies on other plugins being present; always handle `null`.
769+
658770
### Custom databases
659771

660772
Plugins can use `IDatabaseManager` via `context.Databases`:
@@ -683,6 +795,7 @@ var item = await context.Databases.GetFirstItemAsync(
683795

684796
### “My plugin loads but my tool never runs”
685797

798+
- In ChatAIze.Chatbot, ensure Integrations are enabled in the dashboard settings (tools and integration functions are added only when integrations are enabled).
686799
- Ensure your tool name is unique across all plugins and integration functions.
687800
- Ensure `IChatFunction.Callback` is non-null (tools without callbacks are treated as integration functions and executed by the host’s default callback).
688801
- Prefer named methods over lambdas for `AddFunction(Delegate)`; compiler-generated names can be unstable.

0 commit comments

Comments
 (0)