overai 1.4.27 → 1.4.29

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/README.md CHANGED
@@ -4,12 +4,16 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![Downloads](https://img.shields.io/npm/dm/overai.svg)](https://www.npmjs.com/package/overai)
6
6
 
7
- ![OverAI Logo](https://cdn.jsdelivr.net/npm/overai@1.4.26/images/overai.png)
7
+ ![OverAI Logo](https://cdn.jsdelivr.net/npm/overai@latest/images/overai.png)
8
8
 
9
9
  **OverAI** is the comprehensive, production-ready AI Agents framework designed for **Builders, Entrepreneurs, and Enterprise Developers**.
10
10
 
11
11
  Unlike other frameworks that stop at "Hello World", OverAI provides the full stack needed to **Build, Deploy, and Monetize** AI solutions. From simple automation scripts to full-fledged AI SaaS platforms with billing, API keys, and workflow integrations.
12
12
 
13
+ ## 📣 Join the Community
14
+
15
+ Follow this link to join the WhatsApp group: [Join the WhatsApp Community](https://chat.whatsapp.com/JbXwPg47gJ56Fi9lnAeHy9)
16
+
13
17
  ## 🚀 Why Choose OverAI?
14
18
 
15
19
  ### 💼 For Entrepreneurs & SaaS Builders
@@ -322,6 +326,55 @@ Support for the MCP standard allows your agents to safely access local files, da
322
326
 
323
327
  ---
324
328
 
329
+ ## 🤝 A2A (Agent‑to‑Agent) Optionnel
330
+
331
+ OverAI fournit une couche A2A optionnelle pour la négociation et la coordination entre agents, activable à la demande et sans modifier vos agents existants.
332
+
333
+ - Activer la couche A2A par variable d’environnement:
334
+ ```bash
335
+ export OVERAI_A2A_ENABLED=true
336
+ ```
337
+ - Imports publics:
338
+ ```typescript
339
+ import { Agent, Router } from 'overai';
340
+ import { ChannelManager, OverAIAdapter } from 'overai/a2a';
341
+ ```
342
+ - Exemple minimal:
343
+ ```typescript
344
+ const cm = new ChannelManager(); // activé si OVERAI_A2A_ENABLED=true
345
+ const writer = new Agent({ instructions: 'Tu rédiges des fiches produit' });
346
+ const seo = new Agent({ instructions: 'Tu optimises SEO' });
347
+
348
+ const router = new Router({
349
+ writer: { agent: writer, keywords: ['rédige', 'fiche'] },
350
+ seo: { agent: seo, keywords: ['seo', 'métadonnées', 'balises'] }
351
+ }, { default: 'writer' });
352
+
353
+ const a2a = new OverAIAdapter({
354
+ channel: cm,
355
+ agents: { writer, seo },
356
+ router
357
+ });
358
+
359
+ cm.openChannel('ch-1', ['writer', 'seo']);
360
+ await a2a.handle({
361
+ type: 'propose',
362
+ channelId: 'ch-1',
363
+ from: 'writer',
364
+ to: 'seo',
365
+ timestamp: Date.now(),
366
+ taskId: 'task-123',
367
+ proposal: {
368
+ goal: 'Optimiser la fiche produit pour SEO',
369
+ steps: ['mots-clés', 'meta', 'FAQ', 'JSON-LD']
370
+ }
371
+ });
372
+ ```
373
+
374
+ Cette couche est facultative et isolée: si OVERAI_A2A_ENABLED n’est pas défini à true, le module reste inactif et vos agents fonctionnent comme d’habitude.
375
+
376
+ ---
377
+
325
378
  ## 🛠️ Development
326
379
 
327
380
  To contribute or modify the framework:
@@ -0,0 +1,21 @@
1
+ import type { A2AMessage } from '../messages';
2
+ import { ChannelManager } from '../channel';
3
+ import { Agent } from '../../agent/simple';
4
+ import { Router } from '../../agent/router';
5
+ export interface OverAIAdapterConfig {
6
+ channel: ChannelManager;
7
+ agents: Record<string, Agent>;
8
+ router?: Router;
9
+ }
10
+ export declare class OverAIAdapter {
11
+ private channel;
12
+ private agents;
13
+ private router?;
14
+ private machines;
15
+ constructor(config: OverAIAdapterConfig);
16
+ private getMachine;
17
+ handle(message: A2AMessage): Promise<void>;
18
+ private onPropose;
19
+ private onHandoff;
20
+ private onCommit;
21
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OverAIAdapter = void 0;
4
+ const state_1 = require("../state");
5
+ class OverAIAdapter {
6
+ constructor(config) {
7
+ this.machines = new Map();
8
+ this.channel = config.channel;
9
+ this.agents = config.agents;
10
+ this.router = config.router;
11
+ }
12
+ getMachine(channelId) {
13
+ let m = this.machines.get(channelId);
14
+ if (!m) {
15
+ m = new state_1.NegotiationStateMachine();
16
+ this.machines.set(channelId, m);
17
+ }
18
+ return m;
19
+ }
20
+ async handle(message) {
21
+ const machine = this.getMachine(message.channelId);
22
+ machine.apply(message);
23
+ this.channel.send(message);
24
+ switch (message.type) {
25
+ case 'propose':
26
+ await this.onPropose(message);
27
+ break;
28
+ case 'handoff':
29
+ await this.onHandoff(message);
30
+ break;
31
+ case 'commit':
32
+ await this.onCommit(message);
33
+ break;
34
+ default:
35
+ // control messages handled by state machine only
36
+ break;
37
+ }
38
+ }
39
+ async onPropose(msg) {
40
+ const target = msg.to && this.agents[msg.to];
41
+ const prompt = `Objectif: ${msg.proposal.goal}\n` +
42
+ `Étapes: ${(msg.proposal.steps || []).join(' | ')}\n` +
43
+ `Contraintes: ${(msg.proposal.constraints || []).join(' | ')}\n` +
44
+ `Ressources: ${JSON.stringify(msg.proposal.resources || {})}`;
45
+ if (target) {
46
+ const out = await target.start(prompt);
47
+ const commit = {
48
+ type: 'commit',
49
+ channelId: msg.channelId,
50
+ from: msg.to,
51
+ to: msg.from,
52
+ timestamp: Date.now(),
53
+ taskId: msg.taskId,
54
+ result: { success: true, output: out }
55
+ };
56
+ await this.handle(commit);
57
+ }
58
+ else if (this.router) {
59
+ const result = await this.router.chat(prompt);
60
+ const commit = {
61
+ type: 'commit',
62
+ channelId: msg.channelId,
63
+ from: 'router',
64
+ to: msg.from,
65
+ timestamp: Date.now(),
66
+ taskId: msg.taskId,
67
+ result: { success: true, output: result }
68
+ };
69
+ await this.handle(commit);
70
+ }
71
+ }
72
+ async onHandoff(msg) {
73
+ const next = this.agents[msg.nextAgent];
74
+ if (!next)
75
+ return;
76
+ const ctx = msg.context || {};
77
+ const prompt = `Reprise (handoff) avec contexte: ${JSON.stringify(ctx)}`;
78
+ const out = await next.start(prompt);
79
+ const commit = {
80
+ type: 'commit',
81
+ channelId: msg.channelId,
82
+ from: msg.nextAgent,
83
+ to: msg.from,
84
+ timestamp: Date.now(),
85
+ taskId: msg.taskId,
86
+ result: { success: true, output: out }
87
+ };
88
+ await this.handle(commit);
89
+ }
90
+ async onCommit(_msg) {
91
+ // noop: already audited by channel + state machine
92
+ }
93
+ }
94
+ exports.OverAIAdapter = OverAIAdapter;
@@ -0,0 +1,23 @@
1
+ import type { A2AMessage, AgentId, ChannelId } from './messages';
2
+ export interface ChannelRecord {
3
+ id: ChannelId;
4
+ participants: Set<AgentId>;
5
+ audit: A2AMessage[];
6
+ createdAt: number;
7
+ metadata?: Record<string, any>;
8
+ }
9
+ export declare class ChannelManager {
10
+ private channels;
11
+ private agents;
12
+ private enabled;
13
+ static isEnabledEnv(): boolean;
14
+ constructor(enabled?: boolean);
15
+ isEnabled(): boolean;
16
+ registerAgent(agentId: AgentId): void;
17
+ hasAgent(agentId: AgentId): boolean;
18
+ openChannel(id: ChannelId, participants: AgentId[], metadata?: Record<string, any>): ChannelRecord;
19
+ getChannel(id: ChannelId): ChannelRecord | undefined;
20
+ closeChannel(id: ChannelId): boolean;
21
+ send(message: A2AMessage): void;
22
+ getAudit(id: ChannelId): A2AMessage[];
23
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChannelManager = void 0;
4
+ class ChannelManager {
5
+ static isEnabledEnv() {
6
+ const flag = process.env.OVERAI_A2A_ENABLED;
7
+ return String(flag).toLowerCase() === 'true';
8
+ }
9
+ constructor(enabled = ChannelManager.isEnabledEnv()) {
10
+ this.channels = new Map();
11
+ this.agents = new Set();
12
+ this.enabled = enabled;
13
+ }
14
+ isEnabled() {
15
+ return this.enabled;
16
+ }
17
+ registerAgent(agentId) {
18
+ this.agents.add(agentId);
19
+ }
20
+ hasAgent(agentId) {
21
+ return this.agents.has(agentId);
22
+ }
23
+ openChannel(id, participants, metadata) {
24
+ const record = {
25
+ id,
26
+ participants: new Set(participants),
27
+ audit: [],
28
+ createdAt: Date.now(),
29
+ metadata
30
+ };
31
+ this.channels.set(id, record);
32
+ return record;
33
+ }
34
+ getChannel(id) {
35
+ return this.channels.get(id);
36
+ }
37
+ closeChannel(id) {
38
+ return this.channels.delete(id);
39
+ }
40
+ send(message) {
41
+ const channel = this.channels.get(message.channelId);
42
+ if (!channel) {
43
+ throw new Error(`Channel not found: ${message.channelId}`);
44
+ }
45
+ channel.audit.push(message);
46
+ }
47
+ getAudit(id) {
48
+ const channel = this.channels.get(id);
49
+ return channel ? [...channel.audit] : [];
50
+ }
51
+ }
52
+ exports.ChannelManager = ChannelManager;
@@ -0,0 +1,4 @@
1
+ export * from './messages';
2
+ export * from './channel';
3
+ export * from './state';
4
+ export * from './adapters/overai';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./messages"), exports);
18
+ __exportStar(require("./channel"), exports);
19
+ __exportStar(require("./state"), exports);
20
+ __exportStar(require("./adapters/overai"), exports);
@@ -0,0 +1,69 @@
1
+ /**
2
+ * A2A-like Message Schema (optional layer)
3
+ *
4
+ * Defines normalized message types for agent-to-agent negotiation and coordination.
5
+ */
6
+ export type AgentId = string;
7
+ export type ChannelId = string;
8
+ export type TaskId = string;
9
+ export interface BaseMessage {
10
+ type: 'propose' | 'accept' | 'reject' | 'revise' | 'handoff' | 'commit' | 'status' | 'error';
11
+ channelId: ChannelId;
12
+ from: AgentId;
13
+ to?: AgentId;
14
+ taskId?: TaskId;
15
+ correlationId?: string;
16
+ timestamp: number;
17
+ metadata?: Record<string, any>;
18
+ }
19
+ export interface ProposeMessage extends BaseMessage {
20
+ type: 'propose';
21
+ proposal: {
22
+ goal: string;
23
+ steps?: string[];
24
+ constraints?: string[];
25
+ resources?: Record<string, any>;
26
+ };
27
+ }
28
+ export interface AcceptMessage extends BaseMessage {
29
+ type: 'accept';
30
+ acceptedProposalId?: string;
31
+ }
32
+ export interface RejectMessage extends BaseMessage {
33
+ type: 'reject';
34
+ reason?: string;
35
+ suggestedRevision?: string;
36
+ }
37
+ export interface ReviseMessage extends BaseMessage {
38
+ type: 'revise';
39
+ revision: {
40
+ changes: string[];
41
+ };
42
+ }
43
+ export interface HandoffMessage extends BaseMessage {
44
+ type: 'handoff';
45
+ nextAgent: AgentId;
46
+ context?: Record<string, any>;
47
+ }
48
+ export interface CommitMessage extends BaseMessage {
49
+ type: 'commit';
50
+ result?: {
51
+ success: boolean;
52
+ output?: any;
53
+ logs?: string[];
54
+ };
55
+ }
56
+ export interface StatusMessage extends BaseMessage {
57
+ type: 'status';
58
+ status: 'pending' | 'negotiating' | 'in_progress' | 'blocked' | 'completed' | 'failed';
59
+ details?: string;
60
+ }
61
+ export interface ErrorMessage extends BaseMessage {
62
+ type: 'error';
63
+ error: {
64
+ code: string;
65
+ message: string;
66
+ details?: Record<string, any>;
67
+ };
68
+ }
69
+ export type A2AMessage = ProposeMessage | AcceptMessage | RejectMessage | ReviseMessage | HandoffMessage | CommitMessage | StatusMessage | ErrorMessage;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * A2A-like Message Schema (optional layer)
4
+ *
5
+ * Defines normalized message types for agent-to-agent negotiation and coordination.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import type { A2AMessage } from './messages';
2
+ export type NegotiationState = 'idle' | 'proposed' | 'accepted' | 'rejected' | 'revising' | 'handoff' | 'committed' | 'failed';
3
+ export declare class NegotiationStateMachine {
4
+ private state;
5
+ private history;
6
+ getState(): NegotiationState;
7
+ getHistory(): A2AMessage[];
8
+ apply(message: A2AMessage): NegotiationState;
9
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NegotiationStateMachine = void 0;
4
+ class NegotiationStateMachine {
5
+ constructor() {
6
+ this.state = 'idle';
7
+ this.history = [];
8
+ }
9
+ getState() {
10
+ return this.state;
11
+ }
12
+ getHistory() {
13
+ return [...this.history];
14
+ }
15
+ apply(message) {
16
+ this.history.push(message);
17
+ switch (message.type) {
18
+ case 'propose':
19
+ this.state = 'proposed';
20
+ break;
21
+ case 'accept':
22
+ this.state = 'accepted';
23
+ break;
24
+ case 'reject':
25
+ this.state = 'rejected';
26
+ break;
27
+ case 'revise':
28
+ this.state = 'revising';
29
+ break;
30
+ case 'handoff':
31
+ this.state = 'handoff';
32
+ break;
33
+ case 'commit':
34
+ this.state = 'committed';
35
+ break;
36
+ case 'error':
37
+ this.state = 'failed';
38
+ break;
39
+ default:
40
+ // status messages do not change state directly
41
+ break;
42
+ }
43
+ return this.state;
44
+ }
45
+ }
46
+ exports.NegotiationStateMachine = NegotiationStateMachine;
package/package.json CHANGED
@@ -1,9 +1,20 @@
1
1
  {
2
2
  "name": "overai",
3
- "version": "1.4.27",
3
+ "version": "1.4.29",
4
4
  "description": "OverAI TypeScript AI Agents Framework - Build, Deploy, and Monetize AI Agents in Minutes",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./a2a": {
13
+ "types": "./dist/a2a/index.d.ts",
14
+ "default": "./dist/a2a/index.js"
15
+ }
16
+ },
17
+ "readmeFilename": "README.md",
7
18
  "files": [
8
19
  "dist",
9
20
  "images",