Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ modules:
- path: src/core/modules/abi
enabled: true
- path: src/core/modules/chatgpt
enabled: true
enabled: false
- path: src/core/modules/claude
enabled: true
enabled: false
- path: src/core/modules/deepseek
enabled: true
- path: src/core/modules/gemini
Expand All @@ -45,17 +45,19 @@ modules:
- path: src/marketplace/modules/applications/git
enabled: true
- path: src/marketplace/modules/applications/github
enabled: true
enabled: false
- path: src/marketplace/modules/applications/google_search
enabled: true
- path: src/marketplace/modules/applications/linkedin
enabled: true
enabled: false
- path: src/marketplace/modules/applications/naas
enabled: true
enabled: false
- path: src/marketplace/modules/applications/postgres
enabled: true
- path: src/marketplace/modules/applications/powerpoint
enabled: false
- path: src/marketplace/modules/naas-openai-gpt4
enabled: true
- path: src/marketplace/modules/domains/account-executive
enabled: false
- path: src/marketplace/modules/domains/accountant
Expand Down
1 change: 1 addition & 0 deletions src/marketplace/modules/naas-openai-gpt4/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Naas OpenAI GPT-4 Module - Working implementation
182 changes: 182 additions & 0 deletions src/marketplace/modules/naas-openai-gpt4/agents/NaasGPT4Agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
"""
Naas GPT-4 Agent - Working implementation using reverse-engineered API
Consolidates all working code from capture_naas_requests.py, chat_gpt4.py, chat_naas.py
"""

import os
import json
import httpx
from typing import Dict, Any
from dotenv import load_dotenv

load_dotenv()

class NaasGPT4Agent:
"""Working Naas GPT-4 agent using reverse-engineered API"""

def __init__(self):
# Working configuration from reverse engineering
self.base_url = "https://api.naas.ai"
self.chat_id = int(os.getenv("NAAS_CHAT_ID", "15349")) # Configurable chat ID
self.model_id = "507dbbc5-88a1-4bd7-8c35-28cea3faaf1f" # GPT-4 model ID

# Get token from environment
self.token = os.getenv("NAAS_TOKEN")
if not self.token:
raise ValueError("NAAS_TOKEN not found in .env - add your JWT token")

# Exact working headers from reverse engineering
self.headers = {
"accept": "*/*",
"accept-language": "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7",
"authorization": f"Bearer {self.token}",
"content-type": "application/json",
"origin": "https://naas.ai",
"referer": "https://naas.ai/",
"sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}

# HTTP client with SSL bypass for corporate environments
self.client = httpx.Client(
verify=False,
headers=self.headers,
timeout=60.0
)

# Conversation history
self.conversation_history = []

def chat(self, message: str) -> Dict[str, Any]:
"""Send message to GPT-4 using working reverse-engineered format"""

try:
# Add to conversation history
self.conversation_history.append({"role": "user", "content": message})

# Build context-aware prompt
context_prompt = self._build_context_prompt(message)

# Exact working format from reverse engineering
prompt = f"@[openai/gpt-4]{{MODEL::{self.model_id}}} {context_prompt}"

# Working payload structure
payload = {
"id": self.chat_id,
"model_id": self.model_id,
"payload": json.dumps({
"prompt": prompt,
"temperature": 0.7
})
}

endpoint = f"{self.base_url}/chat/{self.chat_id}/completion"

response = self.client.post(endpoint, json=payload)

if response.status_code == 200:
data = response.json()

# Extract response content
content = self._extract_response_content(data)

# Add to conversation history
self.conversation_history.append({"role": "assistant", "content": content})

return {
"success": True,
"content": content,
"tokens": {
"input": data.get("input_tokens", 0),
"output": data.get("output_tokens", 0)
}
}
else:
return {
"success": False,
"error": f"API returned {response.status_code}: {response.text}"
}

except Exception as e:
return {
"success": False,
"error": f"Request failed: {str(e)}"
}

def _build_context_prompt(self, current_message: str) -> str:
"""Build context-aware prompt with conversation history"""

# Keep last 6 messages for context
recent_history = self.conversation_history[-6:] if len(self.conversation_history) > 6 else self.conversation_history

if not recent_history:
return current_message

# Build context
context_parts = []
for msg in recent_history:
role = "User" if msg["role"] == "user" else "Assistant"
context_parts.append(f"{role}: {msg['content']}")

context_parts.append(f"User: {current_message}")
context_parts.append("Assistant:")

return "\\n".join(context_parts)

def _extract_response_content(self, api_response: Dict[str, Any]) -> str:
"""Extract GPT-4 response from API response"""

try:
# Extract from Naas API response structure
if "completion" in api_response and "messages" in api_response["completion"]:
messages = api_response["completion"]["messages"]
# Find the last message from the assistant (from_user: false)
for message in reversed(messages):
if not message.get("from_user", True): # Assistant message
return message.get("message", "").strip()

# Try standard OpenAI format
if "choices" in api_response and api_response["choices"]:
choice = api_response["choices"][0]
if "message" in choice and "content" in choice["message"]:
return choice["message"]["content"].strip()
elif "text" in choice:
return choice["text"].strip()

if "response" in api_response:
return api_response["response"].strip()

if "content" in api_response:
return api_response["content"].strip()

if "text" in api_response:
return api_response["text"].strip()

# Fallback - return formatted response
return f"Response received: {json.dumps(api_response, indent=2)}"

except Exception as e:
return f"Error extracting response: {str(e)}"

def clear_conversation(self):
"""Clear conversation history"""
self.conversation_history = []
return {"success": True, "message": "Conversation cleared"}

def get_conversation_summary(self):
"""Get conversation summary"""
return {
"success": True,
"message_count": len(self.conversation_history),
"recent_messages": self.conversation_history[-4:] if self.conversation_history else []
}


def create_agent():
"""Factory function for ABI module system"""
return NaasGPT4Agent()
143 changes: 143 additions & 0 deletions src/marketplace/modules/naas-openai-gpt4/apps/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/usr/bin/env python3
"""
Clean CLI for Naas GPT-4 - Consolidates all working code
"""

import click
import json
import sys
from pathlib import Path

# Add module path
module_path = Path(__file__).parent.parent
sys.path.insert(0, str(module_path))

from agents.NaasGPT4Agent import NaasGPT4Agent

@click.group()
def cli():
"""Naas GPT-4 CLI - Working implementation"""
pass

@cli.command()
def run():
"""Start chat with GPT-4"""
try:
agent = NaasGPT4Agent()
click.echo("🤖 Naas GPT-4 Chat")
click.echo("Type 'quit' to exit")
click.echo("-" * 30)

while True:
try:
message = click.prompt("You", type=str)

if message.lower() in ['quit', 'exit', 'bye']:
click.echo("Goodbye! 👋")
break

result = agent.chat(message)

if result["success"]:
click.echo(f"naas-openai-gpt4: {result['content']}")
else:
click.echo(f"Error: {result['error']}", err=True)

except KeyboardInterrupt:
click.echo("\\nGoodbye! 👋")
break

except Exception as e:
click.echo(f"Error: {str(e)}", err=True)
sys.exit(1)

@cli.command()
@click.argument('message')
@click.option('--json', '-j', is_flag=True, help='JSON output')
def chat(message, json):
"""Send single message to GPT-4"""
try:
agent = NaasGPT4Agent()
result = agent.chat(message)

if json:
click.echo(json.dumps(result, indent=2))
else:
if result["success"]:
click.echo(f"GPT-4: {result['content']}")
tokens = result.get('tokens', {})
if tokens.get('input') or tokens.get('output'):
click.echo(f"Tokens: {tokens.get('input', 0)} → {tokens.get('output', 0)}")
else:
click.echo(f"Error: {result['error']}", err=True)

except Exception as e:
click.echo(f"Error: {str(e)}", err=True)
sys.exit(1)

@cli.command()
def interactive():
"""Interactive chat session"""
try:
agent = NaasGPT4Agent()
click.echo("🤖 Naas GPT-4 Interactive Chat")
click.echo("Commands: 'clear' (reset), 'quit' (exit)")
click.echo("-" * 50)

while True:
try:
message = click.prompt("You", type=str)

if message.lower() in ['quit', 'exit', 'bye']:
click.echo("Goodbye! 👋")
break

if message.lower() == 'clear':
agent.clear_conversation()
click.echo("Conversation cleared.")
continue

if message.lower() == 'summary':
summary = agent.get_conversation_summary()
click.echo(f"Messages: {summary['message_count']}")
continue

result = agent.chat(message)

if result["success"]:
click.echo(f"GPT-4: {result['content']}")
tokens = result.get('tokens', {})
if tokens.get('input') or tokens.get('output'):
click.echo(f"💡 {tokens.get('input', 0)} → {tokens.get('output', 0)} tokens")
else:
click.echo(f"Error: {result['error']}", err=True)

except KeyboardInterrupt:
click.echo("\\nGoodbye! 👋")
break

except Exception as e:
click.echo(f"Error: {str(e)}", err=True)
sys.exit(1)

@cli.command()
def test():
"""Test connection to Naas API"""
try:
agent = NaasGPT4Agent()
result = agent.chat("test connection")

if result["success"]:
click.echo("✅ Connection OK")
tokens = result.get('tokens', {})
click.echo(f"Test tokens: {tokens.get('input', 0)} → {tokens.get('output', 0)}")
else:
click.echo("❌ Connection Failed")
click.echo(f"Error: {result['error']}")

except Exception as e:
click.echo(f"❌ Error: {str(e)}", err=True)
sys.exit(1)

if __name__ == '__main__':
cli()
Loading
Loading