{"_id":"@cxy13h/ai-run-everywhere","_rev":"2-1b23ab8c5470cf9fdd8545a3dbc9ee84","name":"@cxy13h/ai-run-everywhere","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@cxy13h/ai-run-everywhere","version":"0.1.0","keywords":["ai","react","chat","vision","openai","image"],"license":"MIT","_id":"@cxy13h/ai-run-everywhere@0.1.0","maintainers":[{"name":"cxy13h","email":"cxy13h@gmail.com"}],"dist":{"shasum":"04dbebb7d77b8170dd67fa48ed299defc65da0ec","tarball":"https://registry.npmjs.org/@cxy13h/ai-run-everywhere/-/ai-run-everywhere-0.1.0.tgz","fileCount":9,"integrity":"sha512-RBW2FB8EOIbPKzJ16hKxsEeYEk9Wqtr6jZ3pZyZs3tx9qobocI3brx901oo15oPGNd8FMNy8um9J7ceyy0ZBYw==","signatures":[{"sig":"MEYCIQDPgVVfJzxDOsQ7rkCFGaUzICBemVLkB3WMVAjt9ccbsQIhAPAVpq9C+tvasbmWyD5H2uLVsleYAuIaG9crkwpYFbZE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108867},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"dev":"tsup --watch","build":"tsup","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"cxy13h","email":"cxy13h@gmail.com"},"_npmVersion":"11.6.2","description":"Plug-and-play React component: add AI chat to any <img> element.","directories":{},"_nodeVersion":"24.12.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ai-run-everywhere_0.1.0_1776883448177_0.11943423376280204","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@cxy13h/ai-run-everywhere","version":"0.1.1","description":"Plug-and-play React component: add AI chat to any <img> element.","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0"},"devDependencies":{"@types/react":"^18.2.0","@types/react-dom":"^18.2.0","react":"^18.2.0","react-dom":"^18.2.0","tsup":"^8.0.0","typescript":"^5.3.0"},"keywords":["ai","react","chat","vision","openai","image"],"license":"MIT","gitHead":"5ec645b1e15a39f2c66f982453df49b40b2315c3","_id":"@cxy13h/ai-run-everywhere@0.1.1","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-qnT+DUuB5b8DZxV9h1AB6SHiw3XRiB5vkibil73jRK5BkZhrm/Y5hoVCgXCRoA5/II2X18WZVG3TpHcqthStCg==","shasum":"bed6268be252bb5843f14eee455f3db07d2fda7f","tarball":"https://registry.npmjs.org/@cxy13h/ai-run-everywhere/-/ai-run-everywhere-0.1.1.tgz","fileCount":9,"unpackedSize":109147,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGSB0bfe3UrQhtrqGhSVd3K1ok7A6nh2qDEkKZalMrpjAiEA6gjRq1Ew24l27g29v0klgzCZOmGa92+S2Fa/K0fPysw="}]},"_npmUser":{"name":"cxy13h","email":"cxy13h@gmail.com"},"directories":{},"maintainers":[{"name":"cxy13h","email":"cxy13h@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ai-run-everywhere_0.1.1_1776886353925_0.2610875536738575"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-22T18:44:08.062Z","modified":"2026-04-22T19:32:34.170Z","0.1.0":"2026-04-22T18:44:08.312Z","0.1.1":"2026-04-22T19:32:34.074Z"},"license":"MIT","keywords":["ai","react","chat","vision","openai","image"],"description":"Plug-and-play React component: add AI chat to any <img> element.","maintainers":[{"name":"cxy13h","email":"cxy13h@gmail.com"}],"readme":"# ai-run-everywhere\n\n一个轻量级 React 组件，让你的 `<img>` 元素拥有 AI 对话能力。\n\n[English](./README.md)\n\n包裹任意图片后，右上角会出现一个悬浮按钮，点击即可弹出居中对话面板。用户输入问题后，组件自动提取图片内容发送给大模型，并实时流式展示回答。\n\n## 特性\n\n- **零运行时依赖** — React 作为 peerDependency，不引入任何第三方包\n- **样式完全隔离** — 选择器前缀 `ai-rew-*` + Portal 渲染 + `all: initial` 重置，不会污染宿主也不会被宿主污染\n- **流式输出** — 支持 SSE 流式响应，逐字实时展示回复\n- **跨域安全** — 通过 fetch + blob URL 提取图片，不触发 canvas taint\n- **配置灵活** — 全局配置一次，也可针对单个组件覆盖\n- **OpenAI 兼容** — 支持任何 OpenAI 兼容 API（通过自定义 baseUrl）\n- **ESM + CJS 双格式** — 适配所有主流打包工具\n\n## 安装\n\n```bash\nnpm install @cxy13h/ai-run-everywhere\n```\n\n## 快速上手\n\n### 第一步：全局配置\n\n在应用入口处挂载 `<AiProvider>`，设置 apiKey、baseUrl 和 model：\n\n```tsx\nimport { AiProvider, AiWrap } from \"@cxy13h/ai-run-everywhere\";\n\nfunction App() {\n  return (\n    <AiProvider\n      apiKey=\"sk-your-key\"\n      baseUrl=\"https://api.openai.com/v1\"\n      model=\"gpt-4o-mini\"\n    >\n      <MyPage />\n    </AiProvider>\n  );\n}\n```\n\n### 第二步：包裹图片\n\n在任意 `<img>` 外面包一层 `<AiWrap>`：\n\n```tsx\n<AiWrap>\n  <img src=\"/photo.jpg\" alt=\"产品图\" />\n</AiWrap>\n```\n\n点击右上角的星星按钮即可开始 AI 对话。\n\n### 第三步：单组件覆盖配置\n\n每个 `<AiWrap>` 都可以覆盖全局配置，只对该组件生效：\n\n```tsx\n// 这张图用更高级的模型\n<AiWrap model=\"gpt-4o\">\n  <img src=\"/detail.png\" alt=\"详情图\" />\n</AiWrap>\n\n// 这张图用完全不同的 API\n<AiWrap apiKey=\"sk-another\" baseUrl=\"https://my-proxy.com/v1\">\n  <img src=\"/another.jpg\" alt=\"另一张图\" />\n</AiWrap>\n```\n\n**配置优先级**：`<AiWrap>` props > `<AiProvider>` 全局配置 > 内置默认值\n\n## API 参考\n\n### `<AiProvider>`\n\n全局配置组件，在应用入口处挂载一次。\n\n| Prop | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `apiKey` | `string` | `\"\"` | API 密钥 |\n| `baseUrl` | `string` | `\"https://api.openai.com/v1\"` | OpenAI 兼容 API 地址 |\n| `model` | `string` | `\"gpt-4o-mini\"` | 模型名称 |\n| `systemPrompt` | `string` | 内置默认 | 系统提示词 |\n| `children` | `ReactNode` | — | 子组件 |\n\n### `<AiWrap>`\n\n包裹组件，在任意 `<img>` 外面包一层即可启用 AI 对话。\n\n| Prop | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `children` | `ReactNode` | — | 被包裹的 `<img>` 元素 |\n| `display` | `string` | `\"inline-block\"` | 包裹容器的 CSS display |\n| `className` | `string` | `\"\"` | 自定义 class |\n| `disabled` | `boolean` | `false` | 禁用触发按钮 |\n| `trigger` | `ReactNode` | 星星图标 | 自定义触发按钮内容 |\n| `tooltip` | `string` | `\"Ask AI\"` | 悬停提示文字 |\n| `apiKey` | `string` | — | 覆盖全局 API key |\n| `baseUrl` | `string` | — | 覆盖全局 baseUrl |\n| `model` | `string` | — | 覆盖全局 model |\n| `systemPrompt` | `string` | — | 覆盖全局 systemPrompt |\n\n## 环境变量配置示例（Vite 项目）\n\n```env\n# .env\nVITE_OPENAI_API_KEY=sk-your-key\nVITE_API_BASE_URL=https://api.openai.com/v1\nVITE_MODEL=gpt-4o-mini\n```\n\n```tsx\n<AiProvider\n  apiKey={import.meta.env.VITE_OPENAI_API_KEY}\n  baseUrl={import.meta.env.VITE_API_BASE_URL}\n  model={import.meta.env.VITE_MODEL}\n>\n  <App />\n</AiProvider>\n```\n\n## 样式隔离说明\n\n本包通过三重机制确保不影响宿主项目：\n\n1. **选择器前缀** — 所有 CSS 类名以 `ai-rew-` 开头，不会与宿主冲突\n2. **Portal 渲染** — 对话面板通过 `ReactDOM.createPortal` 挂载到 `document.body`，完全脱离宿主 DOM 树\n3. **`all: initial` 重置** — 面板内部先清除所有继承样式再重新设置，宿主的全局 CSS 不会渗入\n\n包裹容器仅设置 `position: relative` 和 `display`，不影响子元素布局。\n\n## 浏览器兼容性\n\n- Chrome 80+\n- Firefox 78+\n- Safari 14+\n- Edge 80+\n\n## License\n\nMIT\n","readmeFilename":"README.zh-CN.md"}