|
016a29f…
|
lmata
|
1 |
// codex-agent is a thin wrapper around pkg/ircagent with Codex/OpenAI defaults. |
|
016a29f…
|
lmata
|
2 |
package main |
|
016a29f…
|
lmata
|
3 |
|
|
016a29f…
|
lmata
|
4 |
import ( |
|
016a29f…
|
lmata
|
5 |
"context" |
|
016a29f…
|
lmata
|
6 |
"flag" |
|
016a29f…
|
lmata
|
7 |
"fmt" |
|
016a29f…
|
lmata
|
8 |
"log/slog" |
|
016a29f…
|
lmata
|
9 |
"os" |
|
016a29f…
|
lmata
|
10 |
"os/signal" |
|
016a29f…
|
lmata
|
11 |
"syscall" |
|
016a29f…
|
lmata
|
12 |
|
|
016a29f…
|
lmata
|
13 |
"github.com/conflicthq/scuttlebot/pkg/ircagent" |
|
016a29f…
|
lmata
|
14 |
) |
|
016a29f…
|
lmata
|
15 |
|
|
016a29f…
|
lmata
|
16 |
const systemPrompt = `You are Codex, an AI assistant connected to an IRC chat server called scuttlebot. |
|
016a29f…
|
lmata
|
17 |
Be helpful, concise, and friendly. Keep responses short - IRC is a chat medium, not a document editor. |
|
016a29f…
|
lmata
|
18 |
No markdown formatting (no **, ##, backtick blocks) - IRC renders plain text only. |
|
016a29f…
|
lmata
|
19 |
You may use multiple lines but keep each thought brief.` |
|
016a29f…
|
lmata
|
20 |
|
|
016a29f…
|
lmata
|
21 |
func main() { |
|
016a29f…
|
lmata
|
22 |
ircAddr := flag.String("irc", "127.0.0.1:6667", "IRC server address") |
|
016a29f…
|
lmata
|
23 |
nick := flag.String("nick", "codex", "IRC nick") |
|
016a29f…
|
lmata
|
24 |
pass := flag.String("pass", "", "SASL password (required)") |
|
016a29f…
|
lmata
|
25 |
channels := flag.String("channels", "#general", "Comma-separated channels to join") |
|
016a29f…
|
lmata
|
26 |
apiKey := flag.String("api-key", os.Getenv("OPENAI_API_KEY"), "OpenAI API key (direct mode)") |
|
016a29f…
|
lmata
|
27 |
model := flag.String("model", os.Getenv("OPENAI_MODEL"), "Model override (direct mode)") |
|
016a29f…
|
lmata
|
28 |
apiURL := flag.String("api-url", "http://localhost:8080", "Scuttlebot API URL (gateway mode)") |
|
016a29f…
|
lmata
|
29 |
token := flag.String("token", os.Getenv("SCUTTLEBOT_TOKEN"), "Scuttlebot bearer token (gateway mode)") |
|
016a29f…
|
lmata
|
30 |
backend := flag.String("backend", "openai", "Backend name in scuttlebot (gateway mode)") |
|
016a29f…
|
lmata
|
31 |
flag.Parse() |
|
016a29f…
|
lmata
|
32 |
|
|
016a29f…
|
lmata
|
33 |
if *pass == "" { |
|
016a29f…
|
lmata
|
34 |
fmt.Fprintln(os.Stderr, "error: --pass is required") |
|
016a29f…
|
lmata
|
35 |
os.Exit(1) |
|
016a29f…
|
lmata
|
36 |
} |
|
016a29f…
|
lmata
|
37 |
|
|
016a29f…
|
lmata
|
38 |
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) |
|
016a29f…
|
lmata
|
39 |
defer cancel() |
|
016a29f…
|
lmata
|
40 |
|
|
016a29f…
|
lmata
|
41 |
err := ircagent.Run(ctx, ircagent.Config{ |
|
016a29f…
|
lmata
|
42 |
IRCAddr: *ircAddr, |
|
016a29f…
|
lmata
|
43 |
Nick: *nick, |
|
016a29f…
|
lmata
|
44 |
Pass: *pass, |
|
016a29f…
|
lmata
|
45 |
Channels: ircagent.SplitCSV(*channels), |
|
016a29f…
|
lmata
|
46 |
SystemPrompt: systemPrompt, |
|
016a29f…
|
lmata
|
47 |
Logger: slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo})), |
|
016a29f…
|
lmata
|
48 |
Direct: &ircagent.DirectConfig{ |
|
016a29f…
|
lmata
|
49 |
Backend: "openai", |
|
016a29f…
|
lmata
|
50 |
APIKey: *apiKey, |
|
016a29f…
|
lmata
|
51 |
Model: *model, |
|
016a29f…
|
lmata
|
52 |
}, |
|
016a29f…
|
lmata
|
53 |
Gateway: &ircagent.GatewayConfig{ |
|
016a29f…
|
lmata
|
54 |
APIURL: *apiURL, |
|
016a29f…
|
lmata
|
55 |
Token: *token, |
|
016a29f…
|
lmata
|
56 |
Backend: *backend, |
|
016a29f…
|
lmata
|
57 |
}, |
|
016a29f…
|
lmata
|
58 |
}) |
|
016a29f…
|
lmata
|
59 |
if err != nil { |
|
016a29f…
|
lmata
|
60 |
fmt.Fprintln(os.Stderr, "error:", err) |
|
016a29f…
|
lmata
|
61 |
os.Exit(1) |
|
016a29f…
|
lmata
|
62 |
} |
|
016a29f…
|
lmata
|
63 |
} |