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/README.md +68 -53
- package/cli.js +379 -246
- package/onboarding-prompt.md +357 -0
- package/package.json +35 -27
- package/start.ps1 +128 -0
- package/start.sh +186 -0
- package/spawn-interactive.js +0 -51
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
|
package/spawn-interactive.js
DELETED
|
@@ -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
|
-
}
|