-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathruntime.go
More file actions
78 lines (71 loc) · 3.3 KB
/
runtime.go
File metadata and controls
78 lines (71 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package odek
import (
"fmt"
"os"
"runtime"
"time"
)
// BuildRuntimeContext returns a system prompt header with OS, hostname,
// working directory, current date/time, and platform-specific formatting
// rules for the given transport (platform). platform can be "telegram",
// "terminal", "web", or empty for generic.
//
// This context eliminates the need for the agent to run shell commands
// to discover its own environment — the most common waste of tokens in
// CLI agent usage.
func BuildRuntimeContext(platform string) string {
hostname, _ := os.Hostname()
cwd, _ := os.Getwd()
now := time.Now()
ctx := fmt.Sprintf(
"Host: %s (%s)\nUser home directory: %s\nCurrent working directory: %s\nDate: %s",
runtime.GOOS, hostname, os.Getenv("HOME"), cwd,
now.Format("Monday, January 2, 2006 15:04 MST"),
)
switch platform {
case "telegram":
// ═══ REASONING RULE (MANDATORY) — placed FIRST so LLM sees it immediately
telegramCtx := "## ⚡ REASONING RULE — FOLLOW THIS EXACTLY\n" +
"You MUST start your internal reasoning block with a brief " +
"user-facing explanation of what you are about to do.\n" +
"- This first sentence becomes the LIVE PROGRESS INDICATOR users see\n" +
"- Keep it under 20 words\n" +
"- Be specific, funny, and engaging when possible\n" +
"- Write it FOR THE USER, not for yourself\n" +
"\n" +
"✅ GOOD examples:\n" +
" \"Let me dig into that log file for clues...\"\n" +
" \"Alright, pulling the latest changes from git!\"\n" +
" \"One moment — running that test suite to check...\"\n" +
" \"Let me search the codebase for where that error hides...\"\n" +
"\n" +
"❌ BAD examples (too generic, no user value):\n" +
" \"I'll break this down step by step...\"\n" +
" \"Let me think about this problem...\"\n" +
" \"Okay, let me analyze what's needed here...\"\n" +
" \"First, I need to understand the request...\"\n" +
"\n" +
"VIOLATION CONSEQUENCE: If you write a generic self-directed first sentence, " +
"users see NOTHING useful while you work — they have no clue what is happening. " +
"The bot looks broken. Always start with a real explanation.\n\n" +
"Use the send_message tool to send intermediate messages, files (photo/document/voice), " +
"or interactive inline keyboard buttons (buttons parameter with cb: prefix). " +
"For final answers, just return the text directly — no need to use send_message."
// The caller (odek.New) prepends runtimeContext to systemMessage already.
ctx += telegramCtx
case "web":
ctx += "\n\nYou are running in a web UI. " +
"Responses are streamed to the browser via WebSocket in real-time — " +
"each reasoning step and tool call becomes visible as it happens. " +
"Markdown formatting (headings, lists, code blocks, bold, links) is " +
"fully rendered in the browser. Use visual elements like code blocks " +
"and structured lists. The user can reload the page or submit a new " +
"prompt at any time without losing context. Keep responses concise " +
"and visual — the user is reading in a browser."
case "terminal", "":
ctx += "\n\nYou are running in a terminal/CLI environment. " +
"Output is plain text with ANSI color codes. " +
"Keep responses concise — the user is at a shell prompt."
}
return ctx
}