Skip to content

Commit b3f6b39

Browse files
authored
Merge pull request #126 from cagostino/chris/npc_upgrades
Chris/npc upgrades
2 parents 6c45247 + c114fe3 commit b3f6b39

File tree

20 files changed

+1865
-352
lines changed

20 files changed

+1865
-352
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,12 @@ or with the `--port` flag:
11461146
npc serve --port 5337
11471147
11481148
```
1149+
If you want to initialize a project based on templates and then make it available for serving, you can do so like this
1150+
```bash
1151+
npc serve -t 'sales, marketing' -ctx 'im developing a team that will focus on sales and marketing within the logging industry. I need a team that can help me with the following: - generate leads - create marketing campaigns - build a sales funnel - close deals - manage customer relationships - manage sales pipeline - manage marketing campaigns - manage marketing budget' -m llama3.2 -pr ollama
1152+
```
1153+
This will use the specified model and provider to generate a team of npcs to fit the templates and context provided.
1154+
11491155

11501156
Once the server is up and running, you can access the API endpoints at `http://localhost:5337/api/`. Here are some example curl commands to test the endpoints:
11511157

@@ -1156,7 +1162,7 @@ curl -s http://localhost:5337/api/health | jq '.'
11561162
echo -e "\nTesting execute endpoint..."
11571163
curl -s -X POST http://localhost:5337/api/execute \
11581164
-H "Content-Type: application/json" \
1159-
-d '{"commandstr": "hello world", "currentPath": "/media/caug/extradrive1/npcww/npcsh", "conversationId": "test124"}' | jq '.'
1165+
-d '{"commandstr": "hello world", "currentPath": "~/", "conversationId": "test124"}' | jq '.'
11601166
11611167
echo -e "\nTesting conversations endpoint..."
11621168
curl -s "http://localhost:5337/api/conversations?path=/tmp" | jq '.'

examples/morning_routine.pipe

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ steps:
99
task: "Give me an update on the latest events in the market: {{source('market_events')}}."
1010

1111
- step_name: "summarize"
12-
npc: "{{ ref('sibiji') }}"
13-
model: llama3.2
14-
provider: ollama
12+
npc: "{{ ref('critic') }}"
13+
model: gpt-4o-mini
14+
provider: openai
1515
task: "Review the outputs from the {{review_email}} and {{market_update}} and provide me with a summary."
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to create and populate the market_events table needed by the NPC profile compiler.
4+
"""
5+
6+
import sqlite3
7+
import os
8+
import sys
9+
import json
10+
from datetime import datetime, timedelta
11+
12+
13+
def create_market_events_table(db_path):
14+
"""Create and populate the market_events table for the NPC profile compiler."""
15+
conn = sqlite3.connect(db_path)
16+
cursor = conn.cursor()
17+
18+
try:
19+
# Check if table exists
20+
cursor.execute(
21+
"SELECT name FROM sqlite_master WHERE type='table' AND name='market_events'"
22+
)
23+
if cursor.fetchone():
24+
print("Table 'market_events' already exists.")
25+
return True
26+
27+
# Create the market_events table
28+
print("Creating 'market_events' table...")
29+
cursor.execute(
30+
"""
31+
CREATE TABLE market_events (
32+
id INTEGER PRIMARY KEY AUTOINCREMENT,
33+
event_type TEXT,
34+
description TEXT,
35+
impact_level INTEGER,
36+
timestamp DATETIME,
37+
market_sector TEXT,
38+
price_change REAL,
39+
volume INTEGER,
40+
is_processed BOOLEAN DEFAULT 0
41+
)
42+
"""
43+
)
44+
45+
# Add some sample data
46+
print("Adding sample market event data...")
47+
now = datetime.now()
48+
sample_events = [
49+
{
50+
"event_type": "earnings_report",
51+
"description": "XYZ Corp reports quarterly earnings above expectations",
52+
"impact_level": 3,
53+
"timestamp": (now - timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"),
54+
"market_sector": "technology",
55+
"price_change": 2.45,
56+
"volume": 1250000,
57+
"is_processed": 1,
58+
},
59+
{
60+
"event_type": "market_crash",
61+
"description": "Stock market drops 5% on inflation concerns",
62+
"impact_level": 5,
63+
"timestamp": (now - timedelta(days=3)).strftime("%Y-%m-%d %H:%M:%S"),
64+
"market_sector": "global",
65+
"price_change": -5.12,
66+
"volume": 8500000,
67+
"is_processed": 1,
68+
},
69+
{
70+
"event_type": "merger_announcement",
71+
"description": "ABC Inc announces acquisition of DEF Corp",
72+
"impact_level": 4,
73+
"timestamp": (now - timedelta(days=2)).strftime("%Y-%m-%d %H:%M:%S"),
74+
"market_sector": "healthcare",
75+
"price_change": 3.75,
76+
"volume": 3200000,
77+
"is_processed": 0,
78+
},
79+
{
80+
"event_type": "policy_change",
81+
"description": "Central bank raises interest rates by 0.25%",
82+
"impact_level": 4,
83+
"timestamp": (now - timedelta(hours=12)).strftime("%Y-%m-%d %H:%M:%S"),
84+
"market_sector": "finance",
85+
"price_change": -1.20,
86+
"volume": 4800000,
87+
"is_processed": 0,
88+
},
89+
{
90+
"event_type": "product_launch",
91+
"description": "New smartphone model released with innovative features",
92+
"impact_level": 2,
93+
"timestamp": (now - timedelta(days=5)).strftime("%Y-%m-%d %H:%M:%S"),
94+
"market_sector": "consumer_electronics",
95+
"price_change": 1.85,
96+
"volume": 2100000,
97+
"is_processed": 1,
98+
},
99+
]
100+
101+
for event in sample_events:
102+
cursor.execute(
103+
"""
104+
INSERT INTO market_events (event_type, description, impact_level, timestamp, market_sector, price_change, volume, is_processed)
105+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
106+
""",
107+
(
108+
event["event_type"],
109+
event["description"],
110+
event["impact_level"],
111+
event["timestamp"],
112+
event["market_sector"],
113+
event["price_change"],
114+
event["volume"],
115+
event["is_processed"],
116+
),
117+
)
118+
119+
conn.commit()
120+
print("Market events table created and populated successfully.")
121+
return True
122+
123+
except Exception as e:
124+
print(f"Error creating market_events table: {e}")
125+
conn.rollback()
126+
return False
127+
finally:
128+
conn.close()
129+
130+
131+
if __name__ == "__main__":
132+
# Default path or take from command line
133+
default_db_path = os.path.expanduser("~/npcsh_history.db")
134+
135+
if len(sys.argv) > 1:
136+
db_path = sys.argv[1]
137+
else:
138+
db_path = default_db_path
139+
140+
print(f"Setting up market_events table in database at: {db_path}")
141+
success = create_market_events_table(db_path)
142+
143+
if success:
144+
print("Setup completed successfully.")
145+
sys.exit(0)
146+
else:
147+
print("Setup failed.")
148+
sys.exit(1)

npcsh/cli.py

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import argparse
2+
from .npc_sysenv import NPCSH_CHAT_MODEL, NPCSH_CHAT_PROVIDER
23
from .serve import start_flask_server
3-
from .helpers import initialize_npc_project
4+
from .npc_compiler import (
5+
initialize_npc_project,
6+
conjure_team,
7+
)
8+
import os
49

510

611
def main():
@@ -10,12 +15,57 @@ def main():
1015
# Serve command
1116
serve_parser = subparsers.add_parser("serve", help="Start the Flask server")
1217
serve_parser.add_argument("--port", "-p", help="Optional port")
18+
serve_parser.add_argument(
19+
"--cors", "-c", help="CORS origins (comma-separated list)", type=str
20+
)
21+
serve_parser.add_argument(
22+
"--templates", "-t", help="agent templates(comma-separated list)", type=str
23+
)
24+
serve_parser.add_argument(
25+
"--context",
26+
"-ctx",
27+
help="important information when merging templates",
28+
type=str,
29+
)
30+
serve_parser.add_argument(
31+
"--model",
32+
"-m",
33+
help="model",
34+
type=str,
35+
)
36+
serve_parser.add_argument(
37+
"--provider",
38+
"-pr",
39+
help="provider",
40+
type=str,
41+
)
1342

1443
# Init command
1544
init_parser = subparsers.add_parser("init", help="Initialize a new NPC project")
1645
init_parser.add_argument(
1746
"directory", nargs="?", default=".", help="Directory to initialize project in"
1847
)
48+
init_parser.add_argument(
49+
"--templates", "-t", help="agent templates(comma-separated list)", type=str
50+
)
51+
init_parser.add_argument(
52+
"--context",
53+
"-ctx",
54+
help="important information when merging templates",
55+
type=str,
56+
)
57+
init_parser.add_argument(
58+
"--model",
59+
"-m",
60+
help="model",
61+
type=str,
62+
)
63+
init_parser.add_argument(
64+
"--provider",
65+
"-pr",
66+
help="provider",
67+
type=str,
68+
)
1969

2070
build_parser = subparsers.add_parser(
2171
"build", help="Build a NPC team into a standalone executable server"
@@ -50,9 +100,66 @@ def main():
50100
# npc spool
51101

52102
if args.command == "serve":
53-
start_flask_server(port=args.port if args.port else 5337)
103+
if args.cors:
104+
# Parse the CORS origins from the comma-separated string
105+
cors_origins = [origin.strip() for origin in args.cors.split(",")]
106+
else:
107+
cors_origins = None
108+
if args.templates:
109+
templates = [template.strip() for template in args.templates.split(",")]
110+
else:
111+
templates = None
112+
if args.context:
113+
context = args.context.strip()
114+
else:
115+
context = None
116+
if args.model:
117+
model = args.model
118+
else:
119+
model = NPCSH_CHAT_MODEL
120+
if args.provider:
121+
provider = args.provider
122+
else:
123+
provider = NPCSH_CHAT_PROVIDER
124+
125+
if context is not None and os.environ.get("WERKZEUG_RUN_MAIN") != "true":
126+
initialize_npc_project(
127+
args.directory,
128+
templates=templates,
129+
context=context,
130+
model=model,
131+
provider=provider,
132+
)
133+
134+
start_flask_server(
135+
port=args.port if args.port else 5337,
136+
cors_origins=cors_origins,
137+
)
54138
elif args.command == "init":
55-
initialize_npc_project(args.directory)
139+
if args.templates:
140+
templates = [template.strip() for template in args.templates.split(",")]
141+
else:
142+
templates = None
143+
if args.context:
144+
context = args.context.strip()
145+
else:
146+
context = None
147+
if args.model:
148+
model = args.model
149+
else:
150+
model = NPCSH_CHAT_MODEL
151+
if args.provider:
152+
provider = args.provider
153+
else:
154+
provider = NPCSH_CHAT_PROVIDER
155+
156+
initialize_npc_project(
157+
args.directory,
158+
templates=templates,
159+
context=context,
160+
model=model,
161+
provider=provider,
162+
)
56163
elif args.command == "new":
57164
# create a new npc, tool, or assembly line
58165
pass

0 commit comments

Comments
 (0)