// npm 패키지
open-agents-ai
AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop
버전
1441
메인테이너
1
라이선스
CC-BY-NC-4.0
최초 publish
2026-03-10
publisher
robit
tarball
28,994,701 B
AUTO-PUBLISHED·1개 버전 인덱싱됨·최근 publish: 2026-05-14
// exfil path
what is read → where it shipssteals
- ● Telegram
sends to
(no destination string extracted — payload may be dynamic / obfuscated)
evidence in excerpt
> "websocket",
> }) : x)(function(x) {
> const { spawn, spawnSync } = require('node:child_process');
> const child = spawn(process.execPath, args, {
> var cp = require("child_process");// publisher 캠페인by robit
이 계정에서 catch된 패키지 2건고립된 catch가 아닙니다. 동일 publisher가 1개의 다른 패키지를 추가로 발행했고, 모두 파이프라인이 catch했습니다 — 일회성이 아닌 조직적 캠페인의 형태. 아래 링크는 각 형제 catch의 분석으로 이동합니다.
// offending code· @0.187.596· 3 files flagged
llm: benign · 0.85→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
- @0.187.596··AUTO-PUBLISHED·publisher: robitheuristic 80/100static flags 3llm benign (0.85) via ollamainstall-scripts:preinstall,postinstallnew-publisher:12dmature-packageai-agent-frameworkosv-flagged:MAL-2026-4628reads-telegram-dataeval-dynamicpy-pip-install-runtime
→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
// offending code· 3 files flaggedpatterns: 3
--- install scripts --- ### preinstall node dist/preinstall.cjs ### postinstall node dist/postinstall-daemon.cjs --- package/package.json (excerpt) --- { "name": "open-agents-ai", "version": "0.187.596", "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", "readmeFilename": "README.md", "bin": { "open-agents": "dist/launcher.cjs", "oa": "dist/launcher.cjs", "hdra": "dist/launcher.cjs", "hydra-ai": "dist/launcher.cjs" }, "files": [ "dist", "prompts", "voices", "npm-shrinkwrap.json", "README.md", "LICENSE" ], "keywords": [ "ai", "coding-agent", "ollama", "vllm", "open-source", "llm", "cli", "tool-calling", "agentic", "code-generation", "developer-tools", "tts", "voice", "onnx", "ocr", "pdf", "tesseract", "web-scraping", "crawlee", "playwright", "selenium", "browser-automation", "telegram", "telegram-bot", "daemon", "cloudflared", "voice-session", "whisper", "asr", "p2p", "peer-to-peer", "inference-network", "secret-vault", "websocket", "x402", "usdc", "eip-3009", "micropayments", "skill-builder", "factory-ai", "droid", "code-delegation", "mlx-audio", "apple-silicon", "kokoro-tts", "neovim", "embedded-editor" ], "author": "robit-man", "license": "CC-BY-NC-4.0", "scripts": { "preinstall": "node dist/preinstall.cjs", "po --- package/voices/personaplex/clone-voice.py (excerpt) --- #!/usr/bin/env python3 """ clone-voice.py — High-fidelity PersonaPlex voice cloning. Applies LuxTTS-inspired preprocessing before embedding extraction: 1. Resample to 24kHz mono 2. Noise reduction (spectral gating) 3. Silence trimming (energy-based VAD) 4. LUFS normalization to -20 dBFS (tuned for PersonaPlex) 5. Duration optimization (trim to 4-8s sweet spot) 6. Multi-segment embedding averaging for long clips Usage: python clone-voice.py --input voice.wav --name MyVoice [--device cuda] python clone-voice.py --input voice.wav --name MyVoice --segments 3 # multi-segment averaging """ import argparse import os import sys import logging import numpy as np logging.basicConfig(level=logging.INFO, format="%(message)s") log = logging.getLogger(__name__) # --------------------------------------------------------------------------- # Audio preprocessing (LuxTTS-inspired) # --------------------------------------------------------------------------- def preprocess_audio(input_path: str, target_sr: int = 24000, target_lufs: float = -20.0, min_duration: float = 2.0, max_duration: float = 8.0, denoise: bool = True) -> "torch.Tensor": """ Full preprocessing pipeline: 1. Load + resample to 24kHz mono 2. Noise reduction via spectral gating 3. Silence trimming (leading/trailing) 4. LUFS normalization 5. Duration clipping to sweet spot Returns: [ --- package/voices/personaplex/quantize-weights.py (excerpt) --- #!/usr/bin/env python3 """ quantize-weights.py — Quantize PersonaPlex 7B weights to INT4 (NF4) for edge devices. Creates a ~3.5GB quantized checkpoint from the ~14GB bf16 weights. The quantized model runs 3-4x faster on memory-bandwidth-limited devices like Jetson AGX Orin while maintaining voice quality. Usage: python quantize-weights.py [--device cuda] [--output personaplex-7b-nf4.safetensors] Requirements: pip install bitsandbytes safetensors torch """ import argparse import os import sys import logging logging.basicConfig(level=logging.INFO, format="%(message)s") log = logging.getLogger(__name__) def quantize_model(device: str = "cuda", output_path: str = None): """Quantize PersonaPlex 7B to NF4 (4-bit Normal Float)""" import torch from huggingface_hub import hf_hub_download from safetensors.torch import load_file, save_file hf_repo = "nvidia/personaplex-7b-v1" # 1) Download original weights log.info("Downloading PersonaPlex 7B weights...") weight_path = hf_hub_download(hf_repo, "model.safetensors") log.info(f" Weights: {weight_path}") log.info(f" Size: {os.path.getsize(weight_path) / 1024**3:.1f} GB") # 2) Load state dict log.info("Loading state dict...") state_dict = load_file(weight_path, device="cpu") log.info(f" Loaded {len(state_dict)} tensors") # 3) Quantize each weight tensor to INT4 using block-wise NF4 try: import bitsandbytes as bnb from bitsandbytes.functional imp --- bundled output (OSV-MAL flagged — LLM scope expansion) --- --- dist/index.d.ts (bundled) --- export { parseCliArgs, routeCommand } from "./types.js"; export type { ParsedCliArgs, CommandName } from "./types.js"; export { loadConfig, mergeConfig, setConfigValue, DEFAULT_CONFIG } from "./types.js"; export type { AgentConfig, BackendType } from "./types.js"; export { Spinner } from "./types.js"; export { printHeader, printSuccess, printError, printWarning, printInfo, printSection, printKeyValue, printBlank, printReport, formatDuration } from "./types.js"; --- dist/index.js (bundled) --- #!/usr/bin/env node import { createRequire as __oa_createRequire } from "node:module"; import { fileURLToPath as __oa_fileURLToPath } from "node:url"; import { dirname as __oa_dirname } from "node:path"; const require = __oa_createRequire(import.meta.url); const __filename = __oa_fileURLToPath(import.meta.url); const __dirname = __oa_dirname(__filename); var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a2, b) => (typeof require !== "undefined" ? require : a2)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod2) => function __require2() { return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; }; var __export = (target, all2) => { for (var name10 in all2) __defProp(target, name10, { get: all2[name10], enumerable: true }); }; var __copyProps = (to, from3, except, desc) => { if (from3 && typeof from3 === "object" || typeof from3 === "function") { for (let key of __getOwnPropNames(from3)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc(from3, key)) || desc.enumerable }); } return to; }; var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has bee --- dist/launcher.cjs (bundled) --- #!/usr/bin/env node // Robust launcher for open-agents CLI. // - Runs the ESM entry as a child process // - On exit code 120 (update), resets terminal and restarts child // - Prevents raw-mode/mouse-tracking bleedthrough on restart or crash const { spawn, spawnSync } = require('node:child_process'); const { resolve } = require('node:path'); function resetTerminal() { try { if (process.stdin.isTTY && typeof process.stdin.setRawMode === 'function') process.stdin.setRawMode(false); } catch {} // Disable mouse tracking, bracketed paste, show cursor, reset attrs, exit alt screen if active const ESC = '\x1B'; try { process.stdout.write( ESC + '[?25h' + // show cursor ESC + '[?1000l' + // X10 mouse off ESC + '[?1002l' + // button-event mouse off ESC + '[?1003l' + // any-event mouse off ESC + '[?1006l' + // SGR mouse off ESC + '[?1015l' + // urxvt mouse off ESC + '[?2004l' + // bracketed paste off ESC + '[?1049l' + // exit alt screen ESC + '[0m' // reset attributes ); } catch {} // stty sane (POSIX) if (process.platform !== 'win32' && process.stdin.isTTY) { try { spawnSync('stty', ['sane'], { stdio: 'inherit' }); } catch {} } } function runChild() { const entry = resolve(__dirname, 'index.js'); const args = [entry, ...process.argv.slice(2)]; const child = spawn(process.execPath, args, { stdio: 'inherit', env: process.env, }); return child; } (async () => { let restarts = 0; const MAX_RESTARTS = 3; let child = runChild(); const forward = (sig) => { try { child && child.kill(sig); } catch {} }; process.on('SIGINT', () => forward('SIGINT')); process.on('SIGTERM', () => forward('SIGTERM')); function attach(childProc) { childProc.on('exit', (code, signal) => { if (signal) { resetTerminal(); process.kill(process.pid, signal); --- dist/postinstall-daemon.cjs (bundled) --- #!/usr/bin/env node /* eslint-disable */ /** * postinstall-daemon.cjs — system-service installer for the OA API daemon. * * Runs after `npm install -g open-agents-ai`. Responsibilities: * 1. Clean up stale nexus daemon files (preserving prior postinstall behaviour). * 2. Register a per-user system service that runs `oa serve --daemon` * on port 11435, surviving reboots/logins. * Linux → ~/.config/systemd/user/open-agents-daemon.service * macOS → ~/Library/LaunchAgents/ai.open-agents.daemon.plist * Windows → Scheduled Task "OpenAgentsDaemon" (onlogon) * 3. Start (or restart) the service so the daemon is live IMMEDIATELY — * no need to launch `oa` in any terminal. * 4. Never exit non-zero. npm install must not fail because of a service * manager quirk or a permission quirk. We warn and move on. * * Opt-out: set env OA_SKIP_DAEMON_INSTALL=1 before `npm i -g`. * * ES5-safe pure CommonJS — runs on any Node version that survived preinstall. */ "use strict"; var os = require("os"); var path = require("path"); var fs = require("fs"); var cp = require("child_process"); var HOME = os.homedir(); var PLATFORM = os.platform(); // "linux", "darwin", "win32" var IS_WIN = PLATFORM === "win32"; var IS_MAC = PLATFORM === "darwin"; var IS_LINUX = PLATFORM === "linux"; var PORT = parseInt(process.env.OA_PORT || "11435", 10); var SERVICE_LABEL = "open-agents-daemon"; var LAUNCHD_LABEL = "ai.open-agents.daemon"; var WIN_TASK_NAME = "OpenAgentsDaemon"; // ─── Helpers ──────────────────────────────────────────────────────────────── function log(msg) { // Use stdout so npm captures it in the install log. process.stdout.write(" " + msg + "\n"); } function warn(msg) { process.stdout.write(" [daemon] " + msg + "\n"); } function runQuiet(cmd, opts) { try { cp.execSync(cmd, Object.assign({ stdio: "pipe", timeout: 15000 }, opts || {})); return true; } catch (e) { return false; } } function runCaptu --- dist/preinstall.cjs (bundled) --- #!/usr/bin/env node /* eslint-disable */ /** * preinstall — runs BEFORE npm replaces files on disk. Gracefully stops * the running OA daemon so the install window doesn't strand it with * a half-replaced binary that crashes on next relaunch. * * The postinstall hook restarts the daemon after install completes with * the new code in place. * * Opt-out: OA_SKIP_DAEMON_INSTALL=1 (matches postinstall semantics). */ "use strict"; if (process.env.OA_SKIP_DAEMON_INSTALL === "1") { process.exit(0); } var os = require("os"); var path = require("path"); var fs = require("fs"); var cp = require("child_process"); var IS_WIN = os.platform() === "win32"; var IS_LINUX = os.platform() === "linux"; var IS_MAC = os.platform() === "darwin"; var HOME = os.homedir(); var SERVICE_LABEL = "open-agents-daemon"; var LAUNCHD_LABEL = "ai.open-agents.daemon"; var WIN_TASK_NAME = "OpenAgentsDaemon"; function runQuiet(cmd) { try { cp.execSync(cmd, { stdio: "pipe", timeout: 8000 }); return true; } catch (e) { return false; } } function log(msg) { process.stdout.write(" [preinstall] " + msg + "\n"); } function stopServiceManager() { // Stop via the registered service manager if one exists. This is // graceful (sends SIGTERM, waits for exit) AND prevents the manager // from auto-restarting the daemon mid-install. try { if (IS_
