omnipalm 0.1.0__py3-none-any.whl
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.
- omnipalm/__init__.py +15 -0
- omnipalm/agent.py +96 -0
- omnipalm/cli.py +90 -0
- omnipalm/config.py +108 -0
- omnipalm/integrations/__init__.py +23 -0
- omnipalm/integrations/base.py +85 -0
- omnipalm/integrations/facebook.py +77 -0
- omnipalm/integrations/instagram.py +37 -0
- omnipalm/integrations/manager.py +82 -0
- omnipalm/integrations/messenger.py +27 -0
- omnipalm/integrations/threads.py +27 -0
- omnipalm/integrations/whatsapp.py +27 -0
- omnipalm/integrations/workplace.py +27 -0
- omnipalm/py.typed +0 -0
- omnipalm-0.1.0.dist-info/METADATA +106 -0
- omnipalm-0.1.0.dist-info/RECORD +19 -0
- omnipalm-0.1.0.dist-info/WHEEL +4 -0
- omnipalm-0.1.0.dist-info/entry_points.txt +2 -0
- omnipalm-0.1.0.dist-info/licenses/LICENSE +9 -0
omnipalm/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OmniPalm - Meta's AI Agent
|
|
3
|
+
|
|
4
|
+
Automate tasks across Meta's ecosystem with natural language.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
__author__ = "OmniPalm Team"
|
|
9
|
+
__email__ = "hello@omnipalm.org"
|
|
10
|
+
|
|
11
|
+
from omnipalm.agent import Agent
|
|
12
|
+
from omnipalm.config import Config
|
|
13
|
+
from omnipalm.integrations import Integration
|
|
14
|
+
|
|
15
|
+
__all__ = ["Agent", "Config", "Integration", "__version__"]
|
omnipalm/agent.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OmniPalm Agent - The core AI agent for task automation.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
from omnipalm.config import Config
|
|
8
|
+
from omnipalm.integrations import IntegrationManager
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TaskResult(BaseModel):
|
|
12
|
+
"""Result of an agent task execution."""
|
|
13
|
+
success: bool
|
|
14
|
+
message: str
|
|
15
|
+
data: Optional[dict[str, Any]] = None
|
|
16
|
+
error: Optional[str] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Agent:
|
|
20
|
+
"""
|
|
21
|
+
OmniPalm AI Agent.
|
|
22
|
+
|
|
23
|
+
Automate tasks across Meta's ecosystem using natural language commands.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
>>> agent = Agent()
|
|
27
|
+
>>> result = agent.run("Post to Facebook: Hello world!")
|
|
28
|
+
>>> print(result.success)
|
|
29
|
+
True
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, config: Optional[Config] = None):
|
|
33
|
+
"""
|
|
34
|
+
Initialize the OmniPalm agent.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
config: Optional configuration. If not provided, loads from default locations.
|
|
38
|
+
"""
|
|
39
|
+
self.config = config or Config.load()
|
|
40
|
+
self.integrations = IntegrationManager(self.config)
|
|
41
|
+
self._initialized = False
|
|
42
|
+
|
|
43
|
+
def init(self) -> None:
|
|
44
|
+
"""Initialize the agent and all configured integrations."""
|
|
45
|
+
self.integrations.init_all()
|
|
46
|
+
self._initialized = True
|
|
47
|
+
|
|
48
|
+
def run(self, task: str) -> TaskResult:
|
|
49
|
+
"""
|
|
50
|
+
Execute a natural language task.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
task: Natural language description of the task to perform.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
TaskResult containing success status, message, and any data.
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
>>> result = agent.run("Schedule an Instagram post for tomorrow")
|
|
60
|
+
>>> print(result.message)
|
|
61
|
+
'Post scheduled for 2026-02-06 09:00'
|
|
62
|
+
"""
|
|
63
|
+
if not self._initialized:
|
|
64
|
+
self.init()
|
|
65
|
+
|
|
66
|
+
# Parse and execute the task
|
|
67
|
+
try:
|
|
68
|
+
result = self._execute_task(task)
|
|
69
|
+
return TaskResult(
|
|
70
|
+
success=True,
|
|
71
|
+
message=result.get("message", "Task completed successfully"),
|
|
72
|
+
data=result.get("data")
|
|
73
|
+
)
|
|
74
|
+
except Exception as e:
|
|
75
|
+
return TaskResult(
|
|
76
|
+
success=False,
|
|
77
|
+
message="Task failed",
|
|
78
|
+
error=str(e)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
def _execute_task(self, task: str) -> dict[str, Any]:
|
|
82
|
+
"""Internal task execution logic."""
|
|
83
|
+
# This would connect to the LLM and execute the task
|
|
84
|
+
# Placeholder for actual implementation
|
|
85
|
+
return {
|
|
86
|
+
"message": f"Task received: {task}",
|
|
87
|
+
"data": {"status": "pending"}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
def status(self) -> dict[str, Any]:
|
|
91
|
+
"""Get the current status of the agent and integrations."""
|
|
92
|
+
return {
|
|
93
|
+
"initialized": self._initialized,
|
|
94
|
+
"integrations": self.integrations.status(),
|
|
95
|
+
"config": self.config.summary()
|
|
96
|
+
}
|
omnipalm/cli.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OmniPalm CLI - Command line interface for OmniPalm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
@click.version_option(package_name="omnipalm")
|
|
15
|
+
def main():
|
|
16
|
+
"""OmniPalm - Meta's AI Agent for task automation."""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@main.command()
|
|
21
|
+
def init():
|
|
22
|
+
"""Initialize OmniPalm configuration."""
|
|
23
|
+
from omnipalm.config import Config
|
|
24
|
+
|
|
25
|
+
config = Config()
|
|
26
|
+
config.save()
|
|
27
|
+
|
|
28
|
+
console.print(Panel.fit(
|
|
29
|
+
"[green]✓[/green] OmniPalm initialized successfully!\n\n"
|
|
30
|
+
f"Config saved to: [cyan]{config.data_dir}/config.yaml[/cyan]\n\n"
|
|
31
|
+
"Next steps:\n"
|
|
32
|
+
" 1. Add your LLM API key to the config\n"
|
|
33
|
+
" 2. Configure your Meta integrations\n"
|
|
34
|
+
" 3. Run [cyan]omnipalm run 'your task'[/cyan]",
|
|
35
|
+
title="OmniPalm",
|
|
36
|
+
border_style="cyan"
|
|
37
|
+
))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@main.command()
|
|
41
|
+
@click.argument("task")
|
|
42
|
+
def run(task: str):
|
|
43
|
+
"""Run a natural language task."""
|
|
44
|
+
from omnipalm import Agent
|
|
45
|
+
|
|
46
|
+
with console.status("[cyan]Processing task...[/cyan]"):
|
|
47
|
+
agent = Agent()
|
|
48
|
+
result = agent.run(task)
|
|
49
|
+
|
|
50
|
+
if result.success:
|
|
51
|
+
console.print(f"[green]✓[/green] {result.message}")
|
|
52
|
+
if result.data:
|
|
53
|
+
console.print(result.data)
|
|
54
|
+
else:
|
|
55
|
+
console.print(f"[red]✗[/red] {result.message}")
|
|
56
|
+
if result.error:
|
|
57
|
+
console.print(f"[red]Error:[/red] {result.error}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@main.command()
|
|
61
|
+
def status():
|
|
62
|
+
"""Check OmniPalm status and integrations."""
|
|
63
|
+
from omnipalm import Agent
|
|
64
|
+
|
|
65
|
+
agent = Agent()
|
|
66
|
+
status_info = agent.status()
|
|
67
|
+
|
|
68
|
+
table = Table(title="OmniPalm Status")
|
|
69
|
+
table.add_column("Property", style="cyan")
|
|
70
|
+
table.add_column("Value", style="green")
|
|
71
|
+
|
|
72
|
+
table.add_row("Initialized", str(status_info["initialized"]))
|
|
73
|
+
table.add_row("LLM Provider", status_info["config"]["llm_provider"])
|
|
74
|
+
table.add_row("LLM Model", status_info["config"]["llm_model"])
|
|
75
|
+
|
|
76
|
+
integrations = status_info["config"]["integrations_enabled"]
|
|
77
|
+
table.add_row("Integrations", ", ".join(integrations) if integrations else "None")
|
|
78
|
+
|
|
79
|
+
console.print(table)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@main.command()
|
|
83
|
+
def version():
|
|
84
|
+
"""Show OmniPalm version."""
|
|
85
|
+
from omnipalm import __version__
|
|
86
|
+
console.print(f"OmniPalm v{__version__}")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if __name__ == "__main__":
|
|
90
|
+
main()
|
omnipalm/config.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OmniPalm Configuration Management.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, Optional
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
from dotenv import load_dotenv
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LLMConfig(BaseModel):
|
|
13
|
+
"""LLM provider configuration."""
|
|
14
|
+
provider: str = "anthropic"
|
|
15
|
+
model: str = "claude-3-opus"
|
|
16
|
+
api_key: Optional[str] = None
|
|
17
|
+
base_url: Optional[str] = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class IntegrationConfig(BaseModel):
|
|
21
|
+
"""Individual integration configuration."""
|
|
22
|
+
enabled: bool = False
|
|
23
|
+
access_token: Optional[str] = None
|
|
24
|
+
settings: dict[str, Any] = {}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Config(BaseModel):
|
|
28
|
+
"""
|
|
29
|
+
OmniPalm configuration.
|
|
30
|
+
|
|
31
|
+
Manages LLM provider settings and integration configurations.
|
|
32
|
+
"""
|
|
33
|
+
llm: LLMConfig = LLMConfig()
|
|
34
|
+
integrations: dict[str, IntegrationConfig] = {}
|
|
35
|
+
data_dir: Path = Path.home() / ".omnipalm"
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def load(cls, path: Optional[Path] = None) -> "Config":
|
|
39
|
+
"""
|
|
40
|
+
Load configuration from file or environment.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
path: Optional path to config file. Defaults to ~/.omnipalm/config.yaml
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Config instance with loaded settings.
|
|
47
|
+
"""
|
|
48
|
+
load_dotenv()
|
|
49
|
+
|
|
50
|
+
config_path = path or Path.home() / ".omnipalm" / "config.yaml"
|
|
51
|
+
|
|
52
|
+
if config_path.exists():
|
|
53
|
+
return cls._load_from_file(config_path)
|
|
54
|
+
|
|
55
|
+
# Load from environment variables
|
|
56
|
+
return cls._load_from_env()
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def _load_from_file(cls, path: Path) -> "Config":
|
|
60
|
+
"""Load configuration from YAML file."""
|
|
61
|
+
try:
|
|
62
|
+
import yaml
|
|
63
|
+
with open(path) as f:
|
|
64
|
+
data = yaml.safe_load(f)
|
|
65
|
+
return cls(**data)
|
|
66
|
+
except ImportError:
|
|
67
|
+
# YAML not available, use defaults
|
|
68
|
+
return cls()
|
|
69
|
+
except Exception:
|
|
70
|
+
return cls()
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def _load_from_env(cls) -> "Config":
|
|
74
|
+
"""Load configuration from environment variables."""
|
|
75
|
+
llm_config = LLMConfig(
|
|
76
|
+
provider=os.getenv("OMNIPALM_LLM_PROVIDER", "anthropic"),
|
|
77
|
+
model=os.getenv("OMNIPALM_LLM_MODEL", "claude-3-opus"),
|
|
78
|
+
api_key=os.getenv("OMNIPALM_API_KEY"),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return cls(llm=llm_config)
|
|
82
|
+
|
|
83
|
+
def save(self, path: Optional[Path] = None) -> None:
|
|
84
|
+
"""Save configuration to file."""
|
|
85
|
+
config_path = path or self.data_dir / "config.yaml"
|
|
86
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
import yaml
|
|
90
|
+
with open(config_path, "w") as f:
|
|
91
|
+
yaml.dump(self.model_dump(), f, default_flow_style=False)
|
|
92
|
+
except ImportError:
|
|
93
|
+
# Fallback to JSON
|
|
94
|
+
import json
|
|
95
|
+
config_path = config_path.with_suffix(".json")
|
|
96
|
+
with open(config_path, "w") as f:
|
|
97
|
+
json.dump(self.model_dump(), f, indent=2)
|
|
98
|
+
|
|
99
|
+
def summary(self) -> dict[str, Any]:
|
|
100
|
+
"""Get a summary of the configuration (without sensitive data)."""
|
|
101
|
+
return {
|
|
102
|
+
"llm_provider": self.llm.provider,
|
|
103
|
+
"llm_model": self.llm.model,
|
|
104
|
+
"integrations_enabled": [
|
|
105
|
+
name for name, cfg in self.integrations.items() if cfg.enabled
|
|
106
|
+
],
|
|
107
|
+
"data_dir": str(self.data_dir),
|
|
108
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
OmniPalm Integrations - Connect to Meta's ecosystem.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from omnipalm.integrations.base import Integration
|
|
6
|
+
from omnipalm.integrations.manager import IntegrationManager
|
|
7
|
+
from omnipalm.integrations.facebook import FacebookIntegration
|
|
8
|
+
from omnipalm.integrations.instagram import InstagramIntegration
|
|
9
|
+
from omnipalm.integrations.whatsapp import WhatsAppIntegration
|
|
10
|
+
from omnipalm.integrations.messenger import MessengerIntegration
|
|
11
|
+
from omnipalm.integrations.threads import ThreadsIntegration
|
|
12
|
+
from omnipalm.integrations.workplace import WorkplaceIntegration
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Integration",
|
|
16
|
+
"IntegrationManager",
|
|
17
|
+
"FacebookIntegration",
|
|
18
|
+
"InstagramIntegration",
|
|
19
|
+
"WhatsAppIntegration",
|
|
20
|
+
"MessengerIntegration",
|
|
21
|
+
"ThreadsIntegration",
|
|
22
|
+
"WorkplaceIntegration",
|
|
23
|
+
]
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base Integration class for OmniPalm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class IntegrationStatus(BaseModel):
|
|
11
|
+
"""Status of an integration."""
|
|
12
|
+
name: str
|
|
13
|
+
enabled: bool
|
|
14
|
+
connected: bool
|
|
15
|
+
error: Optional[str] = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Integration(ABC):
|
|
19
|
+
"""
|
|
20
|
+
Base class for all OmniPalm integrations.
|
|
21
|
+
|
|
22
|
+
Subclasses must implement the connect, disconnect, and execute methods.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
name: str = "base"
|
|
26
|
+
description: str = "Base integration"
|
|
27
|
+
|
|
28
|
+
def __init__(self, config: dict[str, Any]):
|
|
29
|
+
"""
|
|
30
|
+
Initialize the integration.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
config: Integration-specific configuration.
|
|
34
|
+
"""
|
|
35
|
+
self.config = config
|
|
36
|
+
self._connected = False
|
|
37
|
+
self._error: Optional[str] = None
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def enabled(self) -> bool:
|
|
41
|
+
"""Check if integration is enabled."""
|
|
42
|
+
return self.config.get("enabled", False)
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def connected(self) -> bool:
|
|
46
|
+
"""Check if integration is connected."""
|
|
47
|
+
return self._connected
|
|
48
|
+
|
|
49
|
+
@abstractmethod
|
|
50
|
+
def connect(self) -> bool:
|
|
51
|
+
"""
|
|
52
|
+
Connect to the integration service.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
True if connection successful, False otherwise.
|
|
56
|
+
"""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
@abstractmethod
|
|
60
|
+
def disconnect(self) -> None:
|
|
61
|
+
"""Disconnect from the integration service."""
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
66
|
+
"""
|
|
67
|
+
Execute an action on the integration.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
action: The action to perform (e.g., 'post', 'send', 'schedule').
|
|
71
|
+
params: Action-specific parameters.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Result of the action execution.
|
|
75
|
+
"""
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
def status(self) -> IntegrationStatus:
|
|
79
|
+
"""Get the current status of the integration."""
|
|
80
|
+
return IntegrationStatus(
|
|
81
|
+
name=self.name,
|
|
82
|
+
enabled=self.enabled,
|
|
83
|
+
connected=self._connected,
|
|
84
|
+
error=self._error
|
|
85
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Facebook Integration for OmniPalm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
from omnipalm.integrations.base import Integration
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FacebookIntegration(Integration):
|
|
10
|
+
"""
|
|
11
|
+
Facebook Page integration.
|
|
12
|
+
|
|
13
|
+
Supports posting, scheduling, comment management, and insights.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
name = "facebook"
|
|
17
|
+
description = "Facebook Page management and automation"
|
|
18
|
+
|
|
19
|
+
def connect(self) -> bool:
|
|
20
|
+
"""Connect to Facebook Graph API."""
|
|
21
|
+
access_token = self.config.get("access_token")
|
|
22
|
+
if not access_token:
|
|
23
|
+
self._error = "No access token configured"
|
|
24
|
+
return False
|
|
25
|
+
|
|
26
|
+
# Validate token with Facebook API
|
|
27
|
+
# Placeholder for actual implementation
|
|
28
|
+
self._connected = True
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
def disconnect(self) -> None:
|
|
32
|
+
"""Disconnect from Facebook."""
|
|
33
|
+
self._connected = False
|
|
34
|
+
|
|
35
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
36
|
+
"""
|
|
37
|
+
Execute a Facebook action.
|
|
38
|
+
|
|
39
|
+
Supported actions:
|
|
40
|
+
- post: Create a new post
|
|
41
|
+
- schedule: Schedule a post
|
|
42
|
+
- comment: Reply to a comment
|
|
43
|
+
- insights: Get page insights
|
|
44
|
+
"""
|
|
45
|
+
if not self._connected:
|
|
46
|
+
return {"error": "Not connected to Facebook"}
|
|
47
|
+
|
|
48
|
+
actions = {
|
|
49
|
+
"post": self._post,
|
|
50
|
+
"schedule": self._schedule,
|
|
51
|
+
"comment": self._comment,
|
|
52
|
+
"insights": self._insights,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
handler = actions.get(action)
|
|
56
|
+
if not handler:
|
|
57
|
+
return {"error": f"Unknown action: {action}"}
|
|
58
|
+
|
|
59
|
+
return handler(params)
|
|
60
|
+
|
|
61
|
+
def _post(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
62
|
+
"""Create a Facebook post."""
|
|
63
|
+
message = params.get("message", "")
|
|
64
|
+
# API call placeholder
|
|
65
|
+
return {"success": True, "post_id": "123456789", "message": message}
|
|
66
|
+
|
|
67
|
+
def _schedule(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
68
|
+
"""Schedule a Facebook post."""
|
|
69
|
+
return {"success": True, "scheduled": True}
|
|
70
|
+
|
|
71
|
+
def _comment(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
72
|
+
"""Reply to a comment."""
|
|
73
|
+
return {"success": True, "comment_id": "987654321"}
|
|
74
|
+
|
|
75
|
+
def _insights(self, params: dict[str, Any]) -> dict[str, Any]:
|
|
76
|
+
"""Get page insights."""
|
|
77
|
+
return {"success": True, "reach": 0, "engagement": 0}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Instagram Integration for OmniPalm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
from omnipalm.integrations.base import Integration
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class InstagramIntegration(Integration):
|
|
10
|
+
"""
|
|
11
|
+
Instagram Business integration.
|
|
12
|
+
|
|
13
|
+
Supports posting photos/reels, stories, DMs, and insights.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
name = "instagram"
|
|
17
|
+
description = "Instagram content and engagement automation"
|
|
18
|
+
|
|
19
|
+
def connect(self) -> bool:
|
|
20
|
+
"""Connect to Instagram Graph API."""
|
|
21
|
+
access_token = self.config.get("access_token")
|
|
22
|
+
if not access_token:
|
|
23
|
+
self._error = "No access token configured"
|
|
24
|
+
return False
|
|
25
|
+
self._connected = True
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
def disconnect(self) -> None:
|
|
29
|
+
"""Disconnect from Instagram."""
|
|
30
|
+
self._connected = False
|
|
31
|
+
|
|
32
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
33
|
+
"""Execute an Instagram action."""
|
|
34
|
+
if not self._connected:
|
|
35
|
+
return {"error": "Not connected to Instagram"}
|
|
36
|
+
|
|
37
|
+
return {"success": True, "action": action, "params": params}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration Manager for OmniPalm.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional, TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from omnipalm.config import Config
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class IntegrationManager:
|
|
12
|
+
"""
|
|
13
|
+
Manages all OmniPalm integrations.
|
|
14
|
+
|
|
15
|
+
Handles initialization, connection, and routing of actions to integrations.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, config: "Config"):
|
|
19
|
+
"""
|
|
20
|
+
Initialize the integration manager.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
config: OmniPalm configuration.
|
|
24
|
+
"""
|
|
25
|
+
self.config = config
|
|
26
|
+
self._integrations: dict[str, Any] = {}
|
|
27
|
+
|
|
28
|
+
def init_all(self) -> None:
|
|
29
|
+
"""Initialize all enabled integrations."""
|
|
30
|
+
from omnipalm.integrations import (
|
|
31
|
+
FacebookIntegration,
|
|
32
|
+
InstagramIntegration,
|
|
33
|
+
WhatsAppIntegration,
|
|
34
|
+
MessengerIntegration,
|
|
35
|
+
ThreadsIntegration,
|
|
36
|
+
WorkplaceIntegration,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
integration_classes = {
|
|
40
|
+
"facebook": FacebookIntegration,
|
|
41
|
+
"instagram": InstagramIntegration,
|
|
42
|
+
"whatsapp": WhatsAppIntegration,
|
|
43
|
+
"messenger": MessengerIntegration,
|
|
44
|
+
"threads": ThreadsIntegration,
|
|
45
|
+
"workplace": WorkplaceIntegration,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for name, cls in integration_classes.items():
|
|
49
|
+
int_config = self.config.integrations.get(name)
|
|
50
|
+
if int_config and int_config.enabled:
|
|
51
|
+
integration = cls(int_config.model_dump())
|
|
52
|
+
if integration.connect():
|
|
53
|
+
self._integrations[name] = integration
|
|
54
|
+
|
|
55
|
+
def get(self, name: str) -> Optional[Any]:
|
|
56
|
+
"""Get an integration by name."""
|
|
57
|
+
return self._integrations.get(name)
|
|
58
|
+
|
|
59
|
+
def execute(self, integration_name: str, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
60
|
+
"""
|
|
61
|
+
Execute an action on a specific integration.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
integration_name: Name of the integration.
|
|
65
|
+
action: Action to perform.
|
|
66
|
+
params: Action parameters.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
Result of the action.
|
|
70
|
+
"""
|
|
71
|
+
integration = self.get(integration_name)
|
|
72
|
+
if not integration:
|
|
73
|
+
return {"error": f"Integration '{integration_name}' not found or not enabled"}
|
|
74
|
+
|
|
75
|
+
return integration.execute(action, params)
|
|
76
|
+
|
|
77
|
+
def status(self) -> dict[str, Any]:
|
|
78
|
+
"""Get status of all integrations."""
|
|
79
|
+
return {
|
|
80
|
+
name: integration.status().model_dump()
|
|
81
|
+
for name, integration in self._integrations.items()
|
|
82
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Messenger Integration for OmniPalm."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from omnipalm.integrations.base import Integration
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MessengerIntegration(Integration):
|
|
8
|
+
"""Messenger Platform integration."""
|
|
9
|
+
|
|
10
|
+
name = "messenger"
|
|
11
|
+
description = "Messenger chatbot and messaging automation"
|
|
12
|
+
|
|
13
|
+
def connect(self) -> bool:
|
|
14
|
+
access_token = self.config.get("access_token")
|
|
15
|
+
if not access_token:
|
|
16
|
+
self._error = "No access token configured"
|
|
17
|
+
return False
|
|
18
|
+
self._connected = True
|
|
19
|
+
return True
|
|
20
|
+
|
|
21
|
+
def disconnect(self) -> None:
|
|
22
|
+
self._connected = False
|
|
23
|
+
|
|
24
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
+
if not self._connected:
|
|
26
|
+
return {"error": "Not connected to Messenger"}
|
|
27
|
+
return {"success": True, "action": action, "params": params}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Threads Integration for OmniPalm."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from omnipalm.integrations.base import Integration
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ThreadsIntegration(Integration):
|
|
8
|
+
"""Threads social platform integration."""
|
|
9
|
+
|
|
10
|
+
name = "threads"
|
|
11
|
+
description = "Threads posting and engagement automation"
|
|
12
|
+
|
|
13
|
+
def connect(self) -> bool:
|
|
14
|
+
access_token = self.config.get("access_token")
|
|
15
|
+
if not access_token:
|
|
16
|
+
self._error = "No access token configured"
|
|
17
|
+
return False
|
|
18
|
+
self._connected = True
|
|
19
|
+
return True
|
|
20
|
+
|
|
21
|
+
def disconnect(self) -> None:
|
|
22
|
+
self._connected = False
|
|
23
|
+
|
|
24
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
+
if not self._connected:
|
|
26
|
+
return {"error": "Not connected to Threads"}
|
|
27
|
+
return {"success": True, "action": action, "params": params}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""WhatsApp Business Integration for OmniPalm."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from omnipalm.integrations.base import Integration
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WhatsAppIntegration(Integration):
|
|
8
|
+
"""WhatsApp Business API integration."""
|
|
9
|
+
|
|
10
|
+
name = "whatsapp"
|
|
11
|
+
description = "WhatsApp Business messaging automation"
|
|
12
|
+
|
|
13
|
+
def connect(self) -> bool:
|
|
14
|
+
access_token = self.config.get("access_token")
|
|
15
|
+
if not access_token:
|
|
16
|
+
self._error = "No access token configured"
|
|
17
|
+
return False
|
|
18
|
+
self._connected = True
|
|
19
|
+
return True
|
|
20
|
+
|
|
21
|
+
def disconnect(self) -> None:
|
|
22
|
+
self._connected = False
|
|
23
|
+
|
|
24
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
+
if not self._connected:
|
|
26
|
+
return {"error": "Not connected to WhatsApp"}
|
|
27
|
+
return {"success": True, "action": action, "params": params}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Workplace Integration for OmniPalm."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from omnipalm.integrations.base import Integration
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WorkplaceIntegration(Integration):
|
|
8
|
+
"""Workplace from Meta integration."""
|
|
9
|
+
|
|
10
|
+
name = "workplace"
|
|
11
|
+
description = "Workplace internal communication automation"
|
|
12
|
+
|
|
13
|
+
def connect(self) -> bool:
|
|
14
|
+
access_token = self.config.get("access_token")
|
|
15
|
+
if not access_token:
|
|
16
|
+
self._error = "No access token configured"
|
|
17
|
+
return False
|
|
18
|
+
self._connected = True
|
|
19
|
+
return True
|
|
20
|
+
|
|
21
|
+
def disconnect(self) -> None:
|
|
22
|
+
self._connected = False
|
|
23
|
+
|
|
24
|
+
def execute(self, action: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
+
if not self._connected:
|
|
26
|
+
return {"error": "Not connected to Workplace"}
|
|
27
|
+
return {"success": True, "action": action, "params": params}
|
omnipalm/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: omnipalm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Meta's AI Agent - Automate tasks across Meta's ecosystem with natural language
|
|
5
|
+
Project-URL: Homepage, https://omnipalm.org
|
|
6
|
+
Project-URL: Documentation, https://omnipalm.org/documentation.html
|
|
7
|
+
Project-URL: Repository, https://x.com/omnipalm
|
|
8
|
+
Project-URL: Instagram, https://www.instagram.com/omni.palm
|
|
9
|
+
Author-email: OmniPalm Team <hello@omnipalm.org>
|
|
10
|
+
Maintainer-email: OmniPalm Team <hello@omnipalm.org>
|
|
11
|
+
License: Proprietary
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: agent,ai,automation,facebook,instagram,llm,meta,whatsapp
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Office/Business
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Requires-Dist: click>=8.1.0
|
|
27
|
+
Requires-Dist: httpx>=0.24.0
|
|
28
|
+
Requires-Dist: pydantic>=2.0.0
|
|
29
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
30
|
+
Requires-Dist: requests>=2.28.0
|
|
31
|
+
Requires-Dist: rich>=13.0.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
|
|
40
|
+
# OmniPalm
|
|
41
|
+
|
|
42
|
+
**Meta's AI Agent** - Automate tasks across Meta's ecosystem with natural language.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install omnipalm
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from omnipalm import Agent
|
|
54
|
+
|
|
55
|
+
agent = Agent()
|
|
56
|
+
result = agent.run("Post to Instagram: Check out our new product!")
|
|
57
|
+
print(result)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## CLI Usage
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Initialize configuration
|
|
64
|
+
omnipalm init
|
|
65
|
+
|
|
66
|
+
# Run a task
|
|
67
|
+
omnipalm run "Schedule a Facebook post for tomorrow at 9am"
|
|
68
|
+
|
|
69
|
+
# Check status
|
|
70
|
+
omnipalm status
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Features
|
|
74
|
+
|
|
75
|
+
- **Natural Language Commands** - Just describe what you want to do
|
|
76
|
+
- **Meta Integrations** - Facebook, Instagram, WhatsApp, Messenger, Threads, Workplace, Meta Quest
|
|
77
|
+
- **Multiple LLM Providers** - Claude, GPT-4, Gemini, Llama, and local models
|
|
78
|
+
- **Enterprise Ready** - Built for scale with Meta's infrastructure
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
Create a `.omnipalm.yaml` file:
|
|
83
|
+
|
|
84
|
+
```yaml
|
|
85
|
+
llm:
|
|
86
|
+
provider: anthropic
|
|
87
|
+
model: claude-3-opus
|
|
88
|
+
|
|
89
|
+
integrations:
|
|
90
|
+
facebook:
|
|
91
|
+
enabled: true
|
|
92
|
+
page_id: your-page-id
|
|
93
|
+
instagram:
|
|
94
|
+
enabled: true
|
|
95
|
+
business_account_id: your-account-id
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Links
|
|
99
|
+
|
|
100
|
+
- Website: https://omnipalm.org
|
|
101
|
+
- X (Twitter): https://x.com/omnipalm
|
|
102
|
+
- Instagram: https://www.instagram.com/omni.palm
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
Proprietary - Meta Platforms, Inc.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
omnipalm/__init__.py,sha256=NsYSU7uDs7VF2QMeiTRpvs9EXD6s1gvFrVgAlXEnIz4,359
|
|
2
|
+
omnipalm/agent.py,sha256=6pNxqfz6fARo3vbZjZeX8tbja2yUSW4QDFbJITtLSpw,2904
|
|
3
|
+
omnipalm/cli.py,sha256=0IY3kLYiNMASmt1z4oGxaydtGwGOJPBpxG4nRBXRjNo,2371
|
|
4
|
+
omnipalm/config.py,sha256=vDaGjEWNqrttc0sZzUBsMooC0mM11ItI4fNvFvF2lbQ,3333
|
|
5
|
+
omnipalm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
omnipalm/integrations/__init__.py,sha256=L8V5l6tvg2IsxRlq4fWjq4AGJMilK1w4Dtvf39Hj5UI,780
|
|
7
|
+
omnipalm/integrations/base.py,sha256=LdIuDsL0Y6V14TxBiQWhbOZ9W0_071qPpEb8MSt39Ug,2155
|
|
8
|
+
omnipalm/integrations/facebook.py,sha256=3_q1kAQHnYlJ2ce4x_9enXB-zQ1Lp0Jy6lakv9BMBWQ,2416
|
|
9
|
+
omnipalm/integrations/instagram.py,sha256=0HaMbKESuoxVmT5xqcu9f2jvG2wMe1XhTI-b7LwbREk,1078
|
|
10
|
+
omnipalm/integrations/manager.py,sha256=i_eS2p7FGvN7VI5d8gzzp4Eu2WCB-lZOkQ9X6MZGaGo,2579
|
|
11
|
+
omnipalm/integrations/messenger.py,sha256=wmuxWCZ2kf2ASe4z6oLf7-64bFvgG4xHQ2oSkyHAjfM,858
|
|
12
|
+
omnipalm/integrations/threads.py,sha256=iRZO2ti39Q2BsrhM2zYTrTm4Cuc1UfZK0Q1qn3W9m1I,854
|
|
13
|
+
omnipalm/integrations/whatsapp.py,sha256=JAkYP8oNQhwGpR5zW3rrrEFfxnawra-baHSLidV5KRI,862
|
|
14
|
+
omnipalm/integrations/workplace.py,sha256=li-92eKkYVCm4QpxxDcazj_u9UT0lDV5merwM7VJd0g,860
|
|
15
|
+
omnipalm-0.1.0.dist-info/METADATA,sha256=pwfEBqGlC3Zri9mq_1cir2Xpgp9OghLDa-mYQK1tgQU,2854
|
|
16
|
+
omnipalm-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
17
|
+
omnipalm-0.1.0.dist-info/entry_points.txt,sha256=vZNSMLrwQe1uVW2Ed76xQ4cZR5hlZmWEoOqV7hPAxrk,47
|
|
18
|
+
omnipalm-0.1.0.dist-info/licenses/LICENSE,sha256=rTh0tIq5uFxzs8-THfF3i4Hwy2yIBs10Kp6oSLCxWAY,292
|
|
19
|
+
omnipalm-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Copyright (c) 2026 OmniPalm / Meta Platforms, Inc.
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software is proprietary and confidential. Unauthorized copying,
|
|
6
|
+
modification, distribution, or use of this software, via any medium,
|
|
7
|
+
is strictly prohibited.
|
|
8
|
+
|
|
9
|
+
For licensing inquiries, contact: hello@omnipalm.org
|