evals 2.2.8 → 2.4.0

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.
package/start.sh ADDED
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Arize AX onboarding launcher.
4
+ #
5
+ # Lets you pick an installed coding agent and launches it seeded with the
6
+ # onboarding prompt to walk you through signup → instrument → first trace.
7
+ # This is the no-npm path; if you have Node, `npx evals` gives the same thing
8
+ # with a nicer UI.
9
+ #
10
+ # Run it (do NOT use `curl | bash` — that hijacks stdin and breaks the menu
11
+ # and the launched agent). Use process substitution so the menu and the agent
12
+ # both get a real terminal:
13
+ #
14
+ # bash <(curl -fsSL https://cdn.jsdelivr.net/npm/evals/start.sh)
15
+ #
16
+ # Non-interactive: ARIZE_AGENT=claude bash <(curl -fsSL .../start.sh)
17
+ # or: bash <(curl -fsSL .../start.sh) --agent claude
18
+
19
+ set -euo pipefail
20
+
21
+ # The prompt ships inside the public `evals` npm package; jsDelivr serves package
22
+ # files over HTTP, so it's fetchable even though the source repo is private.
23
+ # Override with ARIZE_PROMPT_URL if needed.
24
+ PROMPT_URL="${ARIZE_PROMPT_URL:-https://cdn.jsdelivr.net/npm/evals/onboarding-prompt.md}"
25
+
26
+ # Prefer the richer, bundled-prompt `npx evals` experience when Node is present.
27
+ # This shell script is the no-npm fallback; if npx exists, hand off to it.
28
+ # Set ARIZE_SKIP_NPX=1 to force this shell path even when npx is available.
29
+ if [ -z "${ARIZE_SKIP_NPX:-}" ] && command -v npx >/dev/null 2>&1; then
30
+ exec npx --yes evals
31
+ fi
32
+
33
+ # Supported agents: id | display label | argv to start the REPL seeded with a prompt.
34
+ # The seed prompt is appended as the final argument at launch.
35
+ AGENT_IDS=(claude codex cursor-agent copilot gemini)
36
+ agent_label() {
37
+ case "$1" in
38
+ claude) echo "Claude Code" ;;
39
+ codex) echo "OpenAI Codex" ;;
40
+ cursor-agent) echo "Cursor" ;;
41
+ copilot) echo "GitHub Copilot" ;;
42
+ gemini) echo "Gemini CLI" ;;
43
+ *) echo "$1" ;;
44
+ esac
45
+ }
46
+ agent_install_url() {
47
+ case "$1" in
48
+ claude) echo "https://docs.claude.com/en/docs/claude-code" ;;
49
+ codex) echo "https://developers.openai.com/codex/cli" ;;
50
+ cursor-agent) echo "https://docs.cursor.com/en/cli/overview" ;;
51
+ copilot) echo "https://github.com/features/copilot/cli" ;;
52
+ gemini) echo "https://github.com/google-gemini/gemini-cli" ;;
53
+ esac
54
+ }
55
+
56
+ # Parse --agent flag
57
+ AGENT="${ARIZE_AGENT:-}"
58
+ while [[ $# -gt 0 ]]; do
59
+ case "$1" in
60
+ --agent) AGENT="${2:-}"; shift 2 ;;
61
+ --agent=*) AGENT="${1#*=}"; shift ;;
62
+ -h|--help)
63
+ echo "Usage: start.sh [--agent <claude|codex|cursor-agent|copilot|gemini>]"
64
+ exit 0 ;;
65
+ *) echo "Unknown argument: $1" >&2; exit 1 ;;
66
+ esac
67
+ done
68
+
69
+ # --- Welcome ---
70
+ if [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then
71
+ _pink=$'\033[1;38;2;255;0;140m'; _dim=$'\033[2m'; _reset=$'\033[0m'
72
+ else
73
+ _pink=""; _dim=""; _reset=""
74
+ fi
75
+ printf '\n%sArize AX%s %s— Evals & Observability for Agentic AI%s\n\n' "$_pink" "$_reset" "$_dim" "$_reset"
76
+ printf "Let's get you tracing. I'll launch your coding agent with a guided prompt that\nwalks you through signup, instrumenting your app, and seeing your first traces.\n\n"
77
+
78
+ # Detect installed agents (PATH lookup only — never executes them).
79
+ DETECTED=()
80
+ for id in "${AGENT_IDS[@]}"; do
81
+ if command -v "$id" >/dev/null 2>&1; then
82
+ DETECTED+=("$id")
83
+ fi
84
+ done
85
+
86
+ # Resolve which agent to launch.
87
+ choose_agent() {
88
+ # Explicit choice wins if it's actually installed.
89
+ if [[ -n "$AGENT" ]]; then
90
+ if command -v "$AGENT" >/dev/null 2>&1; then
91
+ echo "$AGENT"; return 0
92
+ fi
93
+ echo "Requested agent '$AGENT' is not on your PATH." >&2
94
+ return 1
95
+ fi
96
+
97
+ if [[ ${#DETECTED[@]} -eq 0 ]]; then
98
+ echo "No supported coding agent found on your PATH." >&2
99
+ echo "Install one of these, then re-run:" >&2
100
+ for id in "${AGENT_IDS[@]}"; do
101
+ printf ' %-14s %s\n' "$(agent_label "$id")" "$(agent_install_url "$id")" >&2
102
+ done
103
+ return 1
104
+ fi
105
+
106
+ if [[ ${#DETECTED[@]} -eq 1 ]]; then
107
+ echo "${DETECTED[0]}"; return 0
108
+ fi
109
+
110
+ # Interactive menu — read from the real terminal, not the (piped) stdin.
111
+ if [[ ! -r /dev/tty ]]; then
112
+ echo "Multiple agents found but no terminal to prompt on. Set ARIZE_AGENT=<id>." >&2
113
+ return 1
114
+ fi
115
+ {
116
+ echo "Choose your coding agent:"
117
+ local i=1
118
+ for id in "${DETECTED[@]}"; do
119
+ printf ' %d) %s\n' "$i" "$(agent_label "$id")"
120
+ i=$((i + 1))
121
+ done
122
+ } >/dev/tty
123
+ local choice
124
+ while true; do
125
+ printf 'Enter a number [1-%d]: ' "${#DETECTED[@]}" >/dev/tty
126
+ read -r choice </dev/tty || return 1
127
+ if [[ "$choice" =~ ^[0-9]+$ ]] && (( choice >= 1 && choice <= ${#DETECTED[@]} )); then
128
+ echo "${DETECTED[$((choice - 1))]}"; return 0
129
+ fi
130
+ echo "Invalid choice." >/dev/tty
131
+ done
132
+ }
133
+
134
+ CHOSEN="$(choose_agent)" || exit 1
135
+
136
+ # Download the prompt to a temp file. (mktemp templates must end in X's on
137
+ # macOS, so add the .md extension afterwards.)
138
+ PROMPT_FILE="$(mktemp "${TMPDIR:-/tmp}/arize-onboarding-XXXXXX")"
139
+ mv "$PROMPT_FILE" "$PROMPT_FILE.md"
140
+ PROMPT_FILE="$PROMPT_FILE.md"
141
+ cleanup() { rm -f "$PROMPT_FILE"; }
142
+ trap cleanup EXIT
143
+
144
+ echo "Fetching the onboarding prompt…"
145
+ download_failed() {
146
+ echo "Failed to download the onboarding prompt from $PROMPT_URL" >&2
147
+ echo "Check your connection and try again." >&2
148
+ exit 1
149
+ }
150
+ if command -v curl >/dev/null 2>&1; then
151
+ curl -fsSL "$PROMPT_URL" -o "$PROMPT_FILE" || download_failed
152
+ elif command -v wget >/dev/null 2>&1; then
153
+ wget -qO "$PROMPT_FILE" "$PROMPT_URL" || download_failed
154
+ else
155
+ echo "Need curl or wget to download the prompt." >&2
156
+ exit 1
157
+ fi
158
+
159
+ SEED="Read the file $PROMPT_FILE and follow it to set up Arize AX tracing in this project, walking me through each step and asking me questions as needed."
160
+
161
+ echo "Launching $(agent_label "$CHOSEN")…"
162
+ echo
163
+
164
+ # Launch interactive + seeded, on the real terminal. No skip-permissions —
165
+ # the agent's approval model and the prompt's own approval gate must stay intact.
166
+ # Run as a child (not exec) so the EXIT trap cleans up the temp prompt file.
167
+ run_agent() {
168
+ case "$CHOSEN" in
169
+ copilot|gemini) "$CHOSEN" -i "$SEED" ;;
170
+ *) "$CHOSEN" "$SEED" ;;
171
+ esac
172
+ }
173
+
174
+ # Prefer inheriting stdin: TUI agents (e.g. codex/crossterm) need a read-write
175
+ # terminal on fd 0. A `< /dev/tty` redirect opens fd 0 read-only and makes
176
+ # crossterm panic ("reader source not set"). Only reach for /dev/tty when stdin
177
+ # isn't already a terminal (the discouraged `curl | bash`), and open it
178
+ # read-write with `<>`.
179
+ if [ -t 0 ]; then
180
+ run_agent
181
+ elif [ -r /dev/tty ]; then
182
+ run_agent <>/dev/tty
183
+ else
184
+ echo "No interactive terminal available to launch the agent." >&2
185
+ exit 1
186
+ fi
@@ -1,51 +0,0 @@
1
- import { spawn } from 'child_process';
2
- import { openSync } from 'fs';
3
-
4
- function tryOpenTTY() {
5
- if (process.platform === 'win32') {
6
- // On Windows, avoid CON device (issues in Node.js 22)
7
- // Use isTTY check instead, and stdio: 'inherit' for spawning
8
- if (process.stdin.isTTY && process.stdout.isTTY && process.stderr.isTTY) {
9
- return { available: true, useInherit: true };
10
- }
11
- return { available: false };
12
- } else {
13
- // On macOS/Linux, use direct /dev/tty access
14
- try {
15
- const device = '/dev/tty';
16
- openSync(device, 'r');
17
- return { device, available: true, useInherit: false };
18
- } catch (err) {
19
- return { available: false };
20
- }
21
- }
22
- }
23
-
24
- const tty = tryOpenTTY();
25
-
26
- if (tty.available) {
27
- const spawnOptions = tty.useInherit
28
- ? { stdio: 'inherit', shell: true }
29
- : {
30
- stdio: [
31
- openSync(tty.device, 'r'),
32
- openSync(tty.device, 'w'),
33
- openSync(tty.device, 'w')
34
- ]
35
- };
36
-
37
- const child = spawn('node', ['./cli.js'], spawnOptions);
38
-
39
- child.on('close', (code) => {
40
- process.exit(code || 0);
41
- });
42
-
43
- child.on('error', (err) => {
44
- console.error('Failed to start interactive CLI:', err.message);
45
- console.log('Run `npx evals` to complete setup.');
46
- // process.exit(1);
47
- });
48
- } else {
49
- console.log('Run `npx evals` to complete setup.');
50
- // process.exit(1);
51
- }