@hmawla/co-assistant 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +396 -0
- package/config.json.example +32 -0
- package/dist/cli/index.js +4547 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.js +3258 -0
- package/dist/index.js.map +1 -0
- package/heartbeats/email-reply-check.heartbeat.md +39 -0
- package/package.json +79 -0
- package/personality.md +48 -0
- package/plugins/gmail/README.md +78 -0
- package/plugins/gmail/auth.ts +92 -0
- package/plugins/gmail/index.ts +66 -0
- package/plugins/gmail/plugin.json +13 -0
- package/plugins/gmail/tools.ts +336 -0
- package/plugins/google-calendar/README.md +51 -0
- package/plugins/google-calendar/auth.ts +92 -0
- package/plugins/google-calendar/index.ts +82 -0
- package/plugins/google-calendar/plugin.json +13 -0
- package/plugins/google-calendar/tools.ts +328 -0
- package/user.md.example +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hussein Al Mawla
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# 🤖 Co-Assistant
|
|
2
|
+
|
|
3
|
+
AI-powered Telegram personal assistant built on the GitHub Copilot SDK.
|
|
4
|
+
|
|
5
|
+
Chat with state-of-the-art AI models (GPT-5, Claude Sonnet 4, o3, and more) directly from Telegram. Extend it with plugins for Gmail, Google Calendar, or build your own.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
### Prerequisites
|
|
12
|
+
|
|
13
|
+
| Requirement | How to get it |
|
|
14
|
+
|------------|---------------|
|
|
15
|
+
| **Node.js 20+** | [nodejs.org](https://nodejs.org/) |
|
|
16
|
+
| **Telegram Bot Token** | Message [@BotFather](https://t.me/BotFather) → `/newbot` → copy the token |
|
|
17
|
+
| **Telegram User ID** | Message [@userinfobot](https://t.me/userinfobot) → copy the numeric ID |
|
|
18
|
+
| **GitHub Token** | [github.com/settings/tokens](https://github.com/settings/tokens) — create a token with Copilot access |
|
|
19
|
+
|
|
20
|
+
### Install & Configure
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/your-username/co-assistant.git
|
|
24
|
+
cd co-assistant
|
|
25
|
+
npm install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Run the interactive setup wizard — it walks you through every credential and preference:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx tsx src/cli/index.ts setup
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The wizard creates your `.env` file and `config.json`. You can re-run it at any time to update settings.
|
|
35
|
+
|
|
36
|
+
### Personalise
|
|
37
|
+
|
|
38
|
+
Two markdown files control how the AI behaves and who it knows you are:
|
|
39
|
+
|
|
40
|
+
| File | Purpose | Committed? |
|
|
41
|
+
|------|---------|------------|
|
|
42
|
+
| `personality.md` | Defines the assistant's tone, style, and behaviour | ✅ Yes |
|
|
43
|
+
| `user.md` | Your personal profile (name, role, timezone, preferences) | ❌ Gitignored |
|
|
44
|
+
|
|
45
|
+
**Set up your user profile** (copy the template and fill in your details):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cp user.md.example user.md
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Both files are read fresh on each message — edit them anytime without restarting.
|
|
52
|
+
|
|
53
|
+
### Start
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npx tsx src/cli/index.ts start
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Open Telegram, find your bot, and send a message. That's it.
|
|
60
|
+
|
|
61
|
+
**Verbose mode** (shows incoming/outgoing messages and debug logs in the terminal):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx tsx src/cli/index.ts start -v
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Production Deployment
|
|
70
|
+
|
|
71
|
+
For running Co-Assistant permanently on a server (VPS, Raspberry Pi, etc.).
|
|
72
|
+
|
|
73
|
+
### 1. Build
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm run build
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This compiles TypeScript to `dist/` via tsup.
|
|
80
|
+
|
|
81
|
+
### 2. Run with systemd (recommended for Linux)
|
|
82
|
+
|
|
83
|
+
Create a service file:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
sudo nano /etc/systemd/system/co-assistant.service
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```ini
|
|
90
|
+
[Unit]
|
|
91
|
+
Description=Co-Assistant Telegram Bot
|
|
92
|
+
After=network-online.target
|
|
93
|
+
Wants=network-online.target
|
|
94
|
+
|
|
95
|
+
[Service]
|
|
96
|
+
Type=simple
|
|
97
|
+
User=your-username
|
|
98
|
+
WorkingDirectory=/path/to/co-assistant
|
|
99
|
+
ExecStart=/usr/bin/node dist/index.js start
|
|
100
|
+
Restart=always
|
|
101
|
+
RestartSec=10
|
|
102
|
+
Environment=NODE_ENV=production
|
|
103
|
+
|
|
104
|
+
[Install]
|
|
105
|
+
WantedBy=multi-user.target
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Enable and start:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
sudo systemctl daemon-reload
|
|
112
|
+
sudo systemctl enable co-assistant
|
|
113
|
+
sudo systemctl start co-assistant
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Useful commands:**
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
sudo systemctl status co-assistant # Check if running
|
|
120
|
+
sudo journalctl -u co-assistant -f # Live logs
|
|
121
|
+
sudo systemctl restart co-assistant # Restart after config changes
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 3. Alternative: PM2
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm install -g pm2
|
|
128
|
+
pm2 start dist/index.js --name co-assistant -- start
|
|
129
|
+
pm2 save
|
|
130
|
+
pm2 startup # generates command to auto-start on boot
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 4. Alternative: Docker
|
|
134
|
+
|
|
135
|
+
```dockerfile
|
|
136
|
+
FROM node:20-slim
|
|
137
|
+
WORKDIR /app
|
|
138
|
+
COPY package*.json ./
|
|
139
|
+
RUN npm ci --production
|
|
140
|
+
COPY dist/ dist/
|
|
141
|
+
COPY plugins/ plugins/
|
|
142
|
+
COPY heartbeats/ heartbeats/
|
|
143
|
+
COPY personality.md ./
|
|
144
|
+
COPY config.json .env ./
|
|
145
|
+
# Optional — only if you created a user.md:
|
|
146
|
+
# COPY user.md ./
|
|
147
|
+
CMD ["node", "dist/index.js", "start"]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
docker build -t co-assistant .
|
|
152
|
+
docker run -d --restart=always --name co-assistant co-assistant
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Environment Variables
|
|
158
|
+
|
|
159
|
+
All configured via `.env` (the setup wizard handles this):
|
|
160
|
+
|
|
161
|
+
| Variable | Required | Default | Description |
|
|
162
|
+
|----------|----------|---------|-------------|
|
|
163
|
+
| `TELEGRAM_BOT_TOKEN` | ✅ | — | Bot token from @BotFather |
|
|
164
|
+
| `TELEGRAM_USER_ID` | ✅ | — | Your Telegram numeric user ID |
|
|
165
|
+
| `GITHUB_TOKEN` | ✅ | — | GitHub token with Copilot access |
|
|
166
|
+
| `DEFAULT_MODEL` | — | `gpt-4.1` | AI model to use on startup |
|
|
167
|
+
| `LOG_LEVEL` | — | `info` | Logging level (`debug`, `info`, `warn`, `error`) |
|
|
168
|
+
| `HEARTBEAT_INTERVAL_MINUTES` | — | `0` | Scheduled heartbeat interval (0 = disabled) |
|
|
169
|
+
| `AI_SESSION_POOL_SIZE` | — | `3` | Number of parallel AI sessions |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## CLI Commands
|
|
174
|
+
|
|
175
|
+
**How to run commands:**
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# During development (runs TypeScript directly):
|
|
179
|
+
npx tsx src/cli/index.ts setup
|
|
180
|
+
npx tsx src/cli/index.ts start -v
|
|
181
|
+
|
|
182
|
+
# After building (npm run build):
|
|
183
|
+
node dist/cli/index.js setup
|
|
184
|
+
node dist/cli/index.js start
|
|
185
|
+
|
|
186
|
+
# After global install (npm install -g .):
|
|
187
|
+
co-assistant setup
|
|
188
|
+
co-assistant start
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Command | Description |
|
|
192
|
+
|---------|-------------|
|
|
193
|
+
| `setup` | Interactive setup wizard |
|
|
194
|
+
| `start` | Start the bot (`-v` for verbose) |
|
|
195
|
+
| `model` | Show current model |
|
|
196
|
+
| `model <name>` | Switch AI model |
|
|
197
|
+
| `plugin list` | List discovered plugins |
|
|
198
|
+
| `plugin enable <name>` | Enable a plugin |
|
|
199
|
+
| `plugin disable <name>` | Disable a plugin |
|
|
200
|
+
| `plugin configure <name>` | Set up plugin credentials |
|
|
201
|
+
| `heartbeat list` | List heartbeat events |
|
|
202
|
+
| `heartbeat add` | Create a new heartbeat event |
|
|
203
|
+
| `heartbeat remove <name>` | Delete a heartbeat event |
|
|
204
|
+
| `heartbeat run [name]` | Test heartbeat(s) on demand |
|
|
205
|
+
| `status` | Show bot and system status |
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Telegram Commands
|
|
210
|
+
|
|
211
|
+
| Command | Description |
|
|
212
|
+
|---------|-------------|
|
|
213
|
+
| `/help` | List available commands |
|
|
214
|
+
| `/heartbeat [name]` | Run heartbeat event(s) on demand |
|
|
215
|
+
| `/hb [name]` | Shorthand for `/heartbeat` |
|
|
216
|
+
|
|
217
|
+
Anything else you type is a conversation with the AI.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Available Models
|
|
222
|
+
|
|
223
|
+
Models are grouped by rate consumption (requests per prompt):
|
|
224
|
+
|
|
225
|
+
| Tier | Models | Rate |
|
|
226
|
+
|------|--------|------|
|
|
227
|
+
| **Premium** | `gpt-5`, `o3`, `claude-opus-4` | 3x |
|
|
228
|
+
| **Standard** | `gpt-4.1`, `gpt-4o`, `o4-mini`, `claude-sonnet-4` | 1x |
|
|
229
|
+
| **Low** | `gpt-4o-mini`, `gpt-4.1-mini`, `gpt-5-mini`, `o3-mini`, `claude-haiku-4.5` | 0.33x |
|
|
230
|
+
| **Free** | `gpt-4.1-nano` | 0x |
|
|
231
|
+
|
|
232
|
+
Switch via CLI (`co-assistant model claude-sonnet-4`) or in the setup wizard.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Personality & User Profile
|
|
237
|
+
|
|
238
|
+
### `personality.md` — How the AI behaves
|
|
239
|
+
|
|
240
|
+
Defines the assistant's identity, tone, formatting rules, and boundaries. This file is committed to the repo so your team shares the same base personality. Edit it to change the assistant's style.
|
|
241
|
+
|
|
242
|
+
### `user.md` — Who you are
|
|
243
|
+
|
|
244
|
+
Contains your personal details so the AI can address you correctly and understand your context. This file is gitignored — each user creates their own from the template.
|
|
245
|
+
|
|
246
|
+
Both files are injected as system-level context on every message. The AI sees:
|
|
247
|
+
1. Personality instructions (how to behave)
|
|
248
|
+
2. User profile (who it's talking to)
|
|
249
|
+
3. Your actual message
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Plugins
|
|
254
|
+
|
|
255
|
+
### Included Plugins
|
|
256
|
+
|
|
257
|
+
| Plugin | Tools provided |
|
|
258
|
+
|--------|---------------|
|
|
259
|
+
| **Gmail** | Search emails, read email, send email, send reply |
|
|
260
|
+
| **Google Calendar** | List events, create event, update event, delete event |
|
|
261
|
+
|
|
262
|
+
### Enable a Plugin
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
npx tsx src/cli/index.ts plugin enable gmail
|
|
266
|
+
npx tsx src/cli/index.ts plugin configure gmail
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
The configure command walks you through setting up OAuth credentials. For Google plugins, it includes an automated local OAuth flow to obtain refresh tokens.
|
|
270
|
+
|
|
271
|
+
### Create Your Own Plugin
|
|
272
|
+
|
|
273
|
+
Create a directory under `plugins/` with:
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
plugins/my-plugin/
|
|
277
|
+
├── plugin.json # Manifest (id, name, version, credentials)
|
|
278
|
+
└── index.ts # Entry point exporting createPlugin()
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**`plugin.json`:**
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"id": "my-plugin",
|
|
286
|
+
"name": "My Plugin",
|
|
287
|
+
"version": "1.0.0",
|
|
288
|
+
"description": "What it does",
|
|
289
|
+
"requiredCredentials": [
|
|
290
|
+
{ "key": "API_KEY", "description": "API key for the service" }
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**`index.ts`:**
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import type { CoAssistantPlugin, PluginContext } from "../../src/plugins/types.js";
|
|
299
|
+
|
|
300
|
+
export default function createPlugin(): CoAssistantPlugin {
|
|
301
|
+
return {
|
|
302
|
+
id: "my-plugin",
|
|
303
|
+
name: "My Plugin",
|
|
304
|
+
version: "1.0.0",
|
|
305
|
+
description: "What it does",
|
|
306
|
+
requiredCredentials: [{ key: "API_KEY", description: "API key" }],
|
|
307
|
+
|
|
308
|
+
async initialize(context: PluginContext) {
|
|
309
|
+
// Set up connections, validate credentials
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
getTools() {
|
|
313
|
+
return [{
|
|
314
|
+
name: "do_something",
|
|
315
|
+
description: "Does something useful",
|
|
316
|
+
parameters: {
|
|
317
|
+
type: "object",
|
|
318
|
+
properties: {
|
|
319
|
+
input: { type: "string", description: "The input" },
|
|
320
|
+
},
|
|
321
|
+
required: ["input"],
|
|
322
|
+
},
|
|
323
|
+
handler: async (args: Record<string, unknown>) => {
|
|
324
|
+
return `Result for: ${args.input}`;
|
|
325
|
+
},
|
|
326
|
+
}];
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
async destroy() {},
|
|
330
|
+
async healthCheck() { return true; },
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Tool names are automatically prefixed with the plugin ID (e.g., `my-plugin_do_something`) to prevent collisions. Plugins run in a sandbox — failures are isolated and auto-disabled after 5 consecutive errors.
|
|
336
|
+
|
|
337
|
+
> 📖 See [docs/plugin-development.md](docs/plugin-development.md) for the full guide.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Heartbeat Events
|
|
342
|
+
|
|
343
|
+
Heartbeats are scheduled AI prompts that run every N minutes. Use them for periodic checks like "do I have unread emails that need a reply?"
|
|
344
|
+
|
|
345
|
+
### Setup
|
|
346
|
+
|
|
347
|
+
1. Set the interval in `.env`: `HEARTBEAT_INTERVAL_MINUTES=5`
|
|
348
|
+
2. Add a heartbeat event:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
npx tsx src/cli/index.ts heartbeat add
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
3. Or trigger manually via Telegram: `/heartbeat`
|
|
355
|
+
|
|
356
|
+
Heartbeat prompts are stored as `.heartbeat.md` files in the `heartbeats/` directory. They support deduplication via `{{DEDUP_STATE}}` placeholders and `<!-- PROCESSED: id1, id2 -->` markers.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Architecture
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
co-assistant/
|
|
364
|
+
├── src/
|
|
365
|
+
│ ├── ai/ # Copilot SDK client, session pool, model registry
|
|
366
|
+
│ ├── bot/ # Telegraf bot, handlers, middleware (auth, logging)
|
|
367
|
+
│ ├── cli/ # Commander.js CLI (setup, start, plugin, model, heartbeat)
|
|
368
|
+
│ ├── core/ # App orchestrator, config, logger, heartbeat, GC
|
|
369
|
+
│ ├── plugins/ # Plugin registry, manager, sandbox, credentials
|
|
370
|
+
│ ├── storage/ # SQLite database, migrations, repositories
|
|
371
|
+
│ └── utils/ # Google OAuth helper
|
|
372
|
+
├── plugins/ # Installed plugins (gmail, google-calendar)
|
|
373
|
+
├── heartbeats/ # Heartbeat prompt files (.heartbeat.md)
|
|
374
|
+
├── data/ # SQLite database (auto-created)
|
|
375
|
+
├── personality.md # AI personality & behaviour instructions
|
|
376
|
+
├── user.md # Your personal profile (gitignored)
|
|
377
|
+
├── user.md.example # User profile template
|
|
378
|
+
├── config.json # Plugin & runtime configuration (gitignored)
|
|
379
|
+
└── config.json.example
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Key internals:**
|
|
383
|
+
|
|
384
|
+
- **Session pool** — Multiple parallel AI sessions so messages don't queue behind each other
|
|
385
|
+
- **System context** — `personality.md` + `user.md` injected into every AI prompt as system instructions
|
|
386
|
+
- **Plugin sandbox** — Every plugin call wrapped in try/catch with auto-disable after 5 failures
|
|
387
|
+
- **Plugin loader** — Uses `tsx/esm/api` to dynamically import TypeScript plugins from `plugins/`
|
|
388
|
+
- **Garbage collector** — Prunes old conversations (30 days) and health records (7 days); logs memory stats
|
|
389
|
+
- **Heartbeat deduplication** — State files track processed item IDs to avoid duplicate notifications
|
|
390
|
+
- **Reply threading** — Each AI response threads back to the user's original Telegram message
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## License
|
|
395
|
+
|
|
396
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugins": {
|
|
3
|
+
"gmail": {
|
|
4
|
+
"enabled": false,
|
|
5
|
+
"credentials": {
|
|
6
|
+
"GMAIL_CLIENT_ID": "",
|
|
7
|
+
"GMAIL_CLIENT_SECRET": "",
|
|
8
|
+
"GMAIL_REFRESH_TOKEN": ""
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"google-calendar": {
|
|
12
|
+
"enabled": false,
|
|
13
|
+
"credentials": {
|
|
14
|
+
"GCAL_CLIENT_ID": "",
|
|
15
|
+
"GCAL_CLIENT_SECRET": "",
|
|
16
|
+
"GCAL_REFRESH_TOKEN": ""
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"bot": {
|
|
21
|
+
"maxMessageLength": 4096,
|
|
22
|
+
"typingIndicator": true
|
|
23
|
+
},
|
|
24
|
+
"ai": {
|
|
25
|
+
"maxRetries": 3,
|
|
26
|
+
"sessionTimeout": 3600000
|
|
27
|
+
},
|
|
28
|
+
"pluginHealth": {
|
|
29
|
+
"maxFailures": 5,
|
|
30
|
+
"checkInterval": 60000
|
|
31
|
+
}
|
|
32
|
+
}
|