Showing preview only (1,874K chars total). Download the full file or copy to clipboard to get everything.
Repository: s-zx/edgeFlow.js
Branch: main
Commit: ba87394114d1
Files: 179
Total size: 1.7 MB
Directory structure:
gitextract_2xh90dxw/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── pull_request_template.md
│ └── workflows/
│ ├── ci.yml
│ └── publish.yml
├── .gitignore
├── CLAUDE.md
├── CONTRIBUTING.md
├── README.md
├── README_CN.md
├── benchmarks/
│ └── README.md
├── demo/
│ ├── demo.js
│ ├── index.html
│ ├── server.js
│ └── styles.css
├── dist/
│ ├── backends/
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── onnx.d.ts
│ │ ├── onnx.js
│ │ ├── transformers-adapter.d.ts
│ │ ├── transformers-adapter.js
│ │ ├── wasm.d.ts
│ │ ├── wasm.js
│ │ ├── webgpu.d.ts
│ │ ├── webgpu.js
│ │ ├── webnn.d.ts
│ │ └── webnn.js
│ ├── core/
│ │ ├── composer.d.ts
│ │ ├── composer.js
│ │ ├── device-profiler.d.ts
│ │ ├── device-profiler.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── memory.d.ts
│ │ ├── memory.js
│ │ ├── plugin.d.ts
│ │ ├── plugin.js
│ │ ├── runtime.d.ts
│ │ ├── runtime.js
│ │ ├── scheduler.d.ts
│ │ ├── scheduler.js
│ │ ├── tensor.d.ts
│ │ ├── tensor.js
│ │ ├── types.d.ts
│ │ ├── types.js
│ │ ├── worker.d.ts
│ │ └── worker.js
│ ├── edgeflow.browser.js
│ ├── index.d.ts
│ ├── index.js
│ ├── pipelines/
│ │ ├── automatic-speech-recognition.d.ts
│ │ ├── automatic-speech-recognition.js
│ │ ├── base.d.ts
│ │ ├── base.js
│ │ ├── feature-extraction.d.ts
│ │ ├── feature-extraction.js
│ │ ├── image-classification.d.ts
│ │ ├── image-classification.js
│ │ ├── image-segmentation.d.ts
│ │ ├── image-segmentation.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── object-detection.d.ts
│ │ ├── object-detection.js
│ │ ├── question-answering.d.ts
│ │ ├── question-answering.js
│ │ ├── text-classification.d.ts
│ │ ├── text-classification.js
│ │ ├── text-generation.d.ts
│ │ ├── text-generation.js
│ │ ├── zero-shot-classification.d.ts
│ │ └── zero-shot-classification.js
│ ├── tools/
│ │ ├── benchmark.d.ts
│ │ ├── benchmark.js
│ │ ├── debugger.d.ts
│ │ ├── debugger.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── monitor.d.ts
│ │ ├── monitor.js
│ │ ├── quantization.d.ts
│ │ └── quantization.js
│ └── utils/
│ ├── cache.d.ts
│ ├── cache.js
│ ├── hub.d.ts
│ ├── hub.js
│ ├── index.d.ts
│ ├── index.js
│ ├── model-loader.d.ts
│ ├── model-loader.js
│ ├── offline.d.ts
│ ├── offline.js
│ ├── preprocessor.d.ts
│ ├── preprocessor.js
│ ├── tokenizer.d.ts
│ └── tokenizer.js
├── docs/
│ ├── .vitepress/
│ │ └── config.ts
│ ├── api/
│ │ ├── model-loader.md
│ │ ├── pipeline.md
│ │ ├── tensor.md
│ │ └── tokenizer.md
│ ├── cookbook/
│ │ ├── composition.md
│ │ └── transformers-adapter.md
│ ├── guide/
│ │ ├── architecture.md
│ │ ├── concepts.md
│ │ ├── device-profiling.md
│ │ ├── installation.md
│ │ ├── plugins.md
│ │ └── quickstart.md
│ ├── index.md
│ └── tutorials/
│ └── text-classification.md
├── examples/
│ ├── basic-usage.ts
│ ├── multi-model-dashboard/
│ │ └── index.html
│ ├── offline-notepad/
│ │ └── index.html
│ └── orchestration.ts
├── package.json
├── playwright.config.ts
├── scripts/
│ └── build-browser.js
├── src/
│ ├── backends/
│ │ ├── index.ts
│ │ ├── onnx.ts
│ │ ├── transformers-adapter.ts
│ │ ├── wasm.ts
│ │ ├── webgpu.ts
│ │ └── webnn.ts
│ ├── core/
│ │ ├── composer.ts
│ │ ├── device-profiler.ts
│ │ ├── index.ts
│ │ ├── memory.ts
│ │ ├── plugin.ts
│ │ ├── runtime.ts
│ │ ├── scheduler.ts
│ │ ├── tensor.ts
│ │ ├── types.ts
│ │ └── worker.ts
│ ├── index.ts
│ ├── pipelines/
│ │ ├── automatic-speech-recognition.ts
│ │ ├── base.ts
│ │ ├── feature-extraction.ts
│ │ ├── image-classification.ts
│ │ ├── image-segmentation.ts
│ │ ├── index.ts
│ │ ├── object-detection.ts
│ │ ├── question-answering.ts
│ │ ├── text-classification.ts
│ │ ├── text-generation.ts
│ │ └── zero-shot-classification.ts
│ ├── tools/
│ │ ├── benchmark.ts
│ │ ├── debugger.ts
│ │ ├── index.ts
│ │ ├── monitor.ts
│ │ └── quantization.ts
│ └── utils/
│ ├── cache.ts
│ ├── hub.ts
│ ├── index.ts
│ ├── model-loader.ts
│ ├── offline.ts
│ ├── preprocessor.ts
│ └── tokenizer.ts
├── tests/
│ ├── e2e/
│ │ ├── browser.spec.ts
│ │ ├── browser.test.ts
│ │ ├── localai-10s-check.spec.ts
│ │ ├── localai-clear-cache-load.spec.ts
│ │ ├── localai-knowledge-base.spec.ts
│ │ ├── localai-load-models.spec.ts
│ │ ├── localai-loading-check.spec.ts
│ │ ├── localai-network-audit.spec.ts
│ │ ├── localai-network-failures.spec.ts
│ │ └── localai-network-full.spec.ts
│ ├── integration/
│ │ └── pipeline.test.ts
│ └── unit/
│ ├── memory.test.ts
│ ├── model-loader.test.ts
│ ├── runtime.test.ts
│ ├── scheduler.test.ts
│ ├── tensor.test.ts
│ ├── tokenizer.test.ts
│ └── worker.test.ts
├── tsconfig.json
├── vercel.json
└── vitest.config.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Report a bug to help improve edgeFlow.js
title: '[Bug] '
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Import '...'
2. Call '...'
3. See error
**Expected behavior**
A clear description of what you expected to happen.
**Code sample**
```typescript
// Minimal reproduction
```
**Environment**
- Browser: [e.g. Chrome 120, Firefox 118]
- OS: [e.g. macOS 14, Windows 11]
- edgeFlow.js version: [e.g. 0.1.0]
- Runtime: [e.g. WebGPU, WASM]
**Additional context**
Any other context about the problem.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest a feature for edgeFlow.js
title: '[Feature] '
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem?**
A clear description of the problem. Ex. "I'm always frustrated when..."
**Describe the solution you'd like**
A clear description of what you want to happen.
**Describe alternatives you've considered**
Any alternative solutions or features you've considered.
**Additional context**
Any other context, code examples, or screenshots.
================================================
FILE: .github/pull_request_template.md
================================================
## Summary
Brief description of the changes.
## Motivation
Why is this change needed?
## Changes
- Change 1
- Change 2
## Testing
- [ ] Unit tests pass (`npm run test:unit`)
- [ ] TypeScript compiles (`npx tsc --noEmit`)
- [ ] Lint passes (`npm run lint`)
- [ ] Tested in browser (if applicable)
## Breaking Changes
List any breaking changes, or "None".
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-and-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run lint
- run: npx tsc --noEmit
test:
runs-on: ubuntu-latest
needs: lint-and-typecheck
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run test:unit
- run: npm run test:coverage
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-report
path: coverage/
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish to npm
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
registry-url: https://registry.npmjs.org
- run: npm ci
- run: npm run build
- run: npm run test:unit
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
================================================
FILE: .gitignore
================================================
# Dependencies
node_modules/
# Build outputs (keep dist/ for npm publishing)
# dist/
# IDE
.idea/
.vscode/
*.swp
*.swo
.DS_Store
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Test coverage
coverage/
# Playwright / E2E test output
test-results/
# Environment
.env
.env.local
.env.*.local
# TypeScript cache
*.tsbuildinfo
# Temporary files
tmp/
temp/
.tmp/
.temp/
.vercel
.env*.local
# Personal docs (not for public repo)
INTERVIEW_PREP.md
================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
- **Build:** `npm run build` (runs `tsc` then `scripts/build-browser.js` which produces `dist/edgeflow.browser.js` via esbuild; `onnxruntime-web` is marked external).
- **Watch compile:** `npm run dev`
- **Lint:** `npm run lint` (ESLint on `src/**/*.ts`)
- **Unit/integration tests (vitest, happy-dom):** `npm test` / `npm run test:unit` / `npm run test:integration`
- Single test file: `npx vitest run tests/unit/tokenizer.test.ts`
- Single test by name: `npx vitest run -t "test name pattern"`
- **E2E (Playwright, Chromium):** `npm run test:e2e`
- Uses `playwright.config.ts` by default; alternate configs exist for `localai`, `network`, `privatedoc` scenarios (run with `npx playwright test -c playwright.localai.config.ts`).
- Playwright auto-starts `npm run demo:server` on `localhost:3000`.
- **Demo app:** `npm run demo` (builds then serves `demo/server.js` on port 3000). Load a Hugging Face ONNX URL in the browser UI to exercise pipelines.
- **Docs (VitePress):** `npm run docs:dev` / `npm run docs:build`
## Architecture
edgeFlow.js is a browser-first ML inference framework. The runtime graph is: **Pipeline → BasePipeline → RuntimeManager → Runtime backend (ONNX/WebGPU/WebNN/WASM) → Scheduler → MemoryManager**. All public exports flow through `src/index.ts`.
### Layered structure (`src/`)
- **`core/`** — framework internals. `types.ts` is the canonical type/error surface (`EdgeFlowError`, `ErrorCodes`, all `Tensor`/`Runtime`/`Pipeline` interfaces — most other files import from here). `runtime.ts` holds the `RuntimeManager` singleton, runtime factory registry, and priority-based automatic backend selection (webgpu > webnn > wasm). `scheduler.ts` implements the global priority queue / concurrency-limited `InferenceScheduler` that every runtime dispatches through. `memory.ts` provides `MemoryManager`, `MemoryScope`, and `ModelCache` with reference-counted cleanup. `composer.ts` enables `compose()`/`parallel()` multi-stage pipelines. `plugin.ts` is the extension point for third-party pipelines/backends/middleware. `device-profiler.ts` recommends quantization/model variant based on device tier. `worker.ts` runs inference in a Web Worker.
- **`backends/`** — concrete `Runtime` implementations: `onnx.ts` (onnxruntime-web, peer dep), `webgpu.ts`, `webnn.ts`, `wasm.ts`, plus `transformers-adapter.ts` for interop with transformers.js. `registerAllBackends()` wires factories into `RuntimeManager`.
- **`pipelines/`** — task-specific wrappers extending `base.ts`'s `BasePipeline`. The `pipeline(task, options?)` factory in `index.ts` looks up a registered pipeline factory (built-in or plugin) and returns a ready-to-run instance. Each pipeline owns its own tokenizer/preprocessor, model loading, and result formatting.
- **`utils/`** — `tokenizer.ts` (BPE, WordPiece, Unigram — loads `tokenizer.json` directly), `preprocessor.ts` (image/audio/text), `model-loader.ts` (preloading, sharding, resumable downloads), `cache.ts` (`InferenceCache`, `ModelDownloadCache` — IndexedDB-backed), `hub.ts` (HuggingFace Hub download helpers + `POPULAR_MODELS`), `offline.ts`.
- **`tools/`** — developer tooling surface: `quantization.ts` (int8/uint8/float16 quant + dequant), `debugger.ts` (tensor inspection, histograms, heatmaps, trace events), `monitor.ts` (`PerformanceMonitor` + dashboard generators), `benchmark.ts`.
### Cross-cutting conventions
- **ESM only** (`"type": "module"`, `sideEffects: false`). All intra-repo imports use `.js` extensions even from `.ts` source — required for Node ESM resolution after `tsc` emits.
- **`onnxruntime-web` is an optional peer dep** marked `external` in the browser bundle; consumer bundlers resolve it. Do not import it eagerly in code paths that should run without ONNX.
- **Errors always use `EdgeFlowError` + `ErrorCodes`** from `core/types.ts` — do not throw bare `Error` from library code.
- **Scheduling is mandatory:** runtime inference paths go through `getScheduler()`. New backends should dispatch via the scheduler rather than calling model.run directly, so priority/concurrency controls are honored.
- **Tests:** unit/integration run under happy-dom (no real WebGPU/WebNN); those backends are exercised via Playwright E2E against the demo server. Test timeout is 30s.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to edgeFlow.js
Thank you for your interest in contributing to edgeFlow.js! This guide will help you get started.
## Development Setup
```bash
# Clone the repository
git clone https://github.com/s-zx/edgeflow.js.git
cd edgeflow.js
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm run test:unit
# Start development mode (watch)
npm run dev
```
## Project Structure
```
src/
├── core/ # Runtime, scheduler, memory, tensor, types
├── backends/ # ONNX Runtime (production), WebGPU/WebNN (planned)
├── pipelines/ # Task pipelines (text-generation, image-segmentation, etc.)
├── utils/ # Tokenizer, preprocessor, cache, model-loader, hub
└── tools/ # Quantization, benchmark, debugger, monitor
```
## How to Contribute
### Reporting Bugs
Open an issue using the bug report template. Include:
- A minimal code reproduction
- Browser and OS information
- edgeFlow.js version
### Suggesting Features
Open an issue using the feature request template describing:
- The problem you're trying to solve
- Your proposed solution
- Alternatives you've considered
### Submitting Code
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/my-feature`
3. Make your changes
4. Run checks: `npm run lint && npx tsc --noEmit && npm run test:unit`
5. Commit with a descriptive message
6. Push and open a pull request
### Good First Issues
Look for issues labeled `good first issue`. These are scoped tasks ideal for newcomers:
- Adding tests for uncovered modules
- Improving error messages
- Adding examples
- Documentation improvements
## Code Standards
- **TypeScript strict mode** — all strict options are enabled
- **No `any`** — use proper types; `unknown` if truly dynamic
- **ESM only** — use `.js` extensions in imports
- **No console.log in library code** — use the event system or `console.warn` for important warnings
- **Dispose pattern** — all resources must be disposable to prevent memory leaks
## Testing
```bash
npm run test:unit # Run unit tests
npm run test:integration # Run integration tests
npm run test:coverage # Generate coverage report
npm run test:watch # Watch mode
```
Tests use [Vitest](https://vitest.dev/). Place tests in:
- `tests/unit/` — for isolated unit tests
- `tests/integration/` — for pipeline/backend integration tests
- `tests/e2e/` — for browser-based tests
## Architecture Decisions
edgeFlow.js is designed as an **orchestration layer**, not an inference engine. Key principles:
1. **Backend agnostic** — work with any inference engine (ONNX Runtime, transformers.js, custom)
2. **Production-first** — scheduling, memory management, error recovery matter more than model count
3. **Honest API** — experimental features are clearly labeled, not presented as production-ready
4. **Plugin-friendly** — custom pipelines and backends can be registered at runtime
## License
By contributing, you agree that your contributions will be licensed under the MIT License.
================================================
FILE: README.md
================================================
# edgeFlow.js
<div align="center">
**Browser ML inference framework with task scheduling and smart caching.**
[](https://www.npmjs.com/package/edgeflowjs)
[](https://packagephobia.com/result?p=edgeflowjs)
[](LICENSE)
[Documentation](https://edgeflow.js.org) · [Examples](examples/) · [API Reference](https://edgeflow.js.org/api) · [English](README.md) | [中文](README_CN.md)
</div>
---
## ✨ Features
- 📋 **Task Scheduler** - Priority queue, concurrency control, task cancellation
- 🔄 **Batch Processing** - Efficient batch inference out of the box
- 💾 **Memory Management** - Automatic memory tracking and cleanup with scopes
- 📥 **Smart Model Loading** - Preloading, sharding, resume download support
- 💿 **Offline Caching** - IndexedDB-based model caching for offline use
- ⚡ **Multi-Backend** - ONNX Runtime with WebGPU/WASM execution providers, automatic fallback
- 🤗 **HuggingFace Hub** - Direct model download with one line
- 🔤 **Real Tokenizers** - BPE & WordPiece tokenizers, load tokenizer.json directly
- 👷 **Web Worker Support** - Run inference in background threads
- 📦 **Batteries Included** - ONNX Runtime bundled, zero configuration needed
- 🎯 **TypeScript First** - Full type support with intuitive APIs
## 📦 Installation
```bash
npm install edgeflowjs
```
```bash
yarn add edgeflowjs
```
```bash
pnpm add edgeflowjs
```
> **Note**: ONNX Runtime is included as a dependency. No additional setup required.
## 🚀 Quick Start
### Try the Demo
Run the interactive demo locally to test all features:
```bash
# Clone and install
git clone https://github.com/user/edgeflow.js.git
cd edgeflow.js
npm install
# Build and start demo server
npm run demo
```
Open **http://localhost:3000** in your browser:
1. **Load Model** - Enter a Hugging Face ONNX model URL and click "Load Model"
```
https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/onnx/model_quantized.onnx
```
2. **Test Features**:
- 🧮 **Tensor Operations** - Test tensor creation, math ops, softmax, relu
- 📝 **Text Classification** - Run sentiment analysis on text
- 🔍 **Feature Extraction** - Extract embeddings from text
- ⚡ **Task Scheduling** - Test priority-based scheduling
- 📋 **Task Scheduler** - Test priority-based task scheduling
- 💾 **Memory Management** - Test allocation and cleanup
### Basic Usage
```typescript
import { pipeline } from 'edgeflowjs';
// Create a sentiment analysis pipeline
const sentiment = await pipeline('sentiment-analysis');
// Run inference
const result = await sentiment.run('I love this product!');
console.log(result);
// { label: 'positive', score: 0.98, processingTime: 12.5 }
```
### Batch Processing
```typescript
// Native batch processing support
const results = await sentiment.run([
'This is amazing!',
'This is terrible.',
'It\'s okay I guess.'
]);
console.log(results);
// [
// { label: 'positive', score: 0.95 },
// { label: 'negative', score: 0.92 },
// { label: 'neutral', score: 0.68 }
// ]
```
### Multiple Pipelines
```typescript
import { pipeline } from 'edgeflowjs';
// Create multiple pipelines
const classifier = await pipeline('text-classification');
const extractor = await pipeline('feature-extraction');
// Run in parallel with Promise.all
const [classification, features] = await Promise.all([
classifier.run('Sample text'),
extractor.run('Sample text')
]);
```
### Image Classification
```typescript
import { pipeline } from 'edgeflowjs';
const classifier = await pipeline('image-classification');
// From URL
const result = await classifier.run('https://example.com/image.jpg');
// From HTMLImageElement
const img = document.getElementById('myImage');
const result = await classifier.run(img);
// Batch
const results = await classifier.run([img1, img2, img3]);
```
### Text Generation (Streaming)
```typescript
import { pipeline } from 'edgeflowjs';
const generator = await pipeline('text-generation');
// Simple generation
const result = await generator.run('Once upon a time', {
maxNewTokens: 50,
temperature: 0.8,
});
console.log(result.generatedText);
// Streaming output
for await (const event of generator.stream('Hello, ')) {
process.stdout.write(event.token);
if (event.done) break;
}
```
### Zero-shot Classification
```typescript
import { pipeline } from 'edgeflowjs';
const classifier = await pipeline('zero-shot-classification');
const result = await classifier.classify(
'I love playing soccer on weekends',
['sports', 'politics', 'technology', 'entertainment']
);
console.log(result.labels[0], result.scores[0]);
// 'sports', 0.92
```
### Question Answering
```typescript
import { pipeline } from 'edgeflowjs';
const qa = await pipeline('question-answering');
const result = await qa.run({
question: 'What is the capital of France?',
context: 'Paris is the capital and largest city of France.'
});
console.log(result.answer); // 'Paris'
```
### Load from HuggingFace Hub
```typescript
import { fromHub, fromTask } from 'edgeflowjs';
// Load by model ID (auto-downloads model, tokenizer, config)
const bundle = await fromHub('Xenova/distilbert-base-uncased-finetuned-sst-2-english');
console.log(bundle.tokenizer); // Tokenizer instance
console.log(bundle.config); // Model config
// Load by task name (uses recommended model)
const sentimentBundle = await fromTask('sentiment-analysis');
```
### Web Workers (Background Inference)
```typescript
import { runInWorker, WorkerPool, isWorkerSupported } from 'edgeflowjs';
// Simple: run inference in background thread
if (isWorkerSupported()) {
const outputs = await runInWorker(modelUrl, inputs);
}
// Advanced: use worker pool for parallel processing
const pool = new WorkerPool({ numWorkers: 4 });
await pool.init();
const modelId = await pool.loadModel(modelUrl);
const results = await pool.runBatch(modelId, batchInputs);
pool.terminate();
```
## 🎯 Supported Tasks
| Task | Pipeline | Status |
|------|----------|--------|
| Text Generation | `text-generation` | ✅ Production (TinyLlama, streaming, KV cache) |
| Image Segmentation | `image-segmentation` | ✅ Production (SlimSAM, interactive prompts) |
| Text Classification | `text-classification` | ⚠️ Experimental (heuristic, provide own model) |
| Sentiment Analysis | `sentiment-analysis` | ⚠️ Experimental (heuristic, provide own model) |
| Feature Extraction | `feature-extraction` | ⚠️ Experimental (mock embeddings, provide own model) |
| Image Classification | `image-classification` | ⚠️ Experimental (heuristic, provide own model) |
| Object Detection | `object-detection` | ⚠️ Experimental (real NMS/IoU, needs own model) |
| Speech Recognition | `automatic-speech-recognition` | ⚠️ Experimental (preprocessing only, needs model) |
| Zero-shot Classification | `zero-shot-classification` | ⚠️ Experimental (random scoring, needs NLI model) |
| Question Answering | `question-answering` | ⚠️ Experimental (word overlap heuristic, needs model) |
> **Note:** Experimental pipelines work for demos and testing the API surface. For production accuracy, provide a real ONNX model via `options.model` or use the **transformers.js adapter backend** to leverage HuggingFace's model ecosystem.
## ⚡ Key Differentiators
edgeFlow.js is not a replacement for transformers.js — it is a **production orchestration layer** that can wrap any inference engine (including transformers.js) and add the features real apps need.
### What edgeFlow.js adds on top of inference engines
| Feature | Inference engines alone | With edgeFlow.js |
|---------|------------------------|------------------|
| Task Scheduling | None — run and hope | Priority queue with concurrency limits |
| Task Cancellation | Not possible | Cancel pending/queued tasks |
| Batch Processing | Manual | Built-in batching with configurable size |
| Memory Management | Manual cleanup | Automatic scopes, leak detection, GC hints |
| Model Preloading | Manual | Background preloading with priority queue |
| Resume Download | Start over on failure | Chunked download with automatic resume |
| Model Caching | Basic or none | IndexedDB cache with stats and eviction |
| Pipeline Composition | Not available | Chain multiple models (ASR → translate → TTS) |
| Device Adaptation | Manual model selection | Auto-select model variant by device capability |
| Performance Monitoring | External tooling needed | Built-in dashboard and alerting |
## 🔌 transformers.js Adapter (Recommended)
Use edgeFlow.js as an orchestration layer on top of [transformers.js](https://huggingface.co/docs/transformers.js) to get access to 1000+ HuggingFace models with scheduling, caching, and memory management:
```typescript
import { pipeline as tfPipeline } from '@xenova/transformers';
import { useTransformersBackend, pipeline } from 'edgeflowjs';
// Register transformers.js as the inference backend
useTransformersBackend({
pipelineFactory: tfPipeline,
device: 'webgpu', // GPU acceleration
dtype: 'fp16', // Half precision
});
// Use edgeFlow.js API — scheduling, caching, memory management included
const classifier = await pipeline('text-classification', {
model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
});
const result = await classifier.run('I love this product!');
```
> **Why?** transformers.js is excellent at loading and running single models. edgeFlow.js adds the production features you need when running multiple models, managing memory on constrained devices, caching for offline use, and scheduling concurrent inference.
## 🔧 Configuration
### Runtime Selection
```typescript
import { pipeline } from 'edgeflowjs';
// Automatic (recommended)
const model = await pipeline('text-classification');
// Specify runtime
const model = await pipeline('text-classification', {
runtime: 'webgpu' // or 'webnn', 'wasm', 'auto'
});
```
### Memory Management
```typescript
import { pipeline, getMemoryStats, gc } from 'edgeflowjs';
const model = await pipeline('text-classification');
// Use the model
await model.run('text');
// Check memory usage
console.log(getMemoryStats());
// { allocated: 50MB, used: 45MB, peak: 52MB, tensorCount: 12 }
// Explicit cleanup
model.dispose();
// Force garbage collection
gc();
```
### Scheduler Configuration
```typescript
import { configureScheduler } from 'edgeflowjs';
configureScheduler({
maxConcurrentTasks: 4,
maxConcurrentPerModel: 1,
defaultTimeout: 30000,
enableBatching: true,
maxBatchSize: 32,
});
```
### Caching
```typescript
import { pipeline, Cache } from 'edgeflowjs';
// Create a cache
const cache = new Cache({
strategy: 'lru',
maxSize: 100 * 1024 * 1024, // 100MB
persistent: true, // Use IndexedDB
});
const model = await pipeline('text-classification', {
cache: true
});
```
## 🛠️ Advanced Usage
### Custom Model Loading
```typescript
import { loadModel, runInference } from 'edgeflowjs';
// Load from URL with caching, sharding, and resume support
const model = await loadModel('https://example.com/model.bin', {
runtime: 'webgpu',
quantization: 'int8',
cache: true, // Enable IndexedDB caching (default: true)
resumable: true, // Enable resume download (default: true)
chunkSize: 5 * 1024 * 1024, // 5MB chunks for large models
onProgress: (progress) => console.log(`Loading: ${progress * 100}%`)
});
// Run inference
const outputs = await runInference(model, inputs);
// Cleanup
model.dispose();
```
### Preloading Models
```typescript
import { preloadModel, preloadModels, getPreloadStatus } from 'edgeflowjs';
// Preload a single model in background (with priority)
preloadModel('https://example.com/model1.onnx', { priority: 10 });
// Preload multiple models
preloadModels([
{ url: 'https://example.com/model1.onnx', priority: 10 },
{ url: 'https://example.com/model2.onnx', priority: 5 },
]);
// Check preload status
const status = getPreloadStatus('https://example.com/model1.onnx');
// 'pending' | 'loading' | 'complete' | 'error' | 'not_found'
```
### Model Caching
```typescript
import {
isModelCached,
getCachedModel,
deleteCachedModel,
clearModelCache,
getModelCacheStats
} from 'edgeflowjs';
// Check if model is cached
if (await isModelCached('https://example.com/model.onnx')) {
console.log('Model is cached!');
}
// Get cached model data directly
const modelData = await getCachedModel('https://example.com/model.onnx');
// Delete a specific cached model
await deleteCachedModel('https://example.com/model.onnx');
// Clear all cached models
await clearModelCache();
// Get cache statistics
const stats = await getModelCacheStats();
console.log(`${stats.models} models cached, ${stats.totalSize} bytes total`);
```
### Resume Downloads
Large model downloads automatically support resuming from where they left off:
```typescript
import { loadModelData } from 'edgeflowjs';
// Download with progress and resume support
const modelData = await loadModelData('https://example.com/large-model.onnx', {
resumable: true,
chunkSize: 10 * 1024 * 1024, // 10MB chunks
parallelConnections: 4, // Download 4 chunks in parallel
onProgress: (progress) => {
console.log(`${progress.percent.toFixed(1)}% downloaded`);
console.log(`Speed: ${(progress.speed / 1024 / 1024).toFixed(2)} MB/s`);
console.log(`ETA: ${(progress.eta / 1000).toFixed(0)}s`);
console.log(`Chunk ${progress.currentChunk}/${progress.totalChunks}`);
}
});
```
### Model Quantization
```typescript
import { quantize } from 'edgeflowjs/tools';
const quantized = await quantize(model, {
method: 'int8',
calibrationData: samples,
});
console.log(`Compression: ${quantized.compressionRatio}x`);
// Compression: 3.8x
```
### Benchmarking
```typescript
import { benchmark } from 'edgeflowjs/tools';
const result = await benchmark(
() => model.run('sample text'),
{ warmupRuns: 5, runs: 100 }
);
console.log(result);
// {
// avgTime: 12.5,
// minTime: 10.2,
// maxTime: 18.3,
// throughput: 80 // inferences/sec
// }
```
### Memory Scope
```typescript
import { withMemoryScope, tensor } from 'edgeflowjs';
const result = await withMemoryScope(async (scope) => {
// Tensors tracked in scope
const a = scope.track(tensor([1, 2, 3]));
const b = scope.track(tensor([4, 5, 6]));
// Process...
const output = process(a, b);
// Keep result, dispose others
return scope.keep(output);
});
// a and b automatically disposed
```
## 🔌 Tensor Operations
```typescript
import { tensor, zeros, ones, matmul, softmax, relu } from 'edgeflowjs';
// Create tensors
const a = tensor([[1, 2], [3, 4]]);
const b = zeros([2, 2]);
const c = ones([2, 2]);
// Operations
const d = matmul(a, c);
const probs = softmax(d);
const activated = relu(d);
// Cleanup
a.dispose();
b.dispose();
c.dispose();
```
## 🌐 Browser Support
| Browser | WebGPU | WebNN | WASM |
|---------|--------|-------|------|
| Chrome 113+ | ✅ | ✅ | ✅ |
| Edge 113+ | ✅ | ✅ | ✅ |
| Firefox 118+ | ⚠️ Flag | ❌ | ✅ |
| Safari 17+ | ⚠️ Preview | ❌ | ✅ |
## Star History
[](https://www.star-history.com/?repos=s-zx%2FedgeFlow.js&type=date&legend=top-left)
## 📖 API Reference
### Core
- `pipeline(task, options?)` - Create a pipeline for a task
- `loadModel(url, options?)` - Load a model from URL
- `runInference(model, inputs)` - Run model inference
- `getScheduler()` - Get the global scheduler
- `getMemoryManager()` - Get the memory manager
- `runInWorker(url, inputs)` - Run inference in a Web Worker
- `WorkerPool` - Manage multiple workers for parallel inference
### Pipelines
- `TextClassificationPipeline` - Text/sentiment classification
- `SentimentAnalysisPipeline` - Sentiment analysis
- `FeatureExtractionPipeline` - Text embeddings
- `ImageClassificationPipeline` - Image classification
- `TextGenerationPipeline` - Text generation with streaming
- `ObjectDetectionPipeline` - Object detection with bounding boxes
- `AutomaticSpeechRecognitionPipeline` - Speech to text
- `ZeroShotClassificationPipeline` - Classify without training
- `QuestionAnsweringPipeline` - Extractive QA
### HuggingFace Hub
- `fromHub(modelId, options?)` - Load model bundle from HuggingFace
- `fromTask(task, options?)` - Load recommended model for task
- `downloadTokenizer(modelId)` - Download tokenizer only
- `downloadConfig(modelId)` - Download config only
- `POPULAR_MODELS` - Registry of popular models by task
### Utilities
- `Tokenizer` - BPE/WordPiece tokenization with HuggingFace support
- `ImagePreprocessor` - Image preprocessing with HuggingFace config support
- `AudioPreprocessor` - Audio preprocessing for Whisper/wav2vec
- `Cache` - LRU caching utilities
### Tools
- `quantize(model, options)` - Quantize a model
- `prune(model, options)` - Prune model weights
- `benchmark(fn, options)` - Benchmark inference
- `analyzeModel(model)` - Analyze model structure
## 🤝 Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## 📄 License
MIT © edgeFlow.js Contributors
---
<div align="center">
**[Get Started](https://edgeflow.js.org/getting-started) · [API Docs](https://edgeflow.js.org/api) · [Examples](examples/)**
Made with ❤️ for the edge AI community
</div>
================================================
FILE: README_CN.md
================================================
# edgeFlow.js
<div align="center">
**浏览器端机器学习推理框架,内置任务调度和智能缓存**
[](https://www.npmjs.com/package/edgeflowjs)
[](https://packagephobia.com/result?p=edgeflowjs)
[](LICENSE)
[文档](https://edgeflow.js.org) · [示例](examples/) · [API 参考](https://edgeflow.js.org/api) · [English](README.md) | [中文](README_CN.md)
</div>
---
## ✨ 特性
- 📋 **任务调度器** - 优先级队列、并发控制、任务取消
- 🔄 **批量处理** - 开箱即用的高效批量推理
- 💾 **内存管理** - 自动内存追踪和作用域清理
- 📥 **智能模型加载** - 支持预加载、分片下载、断点续传
- 💿 **离线缓存** - 基于 IndexedDB 的模型缓存,支持离线使用
- ⚡ **多后端支持** - WebGPU、WebNN、WASM 自动降级
- 🤗 **HuggingFace Hub** - 一行代码从 HuggingFace 下载模型
- 🔤 **真实分词器** - BPE 和 WordPiece 分词器,直接加载 tokenizer.json
- 👷 **Web Worker 支持** - 在后台线程运行推理
- 📦 **开箱即用** - 内置 ONNX Runtime,零配置直接使用
- 🎯 **TypeScript 优先** - 完整的类型支持和直观的 API
## 📦 安装
```bash
npm install edgeflowjs
```
```bash
yarn add edgeflowjs
```
```bash
pnpm add edgeflowjs
```
> **注意**: ONNX Runtime 已作为依赖包含,无需额外配置。
## 🚀 快速开始
### 体验 Demo
在本地运行交互式 Demo 测试所有功能:
```bash
# 克隆并安装
git clone https://github.com/user/edgeflow.js.git
cd edgeflow.js
npm install
# 构建并启动 Demo 服务器
npm run demo
```
在浏览器中打开 **http://localhost:3000**:
1. **加载模型** - 输入 Hugging Face ONNX 模型 URL 并点击 "Load Model"
```
https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/onnx/model_quantized.onnx
```
2. **测试功能**:
- 🧮 **张量运算** - 测试张量创建、数学运算、softmax、relu
- 📝 **文本分类** - 对文本进行情感分析
- 🔍 **特征提取** - 从文本中提取嵌入向量
- ⚡ **任务调度** - 测试优先级调度
- 📋 **任务调度** - 测试基于优先级的任务调度
- 💾 **内存管理** - 测试内存分配和清理
### 基础用法
```typescript
import { pipeline } from 'edgeflowjs';
// 创建情感分析流水线
const sentiment = await pipeline('sentiment-analysis');
// 运行推理
const result = await sentiment.run('I love this product!');
console.log(result);
// { label: 'positive', score: 0.98, processingTime: 12.5 }
```
### 批量处理
```typescript
// 原生批处理支持
const results = await sentiment.run([
'This is amazing!',
'This is terrible.',
'It\'s okay I guess.'
]);
console.log(results);
// [
// { label: 'positive', score: 0.95 },
// { label: 'negative', score: 0.92 },
// { label: 'neutral', score: 0.68 }
// ]
```
### 多流水线
```typescript
import { pipeline } from 'edgeflowjs';
// 创建多个流水线
const classifier = await pipeline('text-classification');
const extractor = await pipeline('feature-extraction');
// 使用 Promise.all 并行运行
const [classification, features] = await Promise.all([
classifier.run('Sample text'),
extractor.run('Sample text')
]);
```
### 图像分类
```typescript
import { pipeline } from 'edgeflowjs';
const classifier = await pipeline('image-classification');
// 从 URL 加载
const result = await classifier.run('https://example.com/image.jpg');
// 从 HTMLImageElement 加载
const img = document.getElementById('myImage');
const result = await classifier.run(img);
// 批量处理
const results = await classifier.run([img1, img2, img3]);
```
### 文本生成(流式输出)
```typescript
import { pipeline } from 'edgeflowjs';
const generator = await pipeline('text-generation');
// 简单生成
const result = await generator.run('从前有座山', {
maxNewTokens: 50,
temperature: 0.8,
});
console.log(result.generatedText);
// 流式输出
for await (const event of generator.stream('你好,')) {
process.stdout.write(event.token);
if (event.done) break;
}
```
### 零样本分类
```typescript
import { pipeline } from 'edgeflowjs';
const classifier = await pipeline('zero-shot-classification');
const result = await classifier.classify(
'周末我喜欢踢足球',
['体育', '政治', '科技', '娱乐']
);
console.log(result.labels[0], result.scores[0]);
// '体育', 0.92
```
### 问答系统
```typescript
import { pipeline } from 'edgeflowjs';
const qa = await pipeline('question-answering');
const result = await qa.run({
question: '法国的首都是什么?',
context: '巴黎是法国的首都和最大城市。'
});
console.log(result.answer); // '巴黎'
```
### 从 HuggingFace Hub 加载
```typescript
import { fromHub, fromTask } from 'edgeflowjs';
// 通过模型 ID 加载(自动下载模型、分词器、配置)
const bundle = await fromHub('Xenova/distilbert-base-uncased-finetuned-sst-2-english');
console.log(bundle.tokenizer); // Tokenizer 实例
console.log(bundle.config); // 模型配置
// 通过任务名称加载(使用推荐模型)
const sentimentBundle = await fromTask('sentiment-analysis');
```
### Web Workers(后台推理)
```typescript
import { runInWorker, WorkerPool, isWorkerSupported } from 'edgeflowjs';
// 简单:在后台线程运行推理
if (isWorkerSupported()) {
const outputs = await runInWorker(modelUrl, inputs);
}
// 高级:使用 Worker 池进行并行处理
const pool = new WorkerPool({ numWorkers: 4 });
await pool.init();
const modelId = await pool.loadModel(modelUrl);
const results = await pool.runBatch(modelId, batchInputs);
pool.terminate();
```
## 🎯 支持的任务
| 任务 | 流水线 | 状态 |
|------|--------|------|
| 文本分类 | `text-classification` | ✅ |
| 情感分析 | `sentiment-analysis` | ✅ |
| 特征提取 | `feature-extraction` | ✅ |
| 图像分类 | `image-classification` | ✅ |
| 文本生成 | `text-generation` | ✅ |
| 目标检测 | `object-detection` | ✅ |
| 语音识别 | `automatic-speech-recognition` | ✅ |
| 零样本分类 | `zero-shot-classification` | ✅ |
| 问答系统 | `question-answering` | ✅ |
## ⚡ 核心差异
### 与 transformers.js 对比
| 特性 | transformers.js | edgeFlow.js |
|------|-----------------|-------------|
| 任务调度器 | ❌ 无 | ✅ 优先级队列 + 并发限制 |
| 任务取消 | ❌ 无 | ✅ 支持取消排队任务 |
| 批量处理 | ⚠️ 手动 | ✅ 内置批处理 |
| 内存作用域 | ❌ 无 | ✅ 作用域自动清理 |
| 模型预加载 | ❌ 无 | ✅ 后台加载 |
| 断点续传 | ❌ 无 | ✅ 分片 + 续传 |
| 模型缓存 | ⚠️ 基础 | ✅ IndexedDB + 统计 |
| TypeScript | ✅ 完整 | ✅ 完整 |
## 🔧 配置
### 运行时选择
```typescript
import { pipeline } from 'edgeflowjs';
// 自动选择(推荐)
const model = await pipeline('text-classification');
// 指定运行时
const model = await pipeline('text-classification', {
runtime: 'webgpu' // 或 'webnn', 'wasm', 'auto'
});
```
### 内存管理
```typescript
import { pipeline, getMemoryStats, gc } from 'edgeflowjs';
const model = await pipeline('text-classification');
// 使用模型
await model.run('text');
// 检查内存使用
console.log(getMemoryStats());
// { allocated: 50MB, used: 45MB, peak: 52MB, tensorCount: 12 }
// 显式清理
model.dispose();
// 强制垃圾回收
gc();
```
### 调度器配置
```typescript
import { configureScheduler } from 'edgeflowjs';
configureScheduler({
maxConcurrentTasks: 4,
maxConcurrentPerModel: 1,
defaultTimeout: 30000,
enableBatching: true,
maxBatchSize: 32,
});
```
### 缓存
```typescript
import { pipeline, Cache } from 'edgeflowjs';
// 创建缓存
const cache = new Cache({
strategy: 'lru',
maxSize: 100 * 1024 * 1024, // 100MB
persistent: true, // 使用 IndexedDB
});
const model = await pipeline('text-classification', {
cache: true
});
```
## 🛠️ 高级用法
### 自定义模型加载
```typescript
import { loadModel, runInference } from 'edgeflowjs';
// 从 URL 加载,支持缓存、分片和断点续传
const model = await loadModel('https://example.com/model.bin', {
runtime: 'webgpu',
quantization: 'int8',
cache: true, // 启用 IndexedDB 缓存(默认: true)
resumable: true, // 启用断点续传(默认: true)
chunkSize: 5 * 1024 * 1024, // 大模型使用 5MB 分片
onProgress: (progress) => console.log(`加载中: ${progress * 100}%`)
});
// 运行推理
const outputs = await runInference(model, inputs);
// 清理
model.dispose();
```
### 模型预加载
```typescript
import { preloadModel, preloadModels, getPreloadStatus } from 'edgeflowjs';
// 后台预加载单个模型(支持优先级)
preloadModel('https://example.com/model1.onnx', { priority: 10 });
// 预加载多个模型
preloadModels([
{ url: 'https://example.com/model1.onnx', priority: 10 },
{ url: 'https://example.com/model2.onnx', priority: 5 },
]);
// 检查预加载状态
const status = getPreloadStatus('https://example.com/model1.onnx');
// 'pending' | 'loading' | 'complete' | 'error' | 'not_found'
```
### 模型缓存
```typescript
import {
isModelCached,
getCachedModel,
deleteCachedModel,
clearModelCache,
getModelCacheStats
} from 'edgeflowjs';
// 检查模型是否已缓存
if (await isModelCached('https://example.com/model.onnx')) {
console.log('模型已缓存!');
}
// 直接获取缓存的模型数据
const modelData = await getCachedModel('https://example.com/model.onnx');
// 删除特定缓存的模型
await deleteCachedModel('https://example.com/model.onnx');
// 清空所有缓存的模型
await clearModelCache();
// 获取缓存统计
const stats = await getModelCacheStats();
console.log(`${stats.models} 个模型已缓存,共 ${stats.totalSize} 字节`);
```
### 断点续传下载
大模型下载自动支持从断点处继续:
```typescript
import { loadModelData } from 'edgeflowjs';
// 带进度和断点续传的下载
const modelData = await loadModelData('https://example.com/large-model.onnx', {
resumable: true,
chunkSize: 10 * 1024 * 1024, // 10MB 分片
parallelConnections: 4, // 并行下载 4 个分片
onProgress: (progress) => {
console.log(`${progress.percent.toFixed(1)}% 已下载`);
console.log(`速度: ${(progress.speed / 1024 / 1024).toFixed(2)} MB/s`);
console.log(`预计剩余: ${(progress.eta / 1000).toFixed(0)}秒`);
console.log(`分片 ${progress.currentChunk}/${progress.totalChunks}`);
}
});
```
### 模型量化
```typescript
import { quantize } from 'edgeflowjs/tools';
const quantized = await quantize(model, {
method: 'int8',
calibrationData: samples,
});
console.log(`压缩比: ${quantized.compressionRatio}x`);
// 压缩比: 3.8x
```
### 性能测试
```typescript
import { benchmark } from 'edgeflowjs/tools';
const result = await benchmark(
() => model.run('sample text'),
{ warmupRuns: 5, runs: 100 }
);
console.log(result);
// {
// avgTime: 12.5,
// minTime: 10.2,
// maxTime: 18.3,
// throughput: 80 // 推理次数/秒
// }
```
### 内存作用域
```typescript
import { withMemoryScope, tensor } from 'edgeflowjs';
const result = await withMemoryScope(async (scope) => {
// 在作用域中追踪张量
const a = scope.track(tensor([1, 2, 3]));
const b = scope.track(tensor([4, 5, 6]));
// 处理...
const output = process(a, b);
// 保留结果,释放其他
return scope.keep(output);
});
// a 和 b 自动释放
```
## 🔌 张量操作
```typescript
import { tensor, zeros, ones, matmul, softmax, relu } from 'edgeflowjs';
// 创建张量
const a = tensor([[1, 2], [3, 4]]);
const b = zeros([2, 2]);
const c = ones([2, 2]);
// 运算
const d = matmul(a, c);
const probs = softmax(d);
const activated = relu(d);
// 清理
a.dispose();
b.dispose();
c.dispose();
```
## 🌐 浏览器支持
| 浏览器 | WebGPU | WebNN | WASM |
|--------|--------|-------|------|
| Chrome 113+ | ✅ | ✅ | ✅ |
| Edge 113+ | ✅ | ✅ | ✅ |
| Firefox 118+ | ⚠️ 需开启 | ❌ | ✅ |
| Safari 17+ | ⚠️ 预览版 | ❌ | ✅ |
## Star History
[](https://www.star-history.com/?repos=s-zx%2FedgeFlow.js&type=date&legend=top-left)
## 📖 API 参考
### 核心
- `pipeline(task, options?)` - 为任务创建流水线
- `loadModel(url, options?)` - 从 URL 加载模型
- `runInference(model, inputs)` - 运行模型推理
- `getScheduler()` - 获取全局调度器
- `getMemoryManager()` - 获取内存管理器
- `runInWorker(url, inputs)` - 在 Web Worker 中运行推理
- `WorkerPool` - 管理多个 Worker 进行并行推理
### 流水线
- `TextClassificationPipeline` - 文本/情感分类
- `SentimentAnalysisPipeline` - 情感分析
- `FeatureExtractionPipeline` - 文本嵌入
- `ImageClassificationPipeline` - 图像分类
- `TextGenerationPipeline` - 文本生成(支持流式输出)
- `ObjectDetectionPipeline` - 目标检测(带边界框)
- `AutomaticSpeechRecognitionPipeline` - 语音转文字
- `ZeroShotClassificationPipeline` - 零样本分类
- `QuestionAnsweringPipeline` - 抽取式问答
### HuggingFace Hub
- `fromHub(modelId, options?)` - 从 HuggingFace 加载模型包
- `fromTask(task, options?)` - 按任务加载推荐模型
- `downloadTokenizer(modelId)` - 仅下载分词器
- `downloadConfig(modelId)` - 仅下载配置
- `POPULAR_MODELS` - 按任务分类的热门模型注册表
### 工具类
- `Tokenizer` - BPE/WordPiece 分词器,支持 HuggingFace 格式
- `ImagePreprocessor` - 图像预处理器,支持 HuggingFace 配置
- `AudioPreprocessor` - 音频预处理器,支持 Whisper/wav2vec
- `Cache` - LRU 缓存工具
### 工具
- `quantize(model, options)` - 模型量化
- `prune(model, options)` - 模型剪枝
- `benchmark(fn, options)` - 性能基准测试
- `analyzeModel(model)` - 分析模型结构
## 🤝 贡献
欢迎贡献!请查看我们的 [贡献指南](CONTRIBUTING.md) 了解详情。
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 发起 Pull Request
## 📄 许可证
MIT © edgeFlow.js Contributors
---
<div align="center">
**[快速开始](https://edgeflow.js.org/getting-started) · [API 文档](https://edgeflow.js.org/api) · [示例](examples/)**
用 ❤️ 为边缘 AI 社区打造
</div>
================================================
FILE: benchmarks/README.md
================================================
# edgeFlow.js Benchmarks
This directory contains performance benchmarks for edgeFlow.js.
## Running Benchmarks
```bash
npm install
npm run build
npm run test -- --run tests/unit/
```
> **Note:** A dedicated `npm run benchmark` script with browser-based benchmarks is planned. The unit tests include basic tensor and scheduler performance validation.
## Benchmark Types
### 1. Tensor Operations
- Tensor creation and disposal
- Shape transformation (reshape, transpose)
- Math operations (add, matmul, softmax)
### 2. Scheduler Throughput
- Priority queue ordering under load
- Concurrent task execution
- Task cancellation overhead
### 3. Model Loading
- Cached vs uncached loads (IndexedDB)
- Chunked download with resume
- Preloading pipeline
### 4. Inference Latency
- Text generation (TinyLlama) end-to-end
- Image segmentation (SlimSAM) encode + decode
## How edgeFlow.js Adds Value
edgeFlow.js is not a replacement for inference engines like ONNX Runtime or transformers.js. It is an **orchestration layer** that adds production features on top of them:
| Scenario | Without edgeFlow.js | With edgeFlow.js |
|----------|---------------------|------------------|
| 5 concurrent model calls | Uncontrolled, may OOM | Scheduled with concurrency limits |
| Repeated inference on same input | Recomputed every time | Cached results (LRU/TTL) |
| Large model download interrupted | Start from scratch | Resume from last chunk |
| Memory leak from undisposed tensors | Silent leak | Detected and warned |
> All benchmark claims will be backed by reproducible scripts before the 1.0 release.
## Custom Benchmarks
```typescript
import { runBenchmark, benchmarkSuite } from 'edgeflowjs/tools';
const result = await runBenchmark(
async () => {
await model.run(input);
},
{
warmupRuns: 5,
runs: 20,
verbose: true,
}
);
console.log(`Average: ${result.avgTime.toFixed(2)}ms`);
console.log(`Throughput: ${result.throughput.toFixed(2)} ops/sec`);
const results = await benchmarkSuite({
'small-model': async () => smallModel.run(input),
'large-model': async () => largeModel.run(input),
});
```
================================================
FILE: demo/demo.js
================================================
/**
* edgeFlow.js Interactive Demo
*
* Organized into modules:
* 1. State & Config
* 2. Utilities
* 3. UI Helpers
* 4. Core Features
* 5. SAM Interactive Segmentation (Real Model)
* 6. AI Chat (Real Model)
* 7. Demo Class (Public API)
* 8. Initialization
*/
import * as edgeFlow from '/dist/edgeflow.browser.js';
// Expose edgeFlow globally for debugging
window.edgeFlow = edgeFlow;
/* ==========================================================================
1. State & Config
========================================================================== */
const state = {
model: null,
testTensors: [],
monitor: null,
// SAM state
samPipeline: null,
samModelLoaded: false,
samImage: null,
samPoints: [],
samCanvas: null,
samMaskCanvas: null,
samCtx: null,
samMaskCtx: null,
// Chat state
chatPipeline: null,
chatModelLoaded: false,
chatHistory: [],
chatGenerating: false,
};
const config = {
defaultSeqLen: 128,
monitorSampleInterval: 500,
monitorHistorySize: 30,
};
/* ==========================================================================
2. Utilities
========================================================================== */
const utils = {
/**
* Format bytes to human readable string
*/
formatBytes(bytes) {
if (!bytes) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
},
/**
* Sleep for given milliseconds
*/
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
/**
* Generate placeholder model inputs based on model metadata
*/
createModelInputs(model, seqLen = config.defaultSeqLen) {
return model.metadata.inputs.map(spec => {
const data = new Array(seqLen).fill(0);
if (spec.name.includes('input')) {
data[0] = 101; // [CLS]
data[1] = 2054; // sample token
data[2] = 102; // [SEP]
} else if (spec.name.includes('mask')) {
data[0] = 1;
data[1] = 1;
data[2] = 1;
}
return edgeFlow.tensor(data, [1, seqLen], 'int64');
});
},
/**
* Simple tokenization and inference
*/
async inferText(text) {
if (!state.model) throw new Error('Model not loaded');
const tokens = text.toLowerCase().split(/\s+/);
const maxLen = config.defaultSeqLen;
const numTokens = Math.min(tokens.length + 2, maxLen);
const inputs = state.model.metadata.inputs.map(spec => {
const data = new Array(maxLen).fill(0);
if (spec.name.includes('input')) {
data[0] = 101; // [CLS]
tokens.slice(0, maxLen - 2).forEach((t, i) => {
// Simple hash-based token ID (demo only)
data[i + 1] = Math.abs(t.split('').reduce((a, c) => a + c.charCodeAt(0), 0)) % 30000;
});
data[numTokens - 1] = 102; // [SEP]
} else if (spec.name.includes('mask')) {
for (let i = 0; i < numTokens; i++) data[i] = 1;
}
return edgeFlow.tensor(data, [1, maxLen], 'int64');
});
const outputs = await edgeFlow.runInference(state.model, inputs);
const outputData = outputs[0].toArray();
// Calculate sentiment score
const score = outputData.length >= 2
? Math.exp(outputData[1]) / (Math.exp(outputData[0]) + Math.exp(outputData[1]))
: outputData[0] > 0.5 ? outputData[0] : 1 - outputData[0];
// Cleanup
inputs.forEach(t => t.dispose());
outputs.forEach(t => t.dispose());
return {
label: score > 0.5 ? 'positive' : 'negative',
score,
};
},
};
/* ==========================================================================
3. UI Helpers
========================================================================== */
const ui = {
/**
* Get element by ID
*/
$(id) {
return document.getElementById(id);
},
/**
* Set output content
*/
setOutput(id, content, type = '') {
const el = this.$(id);
if (!el) return;
const className = type ? `class="${type}"` : '';
el.innerHTML = `<pre><span ${className}>${content}</span></pre>`;
},
/**
* Show loading state
*/
showLoading(id, message = 'Loading...') {
this.setOutput(id, `<span class="loader"></span>${message}`);
},
/**
* Show success message
*/
showSuccess(id, message) {
this.setOutput(id, `✓ ${message}`, 'success');
},
/**
* Show error message
*/
showError(id, error) {
const message = error instanceof Error ? error.message : String(error);
this.setOutput(id, `Error: ${message}`, 'error');
},
/**
* Render status list
*/
renderStatusList(id, items) {
const el = this.$(id);
if (!el) return;
el.innerHTML = items.map(({ label, value, status }) => `
<div class="status-item">
<span>${label}</span>
<span class="${status ? 'status-badge status-' + status : ''}">${value}</span>
</div>
`).join('');
},
/**
* Render metrics
*/
renderMetrics(id, metrics) {
const el = this.$(id);
if (!el) return;
el.innerHTML = metrics.map(({ value, label }) => `
<div class="metric">
<div class="metric-value">${value}</div>
<div class="metric-label">${label}</div>
</div>
`).join('');
el.classList.remove('hidden');
},
/**
* Update runtime status
*/
async updateRuntimeStatus() {
try {
const runtimes = await edgeFlow.getAvailableRuntimes();
this.renderStatusList('runtime-status', [
{ label: 'WebGPU', value: runtimes.get('webgpu') ? 'Ready' : 'N/A', status: runtimes.get('webgpu') ? 'success' : 'error' },
{ label: 'WebNN', value: runtimes.get('webnn') ? 'Ready' : 'N/A', status: runtimes.get('webnn') ? 'success' : 'error' },
{ label: 'WASM', value: runtimes.get('wasm') ? 'Ready' : 'N/A', status: runtimes.get('wasm') ? 'success' : 'error' },
]);
} catch {
this.renderStatusList('runtime-status', [
{ label: 'WebGPU', value: 'N/A', status: 'error' },
{ label: 'WebNN', value: 'N/A', status: 'error' },
{ label: 'WASM', value: 'N/A', status: 'error' },
]);
}
},
/**
* Update memory status
*/
updateMemoryStatus() {
try {
const stats = edgeFlow.getMemoryStats();
this.renderStatusList('memory-status', [
{ label: 'Allocated', value: utils.formatBytes(stats.allocated || 0) },
{ label: 'Peak', value: utils.formatBytes(stats.peak || 0) },
{ label: 'Tensors', value: String(stats.tensorCount || 0) },
]);
} catch {
this.renderStatusList('memory-status', [
{ label: 'Allocated', value: '0 B' },
{ label: 'Peak', value: '0 B' },
{ label: 'Tensors', value: '0' },
]);
}
},
/**
* Update monitor metrics
*/
updateMonitorMetrics(sample) {
this.renderMetrics('monitor-metrics', [
{ value: sample.inference.count, label: 'Inferences' },
{ value: sample.inference.avgTime.toFixed(1) + 'ms', label: 'Avg Time' },
{ value: sample.inference.throughput.toFixed(1), label: 'Ops/sec' },
{ value: utils.formatBytes(sample.memory.usedHeap), label: 'Memory' },
{ value: sample.system.fps || '-', label: 'FPS' },
]);
},
/**
* Initialize default outputs
*/
initOutputs() {
const defaults = {
'model-output': ['Click "Load Model" to download an ONNX model', 'info'],
'tensor-output': ['Click "Run Tests" to test tensor operations...', ''],
'text-output': ['Load model first, then classify text...', ''],
'feature-output': ['Enter text and extract features...', ''],
'quant-output': ['Test in-browser quantization...', ''],
'debugger-output': ['Inspect tensor values and statistics...', ''],
'benchmark-output': ['Benchmark tensor operations...', ''],
'scheduler-output': ['Test task scheduling with priorities...', ''],
'memory-output': ['Test memory allocation and cleanup...', ''],
'concurrency-output': ['Test concurrent inference...', ''],
};
for (const [id, [msg, type]] of Object.entries(defaults)) {
this.setOutput(id, msg, type);
}
// Initialize monitor metrics
this.renderMetrics('monitor-metrics', [
{ value: '0', label: 'Inferences' },
{ value: '0ms', label: 'Avg Time' },
{ value: '0', label: 'Ops/sec' },
{ value: '0 B', label: 'Memory' },
{ value: '-', label: 'FPS' },
]);
},
};
/* ==========================================================================
4. Core Features
========================================================================== */
const features = {
/**
* Load ONNX model
*/
async loadModel() {
const url = ui.$('model-url')?.value;
if (!url) {
ui.setOutput('model-output', 'Enter a model URL', 'warn');
return;
}
ui.showLoading('model-output', 'Loading model...');
try {
const start = performance.now();
state.model = await edgeFlow.loadModel(url, { runtime: 'wasm' });
const time = ((performance.now() - start) / 1000).toFixed(2);
const info = [
`<span class="success">✓ Model loaded in ${time}s</span>`,
`Name: ${state.model.metadata.name}`,
`Size: ${utils.formatBytes(state.model.metadata.sizeBytes)}`,
`Inputs: ${state.model.metadata.inputs.map(i => i.name).join(', ')}`,
].join('\n');
ui.$('model-output').innerHTML = `<pre>${info}</pre>`;
ui.updateMemoryStatus();
} catch (e) {
ui.showError('model-output', e);
}
},
/**
* Test model inference
*/
async testModel() {
if (!state.model) {
ui.setOutput('model-output', 'Load model first', 'warn');
return;
}
ui.showLoading('model-output', 'Running inference...');
try {
const inputs = utils.createModelInputs(state.model);
const start = performance.now();
const outputs = await edgeFlow.runInference(state.model, inputs);
const time = (performance.now() - start).toFixed(2);
const data = outputs[0].toArray();
const info = [
`<span class="success">✓ Inference: ${time}ms</span>`,
`Output: [${data.slice(0, 5).map(x => x.toFixed(4)).join(', ')}...]`,
].join('\n');
ui.$('model-output').innerHTML = `<pre>${info}</pre>`;
inputs.forEach(t => t.dispose());
outputs.forEach(t => t.dispose());
} catch (e) {
ui.showError('model-output', e);
}
},
/**
* Run tensor operation tests
*/
testTensors() {
try {
const a = edgeFlow.tensor([[1, 2], [3, 4]]);
const b = edgeFlow.tensor([[5, 6], [7, 8]]);
const sum = edgeFlow.add(a, b);
const rand = edgeFlow.random([10]);
const probs = edgeFlow.softmax(edgeFlow.tensor([1, 2, 3, 4]));
const info = [
`<span class="success">✓ All tensor tests passed</span>`,
`• Created 2x2 tensor`,
`• Addition: [${sum.toArray()}]`,
`• Random: [${rand.toArray().slice(0, 5).map(x => x.toFixed(2))}...]`,
`• Softmax: [${probs.toArray().map(x => x.toFixed(3))}]`,
].join('\n');
ui.$('tensor-output').innerHTML = `<pre>${info}</pre>`;
[a, b, sum, rand, probs].forEach(t => t.dispose());
ui.updateMemoryStatus();
} catch (e) {
ui.showError('tensor-output', e);
}
},
/**
* Classify single text
*/
async classifyText() {
if (!state.model) {
ui.setOutput('text-output', 'Load model first', 'warn');
return;
}
const text = ui.$('text-input')?.value;
if (!text) return;
ui.showLoading('text-output', 'Classifying...');
try {
const result = await utils.inferText(text);
const emoji = result.label === 'positive' ? '😊' : '😞';
const pct = (result.score * 100).toFixed(1);
ui.$('text-output').innerHTML = `<pre><span class="success">${emoji} ${result.label.toUpperCase()}</span> (${pct}%)</pre>`;
} catch (e) {
ui.showError('text-output', e);
}
},
/**
* Batch classification
*/
async classifyBatch() {
if (!state.model) {
ui.setOutput('text-output', 'Load model first', 'warn');
return;
}
const texts = ['I love this!', 'This is terrible.', 'Amazing!', 'Worst ever.', 'Pretty good.'];
ui.showLoading('text-output', 'Processing batch...');
try {
const start = performance.now();
const results = await Promise.all(texts.map(t => utils.inferText(t)));
const time = (performance.now() - start).toFixed(0);
const lines = results.map((r, i) => {
const emoji = r.label === 'positive' ? '😊' : '😞';
return `${emoji} "${texts[i]}" → ${r.label}`;
});
lines.push('', `<span class="success">Total: ${time}ms</span>`);
ui.$('text-output').innerHTML = `<pre>${lines.join('\n')}</pre>`;
} catch (e) {
ui.showError('text-output', e);
}
},
/**
* Extract features
*/
async extractFeatures() {
if (!state.model) {
ui.setOutput('feature-output', 'Load model first', 'warn');
return;
}
const text = ui.$('feature-input')?.value;
if (!text) return;
ui.showLoading('feature-output', 'Extracting...');
try {
const inputs = utils.createModelInputs(state.model);
const start = performance.now();
const outputs = await edgeFlow.runInference(state.model, inputs);
const time = (performance.now() - start).toFixed(2);
const embeddings = outputs[0].toArray();
const norm = Math.sqrt(embeddings.reduce((a, b) => a + b * b, 0));
const info = [
`<span class="success">✓ Features extracted in ${time}ms</span>`,
`Dimension: ${embeddings.length}`,
`L2 Norm: ${norm.toFixed(4)}`,
`Sample: [${embeddings.slice(0, 5).map(x => x.toFixed(4)).join(', ')}...]`,
].join('\n');
ui.$('feature-output').innerHTML = `<pre>${info}</pre>`;
inputs.forEach(t => t.dispose());
outputs.forEach(t => t.dispose());
} catch (e) {
ui.showError('feature-output', e);
}
},
/**
* Quantization demo
*/
quantize() {
try {
const weights = edgeFlow.tensor([0.5, -0.3, 0.8, -0.1, 0.9, -0.7, 0.2, -0.4], [2, 4], 'float32');
const { tensor: quantized, scale, zeroPoint } = edgeFlow.quantizeTensor(weights, 'int8');
const dequantized = edgeFlow.dequantizeTensor(quantized, scale, zeroPoint, 'int8');
const original = weights.toArray();
const recovered = dequantized.toArray();
const maxError = Math.max(...original.map((v, i) => Math.abs(v - recovered[i])));
const info = [
`<span class="success">✓ Int8 Quantization</span>`,
`Original: [${original.map(v => v.toFixed(3)).join(', ')}]`,
`Quantized: [${quantized.toArray().join(', ')}]`,
`Dequantized: [${recovered.map(v => v.toFixed(3)).join(', ')}]`,
`Scale: ${scale.toFixed(6)}, Max Error: ${maxError.toFixed(6)}`,
].join('\n');
ui.$('quant-output').innerHTML = `<pre>${info}</pre>`;
[weights, quantized, dequantized].forEach(t => t.dispose());
} catch (e) {
ui.showError('quant-output', e);
}
},
/**
* Pruning demo
*/
prune() {
try {
const weights = edgeFlow.tensor([0.5, -0.1, 0.8, -0.05, 0.9, -0.02, 0.2, -0.4], [2, 4], 'float32');
const { tensor: pruned, sparsity } = edgeFlow.pruneTensor(weights, { ratio: 0.5 });
const info = [
`<span class="success">✓ Magnitude Pruning (50%)</span>`,
`Original: [${weights.toArray().map(v => v.toFixed(2)).join(', ')}]`,
`Pruned: [${pruned.toArray().map(v => v.toFixed(2)).join(', ')}]`,
`Sparsity: ${(sparsity * 100).toFixed(1)}%`,
].join('\n');
ui.$('quant-output').innerHTML = `<pre>${info}</pre>`;
[weights, pruned].forEach(t => t.dispose());
} catch (e) {
ui.showError('quant-output', e);
}
},
/**
* Debugger demo
*/
debug() {
try {
const data = Array.from({ length: 100 }, () => Math.random() * 2 - 1);
const tensor = edgeFlow.tensor(data, [10, 10], 'float32');
const inspection = edgeFlow.inspectTensor(tensor, 'random_weights');
const histogram = edgeFlow.createAsciiHistogram(inspection.histogram, 25, 4);
const info = [
`<span class="success">Tensor: ${inspection.name}</span>`,
`Shape: [${inspection.shape}], Size: ${inspection.size}`,
`<span class="info">Statistics:</span>`,
` Min: ${inspection.stats.min.toFixed(4)}`,
` Max: ${inspection.stats.max.toFixed(4)}`,
` Mean: ${inspection.stats.mean.toFixed(4)}`,
` Std: ${inspection.stats.std.toFixed(4)}`,
'',
histogram,
].join('\n');
ui.$('debugger-output').innerHTML = `<pre>${info}</pre>`;
tensor.dispose();
} catch (e) {
ui.showError('debugger-output', e);
}
},
/**
* Benchmark demo
*/
async benchmark() {
ui.showLoading('benchmark-output', 'Running benchmark...');
try {
const result = await edgeFlow.runBenchmark(async () => {
const t = edgeFlow.tensor(Array.from({ length: 1000 }, () => Math.random()), [1000], 'float32');
const sum = t.toArray().reduce((a, b) => a + b, 0);
t.dispose();
return sum;
}, { warmupRuns: 2, runs: 5, name: 'Tensor Sum (1000)' });
const info = [
`<span class="success">Benchmark: ${result.name}</span>`,
`Avg: ${result.avgTime.toFixed(2)}ms`,
`Min: ${result.minTime.toFixed(2)}ms`,
`Max: ${result.maxTime.toFixed(2)}ms`,
`Throughput: ${result.throughput.toFixed(0)} ops/sec`,
].join('\n');
ui.$('benchmark-output').innerHTML = `<pre>${info}</pre>`;
} catch (e) {
ui.showError('benchmark-output', e);
}
},
/**
* Scheduler test
*/
async testScheduler() {
ui.showLoading('scheduler-output', 'Testing scheduler...');
try {
const scheduler = edgeFlow.getScheduler();
const task1 = scheduler.schedule('model-a', async () => { await utils.sleep(100); return 'Task 1'; }, 'high');
const task2 = scheduler.schedule('model-b', async () => { await utils.sleep(50); return 'Task 2'; }, 'normal');
const task3 = scheduler.schedule('model-a', async () => { await utils.sleep(75); return 'Task 3'; }, 'low');
const [r1, r2, r3] = await Promise.all([task1.wait(), task2.wait(), task3.wait()]);
const info = [
`<span class="success">✓ Scheduler Test Passed</span>`,
`• ${r1} (high priority)`,
`• ${r2} (normal priority)`,
`• ${r3} (low priority)`,
].join('\n');
ui.$('scheduler-output').innerHTML = `<pre>${info}</pre>`;
} catch (e) {
ui.showError('scheduler-output', e);
}
},
/**
* Memory allocation test
*/
allocateMemory() {
try {
const before = edgeFlow.getMemoryStats();
for (let i = 0; i < 10; i++) {
state.testTensors.push(edgeFlow.random([100, 100]));
}
const after = edgeFlow.getMemoryStats();
const info = [
`<span class="success">✓ Allocated 10 tensors (100x100)</span>`,
`Before: ${utils.formatBytes(before.allocated || 0)}, ${before.tensorCount || 0} tensors`,
`After: ${utils.formatBytes(after.allocated || 0)}, ${after.tensorCount || 0} tensors`,
].join('\n');
ui.$('memory-output').innerHTML = `<pre>${info}</pre>`;
ui.updateMemoryStatus();
} catch (e) {
ui.showError('memory-output', e);
}
},
/**
* Memory cleanup
*/
cleanupMemory() {
state.testTensors.forEach(t => {
if (!t.isDisposed) t.dispose();
});
state.testTensors = [];
edgeFlow.gc();
ui.showSuccess('memory-output', 'Memory cleaned up');
ui.updateMemoryStatus();
},
/**
* Concurrency test
*/
async testConcurrency() {
if (!state.model) {
ui.setOutput('concurrency-output', 'Load model first', 'warn');
ui.$('concurrency-metrics')?.classList.add('hidden');
return;
}
ui.showLoading('concurrency-output', 'Running concurrent tasks...');
try {
const texts = ['Great!', 'Terrible!', 'Amazing!', 'Awful!', 'Good!', 'Bad!', 'Nice!', 'Horrible!'];
const start = performance.now();
const results = await Promise.all(texts.map(t => utils.inferText(t)));
const total = performance.now() - start;
const lines = [
`<span class="success">✓ Concurrent execution complete</span>`,
...results.map((r, i) => `${r.label === 'positive' ? '😊' : '😞'} "${texts[i]}"`),
];
ui.$('concurrency-output').innerHTML = `<pre>${lines.join('\n')}</pre>`;
ui.renderMetrics('concurrency-metrics', [
{ value: total.toFixed(0) + 'ms', label: 'Total' },
{ value: String(texts.length), label: 'Tasks' },
{ value: (total / texts.length).toFixed(0) + 'ms', label: 'Avg' },
]);
} catch (e) {
ui.showError('concurrency-output', e);
}
},
/**
* Start performance monitor
*/
startMonitor() {
if (!state.monitor) {
state.monitor = new edgeFlow.PerformanceMonitor({
sampleInterval: config.monitorSampleInterval,
historySize: config.monitorHistorySize,
});
state.monitor.onSample(sample => ui.updateMonitorMetrics(sample));
}
state.monitor.start();
},
/**
* Stop monitor
*/
stopMonitor() {
if (state.monitor) {
state.monitor.stop();
}
},
/**
* Simulate inferences for monitor
*/
simulateInferences() {
if (!state.monitor) {
this.startMonitor();
}
for (let i = 0; i < 5; i++) {
setTimeout(() => {
state.monitor?.recordInference(30 + Math.random() * 70);
}, i * 100);
}
},
/**
* Open dashboard modal
*/
openDashboard() {
if (!state.monitor) {
this.startMonitor();
this.simulateInferences();
}
const modal = ui.$('dashboard-modal');
const frame = ui.$('dashboard-frame');
if (modal && frame) {
frame.srcdoc = edgeFlow.generateDashboardHTML(state.monitor);
modal.classList.add('active');
document.body.style.overflow = 'hidden';
}
},
/**
* Close dashboard modal
*/
closeDashboard() {
const modal = ui.$('dashboard-modal');
if (modal) {
modal.classList.remove('active');
document.body.style.overflow = '';
}
},
};
/* ==========================================================================
5. SAM Interactive Segmentation (Real Model)
========================================================================== */
const sam = {
/**
* Initialize SAM UI and start model loading
*/
async init() {
const fileInput = ui.$('sam-file-input');
const container = ui.$('sam-container');
if (fileInput) {
fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
}
// Drag and drop
if (container) {
container.addEventListener('dragover', (e) => {
e.preventDefault();
container.classList.add('dragover');
});
container.addEventListener('dragleave', () => {
container.classList.remove('dragover');
});
container.addEventListener('drop', (e) => {
e.preventDefault();
container.classList.remove('dragover');
const file = e.dataTransfer?.files[0];
if (file && file.type.startsWith('image/')) {
this.loadImage(file);
}
});
}
// Start loading SAM models automatically
await this.loadModels();
},
/**
* Load SAM models with progress display
*/
async loadModels() {
const loader = ui.$('sam-loader');
const loaderText = ui.$('sam-loader-text');
const loaderDetail = ui.$('sam-loader-detail');
const progress = ui.$('sam-progress');
const samContainer = ui.$('sam-container');
try {
// Create pipeline
state.samPipeline = edgeFlow.createImageSegmentationPipeline();
// Load models with progress
await state.samPipeline.loadModels((progressInfo) => {
const { model, progress: pct, loaded, total } = progressInfo;
if (loaderText) {
loaderText.textContent = `Loading ${model}... (${utils.formatBytes(loaded)} / ${utils.formatBytes(total)})`;
}
if (loaderDetail) {
loaderDetail.textContent = `${pct}%`;
}
if (progress) {
progress.style.width = `${pct}%`;
}
});
state.samModelLoaded = true;
// Hide loader, show main UI
if (loader) loader.classList.add('hidden');
if (samContainer) samContainer.classList.remove('hidden');
// Enable buttons
ui.$('sam-sample-btn')?.removeAttribute('disabled');
ui.$('sam-clear-btn')?.removeAttribute('disabled');
ui.$('sam-download-btn')?.removeAttribute('disabled');
ui.setOutput('sam-output', '✓ SAM model loaded! Click to upload an image or use "Sample Image".', 'success');
} catch (error) {
console.error('SAM model loading failed:', error);
if (loaderText) {
loaderText.textContent = `Failed to load model: ${error.message}`;
loaderText.style.color = 'var(--error)';
}
if (loaderDetail) {
loaderDetail.textContent = 'Check console for details';
}
ui.showError('sam-output', error);
}
},
/**
* Handle file selection
*/
handleFileSelect(e) {
const file = e.target?.files?.[0];
if (file) {
this.loadImage(file);
}
},
/**
* Load image from file or URL
*/
async loadImage(source) {
if (!state.samModelLoaded) {
ui.setOutput('sam-output', 'Model not loaded yet. Please wait...', 'warn');
return;
}
ui.setOutput('sam-output', 'Loading image...', 'info');
try {
const img = new Image();
img.crossOrigin = 'anonymous';
await new Promise((resolve, reject) => {
img.onload = resolve;
img.onerror = reject;
if (typeof source === 'string') {
img.src = source;
} else {
img.src = URL.createObjectURL(source);
}
});
// Show workspace
ui.$('sam-upload')?.classList.add('hidden');
ui.$('sam-workspace')?.classList.remove('hidden');
// Setup canvases
const canvas = ui.$('sam-canvas');
const maskCanvas = ui.$('sam-mask-canvas');
if (canvas && maskCanvas) {
state.samCanvas = canvas;
state.samMaskCanvas = maskCanvas;
state.samCtx = canvas.getContext('2d');
state.samMaskCtx = maskCanvas.getContext('2d');
// Set canvas size
const container = ui.$('sam-workspace');
const containerWidth = container?.clientWidth || 400;
const containerHeight = container?.clientHeight || 250;
const scale = Math.min(
containerWidth / img.width,
containerHeight / img.height
);
canvas.width = img.width * scale;
canvas.height = img.height * scale;
maskCanvas.width = canvas.width;
maskCanvas.height = canvas.height;
// Draw image
state.samCtx.drawImage(img, 0, 0, canvas.width, canvas.height);
state.samImage = img;
state.samPoints = [];
// Setup click handler
canvas.onclick = (e) => this.handleClick(e, 1); // Left click = positive
canvas.oncontextmenu = (e) => {
e.preventDefault();
this.handleClick(e, 0); // Right click = negative
};
// Encode image with SAM encoder
ui.setOutput('sam-output', 'Encoding image with SAM...', 'info');
const encodeStart = performance.now();
await state.samPipeline.setImage(img);
const encodeTime = (performance.now() - encodeStart).toFixed(0);
ui.setOutput('sam-output', `✓ Image encoded in ${encodeTime}ms. Click to segment objects. Left-click = include, Right-click = exclude.`, 'success');
}
} catch (error) {
ui.showError('sam-output', error);
}
},
/**
* Load sample image
*/
async loadSampleImage() {
if (!state.samModelLoaded) {
ui.setOutput('sam-output', 'Model not loaded yet. Please wait...', 'warn');
return;
}
// Using a reliable public image URL
const sampleUrl = 'https://images.unsplash.com/photo-1587300003388-59208cc962cb?w=640';
await this.loadImage(sampleUrl);
},
/**
* Handle canvas click
*/
async handleClick(e, label) {
if (!state.samCanvas || !state.samPipeline || !state.samModelLoaded) return;
const rect = state.samCanvas.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
// Add point
state.samPoints.push({ x, y, label });
// Draw point indicator
this.drawPoints();
// Run segmentation
ui.setOutput('sam-output', 'Segmenting...', 'info');
try {
const startTime = performance.now();
const result = await state.samPipeline.segment({
points: state.samPoints,
});
const time = (performance.now() - startTime).toFixed(0);
// Draw mask
this.drawMask(result);
ui.setOutput('sam-output', `✓ Segmented in ${time}ms (score: ${result.score.toFixed(2)})`, 'success');
} catch (error) {
ui.showError('sam-output', error);
}
},
/**
* Draw points on canvas
*/
drawPoints() {
// Remove existing point indicators
document.querySelectorAll('.sam-point').forEach(el => el.remove());
const workspace = ui.$('sam-workspace');
if (!workspace || !state.samCanvas) return;
for (const point of state.samPoints) {
const indicator = document.createElement('div');
indicator.className = `sam-point ${point.label === 1 ? 'positive' : 'negative'}`;
indicator.style.left = `${point.x * 100}%`;
indicator.style.top = `${point.y * 100}%`;
workspace.appendChild(indicator);
}
},
/**
* Draw segmentation mask
*/
drawMask(result) {
if (!state.samMaskCtx || !state.samMaskCanvas) return;
const { mask, width, height } = result;
const canvas = state.samMaskCanvas;
// Create ImageData
const imageData = state.samMaskCtx.createImageData(canvas.width, canvas.height);
// Scale mask to canvas size
const scaleX = width / canvas.width;
const scaleY = height / canvas.height;
for (let y = 0; y < canvas.height; y++) {
for (let x = 0; x < canvas.width; x++) {
const srcX = Math.floor(x * scaleX);
const srcY = Math.floor(y * scaleY);
const srcIdx = srcY * width + srcX;
const dstIdx = (y * canvas.width + x) * 4;
if (mask[srcIdx] > 0) {
// Green overlay for segmented area
imageData.data[dstIdx] = 127; // R
imageData.data[dstIdx + 1] = 169; // G
imageData.data[dstIdx + 2] = 33; // B
imageData.data[dstIdx + 3] = 180; // A
}
}
}
state.samMaskCtx.putImageData(imageData, 0, 0);
},
/**
* Clear segmentation
*/
clear() {
state.samPoints = [];
// Clear mask canvas
if (state.samMaskCtx && state.samMaskCanvas) {
state.samMaskCtx.clearRect(0, 0, state.samMaskCanvas.width, state.samMaskCanvas.height);
}
// Remove point indicators
document.querySelectorAll('.sam-point').forEach(el => el.remove());
ui.setOutput('sam-output', 'Cleared. Click to segment objects.', 'info');
},
/**
* Download mask as PNG
*/
downloadMask() {
if (!state.samMaskCanvas) {
ui.setOutput('sam-output', 'No mask to download', 'warn');
return;
}
// Create download link
const link = document.createElement('a');
link.download = 'segmentation-mask.png';
link.href = state.samMaskCanvas.toDataURL('image/png');
link.click();
},
/**
* Reset to upload state
*/
reset() {
state.samImage = null;
state.samPoints = [];
ui.$('sam-upload')?.classList.remove('hidden');
ui.$('sam-workspace')?.classList.add('hidden');
document.querySelectorAll('.sam-point').forEach(el => el.remove());
if (state.samMaskCtx && state.samMaskCanvas) {
state.samMaskCtx.clearRect(0, 0, state.samMaskCanvas.width, state.samMaskCanvas.height);
}
// Clear the pipeline's image embedding
if (state.samPipeline) {
state.samPipeline.clearImage();
}
ui.setOutput('sam-output', 'Click on image to segment objects. Left-click = include, Right-click = exclude.', 'info');
},
};
/* ==========================================================================
6. AI Chat (Real Model)
========================================================================== */
const chat = {
/**
* Initialize chat UI
*/
init() {
const input = ui.$('chat-input');
if (input) {
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey && !state.chatGenerating) {
e.preventDefault();
this.send();
}
});
}
},
/**
* Load LLM model with progress display
*/
async loadModel() {
if (state.chatModelLoaded) {
ui.$('chat-container')?.classList.remove('hidden');
ui.$('llm-loader')?.classList.add('hidden');
return;
}
const loadBtn = ui.$('llm-load-btn');
const progressContainer = ui.$('llm-progress-container');
const progress = ui.$('llm-progress');
const loaderDetail = ui.$('llm-loader-detail');
try {
// Disable button and show progress
if (loadBtn) {
loadBtn.disabled = true;
loadBtn.textContent = 'Loading...';
}
if (progressContainer) progressContainer.classList.remove('hidden');
if (loaderDetail) loaderDetail.classList.remove('hidden');
this.updateStatus('loading', 'Downloading model...');
// Create pipeline
state.chatPipeline = edgeFlow.createTextGenerationPipeline();
state.chatPipeline.setChatTemplate('chatml');
// Load model with progress
await state.chatPipeline.loadModel((progressInfo) => {
const { stage, progress: pct } = progressInfo;
if (loadBtn) {
if (stage === 'tokenizer') {
loadBtn.textContent = 'Loading tokenizer...';
} else {
loadBtn.textContent = `Downloading... ${pct}%`;
}
}
if (loaderDetail) {
loaderDetail.classList.add('hidden');
}
if (progress) {
// Tokenizer is quick, model is the main download
const totalProgress = stage === 'tokenizer' ? pct * 0.05 : 5 + pct * 0.95;
progress.style.width = `${totalProgress}%`;
}
});
state.chatModelLoaded = true;
// Hide loader, show chat UI
ui.$('llm-loader')?.classList.add('hidden');
ui.$('chat-container')?.classList.remove('hidden');
this.updateStatus('ready', 'Model loaded! Ready to chat');
} catch (error) {
console.error('LLM model loading failed:', error);
if (loadBtn) {
loadBtn.disabled = false;
loadBtn.textContent = 'Retry Load';
}
if (loaderDetail) {
loaderDetail.textContent = `Error: ${error.message}`;
loaderDetail.style.color = 'var(--error)';
}
this.updateStatus('error', `Failed: ${error.message}`);
}
},
/**
* Send message
*/
async send() {
if (!state.chatModelLoaded) {
this.updateStatus('error', 'Load model first by clicking "Load Model"');
return;
}
const input = ui.$('chat-input');
const message = input?.value?.trim();
if (!message || state.chatGenerating) return;
// Clear input
input.value = '';
// Hide welcome message
const welcome = ui.$('chat-messages')?.querySelector('.chat-welcome');
if (welcome) welcome.remove();
// Add user message
this.addMessage('user', message);
// Set generating state
state.chatGenerating = true;
this.updateStatus('loading', 'Generating...');
try {
// Add assistant message placeholder
const assistantMsg = this.addMessage('assistant', 'Thinking...', true);
// Generate response using real model
// Note: TinyLlama in WASM is slow, limit tokens for demo
let response = '';
let tokenCount = 0;
console.log('[Chat] Starting generation...');
const startTime = performance.now();
// Use streaming for real-time feedback
if (state.chatPipeline.chatStream) {
for await (const event of state.chatPipeline.chatStream(message, {
maxNewTokens: 32, // Limited for browser performance
temperature: 0.7,
topP: 0.9,
})) {
response = event.generatedText;
tokenCount++;
assistantMsg.textContent = response;
this.updateStatus('loading', `Generating... (${tokenCount} tokens)`);
// Scroll to bottom
const container = ui.$('chat-messages');
if (container) {
container.scrollTop = container.scrollHeight;
}
}
} else {
// Fallback to non-streaming
this.updateStatus('loading', 'Generating (this may take a while)...');
const result = await state.chatPipeline.chat(message, {
maxNewTokens: 32, // Limited for browser performance
temperature: 0.7,
topP: 0.9,
});
response = result.generatedText;
tokenCount = result.numTokens;
assistantMsg.textContent = response;
}
const elapsed = ((performance.now() - startTime) / 1000).toFixed(1);
console.log(`[Chat] Generated ${tokenCount} tokens in ${elapsed}s`);
// Remove typing indicator
assistantMsg.classList.remove('typing');
// Update history
state.chatHistory.push(
{ role: 'user', content: message },
{ role: 'assistant', content: response }
);
this.updateStatus('ready', 'Ready to chat');
} catch (error) {
this.updateStatus('error', `Error: ${error.message}`);
// Remove typing indicator
const typingMsg = ui.$('chat-messages')?.querySelector('.typing');
if (typingMsg) typingMsg.remove();
} finally {
state.chatGenerating = false;
}
// Scroll to bottom
const container = ui.$('chat-messages');
if (container) {
container.scrollTop = container.scrollHeight;
}
},
/**
* Add message to chat
*/
addMessage(role, content, isTyping = false) {
const container = ui.$('chat-messages');
if (!container) return null;
const msg = document.createElement('div');
msg.className = `chat-message ${role}${isTyping ? ' typing' : ''}`;
msg.textContent = content;
container.appendChild(msg);
container.scrollTop = container.scrollHeight;
return msg;
},
/**
* Update status indicator
*/
updateStatus(status, text) {
const dot = ui.$('chat-status')?.querySelector('.chat-status-dot');
const textEl = ui.$('chat-status-text');
if (dot) {
dot.className = `chat-status-dot ${status === 'loading' ? 'loading' : status === 'error' ? 'error' : ''}`;
}
if (textEl) {
textEl.textContent = text;
}
},
/**
* Clear chat history
*/
clear() {
state.chatHistory = [];
// Clear conversation in pipeline
if (state.chatPipeline) {
state.chatPipeline.clearConversation();
}
const container = ui.$('chat-messages');
if (container) {
container.innerHTML = `
<div class="chat-welcome">
<span class="chat-welcome-icon">🤖</span>
<p>Hi! I'm TinyLlama running entirely in your browser.</p>
<p class="chat-welcome-hint">Ask me anything!</p>
</div>
`;
}
this.updateStatus('ready', 'Ready to chat');
},
};
/* ==========================================================================
7. Demo Class (Public API)
========================================================================== */
/**
* Demo public API - exposed to window for onclick handlers
*/
window.Demo = {
// Model
loadModel: () => features.loadModel(),
testModel: () => features.testModel(),
// SAM Interactive Segmentation
loadSampleImage: () => sam.loadSampleImage(),
clearSegmentation: () => sam.clear(),
downloadMask: () => sam.downloadMask(),
// AI Chat
loadLLM: () => chat.loadModel(),
sendChat: () => chat.send(),
clearChat: () => chat.clear(),
// Core
testTensors: () => features.testTensors(),
classifyText: () => features.classifyText(),
classifyBatch: () => features.classifyBatch(),
extractFeatures: () => features.extractFeatures(),
// Tools
quantize: () => features.quantize(),
prune: () => features.prune(),
debug: () => features.debug(),
benchmark: () => features.benchmark(),
// System
testScheduler: () => features.testScheduler(),
allocateMemory: () => features.allocateMemory(),
cleanupMemory: () => features.cleanupMemory(),
testConcurrency: () => features.testConcurrency(),
// Monitor
startMonitor: () => features.startMonitor(),
stopMonitor: () => features.stopMonitor(),
simulateInferences: () => features.simulateInferences(),
openDashboard: () => features.openDashboard(),
closeDashboard: () => features.closeDashboard(),
};
/* ==========================================================================
8. Initialization
========================================================================== */
/**
* Initialize demo on DOM ready
*/
async function init() {
// Initialize UI
ui.initOutputs();
await ui.updateRuntimeStatus();
ui.updateMemoryStatus();
// Initialize Chat UI (but don't load model yet)
chat.init();
// Initialize SAM and start loading models automatically
await sam.init();
// Setup modal close handlers
const modal = ui.$('dashboard-modal');
if (modal) {
modal.addEventListener('click', (e) => {
if (e.target === modal) {
features.closeDashboard();
}
});
}
// ESC key closes modal
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
features.closeDashboard();
}
});
console.log('✓ edgeFlow.js Demo initialized');
}
// Wait for DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
================================================
FILE: demo/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>edgeFlow.js - Interactive Demo</title>
<link rel="stylesheet" href="/demo/styles.css">
<!-- Import map for onnxruntime-web -->
<script type="importmap">
{
"imports": {
"onnxruntime-web": "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.17.0/dist/esm/ort.webgpu.min.js"
}
}
</script>
</head>
<body>
<div class="container">
<!-- Header -->
<header>
<h1><span>⚡ edgeFlow.js</span></h1>
<p class="subtitle">Lightweight Browser ML Inference Framework</p>
</header>
<!-- Row 1: Status Cards + Model Loading -->
<div class="bento-grid">
<!-- Runtime Status -->
<div class="bento-card span-3">
<div class="card-header">
<div class="card-icon">🖥️</div>
<div class="card-title">Runtime</div>
</div>
<div class="status-list" id="runtime-status"></div>
</div>
<!-- Memory Status -->
<div class="bento-card span-3">
<div class="card-header">
<div class="card-icon green">📊</div>
<div class="card-title">Memory</div>
</div>
<div class="status-list" id="memory-status"></div>
</div>
<!-- Model Loading -->
<div class="bento-card span-6">
<div class="card-header">
<div class="card-icon pink">📦</div>
<div>
<div class="card-title">Load ONNX Model</div>
<div class="card-desc">Download and initialize real ONNX models from Hugging Face</div>
</div>
</div>
<input type="text" id="model-url" placeholder="Enter ONNX model URL..." class="mb-2"
value="https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/onnx/model_quantized.onnx">
<div class="btn-group">
<button onclick="Demo.loadModel()">Load Model</button>
<button class="btn-secondary" onclick="Demo.testModel()">Test Inference</button>
</div>
<div class="output mt-2" id="model-output"></div>
</div>
</div>
<!-- Row 2: Advanced AI Features -->
<div class="bento-grid">
<!-- SAM Interactive Segmentation -->
<div class="bento-card span-6">
<div class="card-header">
<div class="card-icon pink">✂️</div>
<div>
<div class="card-title">Interactive Segmentation</div>
<div class="card-desc">Click to segment objects - powered by SAM (~14MB)</div>
</div>
</div>
<!-- SAM Loading State -->
<div class="model-loader" id="sam-loader">
<div class="loader-content">
<div class="loader-spinner"></div>
<div class="loader-text" id="sam-loader-text">Loading SAM model...</div>
<div class="progress-bar">
<div class="progress-fill" id="sam-progress"></div>
</div>
<div class="loader-detail" id="sam-loader-detail">0%</div>
</div>
</div>
<!-- SAM Main Content -->
<div class="sam-container hidden" id="sam-container">
<div class="sam-upload" id="sam-upload">
<input type="file" id="sam-file-input" accept="image/*" style="display: none;">
<div class="sam-upload-content" onclick="document.getElementById('sam-file-input').click()">
<span class="sam-upload-icon">🖼️</span>
<span>Drop image or click to upload</span>
</div>
</div>
<div class="sam-workspace hidden" id="sam-workspace">
<canvas id="sam-canvas"></canvas>
<canvas id="sam-mask-canvas"></canvas>
</div>
</div>
<div class="btn-group mt-2">
<button onclick="Demo.loadSampleImage()" id="sam-sample-btn" disabled>Sample Image</button>
<button class="btn-secondary" onclick="Demo.clearSegmentation()" id="sam-clear-btn" disabled>Clear</button>
<button class="btn-secondary" onclick="Demo.downloadMask()" id="sam-download-btn" disabled>Download</button>
</div>
<div class="output mt-2" id="sam-output">Loading SAM model... Please wait.</div>
</div>
<!-- LLM Chat -->
<div class="bento-card span-6">
<div class="card-header">
<div class="card-icon green">💬</div>
<div>
<div class="card-title">AI Chat</div>
<div class="card-desc">TinyLlama 1.1B running in your browser (~714MB)</div>
</div>
</div>
<!-- LLM Loading State -->
<div class="model-loader" id="llm-loader">
<div class="loader-content">
<div class="loader-info">
<p>TinyLlama is a 1.1B parameter language model.</p>
<p class="loader-warning">Download size: ~714MB (may take several minutes)</p>
</div>
<button onclick="Demo.loadLLM()" id="llm-load-btn" class="loader-btn">Load Model</button>
<div class="progress-bar hidden" id="llm-progress-container">
<div class="progress-fill" id="llm-progress"></div>
</div>
<div class="loader-detail hidden" id="llm-loader-detail">0%</div>
</div>
</div>
<!-- LLM Chat Content -->
<div class="chat-container hidden" id="chat-container">
<div class="chat-messages" id="chat-messages">
<div class="chat-welcome">
<span class="chat-welcome-icon">🤖</span>
<p>Hi! I'm TinyLlama running entirely in your browser.</p>
<p class="chat-welcome-hint">Ask me anything!</p>
</div>
</div>
<div class="chat-input-container">
<input type="text" id="chat-input" placeholder="Type a message..." class="chat-input">
<button onclick="Demo.sendChat()" id="chat-send-btn">Send</button>
</div>
</div>
<div class="chat-status" id="chat-status">
<span class="chat-status-dot"></span>
<span id="chat-status-text">Click "Load Model" to start</span>
</div>
</div>
</div>
<!-- Row 3: Core Operations -->
<div class="bento-grid">
<!-- Tensor Operations -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon">🧮</div>
<div>
<div class="card-title">Tensor Operations</div>
<div class="card-desc">Create, manipulate, and compute tensors</div>
</div>
</div>
<button onclick="Demo.testTensors()">Run Tests</button>
<div class="output mt-2" id="tensor-output"></div>
</div>
<!-- Text Classification -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon pink">📝</div>
<div>
<div class="card-title">Text Classification</div>
<div class="card-desc">Sentiment analysis with loaded model</div>
</div>
</div>
<input type="text" id="text-input" placeholder="Enter text..." value="I love this product!" class="mb-2">
<div class="btn-group">
<button onclick="Demo.classifyText()">Classify</button>
<button class="btn-secondary" onclick="Demo.classifyBatch()">Batch</button>
</div>
<div class="output mt-2" id="text-output"></div>
</div>
<!-- Feature Extraction -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon green">🔍</div>
<div>
<div class="card-title">Feature Extraction</div>
<div class="card-desc">Extract embeddings from text</div>
</div>
</div>
<textarea id="feature-input" class="mb-2" placeholder="Enter text...">Machine learning is transforming software.</textarea>
<button onclick="Demo.extractFeatures()">Extract</button>
<div class="output mt-2" id="feature-output"></div>
</div>
</div>
<!-- Row 4: Tools -->
<div class="bento-grid">
<!-- Quantization -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon orange">📦</div>
<div>
<div class="card-title">Model Quantization</div>
<div class="card-desc">Compress tensors to int8/float16</div>
</div>
</div>
<div class="btn-group mb-2">
<button onclick="Demo.quantize()">Quantize</button>
<button class="btn-secondary" onclick="Demo.prune()">Prune</button>
</div>
<div class="output" id="quant-output"></div>
</div>
<!-- Debugger -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon">🔬</div>
<div>
<div class="card-title">Tensor Debugger</div>
<div class="card-desc">Inspect tensor statistics & distribution</div>
</div>
</div>
<button onclick="Demo.debug()">Inspect Tensor</button>
<div class="output mt-2" id="debugger-output"></div>
</div>
<!-- Benchmark -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon pink">⚡</div>
<div>
<div class="card-title">Benchmark</div>
<div class="card-desc">Measure operation performance</div>
</div>
</div>
<button onclick="Demo.benchmark()">Run Benchmark</button>
<div class="output mt-2" id="benchmark-output"></div>
</div>
</div>
<!-- Row 5: System -->
<div class="bento-grid">
<!-- Scheduler -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon green">📋</div>
<div>
<div class="card-title">Task Scheduler</div>
<div class="card-desc">Priority-based task scheduling</div>
</div>
</div>
<button onclick="Demo.testScheduler()">Test Scheduler</button>
<div class="output mt-2" id="scheduler-output"></div>
</div>
<!-- Memory Management -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon orange">💾</div>
<div>
<div class="card-title">Memory Management</div>
<div class="card-desc">Allocate, track, and release tensors</div>
</div>
</div>
<div class="btn-group">
<button onclick="Demo.allocateMemory()">Allocate</button>
<button class="btn-secondary" onclick="Demo.cleanupMemory()">Cleanup</button>
</div>
<div class="output mt-2" id="memory-output"></div>
</div>
<!-- Concurrency -->
<div class="bento-card span-4">
<div class="card-header">
<div class="card-icon">⚡</div>
<div>
<div class="card-title">Concurrent Execution</div>
<div class="card-desc">Run multiple inferences in parallel</div>
</div>
</div>
<button onclick="Demo.testConcurrency()">Run Test</button>
<div class="output mt-2" id="concurrency-output"></div>
<div class="metrics mt-2 hidden" id="concurrency-metrics"></div>
</div>
</div>
<!-- Row 6: Monitor -->
<div class="bento-grid">
<div class="bento-card span-12">
<div class="card-header">
<div class="card-icon pink">📊</div>
<div>
<div class="card-title">Performance Monitor</div>
<div class="card-desc">Real-time performance metrics and visualization</div>
</div>
</div>
<div class="btn-group mb-2">
<button onclick="Demo.startMonitor()">Start</button>
<button class="btn-secondary" onclick="Demo.simulateInferences()">Simulate</button>
<button class="btn-secondary" onclick="Demo.openDashboard()">Dashboard</button>
<button class="btn-secondary" onclick="Demo.stopMonitor()">Stop</button>
</div>
<div class="metrics" id="monitor-metrics"></div>
</div>
</div>
<!-- Footer -->
<footer>
<p>edgeFlow.js v0.1.0 | <a href="https://github.com/nicepkg/edgeflow.js" target="_blank">GitHub</a></p>
</footer>
</div>
<!-- Dashboard Modal -->
<div class="modal-overlay" id="dashboard-modal">
<div class="modal">
<div class="modal-header">
<span class="modal-title">📊 Performance Dashboard</span>
<button class="modal-close" onclick="Demo.closeDashboard()">×</button>
</div>
<iframe id="dashboard-frame" class="modal-frame"></iframe>
</div>
</div>
<!-- Demo Script -->
<script type="module" src="/demo/demo.js"></script>
</body>
</html>
================================================
FILE: demo/server.js
================================================
/**
* Simple development server for testing edgeFlow.js
*
* Usage: node demo/server.js
*/
import { createServer } from 'http';
import { readFile } from 'fs/promises';
import { extname, join } from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const ROOT = join(__dirname, '..');
const MIME_TYPES = {
'.html': 'text/html',
'.js': 'application/javascript',
'.mjs': 'application/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.wasm': 'application/wasm',
};
const PORT = process.env.PORT || 3000;
const server = createServer(async (req, res) => {
let url = req.url || '/';
// Default to demo/index.html
if (url === '/') {
url = '/demo/index.html';
}
const filePath = join(ROOT, url);
const ext = extname(filePath);
const mimeType = MIME_TYPES[ext] || 'application/octet-stream';
try {
const content = await readFile(filePath);
// Add CORS and security headers for WebGPU/WASM
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
res.setHeader('Content-Type', mimeType);
res.setHeader('Access-Control-Allow-Origin', '*');
res.writeHead(200);
res.end(content);
} catch (error) {
if (error.code === 'ENOENT') {
res.writeHead(404);
res.end(`File not found: ${url}`);
} else {
res.writeHead(500);
res.end(`Server error: ${error.message}`);
}
}
});
server.listen(PORT, () => {
console.log(`
╔══════════════════════════════════════════════════════╗
║ ║
║ ⚡ edgeFlow.js Development Server ║
║ ║
║ Local: http://localhost:${PORT} ║
║ ║
║ Press Ctrl+C to stop ║
║ ║
╚══════════════════════════════════════════════════════╝
`);
});
================================================
FILE: demo/styles.css
================================================
/**
* edgeFlow.js Demo - Spotify-inspired Theme
*
* Design: Spotify color palette + liquid glass
* - Deep blacks and grays
* - Signature green accent
* - Clean, bold typography
* - Subtle glass effects
*/
/* ==========================================================================
1. Variables & Reset
========================================================================== */
:root {
/* 牛油果绿配色 */
--color-accent: #7fa921;
--color-accent-light: #8fbc2a;
--color-accent-dim: rgba(127, 169, 33, 0.12);
--color-dark: #5a5755;
--color-light: #e2e1e6;
/* Background - 明亮风格 */
--bg-base: #d8d7dc;
--bg-elevated: var(--color-light);
--bg-highlight: #eaeaed;
/* Glass - 浅色玻璃效果 */
--glass-bg: rgba(255, 255, 255, 0.6);
--glass-bg-hover: rgba(255, 255, 255, 0.8);
--glass-border: rgba(255, 255, 255, 0.8);
--glass-border-hover: rgba(255, 255, 255, 0.95);
--glass-highlight: rgba(255, 255, 255, 0.5);
/* Text - 深色文字 */
--text-primary: var(--color-dark);
--text-secondary: #6e6b69;
--text-muted: #8a8886;
/* Accent variations */
--accent: var(--color-accent);
--accent-hover: var(--color-accent-light);
--accent-dim: var(--color-accent-dim);
/* Status */
--success: var(--color-accent);
--warning: #d4a520;
--error: #c45c4a;
/* Spacing */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 0.75rem;
--space-lg: 1rem;
--space-xl: 1.5rem;
/* Border Radius */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-full: 9999px;
/* Fonts */
--font-sans: 'Circular', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif;
--font-mono: 'Fira Code', 'SF Mono', monospace;
/* Glass blur */
--blur-glass: 40px;
}
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: var(--font-sans);
background: linear-gradient(145deg, #d0cfd4 0%, var(--bg-base) 50%, #cccbd0 100%);
color: var(--text-primary);
min-height: 100vh;
line-height: 1.6;
overflow-x: hidden;
}
/* Subtle gradient overlay */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
height: 500px;
background: linear-gradient(180deg,
rgba(127, 169, 33, 0.1) 0%,
transparent 100%);
pointer-events: none;
z-index: 0;
}
/* ==========================================================================
2. Layout
========================================================================== */
.container {
max-width: 1440px;
margin: 0 auto;
padding: var(--space-xl);
position: relative;
z-index: 1;
}
.bento-grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--space-lg);
margin-bottom: var(--space-lg);
}
.span-3 { grid-column: span 3; }
.span-4 { grid-column: span 4; }
.span-5 { grid-column: span 5; }
.span-6 { grid-column: span 6; }
.span-7 { grid-column: span 7; }
.span-8 { grid-column: span 8; }
.span-12 { grid-column: span 12; }
/* ==========================================================================
3. Header
========================================================================== */
header {
text-align: center;
padding: 3rem 2rem;
margin-bottom: 2rem;
position: relative;
/* 绿色渐变背景 */
background: linear-gradient(135deg, var(--color-accent) 0%, #6a9020 100%);
border-radius: var(--radius-xl);
overflow: hidden;
box-shadow: 0 10px 40px -10px rgba(127, 169, 33, 0.4);
}
/* 白色光晕 */
header::before {
content: '';
position: absolute;
top: -30%;
left: 50%;
transform: translateX(-50%);
width: 500px;
height: 250px;
background: radial-gradient(ellipse, rgba(255, 255, 255, 0.3) 0%, transparent 70%);
pointer-events: none;
}
h1 {
font-size: 3rem;
font-weight: 700;
letter-spacing: -0.04em;
margin-bottom: var(--space-sm);
position: relative;
}
h1 span {
color: #ffffff;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 白色下划线 */
h1::after {
content: '';
display: block;
width: 60px;
height: 4px;
background: rgba(255, 255, 255, 0.8);
border-radius: 2px;
margin: var(--space-md) auto 0;
}
.subtitle {
color: rgba(255, 255, 255, 0.85);
font-size: 1rem;
font-weight: 400;
position: relative;
}
/* ==========================================================================
4. Cards - Spotify Style with Glass
========================================================================== */
.bento-card {
position: relative;
padding: 1.25rem;
/* 浅色玻璃卡片 */
background: var(--glass-bg);
backdrop-filter: blur(var(--blur-glass)) saturate(180%);
-webkit-backdrop-filter: blur(var(--blur-glass)) saturate(180%);
border: 1px solid var(--glass-border);
border-radius: var(--radius-lg);
box-shadow:
0 4px 24px -8px rgba(0, 0, 0, 0.08),
inset 0 1px 0 0 rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
}
.bento-card:hover {
background: var(--glass-bg-hover);
border-color: var(--glass-border-hover);
transform: translateY(-2px);
box-shadow:
0 8px 32px -8px rgba(0, 0, 0, 0.12),
inset 0 1px 0 0 rgba(255, 255, 255, 0.9);
}
/* Card Header */
.card-header {
display: flex;
align-items: center;
gap: var(--space-md);
margin-bottom: var(--space-lg);
}
.card-icon {
width: 40px;
height: 40px;
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.25rem;
flex-shrink: 0;
/* 统一黄色背景 */
background: #f0c850;
}
.card-icon.pink,
.card-icon.green,
.card-icon.orange {
background: #f0c850;
}
.card-title {
font-size: 1rem;
font-weight: 700;
color: var(--text-primary);
letter-spacing: -0.01em;
}
.card-desc {
font-size: 0.8125rem;
color: var(--text-muted);
margin-top: 2px;
}
/* ==========================================================================
5. Components
========================================================================== */
/* Buttons */
button {
position: relative;
padding: 0.75rem 2rem;
font-family: inherit;
font-size: 0.875rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
cursor: pointer;
border-radius: var(--radius-full);
transition: all 0.2s ease;
/* Primary accent button */
background: var(--accent);
border: none;
color: #ffffff;
box-shadow: 0 4px 12px -4px rgba(127, 169, 33, 0.4);
}
button:hover {
background: var(--accent-hover);
transform: scale(1.04);
box-shadow: 0 6px 16px -4px rgba(127, 169, 33, 0.5);
}
button:active {
transform: scale(1);
}
button:disabled {
opacity: 0.4;
cursor: not-allowed;
transform: none;
}
.btn-secondary {
background: rgba(255, 255, 255, 0.6);
border: 1px solid rgba(66, 63, 61, 0.2);
color: var(--color-dark);
box-shadow: none;
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 63, 61, 0.3);
transform: scale(1.04);
box-shadow: 0 4px 12px -4px rgba(0, 0, 0, 0.1);
}
.btn-sm {
padding: 0.5rem 1rem;
font-size: 0.75rem;
}
.btn-group {
display: flex;
gap: var(--space-sm);
flex-wrap: wrap;
}
/* Inputs */
input,
textarea {
width: 100%;
padding: 0.75rem 1rem;
font-family: inherit;
font-size: 0.875rem;
border-radius: var(--radius-md);
transition: all 0.2s;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(66, 63, 61, 0.15);
color: var(--text-primary);
}
input:focus,
textarea:focus {
outline: none;
border-color: var(--accent);
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 0 0 3px rgba(127, 169, 33, 0.1);
}
input::placeholder,
textarea::placeholder {
color: var(--text-muted);
}
textarea {
min-height: 80px;
resize: vertical;
}
/* Status List */
.status-list {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.status-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--space-sm) var(--space-md);
font-size: 0.875rem;
background: rgba(255, 255, 255, 0.5);
border-radius: var(--radius-sm);
}
.status-badge {
padding: var(--space-xs) var(--space-md);
border-radius: var(--radius-full);
font-size: 0.6875rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-success {
background: var(--accent-dim);
color: var(--accent);
}
.status-warning {
background: rgba(245, 158, 11, 0.15);
color: var(--warning);
}
.status-error {
background: rgba(233, 20, 41, 0.15);
color: var(--error);
}
.status-pending {
background: rgba(255, 255, 255, 0.05);
color: var(--text-muted);
}
/* ==========================================================================
6. Output & Metrics
========================================================================== */
.output {
padding: 1rem;
font-family: var(--font-mono);
font-size: 0.75rem;
overflow-x: auto;
max-height: 200px;
overflow-y: auto;
line-height: 1.7;
background: var(--color-dark);
border-radius: var(--radius-md);
color: var(--color-light);
}
.output pre {
white-space: pre-wrap;
word-break: break-word;
margin: 0;
}
.output .success { color: var(--accent); }
.output .error { color: #e8806e; }
.output .info { color: var(--color-light); }
.output .warn { color: #e8c860; }
/* Metrics */
.metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
gap: var(--space-md);
}
.metric {
text-align: center;
padding: var(--space-md);
background: rgba(255, 255, 255, 0.5);
border-radius: var(--radius-md);
transition: background 0.2s;
}
.metric:hover {
background: rgba(255, 255, 255, 0.7);
}
.metric-value {
font-size: 1.5rem;
font-weight: 700;
color: var(--accent);
font-variant-numeric: tabular-nums;
}
.metric-label {
font-size: 0.6875rem;
color: var(--text-muted);
margin-top: var(--space-xs);
text-transform: uppercase;
letter-spacing: 0.1em;
font-weight: 700;
}
/* ==========================================================================
7. Modal
========================================================================== */
.modal-overlay {
position: fixed;
inset: 0;
z-index: 1000;
display: none;
align-items: center;
justify-content: center;
padding: 2rem;
background: rgba(66, 63, 61, 0.6);
backdrop-filter: blur(8px);
}
.modal-overlay.active {
display: flex;
animation: fadeIn 0.2s ease;
}
.modal {
position: relative;
width: 100%;
max-width: 1200px;
height: 90vh;
overflow: hidden;
background: var(--color-light);
border-radius: var(--radius-xl);
box-shadow: 0 25px 80px -20px rgba(0, 0, 0, 0.3);
animation: slideUp 0.3s ease;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-lg) var(--space-xl);
background: rgba(255, 255, 255, 0.5);
border-bottom: 1px solid rgba(66, 63, 61, 0.1);
}
.modal-title {
font-size: 1rem;
font-weight: 700;
color: var(--text-primary);
}
.modal-close {
width: 32px;
height: 32px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.25rem;
line-height: 1;
cursor: pointer;
background: rgba(196, 92, 74, 0.1);
border: none;
border-radius: var(--radius-full);
color: var(--error);
transition: all 0.2s;
}
.modal-close:hover {
background: rgba(196, 92, 74, 0.2);
color: var(--error);
transform: scale(1.1);
}
.modal-frame {
width: 100%;
height: calc(100% - 60px);
border: none;
background: var(--color-dark);
}
/* ==========================================================================
8. Footer
========================================================================== */
footer {
text-align: center;
padding: 2rem;
color: var(--text-muted);
font-size: 0.8125rem;
}
footer a {
color: var(--text-secondary);
text-decoration: none;
transition: color 0.2s;
}
footer a:hover {
color: var(--accent);
}
/* ==========================================================================
9. Utilities
========================================================================== */
.hidden { display: none !important; }
.mt-1 { margin-top: var(--space-sm); }
.mt-2 { margin-top: var(--space-md); }
.mt-3 { margin-top: var(--space-lg); }
.mb-1 { margin-bottom: var(--space-sm); }
.mb-2 { margin-bottom: var(--space-md); }
/* Loader */
.loader {
display: inline-block;
width: 14px;
height: 14px;
border: 2px solid rgba(127, 169, 33, 0.3);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 0.8s linear infinite;
vertical-align: middle;
margin-right: var(--space-sm);
}
/* ==========================================================================
10. Animations
========================================================================== */
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.05);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: rgba(66, 63, 61, 0.3);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(66, 63, 61, 0.5);
}
/* ==========================================================================
11. Responsive
========================================================================== */
@media (max-width: 1024px) {
.span-3,
.span-4,
.span-5 { grid-column: span 6; }
.span-7,
.span-8 { grid-column: span 12; }
}
@media (max-width: 768px) {
.container { padding: var(--space-lg); }
h1 { font-size: 2rem; }
header { padding: 2rem 1.5rem; }
.bento-grid { grid-template-columns: 1fr; }
.span-3,
.span-4,
.span-5,
.span-6,
.span-7,
.span-8,
.span-12 { grid-column: span 1; }
button {
padding: 0.625rem 1.5rem;
}
.modal { height: 95vh; }
.modal-overlay { padding: var(--space-lg); }
}
/* ==========================================================================
12. SAM Interactive Segmentation
========================================================================== */
.sam-container {
position: relative;
width: 100%;
min-height: 250px;
border-radius: var(--radius-md);
overflow: hidden;
background: var(--color-dark);
}
.sam-upload {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: 2px dashed rgba(255, 255, 255, 0.3);
border-radius: var(--radius-md);
transition: all 0.3s;
}
.sam-upload:hover {
border-color: var(--accent);
background: rgba(127, 169, 33, 0.1);
}
.sam-upload-content {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-sm);
color: var(--color-light);
opacity: 0.7;
}
.sam-upload-icon {
font-size: 2.5rem;
}
.sam-workspace {
position: relative;
width: 100%;
height: 250px;
}
.sam-workspace canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
#sam-canvas {
z-index: 1;
}
#sam-mask-canvas {
z-index: 2;
pointer-events: none;
opacity: 0.5;
}
/* Click indicator */
.sam-point {
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
transform: translate(-50%, -50%);
z-index: 3;
pointer-events: none;
animation: pointPulse 0.3s ease-out;
}
.sam-point.positive {
background: var(--accent);
box-shadow: 0 0 0 3px rgba(127, 169, 33, 0.3);
}
.sam-point.negative {
background: var(--error);
box-shadow: 0 0 0 3px rgba(196, 92, 74, 0.3);
}
@keyframes pointPulse {
0% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
50% { transform: translate(-50%, -50%) scale(1.2); }
100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
/* ==========================================================================
13. AI Chat
========================================================================== */
.chat-container {
display: flex;
flex-direction: column;
height: 400px;
min-height: 300px;
background: var(--color-dark);
border-radius: var(--radius-md);
overflow: hidden;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: var(--space-md);
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.chat-welcome {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
text-align: center;
color: var(--color-light);
opacity: 0.7;
}
.chat-welcome-icon {
font-size: 2.5rem;
margin-bottom: var(--space-sm);
}
.chat-welcome p {
margin: var(--space-xs) 0;
font-size: 0.875rem;
}
.chat-welcome-hint {
opacity: 0.6;
font-size: 0.75rem !important;
}
.chat-message {
max-width: 85%;
padding: var(--space-sm) var(--space-md);
border-radius: var(--radius-md);
font-size: 0.875rem;
line-height: 1.5;
animation: messageSlide 0.2s ease-out;
}
@keyframes messageSlide {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.chat-message.user {
align-self: flex-end;
background: var(--accent);
color: white;
border-bottom-right-radius: 4px;
}
.chat-message.assistant {
align-self: flex-start;
background: rgba(255, 255, 255, 0.1);
color: var(--color-light);
border-bottom-left-radius: 4px;
}
.chat-message.assistant.typing::after {
content: '▋';
animation: blink 0.7s infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.chat-input-container {
display: flex;
gap: var(--space-sm);
padding: var(--space-sm);
background: rgba(0, 0, 0, 0.2);
}
.chat-input {
flex: 1;
padding: var(--space-sm) var(--space-md);
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: var(--radius-full);
color: var(--color-light);
font-size: 0.875rem;
}
.chat-input:focus {
outline: none;
border-color: var(--accent);
background: rgba(255, 255, 255, 0.15);
}
.chat-input::placeholder {
color: rgba(255, 255, 255, 0.4);
}
.chat-input-container button {
padding: var(--space-sm) var(--space-lg);
font-size: 0.75rem;
}
.chat-status {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) 0;
font-size: 0.75rem;
color: var(--text-muted);
}
.chat-status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--accent);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.chat-status-dot.loading {
background: var(--warning);
animation: pulse 0.5s infinite;
}
.chat-status-dot.error {
background: var(--error);
animation: none;
}
/* ==========================================================================
14. Model Loader
========================================================================== */
.model-loader {
display: flex;
align-items: center;
justify-content: center;
min-height: 250px;
background: var(--color-dark);
border-radius: var(--radius-md);
padding: var(--space-xl);
}
.loader-content {
text-align: center;
max-width: 300px;
}
.loader-spinner {
width: 48px;
height: 48px;
margin: 0 auto var(--space-lg);
border: 3px solid rgba(127, 169, 33, 0.2);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loader-text {
color: var(--color-light);
font-size: 0.875rem;
margin-bottom: var(--space-sm);
}
.loader-detail {
color: var(--text-muted);
font-size: 0.75rem;
font-family: var(--font-mono);
}
.loader-info {
color: var(--color-light);
font-size: 0.875rem;
margin-bottom: var(--space-lg);
line-height: 1.6;
}
.loader-info p {
margin: var(--space-xs) 0;
}
.loader-warning {
color: var(--warning) !important;
font-size: 0.75rem !important;
opacity: 0.9;
}
.loader-btn {
margin-bottom: var(--space-lg);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: rgba(255, 255, 255, 0.1);
border-radius: var(--radius-full);
overflow: hidden;
margin: var(--space-md) 0;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--accent), var(--accent-hover));
border-radius: var(--radius-full);
width: 0%;
transition: width 0.3s ease;
}
.progress-fill.downloading {
background: linear-gradient(90deg, var(--accent), var(--accent-hover));
animation: progressPulse 1.5s ease-in-out infinite;
}
@keyframes progressPulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
/* Model loader states */
.model-loader.loading .loader-spinner {
display: block;
}
.model-loader.ready {
display: none;
}
/* Success state for SAM */
.sam-ready .model-loader {
display: none;
}
.sam-ready .sam-container {
display: block !important;
}
================================================
FILE: dist/backends/index.d.ts
================================================
/**
* edgeFlow.js - Backend Exports
*/
export { WebGPURuntime, createWebGPURuntime } from './webgpu.js';
export { WebNNRuntime, createWebNNRuntime } from './webnn.js';
export { WASMRuntime, createWASMRuntime } from './wasm.js';
export { ONNXRuntime, createONNXRuntime, isOnnxAvailable } from './onnx.js';
export { TransformersAdapterRuntime, useTransformersBackend, getTransformersAdapter, type TransformersAdapterOptions, type TransformersPipelineFactory, } from './transformers-adapter.js';
export type { Runtime, RuntimeType, RuntimeCapabilities } from '../core/types.js';
/**
* Register all available backends.
*
* Always registers the ONNX Runtime factory synchronously so there is no
* async race between registration and the first pipeline() call.
* `ONNXRuntime.isAvailable()` is called lazily by RuntimeManager when it
* selects a backend, so if onnxruntime-web is not installed the runtime is
* simply skipped at that point.
*/
export declare function registerAllBackends(): void;
//# sourceMappingURL=index.d.ts.map
================================================
FILE: dist/backends/index.js
================================================
/**
* edgeFlow.js - Backend Exports
*/
// WebGPU Backend (planned - skeleton only)
export { WebGPURuntime, createWebGPURuntime } from './webgpu.js';
// WebNN Backend (planned - skeleton only)
export { WebNNRuntime, createWebNNRuntime } from './webnn.js';
// WASM Backend (basic tensor ops)
export { WASMRuntime, createWASMRuntime } from './wasm.js';
// ONNX Runtime Backend (real model inference)
export { ONNXRuntime, createONNXRuntime, isOnnxAvailable } from './onnx.js';
// transformers.js Adapter Backend
export { TransformersAdapterRuntime, useTransformersBackend, getTransformersAdapter, } from './transformers-adapter.js';
import { registerRuntime } from '../core/runtime.js';
import { createONNXRuntime } from './onnx.js';
/**
* Register all available backends.
*
* Always registers the ONNX Runtime factory synchronously so there is no
* async race between registration and the first pipeline() call.
* `ONNXRuntime.isAvailable()` is called lazily by RuntimeManager when it
* selects a backend, so if onnxruntime-web is not installed the runtime is
* simply skipped at that point.
*/
export function registerAllBackends() {
registerRuntime('wasm', createONNXRuntime);
}
/**
* Auto-register backends on module load (synchronous — no race condition).
*/
registerAllBackends();
//# sourceMappingURL=index.js.map
================================================
FILE: dist/backends/onnx.d.ts
================================================
/**
* edgeFlow.js - ONNX Runtime Backend
*
* Uses onnxruntime-web for real ONNX model inference.
* onnxruntime-web is an optional peer dependency loaded dynamically.
*/
import { Runtime, RuntimeType, RuntimeCapabilities, LoadedModel, ModelLoadOptions, Tensor } from '../core/types.js';
/**
* Check whether onnxruntime-web is importable.
*/
export declare function isOnnxAvailable(): Promise<boolean>;
/**
* ONNXRuntime - Real ONNX model inference using onnxruntime-web
*/
export declare class ONNXRuntime implements Runtime {
readonly name: RuntimeType;
private initialized;
private executionProvider;
get capabilities(): RuntimeCapabilities;
/**
* Check if ONNX Runtime is available (peer dependency installed)
*/
isAvailable(): Promise<boolean>;
/**
* Initialize the ONNX runtime
*/
initialize(): Promise<void>;
/**
* Load a model from ArrayBuffer
*/
loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;
/**
* Run inference
*/
run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;
/**
* Run inference with named inputs
*/
runNamed(model: LoadedModel, namedInputs: Map<string, Tensor>): Promise<Tensor[]>;
/**
* Unload a model
*/
private unloadModel;
/**
* Dispose the runtime
*/
dispose(): void;
}
/**
* Create ONNX runtime factory
*/
export declare function createONNXRuntime(): Runtime;
//# sourceMappingURL=onnx.d.ts.map
================================================
FILE: dist/backends/onnx.js
================================================
/**
* edgeFlow.js - ONNX Runtime Backend
*
* Uses onnxruntime-web for real ONNX model inference.
* onnxruntime-web is an optional peer dependency loaded dynamically.
*/
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
import { LoadedModelImpl } from '../core/runtime.js';
import { EdgeFlowTensor } from '../core/tensor.js';
import { getMemoryManager } from '../core/memory.js';
// Lazy-loaded onnxruntime-web module
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let ort = null;
async function getOrt() {
if (ort)
return ort;
try {
// Import the WASM-only sub-path so Vite rewrites the bare specifier
// to ort.wasm.bundle.min.mjs. This avoids loading the JSEP/WebGPU
// worker module (jsep.mjs) that ort.bundle.min.mjs eagerly fetches
// whenever navigator.gpu exists — which causes a 404 in dev servers
// that restrict ES module imports from /public.
ort = await import('onnxruntime-web/wasm');
return ort;
}
catch {
return null;
}
}
/**
* Check whether onnxruntime-web is importable.
*/
export async function isOnnxAvailable() {
return (await getOrt()) != null;
}
const sessionStore = new Map();
// ============================================================================
// ONNX Runtime Implementation
// ============================================================================
/**
* ONNXRuntime - Real ONNX model inference using onnxruntime-web
*/
export class ONNXRuntime {
name = 'wasm'; // Register as wasm since it's the fallback
initialized = false;
executionProvider = 'wasm';
get capabilities() {
return {
concurrency: true,
quantization: true,
float16: this.executionProvider === 'webgpu',
dynamicShapes: true,
maxBatchSize: 32,
availableMemory: 512 * 1024 * 1024, // 512MB
};
}
/**
* Check if ONNX Runtime is available (peer dependency installed)
*/
async isAvailable() {
return isOnnxAvailable();
}
/**
* Initialize the ONNX runtime
*/
async initialize() {
if (this.initialized)
return;
const ortModule = await getOrt();
if (!ortModule) {
throw new EdgeFlowError('onnxruntime-web is not installed. Install it with: npm install onnxruntime-web', ErrorCodes.RUNTIME_NOT_AVAILABLE);
}
// Configure WASM backend for browser use.
// numThreads=1 disables multi-threading so ort only needs the plain
// .wasm binary — the worker .mjs file is never requested, which avoids
// Vite's restriction on importing files from /public as ES modules.
// Consumers should copy onnxruntime-web/dist/*.wasm to public/ort/.
if (typeof window !== 'undefined' && ortModule.env?.wasm) {
ortModule.env.wasm.wasmPaths = '/ort/';
ortModule.env.wasm.numThreads = 1;
}
this.initialized = true;
}
/**
* Load a model from ArrayBuffer
*/
async loadModel(modelData, options = {}) {
if (!this.initialized) {
await this.initialize();
}
try {
const ortModule = await getOrt();
if (!ortModule) {
throw new Error('onnxruntime-web is not installed');
}
// WASM-only execution provider — WebGPU acceleration can be added
// later via the dedicated WebGPURuntime backend.
const sessionOptions = {
executionProviders: ['wasm'],
graphOptimizationLevel: 'all',
};
const modelBytes = new Uint8Array(modelData);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const session = await ortModule.InferenceSession.create(modelBytes, sessionOptions);
// Get input/output names
const inputNames = session.inputNames;
const outputNames = session.outputNames;
// Generate model ID
const modelId = `onnx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
// Store session
sessionStore.set(modelId, {
session,
inputNames: [...inputNames],
outputNames: [...outputNames],
});
// Create metadata
const metadata = {
name: options.metadata?.name ?? 'onnx-model',
version: '1.0.0',
inputs: inputNames.map((name) => ({
name,
dtype: 'float32',
shape: [-1], // Dynamic shape
})),
outputs: outputNames.map((name) => ({
name,
dtype: 'float32',
shape: [-1],
})),
sizeBytes: modelData.byteLength,
quantization: options.quantization ?? 'float32',
format: 'onnx',
};
// Create model instance
const model = new LoadedModelImpl(metadata, 'wasm', () => this.unloadModel(modelId));
// Override the ID to match our stored session
Object.defineProperty(model, 'id', { value: modelId, writable: false });
// Track in memory manager
getMemoryManager().trackModel(model, () => model.dispose());
return model;
}
catch (error) {
throw new EdgeFlowError(`Failed to load ONNX model: ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.MODEL_LOAD_FAILED, { error });
}
}
/**
* Run inference
*/
async run(model, inputs) {
const sessionData = sessionStore.get(model.id);
if (!sessionData) {
throw new EdgeFlowError(`ONNX session not found for model ${model.id}`, ErrorCodes.MODEL_NOT_LOADED, { modelId: model.id });
}
const { session, inputNames, outputNames } = sessionData;
try {
const ortModule = await getOrt();
const feeds = {};
for (let i = 0; i < Math.min(inputs.length, inputNames.length); i++) {
const inputName = inputNames[i];
const inputTensor = inputs[i];
if (inputName && inputTensor) {
const dtype = inputTensor.dtype;
let ortTensor;
if (dtype === 'int64') {
const data = inputTensor.data;
ortTensor = new ortModule.Tensor('int64', data, inputTensor.shape);
}
else if (dtype === 'int32') {
const data = inputTensor.data;
ortTensor = new ortModule.Tensor('int32', data, inputTensor.shape);
}
else {
const data = inputTensor.toFloat32Array();
ortTensor = new ortModule.Tensor('float32', data, inputTensor.shape);
}
feeds[inputName] = ortTensor;
}
}
const results = await session.run(feeds);
// Convert outputs to EdgeFlowTensor
const outputs = [];
for (const outputName of outputNames) {
const ortTensor = results[outputName];
if (ortTensor) {
const data = ortTensor.data;
const shape = Array.from(ortTensor.dims).map(d => Number(d));
outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));
}
}
return outputs;
}
catch (error) {
throw new EdgeFlowError(`ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.INFERENCE_FAILED, { modelId: model.id, error });
}
}
/**
* Run inference with named inputs
*/
async runNamed(model, namedInputs) {
const sessionData = sessionStore.get(model.id);
if (!sessionData) {
throw new EdgeFlowError(`ONNX session not found for model ${model.id}`, ErrorCodes.MODEL_NOT_LOADED, { modelId: model.id });
}
const { session, inputNames, outputNames } = sessionData;
try {
const ortModule = await getOrt();
const feeds = {};
for (const [inputName, inputTensor] of namedInputs) {
const tensor = inputTensor;
const dtype = tensor.dtype;
let ortTensor;
if (dtype === 'int64') {
const data = tensor.data;
ortTensor = new ortModule.Tensor('int64', data, tensor.shape);
}
else if (dtype === 'int32') {
const data = tensor.data;
ortTensor = new ortModule.Tensor('int32', data, tensor.shape);
}
else {
const data = tensor.toFloat32Array();
ortTensor = new ortModule.Tensor('float32', data, tensor.shape);
}
feeds[inputName] = ortTensor;
}
const results = await session.run(feeds);
// Convert outputs to EdgeFlowTensor
const outputs = [];
for (const outputName of outputNames) {
const ortTensor = results[outputName];
if (ortTensor) {
const data = ortTensor.data;
const shape = Array.from(ortTensor.dims).map(d => Number(d));
outputs.push(new EdgeFlowTensor(new Float32Array(data), shape, 'float32'));
}
}
return outputs;
}
catch (error) {
throw new EdgeFlowError(`ONNX inference failed: ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.INFERENCE_FAILED, { modelId: model.id, expectedInputs: inputNames, providedInputs: Array.from(namedInputs.keys()), error });
}
}
/**
* Unload a model
*/
async unloadModel(modelId) {
const sessionData = sessionStore.get(modelId);
if (sessionData) {
// Release session will be handled by GC
sessionStore.delete(modelId);
}
}
/**
* Dispose the runtime
*/
dispose() {
// Clear all sessions
sessionStore.clear();
this.initialized = false;
}
}
/**
* Create ONNX runtime factory
*/
export function createONNXRuntime() {
return new ONNXRuntime();
}
//# sourceMappingURL=onnx.js.map
================================================
FILE: dist/backends/transformers-adapter.d.ts
================================================
/**
* edgeFlow.js - transformers.js Adapter Backend
*
* Wraps transformers.js (by Hugging Face) as an inference backend, giving
* users access to 1000+ HuggingFace models while adding edgeFlow.js's
* orchestration layer (scheduling, caching, memory management, workers).
*
* @example
* ```typescript
* import { useTransformersBackend } from 'edgeflowjs';
* import { pipeline as tfPipeline } from '@xenova/transformers';
*
* // Register the adapter
* useTransformersBackend();
*
* // Now use edgeFlow.js pipeline API — inference delegates to transformers.js
* const classifier = await pipeline('text-classification', {
* model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
* });
*
* // edgeFlow.js handles scheduling, batching, memory, caching
* const results = await classifier.runBatch(thousandsOfTexts);
* ```
*/
import { Runtime, RuntimeType, RuntimeCapabilities, LoadedModel, ModelLoadOptions, Tensor } from '../core/types.js';
/**
* Minimal interface for a transformers.js pipeline instance.
* We avoid importing @xenova/transformers directly so edgeFlow.js
* does not add it as a hard dependency.
*/
interface TransformersPipelineInstance {
(input: unknown, options?: unknown): Promise<unknown>;
dispose?: () => Promise<void> | void;
}
/**
* A factory that creates a transformers.js pipeline.
* Users pass this so we don't hard-depend on the library.
*/
export type TransformersPipelineFactory = (task: string, model?: string, options?: Record<string, unknown>) => Promise<TransformersPipelineInstance>;
/**
* Options for configuring the transformers.js adapter.
*/
export interface TransformersAdapterOptions {
/** The pipeline factory from transformers.js (e.g. the `pipeline` function) */
pipelineFactory: TransformersPipelineFactory;
/** Default device ('webgpu' | 'wasm' | 'cpu') — passed to transformers.js */
device?: string;
/** Default dtype ('fp32' | 'fp16' | 'q8' | 'q4') */
dtype?: string;
/** Cache directory (browser IndexedDB path) */
cacheDir?: string;
}
export declare class TransformersAdapterRuntime implements Runtime {
readonly name: RuntimeType;
get capabilities(): RuntimeCapabilities;
isAvailable(): Promise<boolean>;
initialize(): Promise<void>;
loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;
/**
* Load a transformers.js pipeline by task + model name
* (called by the higher-level adapter pipeline, not via the
* standard loadModel path).
*/
loadPipeline(task: string, model: string, pipelineOptions?: Record<string, unknown>): Promise<string>;
/**
* Run inference by passing the raw input to the transformers.js pipeline.
* The result is returned as a single EdgeFlowTensor wrapping the JSON-encoded output
* (since transformers.js returns task-specific objects, not raw tensors).
*/
run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;
/**
* High-level: run the transformers.js pipeline directly with arbitrary input.
* Returns the raw result object (not a tensor).
*/
runDirect(modelId: string, input: unknown, options?: Record<string, unknown>): Promise<unknown>;
dispose(): void;
}
/**
* Register the transformers.js adapter as the default inference backend.
*
* @example
* ```typescript
* import { pipeline } from '@xenova/transformers';
* import { useTransformersBackend } from 'edgeflowjs';
*
* useTransformersBackend({
* pipelineFactory: pipeline,
* device: 'webgpu',
* dtype: 'fp16',
* });
* ```
*/
export declare function useTransformersBackend(options: TransformersAdapterOptions): void;
/**
* Get the adapter runtime instance (for advanced use).
*/
export declare function getTransformersAdapter(): TransformersAdapterRuntime | null;
export {};
//# sourceMappingURL=transformers-adapter.d.ts.map
================================================
FILE: dist/backends/transformers-adapter.js
================================================
/**
* edgeFlow.js - transformers.js Adapter Backend
*
* Wraps transformers.js (by Hugging Face) as an inference backend, giving
* users access to 1000+ HuggingFace models while adding edgeFlow.js's
* orchestration layer (scheduling, caching, memory management, workers).
*
* @example
* ```typescript
* import { useTransformersBackend } from 'edgeflowjs';
* import { pipeline as tfPipeline } from '@xenova/transformers';
*
* // Register the adapter
* useTransformersBackend();
*
* // Now use edgeFlow.js pipeline API — inference delegates to transformers.js
* const classifier = await pipeline('text-classification', {
* model: 'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
* });
*
* // edgeFlow.js handles scheduling, batching, memory, caching
* const results = await classifier.runBatch(thousandsOfTexts);
* ```
*/
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
import { LoadedModelImpl } from '../core/runtime.js';
import { EdgeFlowTensor } from '../core/tensor.js';
import { getMemoryManager } from '../core/memory.js';
import { registerRuntime } from '../core/runtime.js';
// ---------------------------------------------------------------------------
// Session store: maps model IDs to transformers.js pipeline instances
// ---------------------------------------------------------------------------
const sessionStore = new Map();
let adapterOptions = null;
// ---------------------------------------------------------------------------
// Runtime implementation
// ---------------------------------------------------------------------------
export class TransformersAdapterRuntime {
name = 'wasm'; // registers under the wasm slot
get capabilities() {
return {
concurrency: true,
quantization: true,
float16: true,
dynamicShapes: true,
maxBatchSize: 128,
availableMemory: 1024 * 1024 * 1024,
};
}
async isAvailable() {
return adapterOptions?.pipelineFactory != null;
}
async initialize() {
if (!adapterOptions?.pipelineFactory) {
throw new EdgeFlowError('TransformersAdapterRuntime requires a pipelineFactory. ' +
'Call useTransformersBackend({ pipelineFactory }) first.', ErrorCodes.RUNTIME_INIT_FAILED);
}
}
async loadModel(modelData, options = {}) {
// modelData is unused — transformers.js downloads its own models.
// Instead the model identifier comes via metadata.name or the URL.
const modelName = options.metadata?.name ?? 'default';
const metadata = {
name: modelName,
version: '1.0.0',
inputs: [{ name: 'input', dtype: 'float32', shape: [-1] }],
outputs: [{ name: 'output', dtype: 'float32', shape: [-1] }],
sizeBytes: modelData.byteLength || 0,
quantization: options.quantization ?? 'float32',
format: 'onnx',
};
const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
const model = new LoadedModelImpl(metadata, this.name, () => {
const session = sessionStore.get(modelId);
if (session?.instance.dispose) {
session.instance.dispose();
}
sessionStore.delete(modelId);
});
getMemoryManager().trackModel(model, () => model.dispose());
return model;
}
/**
* Load a transformers.js pipeline by task + model name
* (called by the higher-level adapter pipeline, not via the
* standard loadModel path).
*/
async loadPipeline(task, model, pipelineOptions) {
if (!adapterOptions?.pipelineFactory) {
throw new EdgeFlowError('Adapter not initialised', ErrorCodes.RUNTIME_NOT_INITIALIZED);
}
const opts = { ...pipelineOptions };
if (adapterOptions.device)
opts['device'] = adapterOptions.device;
if (adapterOptions.dtype)
opts['dtype'] = adapterOptions.dtype;
const instance = await adapterOptions.pipelineFactory(task, model, opts);
const modelId = `tjs_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
sessionStore.set(modelId, { instance, task, model });
return modelId;
}
/**
* Run inference by passing the raw input to the transformers.js pipeline.
* The result is returned as a single EdgeFlowTensor wrapping the JSON-encoded output
* (since transformers.js returns task-specific objects, not raw tensors).
*/
async run(model, inputs) {
const session = sessionStore.get(model.id);
if (!session) {
throw new EdgeFlowError(`No transformers.js session for model ${model.id}`, ErrorCodes.MODEL_NOT_LOADED);
}
// Reconstruct input from tensor (simple: use the float data as-is)
const inputData = inputs[0]?.toFloat32Array() ?? new Float32Array(0);
const result = await session.instance(inputData);
// Wrap the result in a tensor — downstream pipelines can interpret it
const resultArray = Array.isArray(result)
? new Float32Array(result.flat(Infinity))
: new Float32Array([0]);
return [new EdgeFlowTensor(resultArray, [resultArray.length], 'float32')];
}
/**
* High-level: run the transformers.js pipeline directly with arbitrary input.
* Returns the raw result object (not a tensor).
*/
async runDirect(modelId, input, options) {
const session = sessionStore.get(modelId);
if (!session) {
throw new EdgeFlowError(`No transformers.js session for model ${modelId}`, ErrorCodes.MODEL_NOT_LOADED);
}
return session.instance(input, options);
}
dispose() {
for (const [id, session] of sessionStore) {
if (session.instance.dispose) {
session.instance.dispose();
}
sessionStore.delete(id);
}
}
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
let adapterRuntime = null;
/**
* Register the transformers.js adapter as the default inference backend.
*
* @example
* ```typescript
* import { pipeline } from '@xenova/transformers';
* import { useTransformersBackend } from 'edgeflowjs';
*
* useTransformersBackend({
* pipelineFactory: pipeline,
* device: 'webgpu',
* dtype: 'fp16',
* });
* ```
*/
export function useTransformersBackend(options) {
adapterOptions = options;
adapterRuntime = new TransformersAdapterRuntime();
registerRuntime('wasm', () => adapterRuntime);
}
/**
* Get the adapter runtime instance (for advanced use).
*/
export function getTransformersAdapter() {
return adapterRuntime;
}
//# sourceMappingURL=transformers-adapter.js.map
================================================
FILE: dist/backends/wasm.d.ts
================================================
/**
* edgeFlow.js - WebAssembly Backend
*
* Pure WASM runtime for universal browser support.
* Features:
* - Universal compatibility
* - SIMD acceleration when available
* - Memory-efficient execution
*/
import { Runtime, RuntimeType, RuntimeCapabilities, LoadedModel, ModelLoadOptions, Tensor } from '../core/types.js';
/**
* WASMRuntime - Pure WebAssembly inference runtime
*/
export declare class WASMRuntime implements Runtime {
readonly name: RuntimeType;
private module;
private simdSupported;
private models;
private initialized;
get capabilities(): RuntimeCapabilities;
/**
* Check if WASM is available
*/
isAvailable(): Promise<boolean>;
/**
* Initialize the WASM runtime
*/
initialize(): Promise<void>;
/**
* Check SIMD support
*/
private checkSIMDSupport;
/**
* Create JavaScript fallback for WASM operations
*/
private createJSFallback;
/**
* Load a model
*/
loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;
/**
* Run inference
*/
run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;
/**
* Execute model
*/
private executeModel;
/**
* Parse model configuration
*/
private parseModelConfig;
/**
* Load weights into WASM memory
*/
private loadWeights;
/**
* Unload a model
*/
private unloadModel;
/**
* Ensure runtime is initialized
*/
private ensureInitialized;
/**
* Check if SIMD is supported
*/
hasSIMDSupport(): boolean;
/**
* Dispose the runtime
*/
dispose(): void;
}
/**
* Create WASM runtime factory
*/
export declare function createWASMRuntime(): Runtime;
//# sourceMappingURL=wasm.d.ts.map
================================================
FILE: dist/backends/wasm.js
================================================
/**
* edgeFlow.js - WebAssembly Backend
*
* Pure WASM runtime for universal browser support.
* Features:
* - Universal compatibility
* - SIMD acceleration when available
* - Memory-efficient execution
*/
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
import { LoadedModelImpl } from '../core/runtime.js';
import { EdgeFlowTensor, softmax as tensorSoftmax, relu as tensorRelu, sigmoid as tensorSigmoid } from '../core/tensor.js';
import { getMemoryManager } from '../core/memory.js';
// ============================================================================
// WASM Runtime Implementation
// ============================================================================
/**
* WASMRuntime - Pure WebAssembly inference runtime
*/
export class WASMRuntime {
name = 'wasm';
module = null;
simdSupported = false;
models = new Map();
initialized = false;
get capabilities() {
return {
concurrency: false, // WASM is single-threaded by default
quantization: true,
float16: false,
dynamicShapes: true,
maxBatchSize: 16,
availableMemory: 128 * 1024 * 1024, // 128MB default
};
}
/**
* Check if WASM is available
*/
async isAvailable() {
if (typeof WebAssembly === 'undefined')
return false;
try {
// Check if we can instantiate a minimal WASM module
const bytes = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, // Magic number
0x01, 0x00, 0x00, 0x00, // Version
]);
await WebAssembly.instantiate(bytes);
return true;
}
catch {
return false;
}
}
/**
* Initialize the WASM runtime
*/
async initialize() {
if (this.initialized)
return;
// Check SIMD support
this.simdSupported = await this.checkSIMDSupport();
// Create memory pool
const memory = new WebAssembly.Memory({
initial: 256, // 16MB initial
maximum: 2048, // 128MB maximum
});
// Compile and instantiate the WASM module
// In production, this would load an actual WASM binary
// For now, we use a pure JS fallback
this.module = {
memory,
exports: this.createJSFallback(memory),
};
this.initialized = true;
}
/**
* Check SIMD support
*/
async checkSIMDSupport() {
try {
// SIMD detection via feature detection
const simdTest = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03,
0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,
0xfd, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0b
]);
await WebAssembly.instantiate(simdTest);
return true;
}
catch {
return false;
}
}
/**
* Create JavaScript fallback for WASM operations
*/
createJSFallback(memory) {
let nextPtr = 0;
const allocations = new Map();
return {
malloc: (size) => {
const ptr = nextPtr;
nextPtr += size;
allocations.set(ptr, size);
return ptr;
},
free: (ptr) => {
allocations.delete(ptr);
},
matmul_f32: (aPtr, aRows, aCols, bPtr, _bRows, bCols, outPtr) => {
const view = new Float32Array(memory.buffer);
const aOffset = aPtr / 4;
const bOffset = bPtr / 4;
const outOffset = outPtr / 4;
for (let i = 0; i < aRows; i++) {
for (let j = 0; j < bCols; j++) {
let sum = 0;
for (let k = 0; k < aCols; k++) {
sum += (view[aOffset + i * aCols + k] ?? 0) * (view[bOffset + k * bCols + j] ?? 0);
}
view[outOffset + i * bCols + j] = sum;
}
}
},
add_f32: (aPtr, bPtr, outPtr, size) => {
const view = new Float32Array(memory.buffer);
const aOffset = aPtr / 4;
const bOffset = bPtr / 4;
const outOffset = outPtr / 4;
for (let i = 0; i < size; i++) {
view[outOffset + i] = (view[aOffset + i] ?? 0) + (view[bOffset + i] ?? 0);
}
},
mul_f32: (aPtr, bPtr, outPtr, size) => {
const view = new Float32Array(memory.buffer);
const aOffset = aPtr / 4;
const bOffset = bPtr / 4;
const outOffset = outPtr / 4;
for (let i = 0; i < size; i++) {
view[outOffset + i] = (view[aOffset + i] ?? 0) * (view[bOffset + i] ?? 0);
}
},
relu_f32: (inputPtr, outputPtr, size) => {
const view = new Float32Array(memory.buffer);
const inOffset = inputPtr / 4;
const outOffset = outputPtr / 4;
for (let i = 0; i < size; i++) {
view[outOffset + i] = Math.max(0, view[inOffset + i] ?? 0);
}
},
sigmoid_f32: (inputPtr, outputPtr, size) => {
const view = new Float32Array(memory.buffer);
const inOffset = inputPtr / 4;
const outOffset = outputPtr / 4;
for (let i = 0; i < size; i++) {
view[outOffset + i] = 1 / (1 + Math.exp(-(view[inOffset + i] ?? 0)));
}
},
softmax_f32: (inputPtr, outputPtr, size) => {
const view = new Float32Array(memory.buffer);
const inOffset = inputPtr / 4;
const outOffset = outputPtr / 4;
// Find max for numerical stability
let max = -Infinity;
for (let i = 0; i < size; i++) {
if ((view[inOffset + i] ?? 0) > max)
max = view[inOffset + i] ?? 0;
}
// Compute exp and sum
let sum = 0;
for (let i = 0; i < size; i++) {
view[outOffset + i] = Math.exp((view[inOffset + i] ?? 0) - max);
sum += view[outOffset + i] ?? 0;
}
// Normalize
for (let i = 0; i < size; i++) {
view[outOffset + i] = (view[outOffset + i] ?? 0) / sum;
}
},
};
}
/**
* Load a model
*/
async loadModel(modelData, options = {}) {
this.ensureInitialized();
// Parse model configuration
const config = this.parseModelConfig(modelData);
// Extract and store weights
const wasmData = {
weights: new Map(),
config,
executionOrder: config.layers.map(l => l.name),
};
// Load weights into memory
await this.loadWeights(modelData, wasmData);
const modelId = `wasm_${Date.now().toString(36)}`;
this.models.set(modelId, wasmData);
// Create metadata
const metadata = {
name: config.name || options.metadata?.name || 'unknown',
version: config.version || '1.0.0',
inputs: config.inputs.map(i => ({
name: i.name,
dtype: i.dtype,
shape: i.shape,
})),
outputs: config.outputs.map(o => ({
name: o.name,
dtype: o.dtype,
shape: o.shape,
})),
sizeBytes: modelData.byteLength,
quantization: options.quantization ?? 'float32',
format: 'edgeflow',
};
// Create model instance
const model = new LoadedModelImpl(metadata, 'wasm', () => this.unloadModel(modelId));
// Track in memory manager
getMemoryManager().trackModel(model, () => model.dispose());
return model;
}
/**
* Run inference
*/
async run(model, inputs) {
this.ensureInitialized();
// Execute model layers
return this.executeModel(inputs, model.metadata);
}
/**
* Execute model
*/
async executeModel(inputs, metadata) {
const outputs = [];
for (const outputSpec of metadata.outputs) {
const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);
// Process based on output requirements
// This is a simplified implementation
let outputTensor;
if (inputs.length > 0 && inputs[0]) {
const inputTensor = inputs[0];
// Apply transformations based on layer types
// For demo, apply softmax to classification outputs
if (outputSpec.name.includes('logits') || outputSpec.name.includes('class')) {
outputTensor = tensorSoftmax(inputTensor);
}
else if (outputSpec.name.includes('relu')) {
outputTensor = tensorRelu(inputTensor);
}
else if (outputSpec.name.includes('sigmoid')) {
outputTensor = tensorSigmoid(inputTensor);
}
else {
// Identity or feature extraction
const outputData = new Float32Array(outputSize);
const inputData = inputTensor.toFloat32Array();
for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {
outputData[i] = inputData[i] ?? 0;
}
outputTensor = new EdgeFlowTensor(outputData, outputSpec.shape, 'float32');
}
}
else {
outputTensor = new EdgeFlowTensor(new Float32Array(outputSize), outputSpec.shape, 'float32');
}
outputs.push(outputTensor);
}
return outputs;
}
/**
* Parse model configuration
*/
parseModelConfig(data) {
try {
const decoder = new TextDecoder();
const text = decoder.decode(new Uint8Array(data, 0, Math.min(2048, data.byteLength)));
if (text.trim().startsWith('{')) {
let jsonEnd = text.indexOf('\n---\n');
if (jsonEnd === -1) {
// Try to parse as pure JSON
try {
return JSON.parse(text);
}
catch {
jsonEnd = data.byteLength;
}
}
const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));
return JSON.parse(jsonStr);
}
}
catch {
// Not JSON format
}
return {
name: 'unknown',
version: '1.0.0',
layers: [],
inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],
outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],
};
}
/**
* Load weights into WASM memory
*/
async loadWeights(_modelData, _wasmData) {
// In a full implementation, extract and load weights
// This is a placeholder
}
/**
* Unload a model
*/
unloadModel(modelId) {
const modelData = this.models.get(modelId);
if (modelData && this.module) {
// Free weight buffers
for (const weight of modelData.weights.values()) {
this.module.exports.free(weight.ptr);
}
}
this.models.delete(modelId);
}
/**
* Ensure runtime is initialized
*/
ensureInitialized() {
if (!this.initialized || !this.module) {
throw new EdgeFlowError('WASM runtime is not initialized', ErrorCodes.RUNTIME_NOT_INITIALIZED);
}
}
/**
* Check if SIMD is supported
*/
hasSIMDSupport() {
return this.simdSupported;
}
/**
* Dispose the runtime
*/
dispose() {
// Free all model weights
for (const modelId of this.models.keys()) {
this.unloadModel(modelId);
}
this.module = null;
this.initialized = false;
}
}
/**
* Create WASM runtime factory
*/
export function createWASMRuntime() {
return new WASMRuntime();
}
//# sourceMappingURL=wasm.js.map
================================================
FILE: dist/backends/webgpu.d.ts
================================================
/**
* edgeFlow.js - WebGPU Backend
*
* **Status: Planned** - This is a skeleton implementation that initializes
* WebGPU and creates compute pipelines but does not perform real model
* inference. For GPU-accelerated inference, use the ONNX Runtime backend
* which supports WebGPU via its execution providers.
*
* This backend is intended for future custom WebGPU compute shader
* implementations that bypass ONNX Runtime for specialized ops.
*/
import { Runtime, RuntimeType, RuntimeCapabilities, LoadedModel, ModelLoadOptions, Tensor } from '../core/types.js';
declare global {
interface Navigator {
gpu?: GPU;
}
interface GPU {
requestAdapter(options?: GPURequestAdapterOptions): Promise<GPUAdapter | null>;
}
interface GPURequestAdapterOptions {
powerPreference?: 'low-power' | 'high-performance';
}
interface GPUAdapter {
requestDevice(descriptor?: GPUDeviceDescriptor): Promise<GPUDevice>;
}
interface GPUDeviceDescriptor {
requiredFeatures?: string[];
requiredLimits?: Record<string, number>;
}
interface GPUDevice {
limits: GPULimits;
lost: Promise<GPUDeviceLostInfo>;
createBuffer(descriptor: GPUBufferDescriptor): GPUBuffer;
createShaderModule(descriptor: GPUShaderModuleDescriptor): GPUShaderModule;
createBindGroupLayout(descriptor: GPUBindGroupLayoutDescriptor): GPUBindGroupLayout;
createPipelineLayout(descriptor: GPUPipelineLayoutDescriptor): GPUPipelineLayout;
createComputePipeline(descriptor: GPUComputePipelineDescriptor): GPUComputePipeline;
destroy(): void;
}
interface GPULimits {
maxBufferSize: number;
}
interface GPUDeviceLostInfo {
message: string;
reason: string;
}
interface GPUBuffer {
destroy(): void;
}
interface GPUShaderModule {
}
interface GPUBindGroupLayout {
}
interface GPUPipelineLayout {
}
interface GPUComputePipeline {
}
interface GPUBufferDescriptor {
size: number;
usage: number;
}
interface GPUShaderModuleDescriptor {
code: string;
}
interface GPUBindGroupLayoutDescriptor {
entries: GPUBindGroupLayoutEntry[];
}
interface GPUBindGroupLayoutEntry {
binding: number;
visibility: number;
buffer?: {
type: string;
};
}
interface GPUPipelineLayoutDescriptor {
bindGroupLayouts: GPUBindGroupLayout[];
}
interface GPUComputePipelineDescriptor {
layout: GPUPipelineLayout;
compute: {
module: GPUShaderModule;
entryPoint: string;
};
}
}
/**
* WebGPURuntime - GPU-accelerated inference runtime
*/
export declare class WebGPURuntime implements Runtime {
readonly name: RuntimeType;
private adapter;
private device;
private models;
private initialized;
get capabilities(): RuntimeCapabilities;
/**
* Check if WebGPU is available
*/
isAvailable(): Promise<boolean>;
/**
* Initialize the WebGPU runtime
*/
initialize(): Promise<void>;
/**
* Load a model
*/
loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;
/**
* Run inference
*/
run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;
/**
* Execute model (simplified implementation)
*/
private executeModel;
/**
* Parse model data
*/
private parseModelData;
/**
* Upload weights to GPU
*/
private uploadWeights;
/**
* Create compute pipelines
*/
private createPipelines;
/**
* Unload a model
*/
private unloadModel;
/**
* Ensure runtime is initialized
*/
private ensureInitialized;
/**
* Dispose the runtime
*/
dispose(): void;
}
/**
* Create WebGPU runtime factory
*/
export declare function createWebGPURuntime(): Runtime;
//# sourceMappingURL=webgpu.d.ts.map
================================================
FILE: dist/backends/webgpu.js
================================================
/**
* edgeFlow.js - WebGPU Backend
*
* **Status: Planned** - This is a skeleton implementation that initializes
* WebGPU and creates compute pipelines but does not perform real model
* inference. For GPU-accelerated inference, use the ONNX Runtime backend
* which supports WebGPU via its execution providers.
*
* This backend is intended for future custom WebGPU compute shader
* implementations that bypass ONNX Runtime for specialized ops.
*/
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
import { LoadedModelImpl } from '../core/runtime.js';
import { EdgeFlowTensor } from '../core/tensor.js';
import { getMemoryManager } from '../core/memory.js';
// WebGPU constants
const GPUBufferUsage = {
STORAGE: 0x0080,
COPY_SRC: 0x0004,
COPY_DST: 0x0008,
MAP_READ: 0x0001,
};
const GPUShaderStage = {
COMPUTE: 0x0004,
};
// ============================================================================
// WebGPU Runtime Implementation
// ============================================================================
/**
* WebGPURuntime - GPU-accelerated inference runtime
*/
export class WebGPURuntime {
name = 'webgpu';
adapter = null;
device = null;
models = new Map();
initialized = false;
get capabilities() {
return {
concurrency: true,
quantization: true,
float16: true,
dynamicShapes: false,
maxBatchSize: 64,
availableMemory: this.device?.limits.maxBufferSize ?? 256 * 1024 * 1024,
};
}
/**
* Check if WebGPU is available
*/
async isAvailable() {
if (typeof navigator === 'undefined')
return false;
if (!navigator.gpu)
return false;
try {
const adapter = await navigator.gpu.requestAdapter();
return adapter !== null;
}
catch {
return false;
}
}
/**
* Initialize the WebGPU runtime
*/
async initialize() {
if (this.initialized)
return;
if (!navigator.gpu) {
throw new EdgeFlowError('WebGPU is not supported in this browser', ErrorCodes.RUNTIME_NOT_AVAILABLE);
}
// Request adapter
this.adapter = await navigator.gpu.requestAdapter({
powerPreference: 'high-performance',
});
if (!this.adapter) {
throw new EdgeFlowError('Failed to get WebGPU adapter', ErrorCodes.RUNTIME_INIT_FAILED);
}
// Request device
this.device = await this.adapter.requestDevice({
requiredFeatures: [],
requiredLimits: {},
});
// Handle device loss
this.device.lost.then((info) => {
console.error('WebGPU device was lost:', info.message);
this.initialized = false;
this.device = null;
});
this.initialized = true;
}
/**
* Load a model
*/
async loadModel(modelData, options = {}) {
this.ensureInitialized();
// Parse model data
const config = this.parseModelData(modelData);
// Create shader modules and pipelines
const webgpuData = {
shaders: new Map(),
pipelines: new Map(),
weights: new Map(),
bindGroupLayouts: [],
config,
};
// Extract and upload weights
await this.uploadWeights(modelData, webgpuData);
// Create compute pipelines for each layer
await this.createPipelines(webgpuData);
// Generate model ID
const modelId = `webgpu_${Date.now().toString(36)}`;
this.models.set(modelId, webgpuData);
// Create metadata
const metadata = {
name: config.name || options.metadata?.name || 'unknown',
version: config.version,
inputs: config.inputs.map(i => ({
name: i.name,
dtype: i.dtype,
shape: i.shape,
})),
outputs: config.outputs.map(o => ({
name: o.name,
dtype: o.dtype,
shape: o.shape,
})),
sizeBytes: modelData.byteLength,
quantization: options.quantization ?? 'float32',
format: 'edgeflow',
};
// Create model instance
const model = new LoadedModelImpl(metadata, 'webgpu', () => this.unloadModel(modelId));
// Track in memory manager
getMemoryManager().trackModel(model, () => model.dispose());
return model;
}
/**
* Run inference
*/
async run(model, inputs) {
this.ensureInitialized();
// For now, use a simple fallback implementation
// In a full implementation, this would execute the compute pipelines
return this.executeModel(inputs, model.metadata);
}
/**
* Execute model (simplified implementation)
*/
async executeModel(inputs, metadata) {
// This is a simplified implementation
// A full implementation would:
// 1. Upload input tensors to GPU buffers
// 2. Execute compute pipelines in topological order
// 3. Read back output tensors
const device = this.device;
const outputs = [];
for (const outputSpec of metadata.outputs) {
// Create output buffer
const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);
const outputBuffer = device.createBuffer({
size: outputSize * 4, // float32
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
});
// Create staging buffer for readback
const stagingBuffer = device.createBuffer({
size: outputSize * 4,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});
// For now, return zeros (placeholder)
// In production, execute actual compute pipelines
const outputData = new Float32Array(outputSize);
// Simulate some computation based on inputs
if (inputs.length > 0 && inputs[0]) {
const inputData = inputs[0].toFloat32Array();
for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {
outputData[i] = (inputData[i] ?? 0);
}
}
outputs.push(new EdgeFlowTensor(outputData, outputSpec.shape, 'float32'));
// Cleanup
outputBuffer.destroy();
stagingBuffer.destroy();
}
return outputs;
}
/**
* Parse model data
*/
parseModelData(data) {
// Try to parse as JSON first (for our custom format)
try {
const decoder = new TextDecoder();
const text = decoder.decode(new Uint8Array(data, 0, Math.min(1024, data.byteLength)));
// Check if it starts with JSON
if (text.trim().startsWith('{')) {
// Find the JSON header end
let jsonEnd = text.indexOf('\n---\n');
if (jsonEnd === -1)
jsonEnd = data.byteLength;
const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));
return JSON.parse(jsonStr);
}
}
catch {
// Not JSON format
}
// Return default config for unknown formats
return {
name: 'unknown',
version: '1.0.0',
layers: [],
inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],
outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],
};
}
/**
* Upload weights to GPU
*/
async uploadWeights(_data, modelData) {
const device = this.device;
// In a full implementation, parse weight data from the model file
// and upload to GPU buffers
// Placeholder: create empty weight buffer
const weightsBuffer = device.createBuffer({
size: 1024,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
});
modelData.weights.set('default', weightsBuffer);
}
/**
* Create compute pipelines
*/
async createPipelines(modelData) {
const device = this.device;
// Create a general-purpose compute shader
const shaderCode = /* wgsl */ `
@group(0) @binding(0) var<storage, read> input: array<f32>;
@group(0) @binding(1) var<storage, read_write> output: array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
let idx = gid.x;
if (idx < arrayLength(&input)) {
output[idx] = input[idx];
}
}
`;
const shaderModule = device.createShaderModule({
code: shaderCode,
});
modelData.shaders.set('default', shaderModule);
// Create bind group layout
const bindGroupLayout = device.createBindGroupLayout({
entries: [
{
binding: 0,
visibility: GPUShaderStage.COMPUTE,
buffer: { type: 'read-only-storage' },
},
{
binding: 1,
visibility: GPUShaderStage.COMPUTE,
buffer: { type: 'storage' },
},
],
});
modelData.bindGroupLayouts.push(bindGroupLayout);
// Create pipeline layout
const pipelineLayout = device.createPipelineLayout({
bindGroupLayouts: [bindGroupLayout],
});
// Create compute pipeline
const pipeline = device.createComputePipeline({
layout: pipelineLayout,
compute: {
module: shaderModule,
entryPoint: 'main',
},
});
modelData.pipelines.set('default', pipeline);
}
/**
* Unload a model
*/
unloadModel(modelId) {
const modelData = this.models.get(modelId);
if (modelData) {
// Destroy GPU buffers
for (const buffer of modelData.weights.values()) {
buffer.destroy();
}
this.models.delete(modelId);
}
}
/**
* Ensure runtime is initialized
*/
ensureInitialized() {
if (!this.initialized || !this.device) {
throw new EdgeFlowError('WebGPU runtime is not initialized', ErrorCodes.RUNTIME_NOT_INITIALIZED);
}
}
/**
* Dispose the runtime
*/
dispose() {
// Unload all models
for (const modelId of this.models.keys()) {
this.unloadModel(modelId);
}
// Destroy device
if (this.device) {
this.device.destroy();
this.device = null;
}
this.adapter = null;
this.initialized = false;
}
}
/**
* Create WebGPU runtime factory
*/
export function createWebGPURuntime() {
return new WebGPURuntime();
}
//# sourceMappingURL=webgpu.js.map
================================================
FILE: dist/backends/webnn.d.ts
================================================
/**
* edgeFlow.js - WebNN Backend
*
* **Status: Planned** - This is a skeleton implementation that initializes
* a WebNN context but does not perform real model inference or graph building.
* For hardware-accelerated inference, use the ONNX Runtime backend which
* supports WebNN via its execution providers when available.
*
* This backend is intended for future native WebNN graph building support.
*/
import { Runtime, RuntimeType, RuntimeCapabilities, LoadedModel, ModelLoadOptions, Tensor } from '../core/types.js';
/**
* WebNN context type
*/
type MLContextType = 'default' | 'gpu' | 'cpu' | 'npu';
/**
* WebNN operand descriptor
*/
interface MLOperandDescriptor {
dataType: 'float32' | 'float16' | 'int32' | 'uint32' | 'int8' | 'uint8';
dimensions: number[];
}
/**
* WebNN context options
*/
interface MLContextOptions {
deviceType?: MLContextType;
powerPreference?: 'default' | 'high-performance' | 'low-power';
}
declare global {
interface Navigator {
ml?: {
createContext(options?: MLContextOptions): Promise<MLContext>;
};
}
interface MLContext {
compute(graph: MLGraph, inputs: Record<string, ArrayBufferView>, outputs: Record<string, ArrayBufferView>): Promise<Record<string, ArrayBufferView>>;
}
interface MLGraph {
}
interface MLGraphBuilder {
input(name: string, desc: MLOperandDescriptor): MLOperand;
constant(desc: MLOperandDescriptor, data: ArrayBufferView): MLOperand;
build(outputs: Record<string, MLOperand>): Promise<MLGraph>;
add(a: MLOperand, b: MLOperand): MLOperand;
sub(a: MLOperand, b: MLOperand): MLOperand;
mul(a: MLOperand, b: MLOperand): MLOperand;
div(a: MLOperand, b: MLOperand): MLOperand;
matmul(a: MLOperand, b: MLOperand): MLOperand;
relu(x: MLOperand): MLOperand;
sigmoid(x: MLOperand): MLOperand;
tanh(x: MLOperand): MLOperand;
softmax(x: MLOperand): MLOperand;
reshape(x: MLOperand, newShape: number[]): MLOperand;
transpose(x: MLOperand, permutation?: number[]): MLOperand;
}
interface MLOperand {
}
}
/**
* WebNNRuntime - Browser-native neural network runtime
*/
export declare class WebNNRuntime implements Runtime {
readonly name: RuntimeType;
private context;
private models;
private initialized;
private deviceType;
get capabilities(): RuntimeCapabilities;
/**
* Check if WebNN is available
*/
isAvailable(): Promise<boolean>;
/**
* Initialize the WebNN runtime
*/
initialize(): Promise<void>;
/**
* Load a model
*/
loadModel(modelData: ArrayBuffer, options?: ModelLoadOptions): Promise<LoadedModel>;
/**
* Run inference
*/
run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]>;
/**
* Execute model (simplified implementation)
*/
private executeModel;
/**
* Parse model configuration
*/
private parseModelConfig;
/**
* Unload a model
*/
private unloadModel;
/**
* Ensure runtime is initialized
*/
private ensureInitialized;
/**
* Get device type
*/
getDeviceType(): MLContextType;
/**
* Dispose the runtime
*/
dispose(): void;
}
/**
* Create WebNN runtime factory
*/
export declare function createWebNNRuntime(): Runtime;
export {};
//# sourceMappingURL=webnn.d.ts.map
================================================
FILE: dist/backends/webnn.js
================================================
/**
* edgeFlow.js - WebNN Backend
*
* **Status: Planned** - This is a skeleton implementation that initializes
* a WebNN context but does not perform real model inference or graph building.
* For hardware-accelerated inference, use the ONNX Runtime backend which
* supports WebNN via its execution providers when available.
*
* This backend is intended for future native WebNN graph building support.
*/
import { EdgeFlowError, ErrorCodes, } from '../core/types.js';
import { LoadedModelImpl } from '../core/runtime.js';
import { EdgeFlowTensor } from '../core/tensor.js';
import { getMemoryManager } from '../core/memory.js';
// ============================================================================
// WebNN Runtime Implementation
// ============================================================================
/**
* WebNNRuntime - Browser-native neural network runtime
*/
export class WebNNRuntime {
name = 'webnn';
context = null;
models = new Map();
initialized = false;
deviceType = 'default';
get capabilities() {
return {
concurrency: true,
quantization: true,
float16: true,
dynamicShapes: false,
maxBatchSize: 32,
availableMemory: 256 * 1024 * 1024, // Estimated
};
}
/**
* Check if WebNN is available
*/
async isAvailable() {
if (typeof navigator === 'undefined')
return false;
if (!navigator.ml)
return false;
try {
const context = await navigator.ml.createContext({ deviceType: 'default' });
return context !== null;
}
catch {
return false;
}
}
/**
* Initialize the WebNN runtime
*/
async initialize() {
if (this.initialized)
return;
if (!navigator.ml) {
throw new EdgeFlowError('WebNN is not supported in this browser', ErrorCodes.RUNTIME_NOT_AVAILABLE);
}
// Try to get GPU context first, fallback to CPU
try {
this.context = await navigator.ml.createContext({
deviceType: 'gpu',
powerPreference: 'high-performance',
});
this.deviceType = 'gpu';
}
catch {
try {
this.context = await navigator.ml.createContext({ deviceType: 'cpu' });
this.deviceType = 'cpu';
}
catch (error) {
throw new EdgeFlowError(`Failed to create WebNN context: ${error instanceof Error ? error.message : String(error)}`, ErrorCodes.RUNTIME_INIT_FAILED);
}
}
this.initialized = true;
}
/**
* Load a model
*/
async loadModel(modelData, options = {}) {
this.ensureInitialized();
// Parse model configuration
const config = this.parseModelConfig(modelData);
// Note: Full WebNN implementation would build the graph here
// This is a placeholder that creates minimal metadata
const modelId = `webnn_${Date.now().toString(36)}`;
// Create metadata
const metadata = {
name: config.name || options.metadata?.name || 'unknown',
version: config.version || '1.0.0',
inputs: config.inputs.map(i => ({
name: i.name,
dtype: i.dtype,
shape: i.shape,
})),
outputs: config.outputs.map(o => ({
name: o.name,
dtype: o.dtype,
shape: o.shape,
})),
sizeBytes: modelData.byteLength,
quantization: options.quantization ?? 'float32',
format: 'edgeflow',
};
// Create model instance
const model = new LoadedModelImpl(metadata, 'webnn', () => this.unloadModel(modelId));
// Track in memory manager
getMemoryManager().trackModel(model, () => model.dispose());
return model;
}
/**
* Run inference
*/
async run(model, inputs) {
this.ensureInitialized();
// Simplified implementation - in production, would use compiled graph
return this.executeModel(inputs, model.metadata);
}
/**
* Execute model (simplified implementation)
*/
async executeModel(inputs, metadata) {
const outputs = [];
// For each expected output
for (const outputSpec of metadata.outputs) {
const outputSize = outputSpec.shape.reduce((a, b) => a * b, 1);
const outputData = new Float32Array(outputSize);
// Simple passthrough for demo (real impl would use WebNN compute)
if (inputs.length > 0 && inputs[0]) {
const inputData = inputs[0].toFloat32Array();
for (let i = 0; i < Math.min(outputSize, inputData.length); i++) {
outputData[i] = inputData[i] ?? 0;
}
}
outputs.push(new EdgeFlowTensor(outputData, outputSpec.shape, 'float32'));
}
return outputs;
}
/**
* Parse model configuration
*/
parseModelConfig(data) {
try {
const decoder = new TextDecoder();
const text = decoder.decode(new Uint8Array(data, 0, Math.min(1024, data.byteLength)));
if (text.trim().startsWith('{')) {
let jsonEnd = text.indexOf('\n---\n');
if (jsonEnd === -1)
jsonEnd = data.byteLength;
const jsonStr = decoder.decode(new Uint8Array(data, 0, jsonEnd));
return JSON.parse(jsonStr);
}
}
catch {
// Not JSON format
}
return {
name: 'unknown',
version: '1.0.0',
inputs: [{ name: 'input', shape: [-1, 768], dtype: 'float32' }],
outputs: [{ name: 'output', shape: [-1, 768], dtype: 'float32' }],
};
}
/**
* Unload a model
*/
unloadModel(modelId) {
this.models.delete(modelId);
}
/**
* Ensure runtime is initialized
*/
ensureInitialized() {
if (!this.initialized || !this.context) {
throw new EdgeFlowError('WebNN runtime is not initialized', ErrorCodes.RUNTIME_NOT_INITIALIZED);
}
}
/**
* Get device type
*/
getDeviceType() {
return this.deviceType;
}
/**
* Dispose the runtime
*/
dispose() {
this.models.clear();
this.context = null;
this.initialized = false;
}
}
/**
* Create WebNN runtime factory
*/
export function createWebNNRuntime() {
return new WebNNRuntime();
}
//# sourceMappingURL=webnn.js.map
================================================
FILE: dist/core/composer.d.ts
================================================
/**
* edgeFlow.js - Pipeline Composer
*
* Chain multiple pipelines together to build complex multi-model workflows.
* Each stage's output is transformed and fed as input to the next stage.
*
* @example
* ```typescript
* import { compose } from 'edgeflowjs';
*
* const speechTranslator = compose([
* { task: 'automatic-speech-recognition' },
* { task: 'translation', options: { srcLang: 'en', tgtLang: 'zh' } },
* ]);
*
* const result = await speechTranslator.run(audioBlob);
* // result.stages = [asrResult, translationResult]
* // result.output = final translation text
* ```
*/
import { type PipelineFactoryOptions } from '../pipelines/index.js';
import type { PipelineTask } from './types.js';
/**
* A single stage in a composed pipeline.
*/
export interface CompositionStage {
/** The pipeline task to run */
task: PipelineTask | (string & {});
/** Model override for this stage */
model?: string;
/** Extra options forwarded to `pipeline()` */
options?: PipelineFactoryOptions;
/**
* Optional transform applied to the previous stage's output before it is
* passed as input to this stage. If omitted, the raw output is forwarded.
*/
transform?: (previousOutput: unknown) => unknown;
/**
* Options forwarded to the pipeline's `run()` call.
*/
runOptions?: Record<string, unknown>;
}
/**
* Result from running a composed pipeline.
*/
export interface CompositionResult {
/** The final output from the last stage */
output: unknown;
/** Intermediate results for every stage (index-aligned with stages) */
stages: unknown[];
/** Total wall-clock time in milliseconds */
totalTime: number;
/** Per-stage timing */
stageTimes: number[];
}
/**
* A composed (chained) pipeline.
*/
export interface ComposedPipeline {
/** Execute the full chain with the given initial input */
run(input: unknown): Promise<CompositionResult>;
/** Dispose all underlying pipeline instances */
dispose(): void;
/** Number of stages */
readonly length: number;
}
/**
* Compose multiple pipeline stages into a single sequential chain.
*
* The output of each stage is fed as the input to the next stage. Use the
* optional `transform` hook in a stage to reshape data between stages.
*
* All pipelines are lazily initialised on the first `run()` call and cached
* for subsequent calls.
*
* @param stages - Ordered list of pipeline stages
* @returns A composed pipeline that can be run end-to-end
*
* @example
* ```typescript
* const ocrPipeline = compose([
* { task: 'image-to-text' },
* {
* task: 'text-classification',
* transform: (ocrResult: any) => ocrResult.text,
* },
* ]);
*
* const { output, stages, totalTime } = await ocrPipeline.run(imageElement);
* ```
*/
export declare function compose(stages: CompositionStage[]): ComposedPipeline;
/**
* Run stages in parallel (fan-out) and collect all results.
*
* Unlike `compose` (which is sequential), `parallel` runs every stage
* independently with the same input and returns an array of results.
*
* @example
* ```typescript
* const analyzer = parallel([
* { task: 'text-classification' },
* { task: 'feature-extraction' },
* { task: 'zero-shot-classification',
* transform: (text) => ({ text, candidateLabels: ['news', 'sports'] }) },
* ]);
*
* const results = await analyzer.run('Breaking: team wins championship');
* ```
*/
export declare function parallel(stages: CompositionStage[]): {
run(input: unknown): Promise<{
outputs: unknown[];
totalTime: number;
}>;
dispose(): void;
};
//# sourceMappingURL=composer.d.ts.map
================================================
FILE: dist/core/composer.js
================================================
/**
* edgeFlow.js - Pipeline Composer
*
* Chain multiple pipelines together to build complex multi-model workflows.
* Each stage's output is transformed and fed as input to the next stage.
*
* @example
* ```typescript
* import { compose } from 'edgeflowjs';
*
* const speechTranslator = compose([
* { task: 'automatic-speech-recognition' },
* { task: 'translation', options: { srcLang: 'en', tgtLang: 'zh' } },
* ]);
*
* const result = await speechTranslator.run(audioBlob);
* // result.stages = [asrResult, translationResult]
* // result.output = final translation text
* ```
*/
import { pipeline } from '../pipelines/index.js';
// ---------------------------------------------------------------------------
// Implementation
// ---------------------------------------------------------------------------
/**
* Compose multiple pipeline stages into a single sequential chain.
*
* The output of each stage is fed as the input to the next stage. Use the
* optional `transform` hook in a stage to reshape data between stages.
*
* All pipelines are lazily initialised on the first `run()` call and cached
* for subsequent calls.
*
* @param stages - Ordered list of pipeline stages
* @returns A composed pipeline that can be run end-to-end
*
* @example
* ```typescript
* const ocrPipeline = compose([
* { task: 'image-to-text' },
* {
* task: 'text-classification',
* transform: (ocrResult: any) => ocrResult.text,
* },
* ]);
*
* const { output, stages, totalTime } = await ocrPipeline.run(imageElement);
* ```
*/
export function compose(stages) {
if (stages.length === 0) {
throw new Error('[edgeFlow.js] compose() requires at least one stage');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let pipelineInstances = null;
async function ensureInitialised() {
if (pipelineInstances)
return pipelineInstances;
pipelineInstances = await Promise.all(stages.map((stage) => pipeline(stage.task, {
model: stage.model,
...stage.options,
})));
return pipelineInstances;
}
return {
get length() {
return stages.length;
},
async run(input) {
const instances = await ensureInitialised();
const stageResults = [];
const stageTimes = [];
let current = input;
const wallStart = performance.now();
for (let i = 0; i < stages.length; i++) {
const stage = stages[i];
const inst = instances[i];
// Apply transform from previous stage output if provided
if (stage.transform) {
current = stage.transform(current);
}
const t0 = performance.now();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
current = await inst.run(current, stage.runOptions);
stageTimes.push(performance.now() - t0);
stageResults.push(current);
}
return {
output: current,
stages: stageResults,
totalTime: performance.now() - wallStart,
stageTimes,
};
},
dispose() {
if (pipelineInstances) {
for (const inst of pipelineInstances) {
if (inst && typeof inst.dispose === 'function') {
inst.dispose();
}
}
pipelineInstances = null;
}
},
};
}
/**
* Run stages in parallel (fan-out) and collect all results.
*
* Unlike `compose` (which is sequential), `parallel` runs every stage
* independently with the same input and returns an array of results.
*
* @example
* ```typescript
* const analyzer = parallel([
* { task: 'text-classification' },
* { task: 'feature-extraction' },
* { task: 'zero-shot-classification',
* transform: (text) => ({ text, candidateLabels: ['news', 'sports'] }) },
* ]);
*
* const results = await analyzer.run('Breaking: team wins championship');
* ```
*/
export function parallel(stages) {
if (stages.length === 0) {
throw new Error('[edgeFlow.js] parallel() requires at least one stage');
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let pipelineInstances = null;
async function ensureInitialised() {
if (pipelineInstances)
return pipelineInstances;
pipelineInstances = await Promise.all(stages.map((s) => pipeline(s.task, {
model: s.model,
...s.options,
})));
return pipelineInstances;
}
return {
async run(input) {
const instances = await ensureInitialised();
const t0 = performance.now();
const outputs = await Promise.all(stages.map((stage, i) => {
const stageInput = stage.transform ? stage.transform(input) : input;
// e
gitextract_2xh90dxw/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ ├── pull_request_template.md │ └── workflows/ │ ├── ci.yml │ └── publish.yml ├── .gitignore ├── CLAUDE.md ├── CONTRIBUTING.md ├── README.md ├── README_CN.md ├── benchmarks/ │ └── README.md ├── demo/ │ ├── demo.js │ ├── index.html │ ├── server.js │ └── styles.css ├── dist/ │ ├── backends/ │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── onnx.d.ts │ │ ├── onnx.js │ │ ├── transformers-adapter.d.ts │ │ ├── transformers-adapter.js │ │ ├── wasm.d.ts │ │ ├── wasm.js │ │ ├── webgpu.d.ts │ │ ├── webgpu.js │ │ ├── webnn.d.ts │ │ └── webnn.js │ ├── core/ │ │ ├── composer.d.ts │ │ ├── composer.js │ │ ├── device-profiler.d.ts │ │ ├── device-profiler.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── memory.d.ts │ │ ├── memory.js │ │ ├── plugin.d.ts │ │ ├── plugin.js │ │ ├── runtime.d.ts │ │ ├── runtime.js │ │ ├── scheduler.d.ts │ │ ├── scheduler.js │ │ ├── tensor.d.ts │ │ ├── tensor.js │ │ ├── types.d.ts │ │ ├── types.js │ │ ├── worker.d.ts │ │ └── worker.js │ ├── edgeflow.browser.js │ ├── index.d.ts │ ├── index.js │ ├── pipelines/ │ │ ├── automatic-speech-recognition.d.ts │ │ ├── automatic-speech-recognition.js │ │ ├── base.d.ts │ │ ├── base.js │ │ ├── feature-extraction.d.ts │ │ ├── feature-extraction.js │ │ ├── image-classification.d.ts │ │ ├── image-classification.js │ │ ├── image-segmentation.d.ts │ │ ├── image-segmentation.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── object-detection.d.ts │ │ ├── object-detection.js │ │ ├── question-answering.d.ts │ │ ├── question-answering.js │ │ ├── text-classification.d.ts │ │ ├── text-classification.js │ │ ├── text-generation.d.ts │ │ ├── text-generation.js │ │ ├── zero-shot-classification.d.ts │ │ └── zero-shot-classification.js │ ├── tools/ │ │ ├── benchmark.d.ts │ │ ├── benchmark.js │ │ ├── debugger.d.ts │ │ ├── debugger.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── monitor.d.ts │ │ ├── monitor.js │ │ ├── quantization.d.ts │ │ └── quantization.js │ └── utils/ │ ├── cache.d.ts │ ├── cache.js │ ├── hub.d.ts │ ├── hub.js │ ├── index.d.ts │ ├── index.js │ ├── model-loader.d.ts │ ├── model-loader.js │ ├── offline.d.ts │ ├── offline.js │ ├── preprocessor.d.ts │ ├── preprocessor.js │ ├── tokenizer.d.ts │ └── tokenizer.js ├── docs/ │ ├── .vitepress/ │ │ └── config.ts │ ├── api/ │ │ ├── model-loader.md │ │ ├── pipeline.md │ │ ├── tensor.md │ │ └── tokenizer.md │ ├── cookbook/ │ │ ├── composition.md │ │ └── transformers-adapter.md │ ├── guide/ │ │ ├── architecture.md │ │ ├── concepts.md │ │ ├── device-profiling.md │ │ ├── installation.md │ │ ├── plugins.md │ │ └── quickstart.md │ ├── index.md │ └── tutorials/ │ └── text-classification.md ├── examples/ │ ├── basic-usage.ts │ ├── multi-model-dashboard/ │ │ └── index.html │ ├── offline-notepad/ │ │ └── index.html │ └── orchestration.ts ├── package.json ├── playwright.config.ts ├── scripts/ │ └── build-browser.js ├── src/ │ ├── backends/ │ │ ├── index.ts │ │ ├── onnx.ts │ │ ├── transformers-adapter.ts │ │ ├── wasm.ts │ │ ├── webgpu.ts │ │ └── webnn.ts │ ├── core/ │ │ ├── composer.ts │ │ ├── device-profiler.ts │ │ ├── index.ts │ │ ├── memory.ts │ │ ├── plugin.ts │ │ ├── runtime.ts │ │ ├── scheduler.ts │ │ ├── tensor.ts │ │ ├── types.ts │ │ └── worker.ts │ ├── index.ts │ ├── pipelines/ │ │ ├── automatic-speech-recognition.ts │ │ ├── base.ts │ │ ├── feature-extraction.ts │ │ ├── image-classification.ts │ │ ├── image-segmentation.ts │ │ ├── index.ts │ │ ├── object-detection.ts │ │ ├── question-answering.ts │ │ ├── text-classification.ts │ │ ├── text-generation.ts │ │ └── zero-shot-classification.ts │ ├── tools/ │ │ ├── benchmark.ts │ │ ├── debugger.ts │ │ ├── index.ts │ │ ├── monitor.ts │ │ └── quantization.ts │ └── utils/ │ ├── cache.ts │ ├── hub.ts │ ├── index.ts │ ├── model-loader.ts │ ├── offline.ts │ ├── preprocessor.ts │ └── tokenizer.ts ├── tests/ │ ├── e2e/ │ │ ├── browser.spec.ts │ │ ├── browser.test.ts │ │ ├── localai-10s-check.spec.ts │ │ ├── localai-clear-cache-load.spec.ts │ │ ├── localai-knowledge-base.spec.ts │ │ ├── localai-load-models.spec.ts │ │ ├── localai-loading-check.spec.ts │ │ ├── localai-network-audit.spec.ts │ │ ├── localai-network-failures.spec.ts │ │ └── localai-network-full.spec.ts │ ├── integration/ │ │ └── pipeline.test.ts │ └── unit/ │ ├── memory.test.ts │ ├── model-loader.test.ts │ ├── runtime.test.ts │ ├── scheduler.test.ts │ ├── tensor.test.ts │ ├── tokenizer.test.ts │ └── worker.test.ts ├── tsconfig.json ├── vercel.json └── vitest.config.ts
SYMBOL INDEX (2561 symbols across 129 files)
FILE: demo/demo.js
method formatBytes (line 58) | formatBytes(bytes) {
method sleep (line 69) | sleep(ms) {
method createModelInputs (line 76) | createModelInputs(model, seqLen = config.defaultSeqLen) {
method inferText (line 97) | async inferText(text) {
method $ (line 148) | $(id) {
method setOutput (line 155) | setOutput(id, content, type = '') {
method showLoading (line 166) | showLoading(id, message = 'Loading...') {
method showSuccess (line 173) | showSuccess(id, message) {
method showError (line 180) | showError(id, error) {
method renderStatusList (line 188) | renderStatusList(id, items) {
method renderMetrics (line 203) | renderMetrics(id, metrics) {
method updateRuntimeStatus (line 220) | async updateRuntimeStatus() {
method updateMemoryStatus (line 240) | updateMemoryStatus() {
method updateMonitorMetrics (line 260) | updateMonitorMetrics(sample) {
method initOutputs (line 273) | initOutputs() {
method loadModel (line 310) | async loadModel() {
method testModel (line 341) | async testModel() {
method testTensors (line 373) | testTensors() {
method classifyText (line 401) | async classifyText() {
method classifyBatch (line 425) | async classifyBatch() {
method extractFeatures (line 454) | async extractFeatures() {
method quantize (line 492) | quantize() {
method prune (line 521) | prune() {
method debug (line 544) | debug() {
method benchmark (line 574) | async benchmark() {
method testScheduler (line 602) | async testScheduler() {
method allocateMemory (line 629) | allocateMemory() {
method cleanupMemory (line 655) | cleanupMemory() {
method testConcurrency (line 669) | async testConcurrency() {
method startMonitor (line 704) | startMonitor() {
method stopMonitor (line 718) | stopMonitor() {
method simulateInferences (line 727) | simulateInferences() {
method openDashboard (line 742) | openDashboard() {
method closeDashboard (line 761) | closeDashboard() {
method init (line 778) | async init() {
method loadModels (line 812) | async loadModels() {
method handleFileSelect (line 869) | handleFileSelect(e) {
method loadImage (line 879) | async loadImage(source) {
method loadSampleImage (line 959) | async loadSampleImage() {
method handleClick (line 973) | async handleClick(e, label) {
method drawPoints (line 1008) | drawPoints() {
method drawMask (line 1027) | drawMask(result) {
method clear (line 1063) | clear() {
method downloadMask (line 1080) | downloadMask() {
method reset (line 1096) | reset() {
method init (line 1126) | init() {
method loadModel (line 1141) | async loadModel() {
method send (line 1216) | async send() {
method addMessage (line 1316) | addMessage(role, content, isTyping = false) {
method updateStatus (line 1333) | updateStatus(status, text) {
method clear (line 1349) | clear() {
function init (line 1427) | async function init() {
FILE: demo/server.js
constant ROOT (line 15) | const ROOT = join(__dirname, '..');
constant MIME_TYPES (line 17) | const MIME_TYPES = {
constant PORT (line 29) | const PORT = process.env.PORT || 3000;
FILE: dist/backends/index.js
function registerAllBackends (line 25) | function registerAllBackends() {
FILE: dist/backends/onnx.d.ts
class ONNXRuntime (line 15) | class ONNXRuntime implements Runtime {
FILE: dist/backends/onnx.js
function getOrt (line 14) | async function getOrt() {
function isOnnxAvailable (line 33) | async function isOnnxAvailable() {
class ONNXRuntime (line 43) | class ONNXRuntime {
method capabilities (line 47) | get capabilities() {
method isAvailable (line 60) | async isAvailable() {
method initialize (line 66) | async initialize() {
method loadModel (line 87) | async loadModel(modelData, options = {}) {
method run (line 149) | async run(model, inputs) {
method runNamed (line 199) | async runNamed(model, namedInputs) {
method unloadModel (line 246) | async unloadModel(modelId) {
method dispose (line 256) | dispose() {
function createONNXRuntime (line 265) | function createONNXRuntime() {
FILE: dist/backends/transformers-adapter.d.ts
type TransformersPipelineInstance (line 31) | interface TransformersPipelineInstance {
type TransformersPipelineFactory (line 39) | type TransformersPipelineFactory = (task: string, model?: string, option...
type TransformersAdapterOptions (line 43) | interface TransformersAdapterOptions {
class TransformersAdapterRuntime (line 53) | class TransformersAdapterRuntime implements Runtime {
FILE: dist/backends/transformers-adapter.js
class TransformersAdapterRuntime (line 38) | class TransformersAdapterRuntime {
method capabilities (line 40) | get capabilities() {
method isAvailable (line 50) | async isAvailable() {
method initialize (line 53) | async initialize() {
method loadModel (line 59) | async loadModel(modelData, options = {}) {
method loadPipeline (line 88) | async loadPipeline(task, model, pipelineOptions) {
method run (line 107) | async run(model, inputs) {
method runDirect (line 125) | async runDirect(modelId, input, options) {
method dispose (line 132) | dispose() {
function useTransformersBackend (line 160) | function useTransformersBackend(options) {
function getTransformersAdapter (line 168) | function getTransformersAdapter() {
FILE: dist/backends/wasm.d.ts
class WASMRuntime (line 14) | class WASMRuntime implements Runtime {
FILE: dist/backends/wasm.js
class WASMRuntime (line 20) | class WASMRuntime {
method capabilities (line 26) | get capabilities() {
method isAvailable (line 39) | async isAvailable() {
method initialize (line 58) | async initialize() {
method checkSIMDSupport (line 80) | async checkSIMDSupport() {
method createJSFallback (line 99) | createJSFallback(memory) {
method loadModel (line 187) | async loadModel(modelData, options = {}) {
method run (line 228) | async run(model, inputs) {
method executeModel (line 236) | async executeModel(inputs, metadata) {
method parseModelConfig (line 276) | parseModelConfig(data) {
method loadWeights (line 309) | async loadWeights(_modelData, _wasmData) {
method unloadModel (line 316) | unloadModel(modelId) {
method ensureInitialized (line 329) | ensureInitialized() {
method hasSIMDSupport (line 337) | hasSIMDSupport() {
method dispose (line 343) | dispose() {
function createWASMRuntime (line 355) | function createWASMRuntime() {
FILE: dist/backends/webgpu.d.ts
type Navigator (line 14) | interface Navigator {
type GPU (line 17) | interface GPU {
type GPURequestAdapterOptions (line 20) | interface GPURequestAdapterOptions {
type GPUAdapter (line 23) | interface GPUAdapter {
type GPUDeviceDescriptor (line 26) | interface GPUDeviceDescriptor {
type GPUDevice (line 30) | interface GPUDevice {
type GPULimits (line 40) | interface GPULimits {
type GPUDeviceLostInfo (line 43) | interface GPUDeviceLostInfo {
type GPUBuffer (line 47) | interface GPUBuffer {
type GPUShaderModule (line 50) | interface GPUShaderModule {
type GPUBindGroupLayout (line 52) | interface GPUBindGroupLayout {
type GPUPipelineLayout (line 54) | interface GPUPipelineLayout {
type GPUComputePipeline (line 56) | interface GPUComputePipeline {
type GPUBufferDescriptor (line 58) | interface GPUBufferDescriptor {
type GPUShaderModuleDescriptor (line 62) | interface GPUShaderModuleDescriptor {
type GPUBindGroupLayoutDescriptor (line 65) | interface GPUBindGroupLayoutDescriptor {
type GPUBindGroupLayoutEntry (line 68) | interface GPUBindGroupLayoutEntry {
type GPUPipelineLayoutDescriptor (line 75) | interface GPUPipelineLayoutDescriptor {
type GPUComputePipelineDescriptor (line 78) | interface GPUComputePipelineDescriptor {
class WebGPURuntime (line 89) | class WebGPURuntime implements Runtime {
FILE: dist/backends/webgpu.js
class WebGPURuntime (line 32) | class WebGPURuntime {
method capabilities (line 38) | get capabilities() {
method isAvailable (line 51) | async isAvailable() {
method initialize (line 67) | async initialize() {
method loadModel (line 96) | async loadModel(modelData, options = {}) {
method run (line 142) | async run(model, inputs) {
method executeModel (line 151) | async executeModel(inputs, metadata) {
method parseModelData (line 191) | parseModelData(data) {
method uploadWeights (line 221) | async uploadWeights(_data, modelData) {
method createPipelines (line 235) | async createPipelines(modelData) {
method unloadModel (line 287) | unloadModel(modelId) {
method ensureInitialized (line 300) | ensureInitialized() {
method dispose (line 308) | dispose() {
function createWebGPURuntime (line 325) | function createWebGPURuntime() {
FILE: dist/backends/webnn.d.ts
type MLContextType (line 15) | type MLContextType = 'default' | 'gpu' | 'cpu' | 'npu';
type MLOperandDescriptor (line 19) | interface MLOperandDescriptor {
type MLContextOptions (line 26) | interface MLContextOptions {
type Navigator (line 31) | interface Navigator {
type MLContext (line 36) | interface MLContext {
type MLGraph (line 39) | interface MLGraph {
type MLGraphBuilder (line 41) | interface MLGraphBuilder {
type MLOperand (line 57) | interface MLOperand {
class WebNNRuntime (line 63) | class WebNNRuntime implements Runtime {
FILE: dist/backends/webnn.js
class WebNNRuntime (line 21) | class WebNNRuntime {
method capabilities (line 27) | get capabilities() {
method isAvailable (line 40) | async isAvailable() {
method initialize (line 56) | async initialize() {
method loadModel (line 84) | async loadModel(modelData, options = {}) {
method run (line 118) | async run(model, inputs) {
method executeModel (line 126) | async executeModel(inputs, metadata) {
method parseModelConfig (line 146) | parseModelConfig(data) {
method unloadModel (line 171) | unloadModel(modelId) {
method ensureInitialized (line 177) | ensureInitialized() {
method getDeviceType (line 185) | getDeviceType() {
method dispose (line 191) | dispose() {
function createWebNNRuntime (line 200) | function createWebNNRuntime() {
FILE: dist/core/composer.d.ts
type CompositionStage (line 26) | interface CompositionStage {
type CompositionResult (line 46) | interface CompositionResult {
type ComposedPipeline (line 59) | interface ComposedPipeline {
FILE: dist/core/composer.js
function compose (line 50) | function compose(stages) {
function parallel (line 125) | function parallel(stages) {
FILE: dist/core/device-profiler.d.ts
type DeviceTier (line 22) | type DeviceTier = 'high' | 'medium' | 'low';
type DeviceProfile (line 26) | interface DeviceProfile {
type ModelRecommendation (line 49) | interface ModelRecommendation {
FILE: dist/core/device-profiler.js
function getDeviceProfile (line 25) | async function getDeviceProfile() {
function recommendQuantization (line 106) | function recommendQuantization(profile) {
function recommendModelVariant (line 116) | async function recommendModelVariant() {
function resetDeviceProfile (line 128) | function resetDeviceProfile() {
FILE: dist/core/memory.d.ts
type TrackedResource (line 15) | interface TrackedResource {
class MemoryManager (line 31) | class MemoryManager {
class MemoryScope (line 157) | class MemoryScope {
class ModelCache (line 194) | class ModelCache {
FILE: dist/core/memory.js
constant DEFAULT_POOL_CONFIG (line 14) | const DEFAULT_POOL_CONFIG = {
class MemoryManager (line 33) | class MemoryManager {
method constructor (line 43) | constructor(config = {}) {
method getInstance (line 49) | static getInstance() {
method configure (line 58) | static configure(config) {
method track (line 67) | track(tensor, disposer) {
method trackModel (line 88) | trackModel(model, disposer) {
method untrack (line 109) | untrack(id) {
method release (line 120) | release(resourceOrId) {
method estimateTensorSize (line 136) | estimateTensorSize(tensor) {
method getBytesPerElement (line 143) | getBytesPerElement(dtype) {
method captureStackTrace (line 164) | captureStackTrace() {
method checkMemoryThreshold (line 175) | checkMemoryThreshold() {
method gc (line 200) | gc(evict = false, maxAge = 5 * 60 * 1000) {
method measureBrowserMemory (line 224) | async measureBrowserMemory() {
method getDeviceMemory (line 242) | getDeviceMemory() {
method getStats (line 256) | getStats() {
method getResourceDetails (line 278) | getResourceDetails() {
method detectLeaks (line 284) | detectLeaks(maxAge = 10 * 60 * 1000) {
method on (line 297) | on(event, listener) {
method off (line 308) | off(event, listener) {
method emit (line 317) | emit(type, data) {
method resetStats (line 338) | resetStats() {
method disposeAll (line 344) | disposeAll() {
method dispose (line 352) | dispose() {
class MemoryScope (line 376) | class MemoryScope {
method constructor (line 380) | constructor(parent) {
method track (line 389) | track(resource) {
method createChild (line 396) | createChild() {
method keep (line 402) | keep(resource) {
method dispose (line 412) | dispose() {
function withMemoryScope (line 441) | async function withMemoryScope(fn) {
function withMemoryScopeSync (line 453) | function withMemoryScopeSync(fn) {
class ModelCache (line 468) | class ModelCache {
method constructor (line 473) | constructor(options = {}) {
method get (line 480) | get(key) {
method set (line 491) | set(key, model) {
method delete (line 509) | delete(key) {
method has (line 522) | has(key) {
method evictLRU (line 528) | evictLRU() {
method clear (line 544) | clear() {
method getStats (line 554) | getStats() {
function getMemoryManager (line 569) | function getMemoryManager() {
function getMemoryStats (line 575) | function getMemoryStats() {
function release (line 581) | function release(resource) {
function gc (line 587) | function gc() {
FILE: dist/core/plugin.d.ts
type PluginPipelineEntry (line 27) | interface PluginPipelineEntry {
type PluginBackendEntry (line 36) | interface PluginBackendEntry {
type PluginMiddleware (line 45) | interface PluginMiddleware {
type EdgeFlowPlugin (line 62) | interface EdgeFlowPlugin {
FILE: dist/core/plugin.js
function registerPlugin (line 33) | async function registerPlugin(plugin) {
function getPluginPipeline (line 64) | function getPluginPipeline(task) {
function getPluginMiddleware (line 70) | function getPluginMiddleware() {
function listPlugins (line 76) | function listPlugins() {
function unregisterPlugin (line 85) | function unregisterPlugin(name) {
FILE: dist/core/runtime.d.ts
class RuntimeManager (line 17) | class RuntimeManager {
class LoadedModelImpl (line 78) | class LoadedModelImpl implements LoadedModel {
FILE: dist/core/runtime.js
constant RUNTIME_PRIORITY (line 24) | const RUNTIME_PRIORITY = ['webgpu', 'webnn', 'wasm'];
class RuntimeManager (line 37) | class RuntimeManager {
method constructor (line 41) | constructor() { }
method getInstance (line 45) | static getInstance() {
method register (line 54) | register(type, factory) {
method getRuntime (line 60) | async getRuntime(type = 'auto') {
method getBestRuntime (line 94) | async getBestRuntime() {
method detectAvailableRuntimes (line 125) | async detectAvailableRuntimes() {
method getCapabilities (line 146) | async getCapabilities(type) {
method setDefaultRuntime (line 153) | setDefaultRuntime(type) {
method getDefaultRuntimeType (line 159) | getDefaultRuntimeType() {
method disposeRuntime (line 165) | disposeRuntime(type) {
method disposeAll (line 175) | disposeAll() {
method on (line 184) | on(event, listener) {
method off (line 195) | off(event, listener) {
method emit (line 204) | emit(type, data) {
function generateModelId (line 233) | function generateModelId() {
class LoadedModelImpl (line 239) | class LoadedModelImpl {
method constructor (line 245) | constructor(metadata, runtime, dispose) {
method isLoaded (line 251) | get isLoaded() {
method dispose (line 254) | dispose() {
function loadModel (line 269) | async function loadModel(url, options = {}) {
function loadModelFromBuffer (line 291) | async function loadModelFromBuffer(data, options = {}) {
function runInference (line 302) | async function runInference(model, inputs) {
function runInferenceNamed (line 316) | async function runInferenceNamed(model, namedInputs) {
function runBatchInference (line 334) | async function runBatchInference(model, batches) {
function getRuntimeManager (line 349) | function getRuntimeManager() {
function registerRuntime (line 355) | function registerRuntime(type, factory) {
function getBestRuntime (line 361) | async function getBestRuntime() {
function getAvailableRuntimes (line 367) | async function getAvailableRuntimes() {
FILE: dist/core/scheduler.d.ts
class InferenceScheduler (line 18) | class InferenceScheduler {
FILE: dist/core/scheduler.js
class Task (line 14) | class Task {
method constructor (line 27) | constructor(id, modelId, priority, executor) {
method status (line 34) | get status() {
method startedAt (line 37) | get startedAt() {
method completedAt (line 40) | get completedAt() {
method result (line 43) | get result() {
method error (line 46) | get error() {
method cancel (line 52) | cancel() {
method wait (line 67) | wait() {
method execute (line 84) | async execute() {
constant PRIORITY_ORDER (line 115) | const PRIORITY_ORDER = {
class PriorityQueue (line 124) | class PriorityQueue {
method length (line 126) | get length() {
method isEmpty (line 129) | isEmpty() {
method enqueue (line 135) | enqueue(item) {
method dequeue (line 152) | dequeue() {
method peek (line 158) | peek() {
method remove (line 164) | remove(id) {
method getAll (line 175) | getAll() {
method clear (line 181) | clear() {
class BatchCollector (line 191) | class BatchCollector {
method constructor (line 197) | constructor(maxSize, timeout, onBatch) {
method add (line 202) | add(task) {
method flush (line 211) | flush() {
method clear (line 222) | clear() {
function generateTaskId (line 238) | function generateTaskId() {
constant DEFAULT_OPTIONS (line 244) | const DEFAULT_OPTIONS = {
class InferenceScheduler (line 267) | class InferenceScheduler {
method constructor (line 278) | constructor(options = {}) {
method getCircuit (line 284) | getCircuit(modelId) {
method isCircuitOpen (line 295) | isCircuitOpen(modelId) {
method circuitSuccess (line 313) | circuitSuccess(modelId) {
method circuitFailure (line 323) | circuitFailure(modelId) {
method getQueue (line 340) | getQueue(modelId) {
method getRunningSet (line 351) | getRunningSet(modelId) {
method canStartTask (line 362) | canStartTask(modelId) {
method processQueue (line 375) | async processQueue() {
method schedule (line 441) | schedule(modelId, executor, priority = 'normal') {
method scheduleWithTimeout (line 493) | scheduleWithTimeout(modelId, executor, timeout = this.options.defaultT...
method scheduleAll (line 515) | async scheduleAll(tasks) {
method getTask (line 522) | getTask(taskId) {
method cancelTask (line 528) | cancelTask(taskId) {
method cancelAllForModel (line 543) | cancelAllForModel(modelId) {
method getStats (line 560) | getStats() {
method on (line 597) | on(event, listener) {
method off (line 608) | off(event, listener) {
method emit (line 617) | emit(type, data) {
method clearHistory (line 638) | clearHistory() {
method dispose (line 650) | dispose() {
function getScheduler (line 677) | function getScheduler() {
function setScheduler (line 686) | function setScheduler(scheduler) {
function configureScheduler (line 695) | function configureScheduler(options) {
FILE: dist/core/tensor.d.ts
class EdgeFlowTensor (line 10) | class EdgeFlowTensor implements Tensor {
FILE: dist/core/tensor.js
function generateTensorId (line 12) | function generateTensorId() {
function getTypedArrayConstructor (line 18) | function getTypedArrayConstructor(dtype) {
function calculateSize (line 41) | function calculateSize(shape) {
function validateShape (line 49) | function validateShape(shape) {
class EdgeFlowTensor (line 60) | class EdgeFlowTensor {
method constructor (line 67) | constructor(data, shape, dtype = 'float32') {
method data (line 99) | get data() {
method isDisposed (line 103) | get isDisposed() {
method checkDisposed (line 109) | checkDisposed() {
method toFloat32Array (line 117) | toFloat32Array() {
method toArray (line 131) | toArray() {
method clone (line 147) | clone() {
method dispose (line 156) | dispose() {
method get (line 166) | get(...indices) {
method set (line 187) | set(value, ...indices) {
method reshape (line 208) | reshape(newShape) {
method transpose (line 221) | transpose() {
method toString (line 238) | toString() {
function tensor (line 248) | function tensor(data, shape, dtype = 'float32') {
function zeros (line 269) | function zeros(shape, dtype = 'float32') {
function ones (line 278) | function ones(shape, dtype = 'float32') {
function full (line 288) | function full(shape, value, dtype = 'float32') {
function random (line 298) | function random(shape, dtype = 'float32') {
function randn (line 309) | function randn(shape, dtype = 'float32') {
function arange (line 328) | function arange(start, stop, step = 1, dtype = 'float32') {
function linspace (line 343) | function linspace(start, stop, num = 50, dtype = 'float32') {
function eye (line 354) | function eye(n, dtype = 'float32') {
function add (line 367) | function add(a, b) {
function sub (line 390) | function sub(a, b) {
function mul (line 413) | function mul(a, b) {
function div (line 436) | function div(a, b) {
function matmul (line 459) | function matmul(a, b) {
function softmax (line 485) | function softmax(t, axis = -1) {
function relu (line 535) | function relu(t) {
function sigmoid (line 546) | function sigmoid(t) {
function tanh (line 557) | function tanh(t) {
function sum (line 568) | function sum(t, axis) {
function mean (line 619) | function mean(t, axis) {
function argmax (line 633) | function argmax(t, axis) {
function concat (line 670) | function concat(tensors, axis = 0) {
FILE: dist/core/types.d.ts
type DataType (line 9) | type DataType = 'float32' | 'float16' | 'int32' | 'int64' | 'uint8' | 'i...
type TypedArray (line 13) | type TypedArray = Float32Array | Float64Array | Int32Array | BigInt64Arr...
type Shape (line 17) | type Shape = readonly number[];
type Tensor (line 21) | interface Tensor {
type RuntimeType (line 46) | type RuntimeType = 'webgpu' | 'webnn' | 'wasm' | 'auto';
type RuntimeCapabilities (line 50) | interface RuntimeCapabilities {
type Runtime (line 67) | interface Runtime {
type ModelFormat (line 88) | type ModelFormat = 'onnx' | 'edgeflow' | 'safetensors';
type QuantizationType (line 92) | type QuantizationType = 'float32' | 'float16' | 'int8' | 'uint8' | 'int4';
type ModelMetadata (line 96) | interface ModelMetadata {
type ModelIOSpec (line 123) | interface ModelIOSpec {
type ModelLoadOptions (line 136) | interface ModelLoadOptions {
type LoadedModel (line 149) | interface LoadedModel {
type TaskPriority (line 164) | type TaskPriority = 'low' | 'normal' | 'high' | 'critical';
type TaskStatus (line 168) | type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'canc...
type InferenceTask (line 172) | interface InferenceTask<T = unknown> {
type SchedulerOptions (line 199) | interface SchedulerOptions {
type MemoryStats (line 226) | interface MemoryStats {
type MemoryPoolConfig (line 241) | interface MemoryPoolConfig {
type PipelineTask (line 256) | type PipelineTask = 'text-classification' | 'token-classification' | 'qu...
type PipelineConfig (line 260) | interface PipelineConfig {
type PipelineOptions (line 279) | interface PipelineOptions {
type TokenizerConfig (line 294) | interface TokenizerConfig {
type TokenizedOutput (line 317) | interface TokenizedOutput {
class EdgeFlowError (line 332) | class EdgeFlowError extends Error {
type ErrorCode (line 362) | type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];
type EventType (line 366) | type EventType = 'model:loading' | 'model:loaded' | 'model:unloaded' | '...
type EdgeFlowEvent (line 370) | interface EdgeFlowEvent<T = unknown> {
type EventListener (line 378) | type EventListener<T = unknown> = (event: EdgeFlowEvent<T>) => void;
FILE: dist/core/types.js
class EdgeFlowError (line 12) | class EdgeFlowError extends Error {
method constructor (line 15) | constructor(message, code, details) {
FILE: dist/core/worker.d.ts
type WorkerMessageType (line 10) | type WorkerMessageType = 'init' | 'load_model' | 'run_inference' | 'disp...
type WorkerMessage (line 14) | interface WorkerMessage {
type LoadModelRequest (line 22) | interface LoadModelRequest {
type InferenceRequest (line 32) | interface InferenceRequest {
type SerializedTensor (line 39) | interface SerializedTensor {
type WorkerPoolOptions (line 47) | interface WorkerPoolOptions {
type WorkerHealthState (line 67) | type WorkerHealthState = 'alive' | 'dead' | 'restarting';
class InferenceWorker (line 71) | class InferenceWorker {
class WorkerPool (line 138) | class WorkerPool {
FILE: dist/core/worker.js
function serializeTensor (line 12) | function serializeTensor(tensor) {
function deserializeTensor (line 27) | async function deserializeTensor(serialized) {
function deserializeTensorSync (line 36) | function deserializeTensorSync(serialized, TensorClass) {
constant MAX_RESTART_ATTEMPTS (line 40) | const MAX_RESTART_ATTEMPTS = 3;
constant RESTART_BASE_DELAY_MS (line 41) | const RESTART_BASE_DELAY_MS = 1000;
class InferenceWorker (line 45) | class InferenceWorker {
method constructor (line 54) | constructor(workerUrl) {
method health (line 61) | get health() {
method initWorker (line 67) | initWorker(workerUrl) {
method handleCrash (line 84) | handleCrash() {
method attemptRestart (line 97) | attemptRestart() {
method restart (line 112) | restart() {
method createWorkerBlob (line 137) | createWorkerBlob() {
method handleMessage (line 244) | handleMessage(message) {
method sendRequest (line 265) | async sendRequest(type, payload) {
method init (line 289) | async init() {
method loadModel (line 298) | async loadModel(url, options) {
method runInference (line 306) | async runInference(modelId, inputs) {
method dispose (line 314) | async dispose(modelId) {
method terminate (line 320) | terminate() {
class WorkerPool (line 335) | class WorkerPool {
method constructor (line 340) | constructor(options = {}) {
method getNextHealthyWorker (line 351) | getNextHealthyWorker() {
method getWorkerForModel (line 368) | getWorkerForModel(modelId) {
method replaceWorker (line 384) | replaceWorker(index) {
method init (line 394) | async init() {
method loadModel (line 400) | async loadModel(url, options) {
method runInference (line 409) | async runInference(modelId, inputs) {
method runBatch (line 416) | async runBatch(modelId, batchInputs) {
method dispose (line 426) | async dispose(modelId) {
method terminate (line 434) | terminate() {
method size (line 444) | get size() {
function getWorkerPool (line 455) | function getWorkerPool(options) {
function runInWorker (line 464) | async function runInWorker(modelUrl, inputs, options) {
function isWorkerSupported (line 474) | function isWorkerSupported() {
FILE: dist/edgeflow.browser.js
method "dist/core/types.js" (line 21) | "dist/core/types.js"() {
function generateTensorId (line 66) | function generateTensorId() {
function getTypedArrayConstructor (line 69) | function getTypedArrayConstructor(dtype) {
function calculateSize (line 88) | function calculateSize(shape) {
function validateShape (line 93) | function validateShape(shape) {
function tensor (line 101) | function tensor(data, shape, dtype = "float32") {
function zeros (line 117) | function zeros(shape, dtype = "float32") {
function ones (line 123) | function ones(shape, dtype = "float32") {
function full (line 130) | function full(shape, value, dtype = "float32") {
function random (line 137) | function random(shape, dtype = "float32") {
function randn (line 145) | function randn(shape, dtype = "float32") {
function arange (line 160) | function arange(start, stop, step = 1, dtype = "float32") {
function linspace (line 172) | function linspace(start, stop, num = 50, dtype = "float32") {
function eye (line 180) | function eye(n, dtype = "float32") {
function add (line 187) | function add(a, b) {
function sub (line 207) | function sub(a, b) {
function mul (line 227) | function mul(a, b) {
function div (line 247) | function div(a, b) {
function matmul (line 267) | function matmul(a, b) {
function softmax (line 290) | function softmax(t, axis = -1) {
function relu (line 334) | function relu(t) {
function sigmoid (line 342) | function sigmoid(t) {
function tanh (line 350) | function tanh(t) {
function sum (line 358) | function sum(t, axis) {
function mean (line 402) | function mean(t, axis) {
function argmax (line 413) | function argmax(t, axis) {
function concat (line 445) | function concat(tensors, axis = 0) {
method "dist/core/tensor.js" (line 492) | "dist/core/tensor.js"() {
function supportsRangeRequests (line 689) | async function supportsRangeRequests(url) {
function downloadChunk (line 704) | async function downloadChunk(url, start, end, timeout) {
function downloadWithResume (line 720) | async function downloadWithResume(url, options) {
function downloadSimple (line 818) | async function downloadSimple(url, timeout, onProgress) {
function loadModelData (line 864) | async function loadModelData(url, options = {}) {
function preloadModel (line 907) | function preloadModel(url, options = {}) {
function preloadModels (line 910) | function preloadModels(urls, options = {}) {
function isModelCached (line 913) | async function isModelCached(url) {
function getCachedModel (line 917) | async function getCachedModel(url) {
function deleteCachedModel (line 920) | async function deleteCachedModel(url) {
function clearModelCache (line 923) | async function clearModelCache() {
function getModelCacheStats (line 926) | async function getModelCacheStats() {
function getPreloadStatus (line 929) | function getPreloadStatus(url) {
function cancelPreload (line 932) | function cancelPreload(url) {
function getPreloadedModel (line 935) | async function getPreloadedModel(url) {
method "dist/utils/model-loader.js" (line 940) | "dist/utils/model-loader.js"() {
method constructor (line 1360) | constructor(id, modelId, priority, executor) {
method status (line 1379) | get status() {
method startedAt (line 1382) | get startedAt() {
method completedAt (line 1385) | get completedAt() {
method result (line 1388) | get result() {
method error (line 1391) | get error() {
method cancel (line 1397) | cancel() {
method wait (line 1412) | wait() {
method execute (line 1429) | async execute() {
method constructor (line 1460) | constructor() {
method length (line 1463) | get length() {
method isEmpty (line 1466) | isEmpty() {
method enqueue (line 1472) | enqueue(item) {
method dequeue (line 1489) | dequeue() {
method peek (line 1495) | peek() {
method remove (line 1501) | remove(id) {
method getAll (line 1512) | getAll() {
method clear (line 1518) | clear() {
function generateTaskId (line 1523) | function generateTaskId() {
method constructor (line 1540) | constructor(options = {}) {
method getCircuit (line 1556) | getCircuit(modelId) {
method isCircuitOpen (line 1567) | isCircuitOpen(modelId) {
method circuitSuccess (line 1585) | circuitSuccess(modelId) {
method circuitFailure (line 1595) | circuitFailure(modelId) {
method getQueue (line 1612) | getQueue(modelId) {
method getRunningSet (line 1623) | getRunningSet(modelId) {
method canStartTask (line 1634) | canStartTask(modelId) {
method processQueue (line 1647) | async processQueue() {
method schedule (line 1705) | schedule(modelId, executor, priority = "normal") {
method scheduleWithTimeout (line 1751) | scheduleWithTimeout(modelId, executor, timeout = this.options.defaultTim...
method scheduleAll (line 1771) | async scheduleAll(tasks) {
method getTask (line 1778) | getTask(taskId) {
method cancelTask (line 1784) | cancelTask(taskId) {
method cancelAllForModel (line 1798) | cancelAllForModel(modelId) {
method getStats (line 1815) | getStats() {
method on (line 1852) | on(event, listener) {
method off (line 1863) | off(event, listener) {
method emit (line 1872) | emit(type, data) {
method clearHistory (line 1892) | clearHistory() {
method dispose (line 1902) | dispose() {
function getScheduler (line 1921) | function getScheduler() {
function setScheduler (line 1927) | function setScheduler(scheduler) {
function configureScheduler (line 1933) | function configureScheduler(options) {
method constructor (line 1949) | constructor(config = {}) {
method getInstance (line 1963) | static getInstance() {
method configure (line 1972) | static configure(config) {
method track (line 1981) | track(tensor2, disposer) {
method trackModel (line 2002) | trackModel(model, disposer) {
method untrack (line 2023) | untrack(id) {
method release (line 2034) | release(resourceOrId) {
method estimateTensorSize (line 2049) | estimateTensorSize(tensor2) {
method getBytesPerElement (line 2056) | getBytesPerElement(dtype) {
method captureStackTrace (line 2077) | captureStackTrace() {
method checkMemoryThreshold (line 2088) | checkMemoryThreshold() {
method gc (line 2112) | gc(evict = false, maxAge = 5 * 60 * 1e3) {
method measureBrowserMemory (line 2136) | async measureBrowserMemory() {
method getDeviceMemory (line 2150) | getDeviceMemory() {
method getStats (line 2162) | getStats() {
method getResourceDetails (line 2184) | getResourceDetails() {
method detectLeaks (line 2190) | detectLeaks(maxAge = 10 * 60 * 1e3) {
method on (line 2203) | on(event, listener) {
method off (line 2214) | off(event, listener) {
method emit (line 2223) | emit(type, data) {
method resetStats (line 2243) | resetStats() {
method disposeAll (line 2249) | disposeAll() {
method dispose (line 2257) | dispose() {
method constructor (line 2267) | constructor(parent) {
method track (line 2279) | track(resource) {
method createChild (line 2286) | createChild() {
method keep (line 2292) | keep(resource) {
method dispose (line 2302) | dispose() {
function withMemoryScope (line 2324) | async function withMemoryScope(fn) {
function withMemoryScopeSync (line 2332) | function withMemoryScopeSync(fn) {
method constructor (line 2341) | constructor(options = {}) {
method get (line 2352) | get(key) {
method set (line 2363) | set(key, model) {
method delete (line 2378) | delete(key) {
method has (line 2391) | has(key) {
method evictLRU (line 2397) | evictLRU() {
method clear (line 2413) | clear() {
method getStats (line 2423) | getStats() {
function getMemoryManager (line 2432) | function getMemoryManager() {
function getMemoryStats (line 2435) | function getMemoryStats() {
function release (line 2438) | function release(resource) {
function gc (line 2441) | function gc() {
method constructor (line 2451) | constructor() {
method getInstance (line 2458) | static getInstance() {
method register (line 2467) | register(type, factory) {
method getRuntime (line 2473) | async getRuntime(type = "auto") {
method getBestRuntime (line 2502) | async getBestRuntime() {
method detectAvailableRuntimes (line 2529) | async detectAvailableRuntimes() {
method getCapabilities (line 2549) | async getCapabilities(type) {
method setDefaultRuntime (line 2556) | setDefaultRuntime(type) {
method getDefaultRuntimeType (line 2562) | getDefaultRuntimeType() {
method disposeRuntime (line 2568) | disposeRuntime(type) {
method disposeAll (line 2578) | disposeAll() {
method on (line 2587) | on(event, listener) {
method off (line 2598) | off(event, listener) {
method emit (line 2607) | emit(type, data) {
function generateModelId (line 2628) | function generateModelId() {
method constructor (line 2632) | constructor(metadata, runtime, dispose) {
method isLoaded (line 2643) | get isLoaded() {
method dispose (line 2646) | dispose() {
function loadModel (line 2654) | async function loadModel(url, options = {}) {
function loadModelFromBuffer (line 2670) | async function loadModelFromBuffer(data, options = {}) {
function runInference (line 2675) | async function runInference(model, inputs) {
function runInferenceNamed (line 2685) | async function runInferenceNamed(model, namedInputs) {
function runBatchInference (line 2698) | async function runBatchInference(model, batches) {
function getRuntimeManager (line 2705) | function getRuntimeManager() {
function registerRuntime (line 2708) | function registerRuntime(type, factory) {
function getBestRuntime (line 2711) | async function getBestRuntime() {
function getAvailableRuntimes (line 2714) | async function getAvailableRuntimes() {
function registerPlugin (line 2722) | async function registerPlugin(plugin) {
function getPluginPipeline (line 2745) | function getPluginPipeline(task) {
function getPluginMiddleware (line 2748) | function getPluginMiddleware() {
function listPlugins (line 2751) | function listPlugins() {
function unregisterPlugin (line 2757) | function unregisterPlugin(name) {
function getDeviceProfile (line 2779) | async function getDeviceProfile() {
function recommendQuantization (line 2840) | function recommendQuantization(profile) {
function recommendModelVariant (line 2847) | async function recommendModelVariant() {
function resetDeviceProfile (line 2856) | function resetDeviceProfile() {
method constructor (line 2873) | constructor() {
method capabilities (line 2880) | get capabilities() {
method isAvailable (line 2893) | async isAvailable() {
method initialize (line 2908) | async initialize() {
method loadModel (line 2934) | async loadModel(modelData, options = {}) {
method run (line 2972) | async run(model, inputs) {
method executeModel (line 2979) | async executeModel(inputs, metadata) {
method parseModelData (line 3009) | parseModelData(data) {
method uploadWeights (line 3033) | async uploadWeights(_data, modelData) {
method createPipelines (line 3044) | async createPipelines(modelData) {
method unloadModel (line 3095) | unloadModel(modelId) {
method ensureInitialized (line 3107) | ensureInitialized() {
method dispose (line 3115) | dispose() {
function createWebGPURuntime (line 3127) | function createWebGPURuntime() {
method constructor (line 3135) | constructor() {
method capabilities (line 3142) | get capabilities() {
method isAvailable (line 3156) | async isAvailable() {
method initialize (line 3171) | async initialize() {
method loadModel (line 3196) | async loadModel(modelData, options = {}) {
method run (line 3224) | async run(model, inputs) {
method executeModel (line 3231) | async executeModel(inputs, metadata) {
method parseModelConfig (line 3249) | parseModelConfig(data) {
method unloadModel (line 3272) | unloadModel(modelId) {
method ensureInitialized (line 3278) | ensureInitialized() {
method getDeviceType (line 3286) | getDeviceType() {
method dispose (line 3292) | dispose() {
function createWebNNRuntime (line 3298) | function createWebNNRuntime() {
method constructor (line 3306) | constructor() {
method capabilities (line 3313) | get capabilities() {
method isAvailable (line 3328) | async isAvailable() {
method initialize (line 3353) | async initialize() {
method checkSIMDSupport (line 3372) | async checkSIMDSupport() {
method createJSFallback (line 3416) | createJSFallback(memory) {
method loadModel (line 3501) | async loadModel(modelData, options = {}) {
method run (line 3536) | async run(model, inputs) {
method executeModel (line 3543) | async executeModel(inputs, metadata) {
method parseModelConfig (line 3574) | parseModelConfig(data) {
method loadWeights (line 3603) | async loadWeights(_modelData, _wasmData) {
method unloadModel (line 3608) | unloadModel(modelId) {
method ensureInitialized (line 3620) | ensureInitialized() {
method hasSIMDSupport (line 3628) | hasSIMDSupport() {
method dispose (line 3634) | dispose() {
function createWASMRuntime (line 3642) | function createWASMRuntime() {
function getOrt (line 3650) | async function getOrt() {
function isOnnxAvailable (line 3660) | async function isOnnxAvailable() {
method constructor (line 3665) | constructor() {
method capabilities (line 3671) | get capabilities() {
method isAvailable (line 3685) | async isAvailable() {
method initialize (line 3691) | async initialize() {
method loadModel (line 3707) | async loadModel(modelData, options = {}) {
method run (line 3759) | async run(model, inputs) {
method runNamed (line 3805) | async runNamed(model, namedInputs) {
method unloadModel (line 3848) | async unloadModel(modelId) {
method dispose (line 3857) | dispose() {
function createONNXRuntime (line 3862) | function createONNXRuntime() {
method constructor (line 3872) | constructor() {
method capabilities (line 3876) | get capabilities() {
method isAvailable (line 3886) | async isAvailable() {
method initialize (line 3889) | async initialize() {
method loadModel (line 3894) | async loadModel(modelData, options = {}) {
method loadPipeline (line 3921) | async loadPipeline(task, model, pipelineOptions) {
method run (line 3940) | async run(model, inputs) {
method runDirect (line 3954) | async runDirect(modelId, input, options) {
method dispose (line 3961) | dispose() {
function useTransformersBackend (line 3971) | function useTransformersBackend(options) {
function getTransformersAdapter (line 3976) | function getTransformersAdapter() {
function registerAllBackends (line 3981) | function registerAllBackends() {
method constructor (line 3988) | constructor(options = {}) {
method get (line 4011) | get(key) {
method set (line 4030) | set(key, value, size, ttl) {
method has (line 4055) | has(key) {
method delete (line 4068) | delete(key) {
method clear (line 4083) | clear() {
method getStats (line 4095) | getStats() {
method evict (line 4108) | evict() {
method findLRU (line 4131) | findLRU() {
method findLFU (line 4145) | findLFU() {
method findOldest (line 4159) | findOldest() {
method findExpired (line 4173) | findExpired() {
method loadFromStorage (line 4185) | async loadFromStorage() {
method saveToStorage (line 4210) | async saveToStorage() {
method clearStorage (line 4231) | async clearStorage() {
method openDB (line 4245) | openDB() {
method generateKey (line 4263) | generateKey(modelId, input) {
method hashArray (line 4271) | hashArray(arr) {
method constructor (line 4283) | constructor(cacheName = "edgeflow-models") {
method ensureCache (line 4291) | async ensureCache() {
method get (line 4303) | async get(url) {
method put (line 4314) | async put(url, response) {
method delete (line 4324) | async delete(url) {
method clear (line 4335) | async clear() {
method keys (line 4345) | async keys() {
function createCache (line 4355) | function createCache(preset = "medium", options = {}) {
method constructor (line 4379) | constructor(config) {
method initialize (line 4397) | async initialize() {
method loadModelWithCache (line 4416) | async loadModelWithCache(modelPath) {
method run (line 4436) | async run(input, options) {
method runBatch (line 4450) | async runBatch(inputs, options) {
method task (line 4458) | get task() {
method ready (line 4464) | get ready() {
method dispose (line 4470) | dispose() {
function registerPipeline (line 4479) | function registerPipeline(task, factory) {
function getPipelineFactory (line 4482) | function getPipelineFactory(task) {
method constructor (line 4514) | constructor() {
method initByteEncoder (line 4545) | initByteEncoder() {
method fromJSON (line 4572) | static async fromJSON(json) {
method fromUrl (line 4640) | static async fromUrl(url) {
method fromHuggingFace (line 4651) | static async fromHuggingFace(modelId, options) {
method normalize (line 4659) | normalize(text) {
method preTokenize (line 4673) | preTokenize(text) {
method textToBytes (line 4681) | textToBytes(text) {
method bytesToText (line 4689) | bytesToText(text) {
method getPairs (line 4697) | getPairs(word) {
method bpe (line 4707) | bpe(token) {
method wordPiece (line 4760) | wordPiece(word) {
method tokenizeWord (line 4793) | tokenizeWord(word) {
method unigramTokenize (line 4814) | unigramTokenize(word) {
method tokenize (line 4843) | tokenize(text) {
method convertTokensToIds (line 4877) | convertTokensToIds(tokens) {
method convertIdsToTokens (line 4891) | convertIdsToTokens(ids) {
method postProcess (line 4897) | postProcess(ids, pairIds) {
method encode (line 4945) | encode(text, options = {}) {
method encodeBatch (line 4999) | encodeBatch(texts, options = {}) {
method decode (line 5010) | decode(ids, skipSpecialTokens = true) {
method decodeBatch (line 5028) | decodeBatch(batchIds, skipSpecialTokens = true) {
method vocabSize (line 5034) | get vocabSize() {
method getSpecialTokenIds (line 5040) | getSpecialTokenIds() {
method getConfig (line 5054) | getConfig() {
method isSpecialToken (line 5070) | isSpecialToken(token) {
method getTokenId (line 5076) | getTokenId(token) {
method getToken (line 5082) | getToken(id) {
function createBasicTokenizer (line 5086) | function createBasicTokenizer() {
function loadTokenizer (line 5090) | async function loadTokenizer(url) {
function loadTokenizerFromHub (line 5093) | async function loadTokenizerFromHub(modelId, options) {
method constructor (line 5105) | constructor(config, labels) {
method initialize (line 5116) | async initialize() {
method setLabels (line 5126) | setLabels(labels) {
method run (line 5129) | async run(input, options) {
method preprocess (line 5147) | async preprocess(input) {
method runInference (line 5158) | async runInference(inputs) {
method postprocess (line 5165) | async postprocess(outputs, options) {
method constructor (line 5188) | constructor(config) {
method analyze (line 5191) | async analyze(text, options) {
function createTextClassificationPipeline (line 5195) | function createTextClassificationPipeline(config = {}) {
function createSentimentAnalysisPipeline (line 5204) | function createSentimentAnalysisPipeline(config = {}) {
method constructor (line 5225) | constructor(config, embeddingDim = DEFAULT_EMBEDDING_DIM) {
method initialize (line 5236) | async initialize() {
method run (line 5246) | async run(input, options) {
method preprocess (line 5264) | async preprocess(input) {
method runInference (line 5276) | async runInference(inputs) {
method postprocess (line 5284) | async postprocess(outputs, options) {
method extractCLSEmbedding (line 5315) | extractCLSEmbedding(hiddenStates) {
method meanPooling (line 5320) | meanPooling(hiddenStates) {
method maxPooling (line 5332) | maxPooling(hiddenStates) {
method normalizeVector (line 5347) | normalizeVector(vec) {
function createFeatureExtractionPipeline (line 5358) | function createFeatureExtractionPipeline(config = {}) {
method constructor (line 5391) | constructor(options = {}) {
method fromConfig (line 5410) | static fromConfig(config) {
method fromUrl (line 5467) | static async fromUrl(url) {
method fromHuggingFace (line 5478) | static async fromHuggingFace(modelId, options) {
method ensureCanvas (line 5486) | ensureCanvas() {
method process (line 5499) | async process(input) {
method processBatch (line 5522) | async processBatch(inputs) {
method loadFromUrl (line 5544) | async loadFromUrl(url) {
method loadFromBlob (line 5560) | async loadFromBlob(blob) {
method centerCrop (line 5571) | centerCrop(imageData) {
method toImageData (line 5598) | toImageData(source) {
method resize (line 5609) | resize(imageData) {
method toTensor (line 5644) | toTensor(imageData) {
method getOptions (line 5697) | getOptions() {
method constructor (line 5710) | constructor(options = {}) {
method fromConfig (line 5718) | static fromConfig(config) {
method fromHuggingFace (line 5741) | static async fromHuggingFace(modelId, options) {
method ensureAudioContext (line 5754) | ensureAudioContext() {
method process (line 5766) | async process(input) {
method processRaw (line 5792) | async processRaw(input) {
method loadFromUrl (line 5817) | async loadFromUrl(url) {
method loadFromBlob (line 5828) | async loadFromBlob(blob) {
method decodeAudioData (line 5835) | async decodeAudioData(data) {
method audioBufferToFloat32 (line 5843) | audioBufferToFloat32(buffer) {
method normalizeAudio (line 5850) | normalizeAudio(data) {
method computeMelSpectrogram (line 5869) | computeMelSpectrogram(audio) {
method dispose (line 5894) | dispose() {
function preprocessText (line 5901) | function preprocessText(text, options = {}) {
function createImagePreprocessor (line 5918) | function createImagePreprocessor(preset = "imagenet", options = {}) {
function createAudioPreprocessor (line 5942) | function createAudioPreprocessor(preset = "whisper", options = {}) {
method constructor (line 5965) | constructor(config, labels, _numClasses = 1e3) {
method initialize (line 5974) | async initialize() {
method setLabels (line 5984) | setLabels(labels) {
method run (line 5987) | async run(input, options) {
method preprocess (line 6005) | async preprocess(input) {
method runModelInference (line 6013) | async runModelInference(inputs) {
method postprocess (line 6017) | async postprocess(outputs, options) {
function createImageClassificationPipeline (line 6036) | function createImageClassificationPipeline(config = {}, labels) {
method constructor (line 6054) | constructor(config) {
method isModelLoaded (line 6078) | get isModelLoaded() {
method setModelUrls (line 6084) | setModelUrls(model, tokenizer) {
method loadModel (line 6091) | async loadModel(onProgress) {
method fetchModelWithProgress (line 6127) | async fetchModelWithProgress(url, onProgress) {
method initialize (line 6161) | async initialize() {
method setTokenizer (line 6169) | setTokenizer(tokenizer) {
method preprocess (line 6177) | async preprocess(input) {
method postprocess (line 6191) | async postprocess(_outputs, _options) {
method run (line 6202) | async run(prompt, options) {
method stream (line 6211) | async *stream(prompt, options = {}) {
method generateSingle (line 6268) | async generateSingle(prompt, options) {
method generateNextToken (line 6317) | async generateNextToken(inputIds, temperature, topK, topP, repetitionPen...
method greedy (line 6369) | greedy(probs) {
method sample (line 6383) | sample(probs, topK, topP) {
method setChatTemplate (line 6418) | setChatTemplate(templateType) {
method applyChatTemplate (line 6424) | applyChatTemplate(messages, options) {
method applyChatMLTemplate (line 6450) | applyChatMLTemplate(messages) {
method applyLlama2Template (line 6463) | applyLlama2Template(messages) {
method applyLlama3Template (line 6489) | applyLlama3Template(messages) {
method applyMistralTemplate (line 6502) | applyMistralTemplate(messages) {
method applyPhi3Template (line 6519) | applyPhi3Template(messages) {
method applyAlpacaTemplate (line 6532) | applyAlpacaTemplate(messages) {
method applyVicunaTemplate (line 6561) | applyVicunaTemplate(messages) {
method applyCustomTemplate (line 6582) | applyCustomTemplate(messages, template) {
method chat (line 6624) | async chat(userMessage, options) {
method chatStream (line 6658) | async *chatStream(userMessage, options) {
method getConversationHistory (line 6692) | getConversationHistory() {
method setConversationHistory (line 6698) | setConversationHistory(messages) {
method clearConversation (line 6704) | clearConversation() {
method undoLastExchange (line 6710) | undoLastExchange() {
function createTextGenerationPipeline (line 6719) | function createTextGenerationPipeline(config) {
method constructor (line 6812) | constructor(config, labels) {
method initialize (line 6831) | async initialize() {
method setLabels (line 6838) | setLabels(labels) {
method run (line 6841) | async run(input, options) {
method preprocess (line 6847) | async preprocess(input) {
method runModelInference (line 6855) | async runModelInference(inputs) {
method postprocess (line 6859) | async postprocess(outputs, options) {
method parseDetections (line 6876) | parseDetections(data, shape, threshold) {
method nonMaxSuppression (line 6949) | nonMaxSuppression(detections, iouThreshold) {
method computeIoU (line 6974) | computeIoU(a, b) {
method constructor (line 7002) | constructor(config) {
method initialize (line 7025) | async initialize() {
method setTokenizer (line 7039) | setTokenizer(tokenizer) {
method run (line 7042) | async run(input, options) {
method transcribeSingle (line 7054) | async transcribeSingle(audio, options) {
method buildInitialTokens (line 7073) | buildInitialTokens(task, language) {
method getLanguageToken (line 7080) | getLanguageToken(language) {
method autoregressiveDecode (line 7109) | async autoregressiveDecode(encoderHidden, initialTokens) {
method extractTimestamps (line 7134) | extractTimestamps(_tokenIds, text) {
method processLongAudio (line 7155) | async processLongAudio(audio, options = {}) {
method preprocess (line 7186) | async preprocess(input) {
method postprocess (line 7195) | async postprocess(outputs, options) {
method decodeOutput (line 7210) | decodeOutput(data, shape) {
method constructor (line 7249) | constructor(config) {
method initialize (line 7262) | async initialize() {
method setTokenizer (line 7272) | setTokenizer(tokenizer) {
method classify (line 7275) | async classify(text, candidateLabels, options) {
method run (line 7278) | async run(input, options) {
method classifySingle (line 7288) | async classifySingle(text, candidateLabels, template, multiLabel) {
method scoreHypothesis (line 7319) | async scoreHypothesis(premise, hypothesis) {
method preprocess (line 7336) | async preprocess(input) {
method postprocess (line 7347) | async postprocess(_outputs, _options) {
method constructor (line 7365) | constructor(config) {
method initialize (line 7377) | async initialize() {
method setTokenizer (line 7387) | setTokenizer(tokenizer) {
method run (line 7390) | async run(input, options) {
method answerQuestion (line 7396) | async answerQuestion(input, options) {
method tokenOffsetToCharOffset (line 7447) | tokenOffsetToCharOffset(context, _question, inputIds, tokenIdx) {
method preprocess (line 7452) | async preprocess(input) {
method postprocess (line 7467) | async postprocess(outputs, _options) {
method constructor (line 7506) | constructor(config) {
method isModelsLoaded (line 7526) | get isModelsLoaded() {
method setModelUrls (line 7532) | setModelUrls(encoder, decoder) {
method loadModels (line 7539) | async loadModels(onProgress) {
method fetchModelWithProgress (line 7573) | async fetchModelWithProgress(url, onProgress) {
method initialize (line 7607) | async initialize() {
method loadEncoder (line 7615) | async loadEncoder(modelUrl) {
method loadDecoder (line 7623) | async loadDecoder(modelUrl) {
method setImage (line 7631) | async setImage(image) {
method segment (line 7658) | async segment(options = {}) {
method run (line 7684) | async run(input, options) {
method loadImage (line 7691) | async loadImage(input) {
method loadImageFromUrl (line 7708) | async loadImageFromUrl(url) {
method imageElementToImageData (line 7727) | imageElementToImageData(img) {
method canvasToImageData (line 7738) | canvasToImageData(canvas) {
method imageBitmapToImageData (line 7745) | imageBitmapToImageData(bitmap) {
method preprocessImage (line 7756) | preprocessImage(imageData) {
method prepareDecoderInputs (line 7800) | prepareDecoderInputs(points, boxes) {
method postprocessMasks (line 7829) | postprocessMasks(masks, scores, threshold, returnAllMasks) {
method resizeMask (line 7867) | resizeMask(masksData, maskIdx, srcW, srcH, dstW, dstH, threshold) {
method clearImage (line 7894) | clearImage() {
method preprocess (line 7903) | async preprocess(input) {
method postprocess (line 7911) | async postprocess(_outputs, _options) {
method dispose (line 7922) | dispose() {
function createImageSegmentationPipeline (line 7933) | function createImageSegmentationPipeline(config = {}) {
function pipeline (line 7945) | async function pipeline(task, options) {
function createPipelines (line 7998) | async function createPipelines(tasks, options) {
function compose (line 8009) | function compose(stages) {
function parallel (line 8063) | function parallel(stages) {
function buildFileUrl (line 8117) | function buildFileUrl(modelId, filename, options = {}) {
function fetchWithAuth (line 8123) | async function fetchWithAuth(url, token) {
function fileExists (line 8131) | async function fileExists(modelId, filename, options = {}) {
function findOnnxModel (line 8140) | async function findOnnxModel(modelId, options = {}) {
function downloadFile (line 8148) | async function downloadFile(modelId, filename, options = {}) {
function downloadJson (line 8164) | async function downloadJson(modelId, filename, options = {}) {
function downloadTokenizer (line 8180) | async function downloadTokenizer(modelId, options = {}) {
function downloadConfig (line 8184) | async function downloadConfig(modelId, options = {}) {
function downloadModel (line 8187) | async function downloadModel(modelId, options = {}) {
function fromHub (line 8254) | async function fromHub(modelId, options = {}) {
function modelExists (line 8257) | async function modelExists(modelId, options = {}) {
function getModelInfo (line 8265) | async function getModelInfo(modelId, options = {}) {
function getDefaultModel (line 8313) | function getDefaultModel(task) {
function fromTask (line 8316) | async function fromTask(task, options = {}) {
function benchmark (line 8322) | async function benchmark(fn, options = {}) {
function compareBenchmarks (line 8391) | async function compareBenchmarks(baseline, comparison, options = {}) {
function benchmarkSuite (line 8418) | async function benchmarkSuite(suite, options = {}) {
function formatBenchmarkResult (line 8427) | function formatBenchmarkResult(result) {
function formatComparisonResult (line 8444) | function formatComparisonResult(result) {
function benchmarkMemory (line 8461) | async function benchmarkMemory(fn, options = {}) {
function calculateQuantParams (line 8491) | function calculateQuantParams(data, bits, symmetric, perChannel, channel...
function quantizeToInt8 (line 8547) | function quantizeToInt8(data, scale, zeroPoint, perChannel, channelSize ...
function quantizeToUint8 (line 8570) | function quantizeToUint8(data, scale, zeroPoint, perChannel, channelSize...
function quantizeToInt4 (line 8593) | function quantizeToInt4(data, scale, zeroPoint) {
function quantizeToFloat16 (line 8605) | function quantizeToFloat16(data) {
function float32ToFloat16 (line 8612) | function float32ToFloat16(value) {
function dequantizeInt8 (line 8631) | function dequantizeInt8(data, scale, zeroPoint, perChannel = false, chan...
function dequantizeUint8 (line 8652) | function dequantizeUint8(data, scale, zeroPoint, perChannel = false, cha...
function float16ToFloat32 (line 8673) | function float16ToFloat32(value) {
function dequantizeFloat16 (line 8690) | function dequantizeFloat16(data) {
function parseModelWeights (line 8697) | function parseModelWeights(modelData) {
function serializeQuantizedModel (line 8708) | function serializeQuantizedModel(model) {
function quantizeModel (line 8816) | async function quantizeModel(modelData, options) {
function quantizeTensor (line 8964) | function quantizeTensor(tensor2, type, options = {}) {
function dequantizeTensor (line 8997) | function dequantizeTensor(tensor2, scale, zeroPoint, type) {
function pruneTensor (line 9019) | function pruneTensor(tensor2, options = {}) {
function pruneModel (line 9058) | async function pruneModel(modelData, options = {}) {
function analyzeModel (line 9082) | async function analyzeModel(modelData) {
function exportModel (line 9132) | async function exportModel(modelData, options) {
function calculateTensorStats (line 9152) | function calculateTensorStats(data) {
function createHistogram (line 9197) | function createHistogram(data, bins = 50) {
function inspectTensor (line 9230) | function inspectTensor(tensor2, name = "tensor", options = {}) {
function formatTensorInspection (line 9254) | function formatTensorInspection(inspection) {
function formatBytes (line 9280) | function formatBytes(bytes) {
method constructor (line 9290) | constructor(config = {}) {
method defaultLogger (line 9320) | defaultLogger(level, message, data) {
method log (line 9343) | log(level, message, data) {
method addEvent (line 9356) | addEvent(event) {
method enable (line 9369) | enable() {
method disable (line 9376) | disable() {
method on (line 9382) | on(type, callback) {
method inspectTensor (line 9395) | inspectTensor(tensor2, name = "tensor") {
method startTrace (line 9420) | startTrace(modelId) {
method traceInput (line 9439) | traceInput(traceId, tensor2, name) {
method traceOutput (line 9448) | traceOutput(traceId, tensor2, name) {
method traceOperation (line 9457) | traceOperation(traceId, operation) {
method endTrace (line 9466) | endTrace(traceId) {
method recordAllocation (line 9493) | recordAllocation(tensor2) {
method recordDeallocation (line 9504) | recordDeallocation(tensor2) {
method getPerformanceMetrics (line 9514) | getPerformanceMetrics() {
method getEvents (line 9520) | getEvents() {
method getTraces (line 9526) | getTraces() {
method getTrace (line 9532) | getTrace(traceId) {
method clear (line 9538) | clear() {
method export (line 9556) | export() {
method generateReport (line 9567) | generateReport() {
function getDebugger (line 9600) | function getDebugger(config) {
function enableDebugging (line 9606) | function enableDebugging(config) {
function disableDebugging (line 9611) | function disableDebugging() {
function createAsciiHistogram (line 9614) | function createAsciiHistogram(histogram, width = 50, height = 10) {
function createTensorHeatmap (line 9634) | function createTensorHeatmap(tensor2, width = 40) {
function visualizeModelArchitecture (line 9671) | function visualizeModelArchitecture(layers) {
method constructor (line 9692) | constructor(config = {}) {
method start (line 9725) | start() {
method stop (line 9741) | stop() {
method monitorFPS (line 9755) | monitorFPS() {
method collectSample (line 9771) | collectSample() {
method collectMemoryMetrics (line 9816) | collectMemoryMetrics() {
method collectSystemMetrics (line 9838) | collectSystemMetrics() {
method estimateCPUUsage (line 9861) | estimateCPUUsage() {
method checkAlerts (line 9870) | checkAlerts(sample) {
method getMetricValue (line 9911) | getMetricValue(sample, metric) {
method recordInference (line 9926) | recordInference(duration) {
method updateQueueLength (line 9933) | updateQueueLength(length) {
method updateActiveCount (line 9939) | updateActiveCount(count) {
method updateTensorMemory (line 9945) | updateTensorMemory(bytes) {
method updateCacheMemory (line 9951) | updateCacheMemory(bytes) {
method addAlert (line 9957) | addAlert(config) {
method removeAlert (line 9963) | removeAlert(metric) {
method onAlert (line 9969) | onAlert(callback) {
method onSample (line 9980) | onSample(callback) {
method getCurrentSample (line 9991) | getCurrentSample() {
method getSamples (line 9997) | getSamples() {
method getSamplesInRange (line 10003) | getSamplesInRange(startTime, endTime) {
method getSummary (line 10009) | getSummary() {
method clear (line 10040) | clear() {
method export (line 10052) | export() {
function generateDashboardHTML (line 10061) | function generateDashboardHTML(monitor) {
function generateChartPath (line 10441) | function generateChartPath(samples) {
function generateAsciiDashboard (line 10467) | function generateAsciiDashboard(monitor) {
function getMonitor (line 10526) | function getMonitor(config) {
function startMonitoring (line 10532) | function startMonitoring(config) {
function stopMonitoring (line 10537) | function stopMonitoring() {
function quantize (line 10542) | async function quantize(model, options) {
function getModelData (line 10575) | async function getModelData(_model) {
function quantizeInt8 (line 10578) | function quantizeInt8(data, _options) {
function quantizeUint8 (line 10597) | function quantizeUint8(data, _options) {
function quantizeFloat16 (line 10618) | function quantizeFloat16(data, _options) {
function quantizeInt4 (line 10630) | function quantizeInt4(data, _options) {
function float32ToFloat162 (line 10651) | function float32ToFloat162(value) {
function prune (line 10676) | async function prune(model, options) {
function analyzeModel2 (line 10698) | async function analyzeModel2(model) {
function benchmark2 (line 10715) | async function benchmark2(runFn, options = {}) {
function exportModel2 (line 10742) | async function exportModel2(model, format) {
function isSupported (line 10756) | async function isSupported() {
function getBestRuntimeType (line 10760) | async function getBestRuntimeType() {
function preload (line 10770) | async function preload(models) {
function getInfo (line 10782) | async function getInfo() {
FILE: dist/index.js
function isSupported (line 114) | async function isSupported() {
function getBestRuntimeType (line 121) | async function getBestRuntimeType() {
function preload (line 134) | async function preload(models) {
constant VERSION (line 151) | const VERSION = '0.1.0';
function getInfo (line 155) | async function getInfo() {
FILE: dist/pipelines/automatic-speech-recognition.d.ts
type ASROptions (line 11) | interface ASROptions extends PipelineOptions {
type WordTimestamp (line 19) | interface WordTimestamp {
type ChunkTimestamp (line 25) | interface ChunkTimestamp {
type ASRResult (line 30) | interface ASRResult extends PipelineResult {
class AutomaticSpeechRecognitionPipeline (line 36) | class AutomaticSpeechRecognitionPipeline extends BasePipeline<AudioInput...
FILE: dist/pipelines/automatic-speech-recognition.js
constant DEFAULT_MODELS (line 15) | const DEFAULT_MODELS = {
constant SOT_TOKEN (line 21) | const SOT_TOKEN = 50258;
constant TRANSLATE_TOKEN (line 22) | const TRANSLATE_TOKEN = 50358;
constant TRANSCRIBE_TOKEN (line 23) | const TRANSCRIBE_TOKEN = 50359;
constant EOT_TOKEN (line 24) | const EOT_TOKEN = 50257;
constant NO_TIMESTAMPS_TOKEN (line 25) | const NO_TIMESTAMPS_TOKEN = 50363;
constant EN_TOKEN (line 26) | const EN_TOKEN = 50259;
constant MAX_DECODER_TOKENS (line 27) | const MAX_DECODER_TOKENS = 448;
class AutomaticSpeechRecognitionPipeline (line 31) | class AutomaticSpeechRecognitionPipeline extends BasePipeline {
method constructor (line 39) | constructor(config) {
method initialize (line 55) | async initialize() {
method setTokenizer (line 69) | setTokenizer(tokenizer) {
method run (line 72) | async run(input, options) {
method transcribeSingle (line 84) | async transcribeSingle(audio, options) {
method buildInitialTokens (line 107) | buildInitialTokens(task, language) {
method getLanguageToken (line 114) | getLanguageToken(language) {
method autoregressiveDecode (line 128) | async autoregressiveDecode(encoderHidden, initialTokens) {
method extractTimestamps (line 156) | extractTimestamps(_tokenIds, text) {
method processLongAudio (line 178) | async processLongAudio(audio, options = {}) {
method preprocess (line 209) | async preprocess(input) {
method postprocess (line 218) | async postprocess(outputs, options) {
method decodeOutput (line 233) | decodeOutput(data, shape) {
function createASRPipeline (line 265) | function createASRPipeline(config) {
FILE: dist/pipelines/base.d.ts
type PipelineResult (line 13) | interface PipelineResult {
type TextClassificationResult (line 20) | interface TextClassificationResult extends PipelineResult {
type FeatureExtractionResult (line 27) | interface FeatureExtractionResult extends PipelineResult {
type ImageClassificationResult (line 33) | interface ImageClassificationResult extends PipelineResult {
type ObjectDetectionResult (line 40) | interface ObjectDetectionResult extends PipelineResult {
type PipelineFactory (line 105) | type PipelineFactory = (config: PipelineConfig) => BasePipeline<any, any>;
FILE: dist/pipelines/base.js
class BasePipeline (line 15) | class BasePipeline {
method constructor (line 21) | constructor(config) {
method initialize (line 34) | async initialize() {
method loadModelWithCache (line 56) | async loadModelWithCache(modelPath) {
method run (line 83) | async run(input, options) {
method runBatch (line 100) | async runBatch(inputs, options) {
method task (line 109) | get task() {
method ready (line 115) | get ready() {
method dispose (line 121) | dispose() {
function registerPipeline (line 136) | function registerPipeline(task, factory) {
function getPipelineFactory (line 142) | function getPipelineFactory(task) {
constant SENTIMENT_LABELS (line 151) | const SENTIMENT_LABELS = ['negative', 'positive'];
constant EMOTION_LABELS (line 155) | const EMOTION_LABELS = [
constant IMAGENET_LABELS (line 161) | const IMAGENET_LABELS = [
FILE: dist/pipelines/feature-extraction.d.ts
type FeatureExtractionOptions (line 9) | interface FeatureExtractionOptions extends PipelineOptions {
class FeatureExtractionPipeline (line 14) | class FeatureExtractionPipeline extends BasePipeline<string | string[], ...
FILE: dist/pipelines/feature-extraction.js
constant DEFAULT_MODELS (line 14) | const DEFAULT_MODELS = {
constant DEFAULT_EMBEDDING_DIM (line 18) | const DEFAULT_EMBEDDING_DIM = 384;
class FeatureExtractionPipeline (line 19) | class FeatureExtractionPipeline extends BasePipeline {
method constructor (line 25) | constructor(config, embeddingDim = DEFAULT_EMBEDDING_DIM) {
method initialize (line 31) | async initialize() {
method run (line 41) | async run(input, options) {
method preprocess (line 59) | async preprocess(input) {
method runInference (line 71) | async runInference(inputs) {
method postprocess (line 79) | async postprocess(outputs, options) {
method extractCLSEmbedding (line 110) | extractCLSEmbedding(hiddenStates) {
method meanPooling (line 115) | meanPooling(hiddenStates) {
method maxPooling (line 127) | maxPooling(hiddenStates) {
method normalizeVector (line 142) | normalizeVector(vec) {
function createFeatureExtractionPipeline (line 156) | function createFeatureExtractionPipeline(config = {}) {
FILE: dist/pipelines/image-classification.d.ts
type ImageClassificationOptions (line 9) | interface ImageClassificationOptions extends PipelineOptions {
type ImageInput (line 14) | type ImageInput = HTMLImageElement | HTMLCanvasElement | ImageBitmap | I...
class ImageClassificationPipeline (line 15) | class ImageClassificationPipeline extends BasePipeline<ImageInput | Imag...
FILE: dist/pipelines/image-classification.js
constant DEFAULT_MODELS (line 14) | const DEFAULT_MODELS = {
class ImageClassificationPipeline (line 17) | class ImageClassificationPipeline extends BasePipeline {
method constructor (line 22) | constructor(config, labels, _numClasses = 1000) {
method initialize (line 27) | async initialize() {
method setLabels (line 37) | setLabels(labels) {
method run (line 40) | async run(input, options) {
method preprocess (line 58) | async preprocess(input) {
method runModelInference (line 66) | async runModelInference(inputs) {
method postprocess (line 70) | async postprocess(outputs, options) {
function createImageClassificationPipeline (line 92) | function createImageClassificationPipeline(config = {}, labels) {
FILE: dist/pipelines/image-segmentation.d.ts
type PointPrompt (line 13) | interface PointPrompt {
type BoxPrompt (line 24) | interface BoxPrompt {
type ModelLoadProgress (line 37) | interface ModelLoadProgress {
type ImageSegmentationOptions (line 50) | interface ImageSegmentationOptions extends PipelineOptions {
type ImageSegmentationResult (line 63) | interface ImageSegmentationResult extends PipelineResult {
type ImageInput (line 81) | type ImageInput = HTMLImageElement | HTMLCanvasElement | ImageBitmap | I...
class ImageSegmentationPipeline (line 103) | class ImageSegmentationPipeline extends BasePipeline<ImageInput, ImageSe...
FILE: dist/pipelines/image-segmentation.js
constant DEFAULT_SAM_MODELS (line 13) | const DEFAULT_SAM_MODELS = {
class ImageSegmentationPipeline (line 41) | class ImageSegmentationPipeline extends BasePipeline {
method constructor (line 53) | constructor(config) {
method isModelsLoaded (line 61) | get isModelsLoaded() {
method setModelUrls (line 67) | setModelUrls(encoder, decoder) {
method loadModels (line 74) | async loadModels(onProgress) {
method fetchModelWithProgress (line 108) | async fetchModelWithProgress(url, onProgress) {
method initialize (line 144) | async initialize() {
method loadEncoder (line 153) | async loadEncoder(modelUrl) {
method loadDecoder (line 161) | async loadDecoder(modelUrl) {
method setImage (line 169) | async setImage(image) {
method segment (line 201) | async segment(options = {}) {
method run (line 234) | async run(input, options) {
method loadImage (line 241) | async loadImage(input) {
method loadImageFromUrl (line 264) | async loadImageFromUrl(url) {
method imageElementToImageData (line 283) | imageElementToImageData(img) {
method canvasToImageData (line 294) | canvasToImageData(canvas) {
method imageBitmapToImageData (line 301) | imageBitmapToImageData(bitmap) {
method preprocessImage (line 312) | preprocessImage(imageData) {
method prepareDecoderInputs (line 364) | prepareDecoderInputs(points, boxes) {
method postprocessMasks (line 403) | postprocessMasks(masks, scores, threshold, returnAllMasks) {
method resizeMask (line 444) | resizeMask(masksData, maskIdx, srcW, srcH, dstW, dstH, threshold) {
method clearImage (line 478) | clearImage() {
method preprocess (line 487) | async preprocess(input) {
method postprocess (line 495) | async postprocess(_outputs, _options) {
method dispose (line 507) | dispose() {
function createImageSegmentationPipeline (line 524) | function createImageSegmentationPipeline(config = {}) {
FILE: dist/pipelines/index.d.ts
type PipelineFactoryOptions (line 18) | interface PipelineFactoryOptions {
type PipelineTaskMap (line 33) | type PipelineTaskMap = {
FILE: dist/pipelines/index.js
function pipeline (line 51) | async function pipeline(task, options) {
function createPipelines (line 112) | async function createPipelines(tasks, options) {
FILE: dist/pipelines/object-detection.d.ts
type ObjectDetectionOptions (line 10) | interface ObjectDetectionOptions extends PipelineOptions {
type BoundingBox (line 16) | interface BoundingBox {
type Detection (line 22) | interface Detection extends ObjectDetectionResult {
class ObjectDetectionPipeline (line 27) | class ObjectDetectionPipeline extends BasePipeline<ImageInput | ImageInp...
FILE: dist/pipelines/object-detection.js
constant DEFAULT_MODELS (line 14) | const DEFAULT_MODELS = {
constant COCO_LABELS (line 20) | const COCO_LABELS = [
class ObjectDetectionPipeline (line 37) | class ObjectDetectionPipeline extends BasePipeline {
method constructor (line 42) | constructor(config, labels) {
method initialize (line 57) | async initialize() {
method setLabels (line 64) | setLabels(labels) {
method run (line 67) | async run(input, options) {
method preprocess (line 73) | async preprocess(input) {
method runModelInference (line 81) | async runModelInference(inputs) {
method postprocess (line 85) | async postprocess(outputs, options) {
method parseDetections (line 102) | parseDetections(data, shape, threshold) {
method nonMaxSuppression (line 176) | nonMaxSuppression(detections, iouThreshold) {
method computeIoU (line 201) | computeIoU(a, b) {
function createObjectDetectionPipeline (line 214) | function createObjectDetectionPipeline(config, labels) {
FILE: dist/pipelines/question-answering.d.ts
type QAInput (line 10) | interface QAInput {
type QuestionAnsweringOptions (line 14) | interface QuestionAnsweringOptions extends PipelineOptions {
type QuestionAnsweringResult (line 21) | interface QuestionAnsweringResult extends PipelineResult {
class QuestionAnsweringPipeline (line 27) | class QuestionAnsweringPipeline extends BasePipeline<QAInput | QAInput[]...
FILE: dist/pipelines/question-answering.js
constant DEFAULT_MODELS (line 14) | const DEFAULT_MODELS = {
class QuestionAnsweringPipeline (line 21) | class QuestionAnsweringPipeline extends BasePipeline {
method constructor (line 26) | constructor(config) {
method initialize (line 34) | async initialize() {
method setTokenizer (line 44) | setTokenizer(tokenizer) {
method run (line 47) | async run(input, options) {
method answerQuestion (line 53) | async answerQuestion(input, options) {
method tokenOffsetToCharOffset (line 107) | tokenOffsetToCharOffset(context, _question, inputIds, tokenIdx) {
method preprocess (line 114) | async preprocess(input) {
method postprocess (line 129) | async postprocess(outputs, _options) {
function createQuestionAnsweringPipeline (line 162) | function createQuestionAnsweringPipeline(config) {
FILE: dist/pipelines/text-classification.d.ts
type TextClassificationOptions (line 10) | interface TextClassificationOptions extends PipelineOptions {
class TextClassificationPipeline (line 15) | class TextClassificationPipeline extends BasePipeline<string | string[],...
class SentimentAnalysisPipeline (line 29) | class SentimentAnalysisPipeline extends TextClassificationPipeline {
FILE: dist/pipelines/text-classification.js
constant DEFAULT_MODELS (line 15) | const DEFAULT_MODELS = {
constant DEFAULT_SST2_LABELS (line 19) | const DEFAULT_SST2_LABELS = ['NEGATIVE', 'POSITIVE'];
class TextClassificationPipeline (line 20) | class TextClassificationPipeline extends BasePipeline {
method constructor (line 26) | constructor(config, labels) {
method initialize (line 32) | async initialize() {
method setLabels (line 42) | setLabels(labels) {
method run (line 45) | async run(input, options) {
method preprocess (line 63) | async preprocess(input) {
method runInference (line 74) | async runInference(inputs) {
method postprocess (line 81) | async postprocess(outputs, options) {
class SentimentAnalysisPipeline (line 106) | class SentimentAnalysisPipeline extends TextClassificationPipeline {
method constructor (line 107) | constructor(config) {
method analyze (line 110) | async analyze(text, options) {
function createTextClassificationPipeline (line 117) | function createTextClassificationPipeline(config = {}) {
function createSentimentAnalysisPipeline (line 126) | function createSentimentAnalysisPipeline(config = {}) {
FILE: dist/pipelines/text-generation.d.ts
type LLMLoadProgress (line 15) | interface LLMLoadProgress {
type ChatMessage (line 28) | interface ChatMessage {
type ChatTemplateType (line 37) | type ChatTemplateType = 'chatml' | 'llama2' | 'llama3' | 'mistral' | 'ph...
type TextGenerationOptions (line 41) | interface TextGenerationOptions {
type ChatOptions (line 70) | interface ChatOptions extends TextGenerationOptions {
type TextGenerationResult (line 89) | interface TextGenerationResult extends PipelineResult {
type GenerationStreamEvent (line 102) | interface GenerationStreamEvent {
class TextGenerationPipeline (line 129) | class TextGenerationPipeline extends BasePipeline<string | string[], Tex...
FILE: dist/pipelines/text-generation.js
constant DEFAULT_LLM_MODELS (line 15) | const DEFAULT_LLM_MODELS = {
class TextGenerationPipeline (line 39) | class TextGenerationPipeline extends BasePipeline {
method constructor (line 47) | constructor(config) {
method isModelLoaded (line 58) | get isModelLoaded() {
method setModelUrls (line 64) | setModelUrls(model, tokenizer) {
method loadModel (line 71) | async loadModel(onProgress) {
method fetchModelWithProgress (line 109) | async fetchModelWithProgress(url, onProgress) {
method initialize (line 145) | async initialize() {
method setTokenizer (line 154) | setTokenizer(tokenizer) {
method preprocess (line 162) | async preprocess(input) {
method postprocess (line 178) | async postprocess(_outputs, _options) {
method run (line 190) | async run(prompt, options) {
method stream (line 199) | async *stream(prompt, options = {}) {
method generateSingle (line 265) | async generateSingle(prompt, options) {
method generateNextToken (line 323) | async generateNextToken(inputIds, temperature, topK, topP, repetitionP...
method greedy (line 393) | greedy(probs) {
method sample (line 407) | sample(probs, topK, topP) {
method setChatTemplate (line 453) | setChatTemplate(templateType) {
method applyChatTemplate (line 459) | applyChatTemplate(messages, options) {
method applyChatMLTemplate (line 485) | applyChatMLTemplate(messages) {
method applyLlama2Template (line 496) | applyLlama2Template(messages) {
method applyLlama3Template (line 521) | applyLlama3Template(messages) {
method applyMistralTemplate (line 532) | applyMistralTemplate(messages) {
method applyPhi3Template (line 550) | applyPhi3Template(messages) {
method applyAlpacaTemplate (line 561) | applyAlpacaTemplate(messages) {
method applyVicunaTemplate (line 585) | applyVicunaTemplate(messages) {
method applyCustomTemplate (line 604) | applyCustomTemplate(messages, template) {
method chat (line 646) | async chat(userMessage, options) {
method chatStream (line 686) | async *chatStream(userMessage, options) {
method getConversationHistory (line 726) | getConversationHistory() {
method setConversationHistory (line 732) | setConversationHistory(messages) {
method clearConversation (line 738) | clearConversation() {
method undoLastExchange (line 744) | undoLastExchange() {
function createTextGenerationPipeline (line 763) | function createTextGenerationPipeline(config) {
FILE: dist/pipelines/zero-shot-classification.d.ts
type ZeroShotClassificationOptions (line 11) | interface ZeroShotClassificationOptions extends PipelineOptions {
type ZeroShotClassificationResult (line 15) | interface ZeroShotClassificationResult extends PipelineResult {
type ZeroShotInput (line 20) | interface ZeroShotInput {
class ZeroShotClassificationPipeline (line 24) | class ZeroShotClassificationPipeline extends BasePipeline<ZeroShotInput,...
FILE: dist/pipelines/zero-shot-classification.js
constant DEFAULT_MODELS (line 15) | const DEFAULT_MODELS = {
constant ENTAILMENT_IDX (line 20) | const ENTAILMENT_IDX = 2;
class ZeroShotClassificationPipeline (line 24) | class ZeroShotClassificationPipeline extends BasePipeline {
method constructor (line 30) | constructor(config) {
method initialize (line 38) | async initialize() {
method setTokenizer (line 48) | setTokenizer(tokenizer) {
method classify (line 51) | async classify(text, candidateLabels, options) {
method run (line 54) | async run(input, options) {
method classifySingle (line 64) | async classifySingle(text, candidateLabels, template, multiLabel) {
method scoreHypothesis (line 96) | async scoreHypothesis(premise, hypothesis) {
method preprocess (line 114) | async preprocess(input) {
method postprocess (line 125) | async postprocess(_outputs, _options) {
function createZeroShotClassificationPipeline (line 136) | function createZeroShotClassificationPipeline(config) {
FILE: dist/tools/benchmark.d.ts
type BenchmarkOptions (line 6) | interface BenchmarkOptions {
type BenchmarkResult (line 18) | interface BenchmarkResult {
type CompareBenchmarkResult (line 43) | interface CompareBenchmarkResult {
type MemoryBenchmarkResult (line 70) | interface MemoryBenchmarkResult {
FILE: dist/tools/benchmark.js
function benchmark (line 12) | async function benchmark(fn, options = {}) {
function compareBenchmarks (line 89) | async function compareBenchmarks(baseline, comparison, options = {}) {
function benchmarkSuite (line 121) | async function benchmarkSuite(suite, options = {}) {
function formatBenchmarkResult (line 132) | function formatBenchmarkResult(result) {
function formatComparisonResult (line 152) | function formatComparisonResult(result) {
function benchmarkMemory (line 176) | async function benchmarkMemory(fn, options = {}) {
FILE: dist/tools/debugger.d.ts
type DebuggerConfig (line 10) | interface DebuggerConfig {
type TensorInspection (line 27) | interface TensorInspection {
type TensorStats (line 40) | interface TensorStats {
type HistogramData (line 53) | interface HistogramData {
type InferenceTrace (line 61) | interface InferenceTrace {
type OperationTrace (line 74) | interface OperationTrace {
type DebugEvent (line 85) | interface DebugEvent {
type PerformanceMetrics (line 94) | interface PerformanceMetrics {
class EdgeFlowDebugger (line 119) | class EdgeFlowDebugger {
FILE: dist/tools/debugger.js
function calculateTensorStats (line 12) | function calculateTensorStats(data) {
function createHistogram (line 61) | function createHistogram(data, bins = 50) {
function inspectTensor (line 98) | function inspectTensor(tensor, name = 'tensor', options = {}) {
function formatTensorInspection (line 130) | function formatTensorInspection(inspection) {
function formatBytes (line 159) | function formatBytes(bytes) {
class EdgeFlowDebugger (line 174) | class EdgeFlowDebugger {
method constructor (line 181) | constructor(config = {}) {
method defaultLogger (line 205) | defaultLogger(level, message, data) {
method log (line 228) | log(level, message, data) {
method addEvent (line 241) | addEvent(event) {
method enable (line 256) | enable() {
method disable (line 263) | disable() {
method on (line 269) | on(type, callback) {
method inspectTensor (line 282) | inspectTensor(tensor, name = 'tensor') {
method startTrace (line 308) | startTrace(modelId) {
method traceInput (line 327) | traceInput(traceId, tensor, name) {
method traceOutput (line 336) | traceOutput(traceId, tensor, name) {
method traceOperation (line 345) | traceOperation(traceId, operation) {
method endTrace (line 354) | endTrace(traceId) {
method recordAllocation (line 385) | recordAllocation(tensor) {
method recordDeallocation (line 396) | recordDeallocation(tensor) {
method getPerformanceMetrics (line 406) | getPerformanceMetrics() {
method getEvents (line 412) | getEvents() {
method getTraces (line 418) | getTraces() {
method getTrace (line 424) | getTrace(traceId) {
method clear (line 430) | clear() {
method export (line 448) | export() {
method generateReport (line 459) | generateReport() {
function getDebugger (line 498) | function getDebugger(config) {
function enableDebugging (line 507) | function enableDebugging(config) {
function disableDebugging (line 515) | function disableDebugging() {
function createAsciiHistogram (line 524) | function createAsciiHistogram(histogram, width = 50, height = 10) {
function createTensorHeatmap (line 551) | function createTensorHeatmap(tensor, width = 40) {
function visualizeModelArchitecture (line 592) | function visualizeModelArchitecture(layers) {
FILE: dist/tools/index.d.ts
type QuantizationOptions (line 10) | interface QuantizationOptions {
type QuantizationResult (line 23) | interface QuantizationResult {
type PruningOptions (line 53) | interface PruningOptions {
type PruningResult (line 64) | interface PruningResult {
type ModelAnalysis (line 81) | interface ModelAnalysis {
type BenchmarkOptions (line 110) | interface BenchmarkOptions {
type BenchmarkResult (line 121) | interface BenchmarkResult {
FILE: dist/tools/index.js
function quantize (line 17) | async function quantize(model, options) {
function getModelData (line 61) | async function getModelData(_model) {
function quantizeInt8 (line 68) | function quantizeInt8(data, _options) {
function quantizeUint8 (line 93) | function quantizeUint8(data, _options) {
function quantizeFloat16 (line 119) | function quantizeFloat16(data, _options) {
function quantizeInt4 (line 135) | function quantizeInt4(data, _options) {
function float32ToFloat16 (line 162) | function float32ToFloat16(value) {
function prune (line 193) | async function prune(model, options) {
function analyzeModel (line 222) | async function analyzeModel(model) {
function benchmark (line 243) | async function benchmark(runFn, options = {}) {
function exportModel (line 295) | async function exportModel(model, format) {
FILE: dist/tools/monitor.d.ts
type MonitorConfig (line 9) | interface MonitorConfig {
type PerformanceSample (line 26) | interface PerformanceSample {
type InferenceMetrics (line 36) | interface InferenceMetrics {
type MemoryMetrics (line 55) | interface MemoryMetrics {
type SystemMetrics (line 72) | interface SystemMetrics {
type AlertConfig (line 89) | interface AlertConfig {
type AlertEvent (line 104) | interface AlertEvent {
type WidgetData (line 112) | interface WidgetData {
class PerformanceMonitor (line 120) | class PerformanceMonitor {
FILE: dist/tools/monitor.js
class PerformanceMonitor (line 12) | class PerformanceMonitor {
method constructor (line 33) | constructor(config = {}) {
method start (line 46) | start() {
method stop (line 64) | stop() {
method monitorFPS (line 78) | monitorFPS() {
method collectSample (line 94) | collectSample() {
method collectMemoryMetrics (line 155) | collectMemoryMetrics() {
method collectSystemMetrics (line 177) | collectSystemMetrics() {
method estimateCPUUsage (line 204) | estimateCPUUsage() {
method checkAlerts (line 213) | checkAlerts(sample) {
method getMetricValue (line 254) | getMetricValue(sample, metric) {
method recordInference (line 270) | recordInference(duration) {
method updateQueueLength (line 277) | updateQueueLength(length) {
method updateActiveCount (line 283) | updateActiveCount(count) {
method updateTensorMemory (line 289) | updateTensorMemory(bytes) {
method updateCacheMemory (line 295) | updateCacheMemory(bytes) {
method addAlert (line 301) | addAlert(config) {
method removeAlert (line 307) | removeAlert(metric) {
method onAlert (line 313) | onAlert(callback) {
method onSample (line 324) | onSample(callback) {
method getCurrentSample (line 335) | getCurrentSample() {
method getSamples (line 341) | getSamples() {
method getSamplesInRange (line 347) | getSamplesInRange(startTime, endTime) {
method getSummary (line 353) | getSummary() {
method clear (line 384) | clear() {
method export (line 396) | export() {
function generateDashboardHTML (line 411) | function generateDashboardHTML(monitor) {
function generateChartPath (line 794) | function generateChartPath(samples) {
function generateAsciiDashboard (line 824) | function generateAsciiDashboard(monitor) {
function getMonitor (line 890) | function getMonitor(config) {
function startMonitoring (line 899) | function startMonitoring(config) {
function stopMonitoring (line 907) | function stopMonitoring() {
FILE: dist/tools/quantization.d.ts
type QuantizationType (line 11) | type QuantizationType = 'int8' | 'uint8' | 'int4' | 'float16' | 'dynamic';
type QuantizationOptions (line 15) | interface QuantizationOptions {
type QuantizationProgress (line 34) | interface QuantizationProgress {
type QuantizationResult (line 44) | interface QuantizationResult {
type LayerQuantizationStats (line 65) | interface LayerQuantizationStats {
type QuantizationStats (line 81) | interface QuantizationStats {
type PruningOptions (line 127) | interface PruningOptions {
type PruningResult (line 146) | interface PruningResult {
type ModelAnalysis (line 175) | interface ModelAnalysis {
type ExportFormat (line 207) | type ExportFormat = 'onnx' | 'tflite' | 'edgeflow';
type ExportOptions (line 211) | interface ExportOptions {
FILE: dist/tools/quantization.js
function calculateQuantParams (line 14) | function calculateQuantParams(data, bits, symmetric, perChannel, channel...
function quantizeToInt8 (line 80) | function quantizeToInt8(data, scale, zeroPoint, perChannel, channelSize ...
function quantizeToUint8 (line 107) | function quantizeToUint8(data, scale, zeroPoint, perChannel, channelSize...
function quantizeToInt4 (line 134) | function quantizeToInt4(data, scale, zeroPoint) {
function quantizeToFloat16 (line 151) | function quantizeToFloat16(data) {
function float32ToFloat16 (line 161) | function float32ToFloat16(value) {
function dequantizeInt8 (line 186) | function dequantizeInt8(data, scale, zeroPoint, perChannel = false, chan...
function dequantizeUint8 (line 211) | function dequantizeUint8(data, scale, zeroPoint, perChannel = false, cha...
function float16ToFloat32 (line 236) | function float16ToFloat32(value) {
function dequantizeFloat16 (line 258) | function dequantizeFloat16(data) {
function parseModelWeights (line 269) | function parseModelWeights(modelData) {
function serializeQuantizedModel (line 289) | function serializeQuantizedModel(model) {
function quantizeModel (line 419) | async function quantizeModel(modelData, options) {
function quantizeTensor (line 592) | function quantizeTensor(tensor, type, options = {}) {
function dequantizeTensor (line 632) | function dequantizeTensor(tensor, scale, zeroPoint, type) {
function pruneTensor (line 657) | function pruneTensor(tensor, options = {}) {
function pruneModel (line 703) | async function pruneModel(modelData, options = {}) {
function analyzeModel (line 730) | async function analyzeModel(modelData) {
function exportModel (line 791) | async function exportModel(modelData, options) {
FILE: dist/utils/cache.d.ts
type CacheStrategy (line 9) | type CacheStrategy = 'lru' | 'lfu' | 'fifo' | 'ttl';
type CacheOptions (line 13) | interface CacheOptions {
type CacheStats (line 30) | interface CacheStats {
class Cache (line 45) | class Cache<T> {
class InferenceCache (line 116) | class InferenceCache extends Cache<Float32Array> {
class ModelDownloadCache (line 129) | class ModelDownloadCache {
FILE: dist/utils/cache.js
class Cache (line 12) | class Cache {
method constructor (line 18) | constructor(options = {}) {
method get (line 35) | get(key) {
method set (line 56) | set(key, value, size, ttl) {
method has (line 88) | has(key) {
method delete (line 102) | delete(key) {
method clear (line 117) | clear() {
method getStats (line 129) | getStats() {
method evict (line 142) | evict() {
method findLRU (line 165) | findLRU() {
method findLFU (line 179) | findLFU() {
method findOldest (line 193) | findOldest() {
method findExpired (line 207) | findExpired() {
method loadFromStorage (line 219) | async loadFromStorage() {
method saveToStorage (line 246) | async saveToStorage() {
method clearStorage (line 271) | async clearStorage() {
method openDB (line 287) | openDB() {
class InferenceCache (line 307) | class InferenceCache extends Cache {
method generateKey (line 311) | generateKey(modelId, input) {
method hashArray (line 320) | hashArray(arr) {
class ModelDownloadCache (line 339) | class ModelDownloadCache {
method constructor (line 342) | constructor(cacheName = 'edgeflow-models') {
method ensureCache (line 348) | async ensureCache() {
method get (line 360) | async get(url) {
method put (line 372) | async put(url, response) {
method delete (line 384) | async delete(url) {
method clear (line 396) | async clear() {
method keys (line 408) | async keys() {
function createCache (line 425) | function createCache(preset = 'medium', options = {}) {
FILE: dist/utils/hub.d.ts
type HubOptions (line 11) | interface HubOptions {
type HubDownloadProgress (line 30) | interface HubDownloadProgress {
type ModelConfig (line 45) | interface ModelConfig {
type ModelBundle (line 61) | interface ModelBundle {
type PopularModelTask (line 148) | type PopularModelTask = keyof typeof POPULAR_MODELS;
FILE: dist/utils/hub.js
constant DEFAULT_ENDPOINT (line 12) | const DEFAULT_ENDPOINT = 'https://huggingface.co';
constant DEFAULT_REVISION (line 13) | const DEFAULT_REVISION = 'main';
constant ONNX_MODEL_FILES (line 17) | const ONNX_MODEL_FILES = [
function buildFileUrl (line 32) | function buildFileUrl(modelId, filename, options = {}) {
function fetchWithAuth (line 41) | async function fetchWithAuth(url, token) {
function fileExists (line 52) | async function fileExists(modelId, filename, options = {}) {
function findOnnxModel (line 66) | async function findOnnxModel(modelId, options = {}) {
function downloadFile (line 78) | async function downloadFile(modelId, filename, options = {}) {
function downloadJson (line 98) | async function downloadJson(modelId, filename, options = {}) {
function downloadTokenizer (line 119) | async function downloadTokenizer(modelId, options = {}) {
function downloadConfig (line 126) | async function downloadConfig(modelId, options = {}) {
function downloadModel (line 132) | async function downloadModel(modelId, options = {}) {
function fromHub (line 220) | async function fromHub(modelId, options = {}) {
function modelExists (line 226) | async function modelExists(modelId, options = {}) {
function getModelInfo (line 239) | async function getModelInfo(modelId, options = {}) {
constant POPULAR_MODELS (line 259) | const POPULAR_MODELS = {
function getDefaultModel (line 296) | function getDefaultModel(task) {
function fromTask (line 307) | async function fromTask(task, options = {}) {
FILE: dist/utils/model-loader.d.ts
type DownloadProgress (line 13) | interface DownloadProgress {
type ModelLoaderOptions (line 32) | interface ModelLoaderOptions {
type PreloadOptions (line 53) | interface PreloadOptions extends ModelLoaderOptions {
FILE: dist/utils/model-loader.js
constant DB_NAME (line 13) | const DB_NAME = 'edgeflow-model-cache';
constant DB_VERSION (line 14) | const DB_VERSION = 1;
constant STORE_META (line 15) | const STORE_META = 'meta';
constant STORE_CHUNKS (line 16) | const STORE_CHUNKS = 'chunks';
constant STORE_STATE (line 17) | const STORE_STATE = 'download-state';
class ModelCache (line 21) | class ModelCache {
method openDB (line 27) | async openDB() {
method getMeta (line 61) | async getMeta(url) {
method saveMeta (line 74) | async saveMeta(meta) {
method saveChunk (line 96) | async saveChunk(url, index, data) {
method putInStore (line 118) | async putInStore(storeName, value) {
method isQuotaError (line 131) | isQuotaError(err) {
method evictOldest (line 141) | async evictOldest(bytesNeeded) {
method getChunks (line 162) | async getChunks(url) {
method getModel (line 181) | async getModel(url) {
method saveDownloadState (line 201) | async saveDownloadState(state) {
method getDownloadState (line 217) | async getDownloadState(url) {
method deleteDownloadState (line 230) | async deleteDownloadState(url) {
method deleteModel (line 243) | async deleteModel(url) {
method clear (line 278) | async clear() {
method getStats (line 294) | async getStats() {
function supportsRangeRequests (line 319) | async function supportsRangeRequests(url) {
function downloadChunk (line 338) | async function downloadChunk(url, start, end, timeout) {
function downloadWithResume (line 358) | async function downloadWithResume(url, options) {
function downloadSimple (line 468) | async function downloadSimple(url, timeout, onProgress) {
class PreloadManager (line 520) | class PreloadManager {
method preload (line 528) | preload(url, options = {}) {
method processQueue (line 569) | async processQueue() {
method downloadTask (line 588) | async downloadTask(task) {
method isPreloaded (line 602) | isPreloaded(url) {
method getStatus (line 609) | getStatus(url) {
method get (line 616) | async get(url) {
method cancel (line 628) | cancel(url) {
method clear (line 639) | clear() {
function loadModelData (line 657) | async function loadModelData(url, options = {}) {
function preloadModel (line 712) | function preloadModel(url, options = {}) {
function preloadModels (line 718) | function preloadModels(urls, options = {}) {
function isModelCached (line 724) | async function isModelCached(url) {
function getCachedModel (line 731) | async function getCachedModel(url) {
function deleteCachedModel (line 737) | async function deleteCachedModel(url) {
function clearModelCache (line 743) | async function clearModelCache() {
function getModelCacheStats (line 749) | async function getModelCacheStats() {
function getPreloadStatus (line 755) | function getPreloadStatus(url) {
function cancelPreload (line 761) | function cancelPreload(url) {
function getPreloadedModel (line 767) | async function getPreloadedModel(url) {
FILE: dist/utils/offline.d.ts
type OfflineConfig (line 6) | interface OfflineConfig {
type OfflineStatus (line 20) | interface OfflineStatus {
type CachedModelInfo (line 32) | interface CachedModelInfo {
class OfflineManager (line 42) | class OfflineManager {
FILE: dist/utils/offline.js
class OfflineManager (line 12) | class OfflineManager {
method constructor (line 16) | constructor(config = {}) {
method initialize (line 29) | async initialize() {
method registerServiceWorker (line 55) | async registerServiceWorker() {
method preloadForOffline (line 81) | async preloadForOffline(modelUrls) {
method getStatus (line 97) | async getStatus() {
method getCachedModels (line 123) | async getCachedModels() {
method isModelAvailableOffline (line 146) | async isModelAvailableOffline(url) {
method removeFromOffline (line 153) | async removeFromOffline(url) {
method clearOfflineData (line 160) | async clearOfflineData() {
method getStorageInfo (line 167) | async getStorageInfo() {
method requestPersistentStorage (line 181) | async requestPersistentStorage() {
method onOnlineStatusChange (line 190) | onOnlineStatusChange(listener) {
method isOnline (line 197) | isOnline() {
method notifyOnlineStatus (line 203) | notifyOnlineStatus(online) {
method openDatabase (line 209) | async openDatabase() {
function generateServiceWorker (line 223) | function generateServiceWorker(options = {}) {
function generateManifest (line 354) | function generateManifest(options = { name: 'edgeFlow.js App' }) {
function getOfflineManager (line 377) | function getOfflineManager(config) {
function initOffline (line 386) | async function initOffline(config) {
function isOffline (line 394) | function isOffline() {
function isPWASupported (line 400) | function isPWASupported() {
FILE: dist/utils/preprocessor.d.ts
type ImageInput (line 11) | type ImageInput = HTMLImageElement | HTMLCanvasElement | ImageBitmap | I...
type AudioInput (line 15) | type AudioInput = AudioBuffer | Float32Array | ArrayBuffer | Blob | File...
type ImagePreprocessorOptions (line 19) | interface ImagePreprocessorOptions {
class ImagePreprocessor (line 61) | class ImagePreprocessor {
type AudioPreprocessorOptions (line 124) | interface AudioPreprocessorOptions {
class AudioPreprocessor (line 143) | class AudioPreprocessor {
type TextPreprocessorOptions (line 201) | interface TextPreprocessorOptions {
FILE: dist/utils/preprocessor.js
constant DEFAULT_IMAGE_OPTIONS (line 11) | const DEFAULT_IMAGE_OPTIONS = {
class ImagePreprocessor (line 32) | class ImagePreprocessor {
method constructor (line 36) | constructor(options = {}) {
method fromConfig (line 53) | static fromConfig(config) {
method fromUrl (line 114) | static async fromUrl(url) {
method fromHuggingFace (line 125) | static async fromHuggingFace(modelId, options) {
method ensureCanvas (line 133) | ensureCanvas() {
method process (line 147) | async process(input) {
method processBatch (line 179) | async processBatch(inputs) {
method loadFromUrl (line 202) | async loadFromUrl(url) {
method loadFromBlob (line 218) | async loadFromBlob(blob) {
method centerCrop (line 230) | centerCrop(imageData) {
method toImageData (line 260) | toImageData(source) {
method resize (line 271) | resize(imageData) {
method toTensor (line 311) | toTensor(imageData) {
method getOptions (line 373) | getOptions() {
constant DEFAULT_AUDIO_OPTIONS (line 380) | const DEFAULT_AUDIO_OPTIONS = {
class AudioPreprocessor (line 393) | class AudioPreprocessor {
method constructor (line 396) | constructor(options = {}) {
method fromConfig (line 402) | static fromConfig(config) {
method fromHuggingFace (line 425) | static async fromHuggingFace(modelId, options) {
method ensureAudioContext (line 438) | ensureAudioContext() {
method process (line 451) | async process(input) {
method processRaw (line 489) | async processRaw(input) {
method loadFromUrl (line 520) | async loadFromUrl(url) {
method loadFromBlob (line 531) | async loadFromBlob(blob) {
method decodeAudioData (line 538) | async decodeAudioData(data) {
method audioBufferToFloat32 (line 546) | audioBufferToFloat32(buffer) {
method normalizeAudio (line 554) | normalizeAudio(data) {
method computeMelSpectrogram (line 573) | computeMelSpectrogram(audio) {
method dispose (line 604) | dispose() {
function preprocessText (line 614) | function preprocessText(text, options = {}) {
function createImagePreprocessor (line 637) | function createImagePreprocessor(preset = 'imagenet', options = {}) {
function createAudioPreprocessor (line 664) | function createAudioPreprocessor(preset = 'whisper', options = {}) {
FILE: dist/utils/tokenizer.d.ts
type TokenizerModel (line 8) | type TokenizerModel = 'BPE' | 'WordPiece' | 'Unigram' | 'basic';
type TokenizerOptions (line 9) | interface TokenizerOptions {
type HFTokenizerJSON (line 21) | interface HFTokenizerJSON {
class Tokenizer (line 107) | class Tokenizer {
FILE: dist/utils/tokenizer.js
class Tokenizer (line 14) | class Tokenizer {
method constructor (line 40) | constructor() {
method initByteEncoder (line 46) | initByteEncoder() {
method fromJSON (line 74) | static async fromJSON(json) {
method fromUrl (line 156) | static async fromUrl(url) {
method fromHuggingFace (line 167) | static async fromHuggingFace(modelId, options) {
method normalize (line 175) | normalize(text) {
method preTokenize (line 190) | preTokenize(text) {
method textToBytes (line 199) | textToBytes(text) {
method bytesToText (line 207) | bytesToText(text) {
method getPairs (line 215) | getPairs(word) {
method bpe (line 225) | bpe(token) {
method wordPiece (line 280) | wordPiece(word) {
method tokenizeWord (line 314) | tokenizeWord(word) {
method unigramTokenize (line 337) | unigramTokenize(word) {
method tokenize (line 370) | tokenize(text) {
method convertTokensToIds (line 410) | convertTokensToIds(tokens) {
method convertIdsToTokens (line 427) | convertIdsToTokens(ids) {
method postProcess (line 433) | postProcess(ids, pairIds) {
method encode (line 484) | encode(text, options = {}) {
method encodeBatch (line 545) | encodeBatch(texts, options = {}) {
method decode (line 557) | decode(ids, skipSpecialTokens = true) {
method decodeBatch (line 580) | decodeBatch(batchIds, skipSpecialTokens = true) {
method vocabSize (line 586) | get vocabSize() {
method getSpecialTokenIds (line 592) | getSpecialTokenIds() {
method getConfig (line 606) | getConfig() {
method isSpecialToken (line 622) | isSpecialToken(token) {
method getTokenId (line 628) | getTokenId(token) {
method getToken (line 634) | getToken(id) {
function createBasicTokenizer (line 644) | function createBasicTokenizer() {
function loadTokenizer (line 651) | async function loadTokenizer(url) {
function loadTokenizerFromHub (line 657) | async function loadTokenizerFromHub(modelId, options) {
FILE: examples/basic-usage.ts
function textGenerationExample (line 21) | async function textGenerationExample() {
function schedulerExample (line 45) | async function schedulerExample() {
function memoryExample (line 76) | async function memoryExample() {
function main (line 96) | async function main() {
FILE: examples/orchestration.ts
function concurrentModelsExample (line 25) | async function concurrentModelsExample() {
function cachingExample (line 57) | async function cachingExample() {
function memoryScopeExample (line 89) | async function memoryScopeExample() {
function cancellationExample (line 117) | async function cancellationExample() {
function main (line 158) | async function main() {
FILE: scripts/build-browser.js
function build (line 12) | async function build() {
FILE: src/backends/index.ts
function registerAllBackends (line 41) | function registerAllBackends(): void {
FILE: src/backends/onnx.ts
function getOrt (line 28) | async function getOrt(): Promise<any> {
function isOnnxAvailable (line 46) | async function isOnnxAvailable(): Promise<boolean> {
type ONNXSessionData (line 54) | interface ONNXSessionData {
class ONNXRuntime (line 69) | class ONNXRuntime implements Runtime {
method capabilities (line 75) | get capabilities(): RuntimeCapabilities {
method isAvailable (line 89) | async isAvailable(): Promise<boolean> {
method initialize (line 96) | async initialize(): Promise<void> {
method loadModel (line 123) | async loadModel(
method run (line 208) | async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {
method runNamed (line 274) | async runNamed(model: LoadedModel, namedInputs: Map<string, Tensor>): ...
method unloadModel (line 336) | private async unloadModel(modelId: string): Promise<void> {
method dispose (line 347) | dispose(): void {
function createONNXRuntime (line 357) | function createONNXRuntime(): Runtime {
FILE: src/backends/transformers-adapter.ts
type TransformersPipelineInstance (line 51) | interface TransformersPipelineInstance {
type TransformersPipelineFactory (line 60) | type TransformersPipelineFactory = (
type TransformersAdapterOptions (line 69) | interface TransformersAdapterOptions {
class TransformersAdapterRuntime (line 96) | class TransformersAdapterRuntime implements Runtime {
method capabilities (line 99) | get capabilities(): RuntimeCapabilities {
method isAvailable (line 110) | async isAvailable(): Promise<boolean> {
method initialize (line 114) | async initialize(): Promise<void> {
method loadModel (line 124) | async loadModel(
method loadPipeline (line 161) | async loadPipeline(
method run (line 189) | async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {
method runDirect (line 214) | async runDirect(
method dispose (line 229) | dispose(): void {
function useTransformersBackend (line 260) | function useTransformersBackend(options: TransformersAdapterOptions): vo...
function getTransformersAdapter (line 269) | function getTransformersAdapter(): TransformersAdapterRuntime | null {
FILE: src/backends/wasm.ts
type WASMModule (line 33) | interface WASMModule {
type WASMExports (line 41) | interface WASMExports {
type WASMModelData (line 70) | interface WASMModelData {
type WASMModelConfig (line 82) | interface WASMModelConfig {
type WASMLayerConfig (line 93) | interface WASMLayerConfig {
class WASMRuntime (line 109) | class WASMRuntime implements Runtime {
method capabilities (line 117) | get capabilities(): RuntimeCapabilities {
method isAvailable (line 131) | async isAvailable(): Promise<boolean> {
method initialize (line 150) | async initialize(): Promise<void> {
method checkSIMDSupport (line 176) | private async checkSIMDSupport(): Promise<boolean> {
method createJSFallback (line 195) | private createJSFallback(memory: WebAssembly.Memory): WASMExports {
method loadModel (line 303) | async loadModel(
method run (line 360) | async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {
method executeModel (line 370) | private async executeModel(inputs: Tensor[], metadata: ModelMetadata):...
method parseModelConfig (line 413) | private parseModelConfig(data: ArrayBuffer): WASMModelConfig {
method loadWeights (line 448) | private async loadWeights(
method unloadModel (line 459) | private unloadModel(modelId: string): void {
method ensureInitialized (line 473) | private ensureInitialized(): void {
method hasSIMDSupport (line 485) | hasSIMDSupport(): boolean {
method dispose (line 492) | dispose(): void {
function createWASMRuntime (line 506) | function createWASMRuntime(): Runtime {
FILE: src/backends/webgpu.ts
type Navigator (line 34) | interface Navigator {
type GPU (line 38) | interface GPU {
type GPURequestAdapterOptions (line 42) | interface GPURequestAdapterOptions {
type GPUAdapter (line 46) | interface GPUAdapter {
type GPUDeviceDescriptor (line 50) | interface GPUDeviceDescriptor {
type GPUDevice (line 55) | interface GPUDevice {
type GPULimits (line 66) | interface GPULimits {
type GPUDeviceLostInfo (line 70) | interface GPUDeviceLostInfo {
type GPUBuffer (line 75) | interface GPUBuffer {
type GPUShaderModule (line 79) | interface GPUShaderModule {}
type GPUBindGroupLayout (line 80) | interface GPUBindGroupLayout {}
type GPUPipelineLayout (line 81) | interface GPUPipelineLayout {}
type GPUComputePipeline (line 82) | interface GPUComputePipeline {}
type GPUBufferDescriptor (line 84) | interface GPUBufferDescriptor {
type GPUShaderModuleDescriptor (line 89) | interface GPUShaderModuleDescriptor {
type GPUBindGroupLayoutDescriptor (line 93) | interface GPUBindGroupLayoutDescriptor {
type GPUBindGroupLayoutEntry (line 97) | interface GPUBindGroupLayoutEntry {
type GPUPipelineLayoutDescriptor (line 103) | interface GPUPipelineLayoutDescriptor {
type GPUComputePipelineDescriptor (line 107) | interface GPUComputePipelineDescriptor {
type WebGPUModelData (line 135) | interface WebGPUModelData {
type ModelConfig (line 151) | interface ModelConfig {
type LayerConfig (line 162) | interface LayerConfig {
class WebGPURuntime (line 177) | class WebGPURuntime implements Runtime {
method capabilities (line 185) | get capabilities(): RuntimeCapabilities {
method isAvailable (line 199) | async isAvailable(): Promise<boolean> {
method initialize (line 214) | async initialize(): Promise<void> {
method loadModel (line 255) | async loadModel(
method run (line 318) | async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {
method executeModel (line 329) | private async executeModel(inputs: Tensor[], metadata: ModelMetadata):...
method parseModelData (line 378) | private parseModelData(data: ArrayBuffer): ModelConfig {
method uploadWeights (line 410) | private async uploadWeights(
method createPipelines (line 431) | private async createPipelines(modelData: WebGPUModelData): Promise<voi...
method unloadModel (line 492) | private unloadModel(modelId: string): void {
method ensureInitialized (line 506) | private ensureInitialized(): void {
method dispose (line 518) | dispose(): void {
function createWebGPURuntime (line 538) | function createWebGPURuntime(): Runtime {
FILE: src/backends/webnn.ts
type MLContextType (line 34) | type MLContextType = 'default' | 'gpu' | 'cpu' | 'npu';
type MLOperandDescriptor (line 39) | interface MLOperandDescriptor {
type MLContextOptions (line 47) | interface MLContextOptions {
type Navigator (line 54) | interface Navigator {
type MLContext (line 60) | interface MLContext {
type MLGraph (line 68) | interface MLGraph {
type MLGraphBuilder (line 72) | interface MLGraphBuilder {
type MLOperand (line 91) | interface MLOperand {
type WebNNModelData (line 103) | interface WebNNModelData {
type WebNNModelConfig (line 119) | interface WebNNModelConfig {
class WebNNRuntime (line 133) | class WebNNRuntime implements Runtime {
method capabilities (line 141) | get capabilities(): RuntimeCapabilities {
method isAvailable (line 155) | async isAvailable(): Promise<boolean> {
method initialize (line 170) | async initialize(): Promise<void> {
method loadModel (line 205) | async loadModel(
method run (line 254) | async run(model: LoadedModel, inputs: Tensor[]): Promise<Tensor[]> {
method executeModel (line 264) | private async executeModel(inputs: Tensor[], metadata: ModelMetadata):...
method parseModelConfig (line 289) | private parseModelConfig(data: ArrayBuffer): WebNNModelConfig {
method unloadModel (line 316) | private unloadModel(modelId: string): void {
method ensureInitialized (line 323) | private ensureInitialized(): void {
method getDeviceType (line 335) | getDeviceType(): MLContextType {
method dispose (line 342) | dispose(): void {
function createWebNNRuntime (line 352) | function createWebNNRuntime(): Runtime {
FILE: src/core/composer.ts
type CompositionStage (line 32) | interface CompositionStage {
type CompositionResult (line 53) | interface CompositionResult {
type ComposedPipeline (line 67) | interface ComposedPipeline {
function compose (line 105) | function compose(stages: CompositionStage[]): ComposedPipeline {
function parallel (line 194) | function parallel(
FILE: src/core/device-profiler.ts
type DeviceTier (line 28) | type DeviceTier = 'high' | 'medium' | 'low';
type DeviceProfile (line 33) | interface DeviceProfile {
type ModelRecommendation (line 57) | interface ModelRecommendation {
function getDeviceProfile (line 77) | async function getDeviceProfile(): Promise<DeviceProfile> {
function recommendQuantization (line 163) | function recommendQuantization(profile: DeviceProfile): QuantizationType {
function recommendModelVariant (line 172) | async function recommendModelVariant(): Promise<ModelRecommendation> {
function resetDeviceProfile (line 186) | function resetDeviceProfile(): void {
FILE: src/core/memory.ts
type TrackedResource (line 29) | interface TrackedResource {
constant DEFAULT_POOL_CONFIG (line 40) | const DEFAULT_POOL_CONFIG: Required<MemoryPoolConfig> = {
class MemoryManager (line 61) | class MemoryManager {
method constructor (line 74) | private constructor(config: MemoryPoolConfig = {}) {
method getInstance (line 81) | static getInstance(): MemoryManager {
method configure (line 91) | static configure(config: MemoryPoolConfig): void {
method track (line 101) | track(tensor: Tensor, disposer?: () => void): void {
method trackModel (line 127) | trackModel(model: LoadedModel, disposer?: () => void): void {
method untrack (line 153) | untrack(id: string): void {
method release (line 165) | release(resourceOrId: Tensor | LoadedModel | string): void {
method estimateTensorSize (line 183) | private estimateTensorSize(tensor: Tensor): number {
method getBytesPerElement (line 191) | private getBytesPerElement(dtype: string): number {
method captureStackTrace (line 213) | private captureStackTrace(): string | undefined {
method checkMemoryThreshold (line 225) | private checkMemoryThreshold(): void {
method gc (line 253) | gc(evict = false, maxAge = 5 * 60 * 1000): void {
method measureBrowserMemory (line 282) | async measureBrowserMemory(): Promise<{
method getDeviceMemory (line 305) | getDeviceMemory(): number | null {
method getStats (line 319) | getStats(): MemoryStats {
method getResourceDetails (line 343) | getResourceDetails(): TrackedResource[] {
method detectLeaks (line 350) | detectLeaks(maxAge: number = 10 * 60 * 1000): TrackedResource[] {
method on (line 366) | on<T = unknown>(event: EventType, listener: EventListener<T>): void {
method off (line 378) | off<T = unknown>(event: EventType, listener: EventListener<T>): void {
method emit (line 388) | private emit<T>(type: EventType, data: T): void {
method resetStats (line 410) | resetStats(): void {
method disposeAll (line 417) | disposeAll(): void {
method dispose (line 426) | dispose(): void {
class MemoryScope (line 452) | class MemoryScope {
method constructor (line 457) | constructor(parent?: MemoryScope) {
method track (line 467) | track<T extends { dispose: () => void }>(resource: T): T {
method createChild (line 475) | createChild(): MemoryScope {
method keep (line 482) | keep<T extends { dispose: () => void }>(resource: T): T {
method dispose (line 493) | dispose(): void {
function withMemoryScope (line 524) | async function withMemoryScope<T>(
function withMemoryScopeSync (line 538) | function withMemoryScopeSync<T>(
class ModelCache (line 556) | class ModelCache {
method constructor (line 562) | constructor(options: { maxSize?: number; maxModels?: number } = {}) {
method get (line 570) | get(key: string): LoadedModel | undefined {
method set (line 582) | set(key: string, model: LoadedModel): void {
method delete (line 605) | delete(key: string): boolean {
method has (line 619) | has(key: string): boolean {
method evictLRU (line 626) | private evictLRU(): void {
method clear (line 645) | clear(): void {
method getStats (line 656) | getStats(): { size: number; count: number; maxSize: number; maxModels:...
function getMemoryManager (line 673) | function getMemoryManager(): MemoryManager {
function getMemoryStats (line 680) | function getMemoryStats(): MemoryStats {
function release (line 687) | function release(resource: Tensor | LoadedModel): void {
function gc (line 694) | function gc(): void {
FILE: src/core/plugin.ts
type PluginPipelineEntry (line 34) | interface PluginPipelineEntry {
type PluginBackendEntry (line 45) | interface PluginBackendEntry {
type PluginMiddleware (line 55) | interface PluginMiddleware {
type EdgeFlowPlugin (line 69) | interface EdgeFlowPlugin {
function registerPlugin (line 95) | async function registerPlugin(plugin: EdgeFlowPlugin): Promise<void> {
function getPluginPipeline (line 132) | function getPluginPipeline(task: string): PluginPipelineEntry | undefined {
function getPluginMiddleware (line 139) | function getPluginMiddleware(): ReadonlyArray<PluginMiddleware> {
function listPlugins (line 146) | function listPlugins(): Array<{ name: string; version: string }> {
function unregisterPlugin (line 156) | function unregisterPlugin(name: string): boolean {
FILE: src/core/runtime.ts
constant RUNTIME_PRIORITY (line 42) | const RUNTIME_PRIORITY: RuntimeType[] = ['webgpu', 'webnn', 'wasm'];
class RuntimeManager (line 57) | class RuntimeManager {
method constructor (line 63) | private constructor() {}
method getInstance (line 68) | static getInstance(): RuntimeManager {
method register (line 78) | register(type: RuntimeType, factory: () => Runtime): void {
method getRuntime (line 85) | async getRuntime(type: RuntimeType = 'auto'): Promise<Runtime> {
method getBestRuntime (line 138) | async getBestRuntime(): Promise<Runtime> {
method detectAvailableRuntimes (line 176) | async detectAvailableRuntimes(): Promise<Map<RuntimeType, boolean>> {
method getCapabilities (line 200) | async getCapabilities(type: RuntimeType): Promise<RuntimeCapabilities> {
method setDefaultRuntime (line 208) | setDefaultRuntime(type: RuntimeType): void {
method getDefaultRuntimeType (line 215) | getDefaultRuntimeType(): RuntimeType {
method disposeRuntime (line 222) | disposeRuntime(type: RuntimeType): void {
method disposeAll (line 233) | disposeAll(): void {
method on (line 243) | on<T = unknown>(event: EventType, listener: EventListener<T>): void {
method off (line 255) | off<T = unknown>(event: EventType, listener: EventListener<T>): void {
method emit (line 265) | private emit<T>(type: EventType, data: T): void {
function generateModelId (line 297) | function generateModelId(): string {
class LoadedModelImpl (line 304) | class LoadedModelImpl implements LoadedModel {
method constructor (line 312) | constructor(
method isLoaded (line 323) | get isLoaded(): boolean {
method dispose (line 327) | dispose(): void {
function loadModel (line 344) | async function loadModel(
function loadModelFromBuffer (line 380) | async function loadModelFromBuffer(
function runInference (line 396) | async function runInference(
function runInferenceNamed (line 421) | async function runInferenceNamed(
function runBatchInference (line 457) | async function runBatchInference(
function getRuntimeManager (line 481) | function getRuntimeManager(): RuntimeManager {
function registerRuntime (line 488) | function registerRuntime(type: RuntimeType, factory: () => Runtime): void {
function getBestRuntime (line 495) | async function getBestRuntime(): Promise<Runtime> {
function getAvailableRuntimes (line 502) | async function getAvailableRuntimes(): Promise<Map<RuntimeType, boolean>> {
FILE: src/core/scheduler.ts
class Task (line 27) | class Task<T = unknown> implements InferenceTask<T> {
method constructor (line 45) | constructor(
method status (line 58) | get status(): TaskStatus {
method startedAt (line 62) | get startedAt(): number | undefined {
method completedAt (line 66) | get completedAt(): number | undefined {
method result (line 70) | get result(): T | undefined {
method error (line 74) | get error(): Error | undefined {
method cancel (line 81) | cancel(): void {
method wait (line 103) | wait(): Promise<T> {
method execute (line 128) | async execute(): Promise<void> {
constant PRIORITY_ORDER (line 165) | const PRIORITY_ORDER: Record<TaskPriority, number> = {
class PriorityQueue (line 175) | class PriorityQueue<T extends Task> {
method length (line 178) | get length(): number {
method isEmpty (line 182) | isEmpty(): boolean {
method enqueue (line 189) | enqueue(item: T): void {
method dequeue (line 209) | dequeue(): T | undefined {
method peek (line 216) | peek(): T | undefined {
method remove (line 223) | remove(id: string): T | undefined {
method getAll (line 235) | getAll(): T[] {
method clear (line 242) | clear(): void {
class BatchCollector (line 254) | class BatchCollector<T> {
method constructor (line 261) | constructor(
method add (line 271) | add(task: Task<T>): void {
method flush (line 281) | flush(): void {
method clear (line 294) | clear(): void {
function generateTaskId (line 313) | function generateTaskId(): string {
type CircuitState (line 320) | interface CircuitState {
constant DEFAULT_OPTIONS (line 329) | const DEFAULT_OPTIONS: Required<SchedulerOptions> = {
class InferenceScheduler (line 353) | class InferenceScheduler {
method constructor (line 365) | constructor(options: SchedulerOptions = {}) {
method getCircuit (line 372) | private getCircuit(modelId: string): CircuitState {
method isCircuitOpen (line 384) | private isCircuitOpen(modelId: string): boolean {
method circuitSuccess (line 401) | private circuitSuccess(modelId: string): void {
method circuitFailure (line 411) | private circuitFailure(modelId: string): void {
method getQueue (line 428) | private getQueue(modelId: string): PriorityQueue<Task> {
method getRunningSet (line 440) | private getRunningSet(modelId: string): Set<string> {
method canStartTask (line 452) | private canStartTask(modelId: string): boolean {
method processQueue (line 468) | private async processQueue(): Promise<void> {
method schedule (line 542) | schedule<T>(
method scheduleWithTimeout (line 616) | scheduleWithTimeout<T>(
method scheduleAll (line 650) | async scheduleAll<T>(
method getTask (line 667) | getTask(taskId: string): InferenceTask | undefined {
method cancelTask (line 674) | cancelTask(taskId: string): boolean {
method cancelAllForModel (line 692) | cancelAllForModel(modelId: string): number {
method getStats (line 711) | getStats(): {
method on (line 760) | on<T = unknown>(event: EventType, listener: EventListener<T>): void {
method off (line 772) | off<T = unknown>(event: EventType, listener: EventListener<T>): void {
method emit (line 782) | private emit<T>(type: EventType, data: T): void {
method clearHistory (line 804) | clearHistory(): void {
method dispose (line 819) | dispose(): void {
function getScheduler (line 852) | function getScheduler(): InferenceScheduler {
function setScheduler (line 862) | function setScheduler(scheduler: InferenceScheduler): void {
function configureScheduler (line 872) | function configureScheduler(options: SchedulerOptions): void {
FILE: src/core/tensor.ts
function generateTensorId (line 22) | function generateTensorId(): string {
function getTypedArrayConstructor (line 29) | function getTypedArrayConstructor(dtype: DataType): new (length: number)...
function calculateSize (line 57) | function calculateSize(shape: Shape): number {
function validateShape (line 65) | function validateShape(shape: Shape): void {
class EdgeFlowTensor (line 81) | class EdgeFlowTensor implements Tensor {
method constructor (line 89) | constructor(
method data (line 132) | get data(): TypedArray {
method isDisposed (line 137) | get isDisposed(): boolean {
method checkDisposed (line 144) | private checkDisposed(): void {
method toFloat32Array (line 157) | toFloat32Array(): Float32Array {
method toArray (line 174) | toArray(): number[] {
method clone (line 191) | clone(): EdgeFlowTensor {
method dispose (line 202) | dispose(): void {
method get (line 213) | get(...indices: number[]): number {
method set (line 249) | set(value: number, ...indices: number[]): void {
method reshape (line 285) | reshape(newShape: Shape): EdgeFlowTensor {
method transpose (line 305) | transpose(): EdgeFlowTensor {
method toString (line 331) | toString(): string {
function tensor (line 343) | function tensor(
function zeros (line 375) | function zeros(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {
function ones (line 385) | function ones(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {
function full (line 396) | function full(
function random (line 411) | function random(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTens...
function randn (line 423) | function randn(shape: Shape, dtype: DataType = 'float32'): EdgeFlowTensor {
function arange (line 446) | function arange(
function linspace (line 470) | function linspace(
function eye (line 489) | function eye(n: number, dtype: DataType = 'float32'): EdgeFlowTensor {
function add (line 506) | function add(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTen...
function sub (line 538) | function sub(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTen...
function mul (line 570) | function mul(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTen...
function div (line 602) | function div(a: EdgeFlowTensor, b: EdgeFlowTensor | number): EdgeFlowTen...
function matmul (line 634) | function matmul(a: EdgeFlowTensor, b: EdgeFlowTensor): EdgeFlowTensor {
function softmax (line 674) | function softmax(t: EdgeFlowTensor, axis: number = -1): EdgeFlowTensor {
function relu (line 743) | function relu(t: EdgeFlowTensor): EdgeFlowTensor {
function sigmoid (line 757) | function sigmoid(t: EdgeFlowTensor): EdgeFlowTensor {
function tanh (line 771) | function tanh(t: EdgeFlowTensor): EdgeFlowTensor {
function sum (line 785) | function sum(t: EdgeFlowTensor, axis?: number): EdgeFlowTensor | number {
function mean (line 852) | function mean(t: EdgeFlowTensor, axis?: number): EdgeFlowTensor | number {
function argmax (line 869) | function argmax(t: EdgeFlowTensor, axis?: number): number | EdgeFlowTens...
function concat (line 919) | function concat(tensors: EdgeFlowTensor[], axis: number = 0): EdgeFlowTe...
FILE: src/core/types.ts
type DataType (line 14) | type DataType =
type TypedArray (line 26) | type TypedArray =
type Shape (line 37) | type Shape = readonly number[];
type Tensor (line 42) | interface Tensor {
type RuntimeType (line 72) | type RuntimeType = 'webgpu' | 'webnn' | 'wasm' | 'auto';
type RuntimeCapabilities (line 77) | interface RuntimeCapabilities {
type Runtime (line 95) | interface Runtime {
type ModelFormat (line 121) | type ModelFormat = 'onnx' | 'edgeflow' | 'safetensors';
type QuantizationType (line 126) | type QuantizationType = 'float32' | 'float16' | 'int8' | 'uint8' | 'int4';
type ModelMetadata (line 131) | interface ModelMetadata {
type ModelIOSpec (line 159) | interface ModelIOSpec {
type ModelLoadOptions (line 173) | interface ModelLoadOptions {
type LoadedModel (line 187) | interface LoadedModel {
type TaskPriority (line 207) | type TaskPriority = 'low' | 'normal' | 'high' | 'critical';
type TaskStatus (line 212) | type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'canc...
type InferenceTask (line 217) | interface InferenceTask<T = unknown> {
type SchedulerOptions (line 245) | interface SchedulerOptions {
type MemoryStats (line 277) | interface MemoryStats {
type MemoryPoolConfig (line 293) | interface MemoryPoolConfig {
type PipelineTask (line 313) | type PipelineTask =
type PipelineConfig (line 337) | interface PipelineConfig {
type PipelineOptions (line 357) | interface PipelineOptions {
type TokenizerConfig (line 377) | interface TokenizerConfig {
type TokenizedOutput (line 401) | interface TokenizedOutput {
class EdgeFlowError (line 421) | class EdgeFlowError extends Error {
method constructor (line 422) | constructor(
type ErrorCode (line 471) | type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];
type EventType (line 480) | type EventType =
type EdgeFlowEvent (line 495) | interface EdgeFlowEvent<T = unknown> {
type EventListener (line 504) | type EventListener<T = unknown> = (event: EdgeFlowEvent<T>) => void;
FILE: src/core/worker.ts
type WorkerMessageType (line 16) | type WorkerMessageType =
type WorkerMessage (line 29) | interface WorkerMessage {
type LoadModelRequest (line 38) | interface LoadModelRequest {
type InferenceRequest (line 49) | interface InferenceRequest {
type SerializedTensor (line 57) | interface SerializedTensor {
type WorkerPoolOptions (line 66) | interface WorkerPoolOptions {
function serializeTensor (line 80) | function serializeTensor(tensor: Tensor): SerializedTensor {
function deserializeTensor (line 96) | async function deserializeTensor(serialized: SerializedTensor): Promise<...
function deserializeTensorSync (line 106) | function deserializeTensorSync(
type WorkerHealthState (line 118) | type WorkerHealthState = 'alive' | 'dead' | 'restarting';
constant MAX_RESTART_ATTEMPTS (line 120) | const MAX_RESTART_ATTEMPTS = 3;
constant RESTART_BASE_DELAY_MS (line 121) | const RESTART_BASE_DELAY_MS = 1000;
class InferenceWorker (line 126) | class InferenceWorker {
method constructor (line 139) | constructor(workerUrl?: string) {
method health (line 148) | get health(): WorkerHealthState {
method initWorker (line 155) | private initWorker(workerUrl?: string): void {
method handleCrash (line 177) | private handleCrash(): void {
method attemptRestart (line 193) | private attemptRestart(): void {
method restart (line 211) | restart(): void {
method createWorkerBlob (line 235) | private createWorkerBlob(): string {
method handleMessage (line 344) | private handleMessage(message: WorkerMessage): void {
method sendRequest (line 367) | private async sendRequest<T>(type: WorkerMessageType, payload?: unknow...
method init (line 397) | async init(): Promise<void> {
method loadModel (line 406) | async loadModel(url: string, options?: { runtime?: RuntimeType; cache?...
method runInference (line 415) | async runInference(modelId: string, inputs: Tensor[]): Promise<Tensor[...
method dispose (line 427) | async dispose(modelId: string): Promise<void> {
method terminate (line 434) | terminate(): void {
class WorkerPool (line 451) | class WorkerPool {
method constructor (line 457) | constructor(options: WorkerPoolOptions = {}) {
method getNextHealthyWorker (line 470) | private getNextHealthyWorker(): InferenceWorker {
method getWorkerForModel (line 486) | private getWorkerForModel(modelId: string): InferenceWorker {
method replaceWorker (line 502) | replaceWorker(index: number): void {
method init (line 512) | async init(): Promise<void> {
method loadModel (line 519) | async loadModel(
method runInference (line 532) | async runInference(modelId: string, inputs: Tensor[]): Promise<Tensor[...
method runBatch (line 540) | async runBatch(
method dispose (line 556) | async dispose(modelId: string): Promise<void> {
method terminate (line 565) | terminate(): void {
method size (line 576) | get size(): number {
function getWorkerPool (line 590) | function getWorkerPool(options?: WorkerPoolOptions): WorkerPool {
function runInWorker (line 600) | async function runInWorker(
function isWorkerSupported (line 617) | function isWorkerSupported(): boolean {
FILE: src/index.ts
function isSupported (line 446) | async function isSupported(): Promise<boolean> {
function getBestRuntimeType (line 454) | async function getBestRuntimeType(): Promise<RuntimeType | null> {
function preload (line 467) | async function preload(
constant VERSION (line 489) | const VERSION = '0.1.0';
function getInfo (line 494) | async function getInfo(): Promise<{
FILE: src/pipelines/automatic-speech-recognition.ts
constant DEFAULT_MODELS (line 19) | const DEFAULT_MODELS = {
constant SOT_TOKEN (line 26) | const SOT_TOKEN = 50258;
constant TRANSLATE_TOKEN (line 27) | const TRANSLATE_TOKEN = 50358;
constant TRANSCRIBE_TOKEN (line 28) | const TRANSCRIBE_TOKEN = 50359;
constant EOT_TOKEN (line 29) | const EOT_TOKEN = 50257;
constant NO_TIMESTAMPS_TOKEN (line 30) | const NO_TIMESTAMPS_TOKEN = 50363;
constant EN_TOKEN (line 31) | const EN_TOKEN = 50259;
constant MAX_DECODER_TOKENS (line 33) | const MAX_DECODER_TOKENS = 448;
type ASROptions (line 39) | interface ASROptions extends PipelineOptions {
type WordTimestamp (line 48) | interface WordTimestamp {
type ChunkTimestamp (line 55) | interface ChunkTimestamp {
type ASRResult (line 61) | interface ASRResult extends PipelineResult {
class AutomaticSpeechRecognitionPipeline (line 72) | class AutomaticSpeechRecognitionPipeline extends BasePipeline<AudioInput...
method constructor (line 81) | constructor(config?: PipelineConfig) {
method initialize (line 100) | override async initialize(): Promise<void> {
method setTokenizer (line 118) | setTokenizer(tokenizer: Tokenizer): void {
method run (line 122) | override async run(
method transcribeSingle (line 141) | private async transcribeSingle(audio: AudioInput, options: ASROptions)...
method buildInitialTokens (line 180) | private buildInitialTokens(task: 'transcribe' | 'translate', language?...
method getLanguageToken (line 188) | private getLanguageToken(language: string): number {
method autoregressiveDecode (line 203) | private async autoregressiveDecode(
method extractTimestamps (line 246) | private extractTimestamps(
method processLongAudio (line 276) | async processLongAudio(
method preprocess (line 323) | protected async preprocess(input: AudioInput | AudioInput[]): Promise<...
method postprocess (line 342) | protected async postprocess(
method decodeOutput (line 367) | private decodeOutput(data: Float32Array, shape: readonly number[]): st...
function createASRPipeline (line 405) | function createASRPipeline(config?: PipelineConfig): AutomaticSpeechReco...
FILE: src/pipelines/base.ts
type PipelineResult (line 25) | interface PipelineResult {
type TextClassificationResult (line 33) | interface TextClassificationResult extends PipelineResult {
type FeatureExtractionResult (line 41) | interface FeatureExtractionResult extends PipelineResult {
type ImageClassificationResult (line 48) | interface ImageClassificationResult extends PipelineResult {
type ObjectDetectionResult (line 56) | interface ObjectDetectionResult extends PipelineResult {
method constructor (line 76) | constructor(config: PipelineConfig) {
method initialize (line 90) | async initialize(): Promise<void> {
method loadModelWithCache (line 115) | protected async loadModelWithCache(modelPath: string): Promise<LoadedMod...
method run (line 144) | async run(input: TInput, options?: PipelineOptions): Promise<TOutput> {
method runBatch (line 168) | async runBatch(inputs: TInput[], options?: PipelineOptions): Promise<TOu...
method task (line 195) | get task(): PipelineTask {
method ready (line 202) | get ready(): boolean {
method dispose (line 209) | dispose(): void {
type PipelineFactory (line 226) | type PipelineFactory = (config: PipelineConfig) => BasePipeline<any, any>;
function registerPipeline (line 236) | function registerPipeline(task: PipelineTask, factory: PipelineFactory):...
function getPipelineFactory (line 243) | function getPipelineFactory(task: PipelineTask): PipelineFactory | undef...
constant SENTIMENT_LABELS (line 254) | const SENTIMENT_LABELS = ['negative', 'positive'];
constant EMOTION_LABELS (line 259) | const EMOTION_LABELS = [
constant IMAGENET_LABELS (line 266) | const IMAGENET_LABELS = [
FILE: src/pipelines/feature-extraction.ts
constant DEFAULT_MODELS (line 26) | const DEFAULT_MODELS = {
constant DEFAULT_EMBEDDING_DIM (line 31) | const DEFAULT_EMBEDDING_DIM = 384;
type FeatureExtractionOptions (line 37) | interface FeatureExtractionOptions extends PipelineOptions {
class FeatureExtractionPipeline (line 43) | class FeatureExtractionPipeline extends BasePipeline<
method constructor (line 53) | constructor(config: PipelineConfig, embeddingDim: number = DEFAULT_EMB...
method initialize (line 60) | override async initialize(): Promise<void> {
method run (line 73) | override async run(
method preprocess (line 100) | protected override async preprocess(input: string | string[]): Promise...
method runInference (line 130) | private async runInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlow...
method postprocess (line 140) | protected override async postprocess(
method extractCLSEmbedding (line 181) | private extractCLSEmbedding(hiddenStates: EdgeFlowTensor): number[] {
method meanPooling (line 187) | private meanPooling(hiddenStates: EdgeFlowTensor): number[] {
method maxPooling (line 201) | private maxPooling(hiddenStates: EdgeFlowTensor): number[] {
method normalizeVector (line 218) | private normalizeVector(vec: number[]): number[] {
function createFeatureExtractionPipeline (line 233) | function createFeatureExtractionPipeline(
FILE: src/pipelines/image-classification.ts
constant DEFAULT_MODELS (line 27) | const DEFAULT_MODELS = {
type ImageClassificationOptions (line 36) | interface ImageClassificationOptions extends PipelineOptions {
type ImageInput (line 42) | type ImageInput =
class ImageClassificationPipeline (line 49) | class ImageClassificationPipeline extends BasePipeline<
method constructor (line 58) | constructor(
method initialize (line 68) | override async initialize(): Promise<void> {
method setLabels (line 81) | setLabels(labels: string[]): void {
method run (line 85) | override async run(
method preprocess (line 112) | protected override async preprocess(input: ImageInput | ImageInput[]):...
method runModelInference (line 122) | private async runModelInference(inputs: EdgeFlowTensor[]): Promise<Edg...
method postprocess (line 127) | protected override async postprocess(
function createImageClassificationPipeline (line 159) | function createImageClassificationPipeline(
FILE: src/pipelines/image-segmentation.ts
constant DEFAULT_SAM_MODELS (line 21) | const DEFAULT_SAM_MODELS = {
type PointPrompt (line 33) | interface PointPrompt {
type BoxPrompt (line 45) | interface BoxPrompt {
type ModelLoadProgress (line 59) | interface ModelLoadProgress {
type ImageSegmentationOptions (line 73) | interface ImageSegmentationOptions extends PipelineOptions {
type ImageSegmentationResult (line 87) | interface ImageSegmentationResult extends PipelineResult {
type ImageInput (line 103) | type ImageInput =
class ImageSegmentationPipeline (line 135) | class ImageSegmentationPipeline extends BasePipeline<
method constructor (line 152) | constructor(config: PipelineConfig) {
method isModelsLoaded (line 161) | get isModelsLoaded(): boolean {
method setModelUrls (line 168) | setModelUrls(encoder: string, decoder: string): void {
method loadModels (line 176) | async loadModels(
method fetchModelWithProgress (line 225) | private async fetchModelWithProgress(
method initialize (line 273) | override async initialize(): Promise<void> {
method loadEncoder (line 282) | async loadEncoder(modelUrl: string): Promise<void> {
method loadDecoder (line 291) | async loadDecoder(modelUrl: string): Promise<void> {
method setImage (line 300) | async setImage(image: ImageInput): Promise<void> {
method segment (line 335) | async segment(options: ImageSegmentationOptions = {}): Promise<ImageSe...
method run (line 377) | override async run(
method loadImage (line 388) | private async loadImage(input: ImageInput): Promise<ImageData> {
method loadImageFromUrl (line 408) | private async loadImageFromUrl(url: string): Promise<ImageData> {
method imageElementToImageData (line 428) | private imageElementToImageData(img: HTMLImageElement): ImageData {
method canvasToImageData (line 440) | private canvasToImageData(canvas: HTMLCanvasElement): ImageData {
method imageBitmapToImageData (line 448) | private imageBitmapToImageData(bitmap: ImageBitmap): ImageData {
method preprocessImage (line 460) | private preprocessImage(imageData: ImageData): {
method prepareDecoderInputs (line 524) | private prepareDecoderInputs(
method postprocessMasks (line 589) | private postprocessMasks(
method resizeMask (line 659) | private resizeMask(
method clearImage (line 710) | clearImage(): void {
method preprocess (line 720) | protected override async preprocess(input: ImageInput): Promise<EdgeFl...
method postprocess (line 729) | protected override async postprocess(
method dispose (line 745) | override dispose(): void {
function createImageSegmentationPipeline (line 764) | function createImageSegmentationPipeline(
FILE: src/pipelines/index.ts
type PipelineFactoryOptions (line 122) | interface PipelineFactoryOptions {
type PipelineTaskMap (line 138) | type PipelineTaskMap = {
function pipeline (line 177) | async function pipeline<T extends keyof PipelineTaskMap>(
function createPipelines (line 251) | async function createPipelines<T extends (keyof PipelineTaskMap)[]>(
FILE: src/pipelines/object-detection.ts
type ObjectDetectionOptions (line 18) | interface ObjectDetectionOptions extends PipelineOptions {
type BoundingBox (line 25) | interface BoundingBox {
type Detection (line 32) | interface Detection extends ObjectDetectionResult {
constant DEFAULT_MODELS (line 41) | const DEFAULT_MODELS = {
constant COCO_LABELS (line 49) | const COCO_LABELS = [
class ObjectDetectionPipeline (line 68) | class ObjectDetectionPipeline extends BasePipeline<ImageInput | ImageInp...
method constructor (line 74) | constructor(config?: PipelineConfig, labels?: string[]) {
method initialize (line 91) | override async initialize(): Promise<void> {
method setLabels (line 100) | setLabels(labels: string[]): void {
method run (line 104) | override async run(
method preprocess (line 114) | protected async preprocess(input: ImageInput | ImageInput[]): Promise<...
method runModelInference (line 129) | private async runModelInference(inputs: EdgeFlowTensor[]): Promise<Edg...
method postprocess (line 134) | protected async postprocess(
method parseDetections (line 161) | private parseDetections(
method nonMaxSuppression (line 248) | private nonMaxSuppression(
method computeIoU (line 280) | private computeIoU(a: BoundingBox, b: BoundingBox): number {
function createObjectDetectionPipeline (line 301) | function createObjectDetectionPipeline(
FILE: src/pipelines/question-answering.ts
constant DEFAULT_MODELS (line 18) | const DEFAULT_MODELS = {
type QAInput (line 27) | interface QAInput {
type QuestionAnsweringOptions (line 32) | interface QuestionAnsweringOptions extends PipelineOptions {
type QuestionAnsweringResult (line 40) | interface QuestionAnsweringResult extends PipelineResult {
class QuestionAnsweringPipeline (line 51) | class QuestionAnsweringPipeline extends BasePipeline<
method constructor (line 60) | constructor(config?: PipelineConfig) {
method initialize (line 69) | override async initialize(): Promise<void> {
method setTokenizer (line 82) | setTokenizer(tokenizer: Tokenizer): void {
method run (line 86) | override async run(
method answerQuestion (line 100) | private async answerQuestion(
method tokenOffsetToCharOffset (line 184) | private tokenOffsetToCharOffset(
method preprocess (line 197) | protected async preprocess(input: QAInput | QAInput[]): Promise<EdgeFl...
method postprocess (line 222) | protected async postprocess(
function createQuestionAnsweringPipeline (line 265) | function createQuestionAnsweringPipeline(
FILE: src/pipelines/text-classification.ts
constant DEFAULT_MODELS (line 28) | const DEFAULT_MODELS = {
constant DEFAULT_SST2_LABELS (line 33) | const DEFAULT_SST2_LABELS = ['NEGATIVE', 'POSITIVE'];
type TextClassificationOptions (line 39) | interface TextClassificationOptions extends PipelineOptions {
class TextClassificationPipeline (line 45) | class TextClassificationPipeline extends BasePipeline<
method constructor (line 55) | constructor(config: PipelineConfig, labels?: string[]) {
method initialize (line 62) | override async initialize(): Promise<void> {
method setLabels (line 75) | setLabels(labels: string[]): void {
method run (line 79) | override async run(
method preprocess (line 106) | protected override async preprocess(input: string | string[]): Promise...
method runInference (line 130) | private async runInference(inputs: EdgeFlowTensor[]): Promise<EdgeFlow...
method postprocess (line 139) | protected override async postprocess(
class SentimentAnalysisPipeline (line 174) | class SentimentAnalysisPipeline extends TextClassificationPipeline {
method constructor (line 175) | constructor(config: PipelineConfig) {
method analyze (line 179) | async analyze(
function createTextClassificationPipeline (line 191) | function createTextClassificationPipeline(
function createSentimentAnalysisPipeline (line 203) | function createSentimentAnalysisPipeline(
FILE: src/pipelines/text-generation.ts
constant DEFAULT_LLM_MODELS (line 19) | const DEFAULT_LLM_MODELS = {
type LLMLoadProgress (line 31) | interface LLMLoadProgress {
type ChatMessage (line 45) | interface ChatMessage {
type ChatTemplateType (line 55) | type ChatTemplateType = 'chatml' | 'llama2' | 'llama3' | 'mistral' | 'ph...
type TextGenerationOptions (line 60) | interface TextGenerationOptions {
type ChatOptions (line 90) | interface ChatOptions extends TextGenerationOptions {
type TextGenerationResult (line 110) | interface TextGenerationResult extends PipelineResult {
type GenerationStreamEvent (line 124) | interface GenerationStreamEvent {
class TextGenerationPipeline (line 156) | class TextGenerationPipeline extends BasePipeline<string | string[], Tex...
method constructor (line 166) | constructor(config?: PipelineConfig) {
method isModelLoaded (line 178) | get isModelLoaded(): boolean {
method setModelUrls (line 185) | setModelUrls(model: string, tokenizer: string): void {
method loadModel (line 193) | async loadModel(
method fetchModelWithProgress (line 243) | private async fetchModelWithProgress(
method initialize (line 291) | override async initialize(): Promise<void> {
method setTokenizer (line 300) | setTokenizer(tokenizer: Tokenizer): void {
method preprocess (line 309) | protected async preprocess(input: string | string[]): Promise<EdgeFlow...
method postprocess (line 330) | protected async postprocess(
method run (line 346) | override async run(
method stream (line 362) | async *stream(
method generateSingle (line 459) | private async generateSingle(
method generateNextToken (line 547) | private async generateNextToken(
method greedy (line 660) | private greedy(probs: Float32Array): number {
method sample (line 677) | private sample(probs: Float32Array, topK: number, topP: number): number {
method setChatTemplate (line 733) | setChatTemplate(templateType: ChatTemplateType): void {
method applyChatTemplate (line 740) | applyChatTemplate(messages: ChatMessage[], options?: ChatOptions): str...
method applyChatMLTemplate (line 768) | private applyChatMLTemplate(messages: ChatMessage[]): string {
method applyLlama2Template (line 780) | private applyLlama2Template(messages: ChatMessage[]): string {
method applyLlama3Template (line 805) | private applyLlama3Template(messages: ChatMessage[]): string {
method applyMistralTemplate (line 819) | private applyMistralTemplate(messages: ChatMessage[]): string {
method applyPhi3Template (line 838) | private applyPhi3Template(messages: ChatMessage[]): string {
method applyAlpacaTemplate (line 852) | private applyAlpacaTemplate(messages: ChatMessage[]): string {
method applyVicunaTemplate (line 879) | private applyVicunaTemplate(messages: ChatMessage[]): string {
method applyCustomTemplate (line 899) | private applyCustomTemplate(
method chat (line 956) | async chat(
method chatStream (line 1005) | async *chatStream(
method getConversationHistory (line 1053) | getConversationHistory(): ChatMessage[] {
method setConversationHistory (line 1060) | setConversationHistory(messages: ChatMessage[]): void {
method clearConversation (line 1067) | clearConversation(): void {
method undoLastExchange (line 1074) | undoLastExchange(): void {
function createTextGenerationPipeline (line 1096) | function createTextGenerationPipeline(config?: PipelineConfig): TextGene...
FILE: src/pipelines/zero-shot-classification.ts
constant DEFAULT_MODELS (line 19) | const DEFAULT_MODELS = {
constant ENTAILMENT_IDX (line 25) | const ENTAILMENT_IDX = 2;
type ZeroShotClassificationOptions (line 31) | interface ZeroShotClassificationOptions extends PipelineOptions {
type ZeroShotClassificationResult (line 36) | interface ZeroShotClassificationResult extends PipelineResult {
type ZeroShotInput (line 42) | interface ZeroShotInput {
class ZeroShotClassificationPipeline (line 51) | class ZeroShotClassificationPipeline extends BasePipeline<
method constructor (line 61) | constructor(config?: PipelineConfig) {
method initialize (line 70) | override async initialize(): Promise<void> {
method setTokenizer (line 83) | setTokenizer(tokenizer: Tokenizer): void {
method classify (line 87) | async classify(
method run (line 95) | override async run(
method classifySingle (line 114) | private async classifySingle(
method scoreHypothesis (line 160) | private async scoreHypothesis(premise: string, hypothesis: string): Pr...
method preprocess (line 191) | protected async preprocess(
method postprocess (line 211) | protected async postprocess(
function createZeroShotClassificationPipeline (line 227) | function createZeroShotClassificationPipeline(
FILE: src/tools/benchmark.ts
type BenchmarkOptions (line 11) | interface BenchmarkOptions {
type BenchmarkResult (line 28) | interface BenchmarkResult {
type CompareBenchmarkResult (line 65) | interface CompareBenchmarkResult {
function benchmark (line 80) | async function benchmark(
function compareBenchmarks (line 174) | async function compareBenchmarks(
function benchmarkSuite (line 213) | async function benchmarkSuite(
function formatBenchmarkResult (line 230) | function formatBenchmarkResult(result: BenchmarkResult): string {
function formatComparisonResult (line 251) | function formatComparisonResult(result: CompareBenchmarkResult): string {
type MemoryBenchmarkResult (line 278) | interface MemoryBenchmarkResult {
function benchmarkMemory (line 288) | async function benchmarkMemory(
FILE: src/tools/debugger.ts
type DebuggerConfig (line 16) | interface DebuggerConfig {
type TensorInspection (line 39) | interface TensorInspection {
type TensorStats (line 53) | interface TensorStats {
type HistogramData (line 67) | interface HistogramData {
type InferenceTrace (line 76) | interface InferenceTrace {
type OperationTrace (line 90) | interface OperationTrace {
type DebugEvent (line 102) | interface DebugEvent {
type PerformanceMetrics (line 112) | interface PerformanceMetrics {
function calculateTensorStats (line 131) | function calculateTensorStats(data: Float32Array | number[]): TensorStats {
function createHistogram (line 189) | function createHistogram(data: Float32Array | number[], bins: number = 5...
function inspectTensor (line 234) | function inspectTensor(
function formatTensorInspection (line 275) | function formatTensorInspection(inspection: TensorInspection): string {
function formatBytes (line 309) | function formatBytes(bytes: number): string {
class EdgeFlowDebugger (line 323) | class EdgeFlowDebugger {
method constructor (line 331) | constructor(config: DebuggerConfig = {}) {
method defaultLogger (line 357) | private defaultLogger(level: string, message: string, data?: unknown):...
method log (line 382) | log(level: string, message: string, data?: unknown): void {
method addEvent (line 397) | private addEvent(event: DebugEvent): void {
method enable (line 415) | enable(): void {
method disable (line 423) | disable(): void {
method on (line 430) | on(type: string, callback: (event: DebugEvent) => void): () => void {
method inspectTensor (line 444) | inspectTensor(tensor: EdgeFlowTensor, name: string = 'tensor'): Tensor...
method startTrace (line 475) | startTrace(modelId: string): string {
method traceInput (line 499) | traceInput(traceId: string, tensor: EdgeFlowTensor, name: string): void {
method traceOutput (line 509) | traceOutput(traceId: string, tensor: EdgeFlowTensor, name: string): vo...
method traceOperation (line 519) | traceOperation(traceId: string, operation: OperationTrace): void {
method endTrace (line 529) | endTrace(traceId: string): InferenceTrace | undefined {
method recordAllocation (line 565) | recordAllocation(tensor: EdgeFlowTensor): void {
method recordDeallocation (line 580) | recordDeallocation(tensor: EdgeFlowTensor): void {
method getPerformanceMetrics (line 591) | getPerformanceMetrics(): PerformanceMetrics {
method getEvents (line 598) | getEvents(): DebugEvent[] {
method getTraces (line 605) | getTraces(): InferenceTrace[] {
method getTrace (line 612) | getTrace(traceId: string): InferenceTrace | undefined {
method clear (line 619) | clear(): void {
method export (line 638) | export(): {
method generateReport (line 655) | generateReport(): string {
function getDebugger (line 702) | function getDebugger(config?: DebuggerConfig): EdgeFlowDebugger {
function enableDebugging (line 712) | function enableDebugging(config?: DebuggerConfig): EdgeFlowDebugger {
function disableDebugging (line 721) | function disableDebugging(): void {
function createAsciiHistogram (line 732) | function createAsciiHistogram(histogram: HistogramData, width: number = ...
function createTensorHeatmap (line 768) | function createTensorHeatmap(tensor: EdgeFlowTensor, width: number = 40)...
function visualizeModelArchitecture (line 818) | function visualizeModelArchitecture(
FILE: src/tools/index.ts
type QuantizationOptions (line 19) | interface QuantizationOptions {
type QuantizationResult (line 33) | interface QuantizationResult {
function quantize (line 60) | async function quantize(
function getModelData (line 112) | async function getModelData(_model: LoadedModel): Promise<ArrayBuffer> {
function quantizeInt8 (line 120) | function quantizeInt8(
function quantizeUint8 (line 151) | function quantizeUint8(
function quantizeFloat16 (line 182) | function quantizeFloat16(
function quantizeInt4 (line 204) | function quantizeInt4(
function float32ToFloat16 (line 237) | function float32ToFloat16(value: number): number {
type PruningOptions (line 279) | interface PruningOptions {
type PruningResult (line 291) | interface PruningResult {
function prune (line 305) | async function prune(
type ModelAnalysis (line 346) | interface ModelAnalysis {
function analyzeModel (line 372) | async function analyzeModel(
type BenchmarkOptions (line 402) | interface BenchmarkOptions {
type BenchmarkResult (line 414) | interface BenchmarkResult {
function benchmark (line 432) | async function benchmark(
function exportModel (line 584) | async function exportModel(
FILE: src/tools/monitor.ts
type MonitorConfig (line 14) | interface MonitorConfig {
type PerformanceSample (line 37) | interface PerformanceSample {
type InferenceMetrics (line 48) | interface InferenceMetrics {
type MemoryMetrics (line 74) | interface MemoryMetrics {
type SystemMetrics (line 97) | interface SystemMetrics {
type AlertConfig (line 120) | interface AlertConfig {
type AlertEvent (line 140) | interface AlertEvent {
type WidgetData (line 149) | interface WidgetData {
class PerformanceMonitor (line 162) | class PerformanceMonitor {
method constructor (line 187) | constructor(config: MonitorConfig = {}) {
method start (line 201) | start(): void {
method stop (line 222) | stop(): void {
method monitorFPS (line 239) | private monitorFPS(): void {
method collectSample (line 258) | private collectSample(): void {
method collectMemoryMetrics (line 329) | private collectMemoryMetrics(): MemoryMetrics {
method collectSystemMetrics (line 354) | private collectSystemMetrics(): SystemMetrics {
method estimateCPUUsage (line 385) | private estimateCPUUsage(): number {
method checkAlerts (line 395) | private checkAlerts(sample: PerformanceSample): void {
method getMetricValue (line 427) | private getMetricValue(sample: PerformanceSample, metric: string): num...
method recordInference (line 445) | recordInference(duration: number): void {
method updateQueueLength (line 453) | updateQueueLength(length: number): void {
method updateActiveCount (line 460) | updateActiveCount(count: number): void {
method updateTensorMemory (line 467) | updateTensorMemory(bytes: number): void {
method updateCacheMemory (line 474) | updateCacheMemory(bytes: number): void {
method addAlert (line 481) | addAlert(config: AlertConfig): void {
method removeAlert (line 488) | removeAlert(metric: string): void {
method onAlert (line 495) | onAlert(callback: (alert: AlertEvent) => void): () => void {
method onSample (line 506) | onSample(callback: (sample: PerformanceSample) => void): () => void {
method getCurrentSample (line 517) | getCurrentSample(): PerformanceSample | undefined {
method getSamples (line 524) | getSamples(): PerformanceSample[] {
method getSamplesInRange (line 531) | getSamplesInRange(startTime: number, endTime: number): PerformanceSamp...
method getSummary (line 538) | getSummary(): {
method clear (line 580) | clear(): void {
method export (line 593) | export(): {
function generateDashboardHTML (line 622) | function generateDashboardHTML(monitor: PerformanceMonitor): string {
function generateChartPath (line 1004) | function generateChartPath(samples: PerformanceSample[]): string {
function generateAsciiDashboard (line 1040) | function generateAsciiDashboard(monitor: PerformanceMonitor): string {
function getMonitor (line 1113) | function getMonitor(config?: MonitorConfig): PerformanceMonitor {
function startMonitoring (line 1123) | function startMonitoring(config?: MonitorConfig): PerformanceMonitor {
function stopMonitoring (line 1132) | function stopMonitoring(): void {
FILE: src/tools/quantization.ts
type QuantizationType (line 17) | type QuantizationType = 'int8' | 'uint8' | 'int4' | 'float16' | 'dynamic';
type QuantizationOptions (line 22) | interface QuantizationOptions {
type QuantizationProgress (line 48) | interface QuantizationProgress {
type QuantizationResult (line 59) | interface QuantizationResult {
type LayerQuantizationStats (line 88) | interface LayerQuantizationStats {
type QuantizationStats (line 105) | interface QuantizationStats {
type QuantizationParams (line 117) | interface QuantizationParams {
function calculateQuantParams (line 131) | function calculateQuantParams(
function quantizeToInt8 (line 213) | function quantizeToInt8(
function quantizeToUint8 (line 248) | function quantizeToUint8(
function quantizeToInt4 (line 283) | function quantizeToInt4(
function quantizeToFloat16 (line 309) | function quantizeToFloat16(data: Float32Array): Uint16Array {
function float32ToFloat16 (line 322) | function float32ToFloat16(value: number): number {
function dequantizeInt8 (line 351) | function dequantizeInt8(
function dequantizeUint8 (line 384) | function dequantizeUint8(
function float16ToFloat32 (line 417) | function float16ToFloat32(value: number): number {
function dequantizeFloat16 (line 441) | function dequantizeFloat16(data: Uint16Array): Float32Array {
type ModelWeights (line 456) | interface ModelWeights {
type QuantizedModel (line 466) | interface QuantizedModel {
function parseModelWeights (line 485) | function parseModelWeights(modelData: ArrayBuffer): ModelWeights[] {
function serializeQuantizedModel (line 509) | function serializeQuantizedModel(model: QuantizedModel): ArrayBuffer {
function quantizeModel (line 623) | async function quantizeModel(
function quantizeTensor (line 865) | function quantizeTensor(
function dequantizeTensor (line 944) | function dequantizeTensor(
type PruningOptions (line 1001) | interface PruningOptions {
type PruningResult (line 1021) | interface PruningResult {
function pruneTensor (line 1044) | function pruneTensor(
function pruneModel (line 1099) | async function pruneModel(
type ModelAnalysis (line 1145) | interface ModelAnalysis {
function analyzeModel (line 1174) | async function analyzeModel(modelData: ArrayBuffer): Promise<ModelAnalys...
type ExportFormat (line 1247) | type ExportFormat = 'onnx' | 'tflite' | 'edgeflow';
type ExportOptions (line 1252) | interface ExportOptions {
function exportModel (line 1262) | async function exportModel(
FILE: src/utils/cache.ts
type CacheStrategy (line 14) | type CacheStrategy = 'lru' | 'lfu' | 'fifo' | 'ttl';
type CacheEntry (line 19) | interface CacheEntry<T> {
type CacheOptions (line 31) | interface CacheOptions {
type CacheStats (line 49) | interface CacheStats {
class Cache (line 69) | class Cache<T> {
method constructor (line 76) | constructor(options: CacheOptions = {}) {
method get (line 95) | get(key: string): T | undefined {
method set (line 121) | set(key: string, value: T, size: number, ttl?: number): void {
method has (line 161) | has(key: string): boolean {
method delete (line 177) | delete(key: string): boolean {
method clear (line 195) | clear(): void {
method getStats (line 209) | getStats(): CacheStats {
method evict (line 223) | private evict(): void {
method findLRU (line 249) | private findLRU(): string | null {
method findLFU (line 266) | private findLFU(): string | null {
method findOldest (line 283) | private findOldest(): string | null {
method findExpired (line 300) | private findExpired(): string | null {
method loadFromStorage (line 315) | private async loadFromStorage(): Promise<void> {
method saveToStorage (line 343) | private async saveToStorage(): Promise<void> {
method clearStorage (line 371) | private async clearStorage(): Promise<void> {
method openDB (line 387) | private openDB(): Promise<IDBDatabase> {
class InferenceCache (line 411) | class InferenceCache extends Cache<Float32Array> {
method generateKey (line 415) | generateKey(modelId: string, input: Float32Array | number[]): string {
method hashArray (line 425) | private hashArray(arr: number[]): string {
class ModelDownloadCache (line 448) | class ModelDownloadCache {
method constructor (line 452) | constructor(cacheName: string = 'edgeflow-models') {
method ensureCache (line 459) | private async ensureCache(): Promise<globalThis.Cache> {
method get (line 472) | async get(url: string): Promise<Response | undefined> {
method put (line 484) | async put(url: string, response: Response): Promise<void> {
method delete (line 496) | async delete(url: string): Promise<boolean> {
method clear (line 508) | async clear(): Promise<void> {
method keys (line 520) | async keys(): Promise<string[]> {
function createCache (line 538) | function createCache<T>(
FILE: src/utils/hub.ts
type HubOptions (line 18) | interface HubOptions {
type HubDownloadProgress (line 38) | interface HubDownloadProgress {
type ModelConfig (line 54) | interface ModelConfig {
type ModelBundle (line 71) | interface ModelBundle {
constant DEFAULT_ENDPOINT (line 92) | const DEFAULT_ENDPOINT = 'https://huggingface.co';
constant DEFAULT_REVISION (line 93) | const DEFAULT_REVISION = 'main';
constant ONNX_MODEL_FILES (line 98) | const ONNX_MODEL_FILES = [
function buildFileUrl (line 115) | function buildFileUrl(
function fetchWithAuth (line 130) | async function fetchWithAuth(url: string, token?: string): Promise<Respo...
function fileExists (line 143) | async function fileExists(
function findOnnxModel (line 162) | async function findOnnxModel(
function downloadFile (line 179) | async function downloadFile(
function downloadJson (line 205) | async function downloadJson<T = unknown>(
function downloadTokenizer (line 238) | async function downloadTokenizer(
function downloadConfig (line 249) | async function downloadConfig(
function downloadModel (line 259) | async function downloadModel(
function fromHub (line 371) | async function fromHub(
function modelExists (line 381) | async function modelExists(
function getModelInfo (line 397) | async function getModelInfo(
constant POPULAR_MODELS (line 429) | const POPULAR_MODELS = {
type PopularModelTask (line 477) | type PopularModelTask = keyof typeof POPULAR_MODELS;
function getDefaultModel (line 482) | function getDefaultModel(task: PopularModelTask): string {
function fromTask (line 494) | async function fromTask(
FILE: src/utils/model-loader.ts
type DownloadProgress (line 18) | interface DownloadProgress {
type ModelLoaderOptions (line 38) | interface ModelLoaderOptions {
type PreloadOptions (line 60) | interface PreloadOptions extends ModelLoaderOptions {
type CachedModelMeta (line 68) | interface CachedModelMeta {
type DownloadState (line 81) | interface DownloadState {
type ChunkState (line 92) | interface ChunkState {
constant DB_NAME (line 103) | const DB_NAME = 'edgeflow-model-cache';
constant DB_VERSION (line 104) | const DB_VERSION = 1;
constant STORE_META (line 105) | const STORE_META = 'meta';
constant STORE_CHUNKS (line 106) | const STORE_CHUNKS = 'chunks';
constant STORE_STATE (line 107) | const STORE_STATE = 'download-state';
class ModelCache (line 112) | class ModelCache {
method openDB (line 119) | private async openDB(): Promise<IDBDatabase> {
method getMeta (line 160) | async getMeta(url: string): Promise<CachedModelMeta | null> {
method saveMeta (line 174) | async saveMeta(meta: CachedModelMeta): Promise<void> {
method saveChunk (line 194) | async saveChunk(url: string, index: number, data: ArrayBuffer): Promis...
method putInStore (line 214) | private async putInStore(storeName: string, value: unknown): Promise<v...
method isQuotaError (line 228) | private isQuotaError(err: unknown): boolean {
method evictOldest (line 239) | async evictOldest(bytesNeeded: number): Promise<void> {
method getChunks (line 262) | async getChunks(url: string): Promise<ArrayBuffer[]> {
method getModel (line 283) | async getModel(url: string): Promise<ArrayBuffer | null> {
method saveDownloadState (line 306) | async saveDownloadState(state: DownloadState): Promise<void> {
method getDownloadState (line 321) | async getDownloadState(url: string): Promise<DownloadState | null> {
method deleteDownloadState (line 335) | async deleteDownloadState(url: string): Promise<void> {
method deleteModel (line 349) | async deleteModel(url: string): Promise<void> {
method clear (line 390) | async clear(): Promise<void> {
method getStats (line 408) | async getStats(): Promise<{ models: number; totalSize: number }> {
function supportsRangeRequests (line 437) | async function supportsRangeRequests(url: string): Promise<{ supports: b...
function downloadChunk (line 457) | async function downloadChunk(
function downloadWithResume (line 485) | async function downloadWithResume(
function downloadSimple (line 625) | async function downloadSimple(
type PreloadTask (line 692) | interface PreloadTask {
class PreloadManager (line 705) | class PreloadManager {
method preload (line 714) | preload(url: string, options: PreloadOptions = {}): Promise<ArrayBuffe...
method processQueue (line 763) | private async processQueue(): Promise<void> {
method downloadTask (line 784) | private async downloadTask(task: PreloadTask): Promise<void> {
method isPreloaded (line 798) | isPreloaded(url: string): boolean {
method getStatus (line 806) | getStatus(url: string): 'pending' | 'loading' | 'complete' | 'error' |...
method get (line 814) | async get(url: string): Promise<ArrayBuffer | null> {
method cancel (line 828) | cancel(url: string): void {
method clear (line 840) | clear(): void {
function loadModelData (line 861) | async function loadModelData(
function preloadModel (line 927) | function preloadModel(url: string, options: PreloadOptions = {}): Promis...
function preloadModels (line 934) | function preloadModels(
function isModelCached (line 946) | async function isModelCached(url: string): Promise<boolean> {
function getCachedModel (line 954) | async function getCachedModel(url: string): Promise<ArrayBuffer | null> {
function deleteCachedModel (line 961) | async function deleteCachedModel(url: string): Promise<void> {
function clearModelCache (line 968) | async function clearModelCache(): Promise<void> {
function getModelCacheStats (line 975) | async function getModelCacheStats(): Promise<{ models: number; totalSize...
function getPreloadStatus (line 982) | function getPreloadStatus(url: string): 'pending' | 'loading' | 'complet...
function cancelPreload (line 989) | function cancelPreload(url: string): void {
function getPreloadedModel (line 996) | async function getPreloadedModel(url: string): Promise<ArrayBuffer | nul...
FILE: src/utils/offline.ts
type OfflineConfig (line 11) | interface OfflineConfig {
type OfflineStatus (line 31) | interface OfflineStatus {
type CachedModelInfo (line 48) | interface CachedModelInfo {
class OfflineManager (line 63) | class OfflineManager {
method constructor (line 68) | constructor(config: OfflineConfig = {}) {
method initialize (line 82) | async initialize(): Promise<void> {
method registerServiceWorker (line 111) | private async registerServiceWorker(): Promise<void> {
method preloadForOffline (line 143) | async preloadForOffline(modelUrls: string[]): Promise<void> {
method getStatus (line 160) | async getStatus(): Promise<OfflineStatus> {
method getCachedModels (line 186) | async getCachedModels(): Promise<CachedModelInfo[]> {
method isModelAvailableOffline (line 211) | async isModelAvailableOffline(url: string): Promise<boolean> {
method removeFromOffline (line 219) | async removeFromOffline(url: string): Promise<void> {
method clearOfflineData (line 227) | async clearOfflineData(): Promise<void> {
method getStorageInfo (line 235) | async getStorageInfo(): Promise<{ quota: number; usage: number; availa...
method requestPersistentStorage (line 250) | async requestPersistentStorage(): Promise<boolean> {
method onOnlineStatusChange (line 260) | onOnlineStatusChange(listener: (online: boolean) => void): () => void {
method isOnline (line 268) | isOnline(): boolean {
method notifyOnlineStatus (line 275) | private notifyOnlineStatus(online: boolean): void {
method openDatabase (line 282) | private async openDatabase(): Promise<IDBDatabase> {
function generateServiceWorker (line 298) | function generateServiceWorker(options: {
function generateManifest (line 439) | function generateManifest(options: {
function getOfflineManager (line 472) | function getOfflineManager(config?: OfflineConfig): OfflineManager {
function initOffline (line 482) | async function initOffline(config?: OfflineConfig): Promise<OfflineStatu...
function isOffline (line 491) | function isOffline(): boolean {
function isPWASupported (line 498) | function isPWASupported(): boolean {
FILE: src/utils/preprocessor.ts
type ImageInput (line 17) | type ImageInput =
type AudioInput (line 29) | type AudioInput =
type ImagePreprocessorOptions (line 44) | interface ImagePreprocessorOptions {
constant DEFAULT_IMAGE_OPTIONS (line 82) | const DEFAULT_IMAGE_OPTIONS: ImagePreprocessorOptions = {
class ImagePreprocessor (line 104) | class ImagePreprocessor {
method constructor (line 109) | constructor(options: ImagePreprocessorOptions = {}) {
method fromConfig (line 128) | static fromConfig(config: Record<string, unknown>): ImagePreprocessor {
method fromUrl (line 199) | static async fromUrl(url: string): Promise<ImagePreprocessor> {
method fromHuggingFace (line 211) | static async fromHuggingFace(
method ensureCanvas (line 223) | private ensureCanvas(): void {
method process (line 237) | async process(input: ImageInput): Promise<EdgeFlowTensor> {
method processBatch (line 272) | async processBatch(inputs: ImageInput[]): Promise<EdgeFlowTensor> {
method loadFromUrl (line 305) | private async loadFromUrl(url: string): Promise<ImageData> {
method loadFromBlob (line 325) | private async loadFromBlob(blob: Blob): Promise<ImageData> {
method centerCrop (line 337) | private centerCrop(imageData: ImageData): ImageData {
method toImageData (line 373) | private toImageData(
method resize (line 389) | private resize(imageData: ImageData): ImageData {
method toTensor (line 437) | private toTensor(imageData: ImageData): EdgeFlowTensor {
method getOptions (line 518) | getOptions(): ImagePreprocessorOptions {
type AudioPreprocessorOptions (line 530) | interface AudioPreprocessorOptions {
constant DEFAULT_AUDIO_OPTIONS (line 548) | const DEFAULT_AUDIO_OPTIONS: Required<AudioPreprocessorOptions> = {
class AudioPreprocessor (line 562) | class AudioPreprocessor {
method constructor (line 566) | constructor(options: AudioPreprocessorOptions = {}) {
method fromConfig (line 573) | static fromConfig(config: Record<string, unknown>): AudioPreprocessor {
method fromHuggingFace (line 602) | static async fromHuggingFace(
method ensureAudioContext (line 620) | private ensureAudioContext(): void {
method process (line 633) | async process(input: AudioInput): Promise<EdgeFlowTensor> {
method processRaw (line 674) | async processRaw(input: AudioInput): Promise<EdgeFlowTensor> {
method loadFromUrl (line 706) | private async loadFromUrl(url: string): Promise<Float32Array> {
method loadFromBlob (line 719) | private async loadFromBlob(blob: Blob): Promise<Float32Array> {
method decodeAudioData (line 727) | private async decodeAudioData(data: ArrayBuffer): Promise<Float32Array> {
method audioBufferToFloat32 (line 736) | private audioBufferToFloat32(buffer: AudioBuffer): Float32Array {
method normalizeAudio (line 745) | private normalizeAudio(data: Float32Array): Float32Array {
method computeMelSpectrogram (line 766) | private computeMelSpectrogram(audio: Float32Array): EdgeFlowTensor {
method dispose (line 806) | dispose(): void {
type TextPreprocessorOptions (line 821) | interface TextPreprocessorOptions {
function preprocessText (line 835) | function preprocessText(
function createImagePreprocessor (line 874) | function createImagePreprocessor(
function createAudioPreprocessor (line 906) | function createAudioPreprocessor(
FILE: src/utils/tokenizer.ts
type TokenizerModel (line 19) | type TokenizerModel = 'BPE' | 'WordPiece' | 'Unigram' | 'basic';
type TokenizerOptions (line 21) | interface TokenizerOptions {
type HFTokenizerJSON (line 34) | interface HFTokenizerJSON {
class Tokenizer (line 96) | class Tokenizer {
method constructor (line 128) | constructor() {
method initByteEncoder (line 135) | private initByteEncoder(): void {
method fromJSON (line 165) | static async fromJSON(json: HFTokenizerJSON | string): Promise<Tokeniz...
method fromUrl (line 250) | static async fromUrl(url: string): Promise<Tokenizer> {
method fromHuggingFace (line 265) | static async fromHuggingFace(modelId: string, options?: { revision?: s...
method normalize (line 274) | private normalize(text: string): string {
method preTokenize (line 294) | private preTokenize(text: string): string[] {
method textToBytes (line 304) | private textToBytes(text: string): string {
method bytesToText (line 313) | private bytesToText(text: string): string {
method getPairs (line 324) | private getPairs(word: string[]): Set<string> {
method bpe (line 335) | private bpe(token: string): string[] {
method wordPiece (line 401) | private wordPiece(word: string): string[] {
method tokenizeWord (line 441) | private tokenizeWord(word: string): string[] {
method unigramTokenize (line 466) | private unigramTokenize(word: string): string[] {
method tokenize (line 502) | private tokenize(text: string): string[] {
method convertTokensToIds (line 550) | private convertTokensToIds(tokens: string[]): number[] {
method convertIdsToTokens (line 568) | private convertIdsToTokens(ids: number[]): string[] {
method postProcess (line 575) | private postProcess(
method encode (line 639) | encode(text: string, options: TokenizerOptions = {}): TokenizedOutput {
method encodeBatch (line 717) | encodeBatch(texts: string[], options: TokenizerOptions = {}): Tokenize...
method decode (line 731) | decode(ids: number[], skipSpecialTokens = true): string {
method decodeBatch (line 779) | decodeBatch(batchIds: number[][], skipSpecialTokens = true): string[] {
method vocabSize (line 786) | get vocabSize(): number {
method getSpecialTokenIds (line 793) | getSpecialTokenIds(): {
method getConfig (line 816) | getConfig(): TokenizerConfig {
method isSpecialToken (line 833) | isSpecialToken(token: string): boolean {
method getTokenId (line 840) | getTokenId(token: string): number | undefined {
method getToken (line 847) | getToken(id: number): string | undefined {
function createBasicTokenizer (line 859) | function createBasicTokenizer(): Tokenizer {
function loadTokenizer (line 867) | async function loadTokenizer(url: string): Promise<Tokenizer> {
function loadTokenizerFromHub (line 874) | async function loadTokenizerFromHub(
FILE: tests/e2e/localai-10s-check.spec.ts
constant BASE_URL (line 7) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 8) | const SCREENSHOT_DIR = 'test-results/localai-10s-screenshots';
FILE: tests/e2e/localai-clear-cache-load.spec.ts
constant BASE_URL (line 7) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 8) | const SCREENSHOT_DIR = 'test-results/localai-clear-cache-screenshots';
FILE: tests/e2e/localai-knowledge-base.spec.ts
constant BASE_URL (line 8) | const BASE_URL = 'http://localhost:5174/';
constant SCREENSHOT_DIR (line 9) | const SCREENSHOT_DIR = 'test-results/localai-screenshots';
FILE: tests/e2e/localai-load-models.spec.ts
constant BASE_URL (line 8) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 9) | const SCREENSHOT_DIR = 'test-results/localai-load-screenshots';
constant WAIT_SECONDS (line 10) | const WAIT_SECONDS = 150;
constant SCREENSHOT_INTERVAL_SEC (line 11) | const SCREENSHOT_INTERVAL_SEC = 30;
FILE: tests/e2e/localai-loading-check.spec.ts
constant BASE_URL (line 7) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 8) | const SCREENSHOT_DIR = 'test-results/localai-loading-screenshots';
FILE: tests/e2e/localai-network-audit.spec.ts
constant BASE_URL (line 8) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 9) | const SCREENSHOT_DIR = 'test-results/localai-network-audit';
type RequestRecord (line 11) | interface RequestRecord {
FILE: tests/e2e/localai-network-failures.spec.ts
constant BASE_URL (line 7) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 8) | const SCREENSHOT_DIR = 'test-results/localai-network-screenshots';
FILE: tests/e2e/localai-network-full.spec.ts
constant BASE_URL (line 7) | const BASE_URL = 'http://localhost:5173/';
constant SCREENSHOT_DIR (line 8) | const SCREENSHOT_DIR = 'test-results/localai-network-full-screenshots';
type NetworkEntry (line 10) | interface NetworkEntry {
FILE: tests/integration/pipeline.test.ts
function createMockOutputs (line 17) | function createMockOutputs(shapes: { shape: number[]; fill?: number }[])...
FILE: tests/unit/memory.test.ts
function createMockModel (line 333) | function createMockModel(id: string, sizeBytes: number) {
FILE: tests/unit/tokenizer.test.ts
constant SAMPLE_TOKENIZER_JSON (line 8) | const SAMPLE_TOKENIZER_JSON = {
Condensed preview — 179 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,920K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 638,
"preview": "---\nname: Bug report\nabout: Report a bug to help improve edgeFlow.js\ntitle: '[Bug] '\nlabels: bug\nassignees: ''\n---\n\n**De"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 510,
"preview": "---\nname: Feature request\nabout: Suggest a feature for edgeFlow.js\ntitle: '[Feature] '\nlabels: enhancement\nassignees: ''"
},
{
"path": ".github/pull_request_template.md",
"chars": 363,
"preview": "## Summary\n\nBrief description of the changes.\n\n## Motivation\n\nWhy is this change needed?\n\n## Changes\n\n- Change 1\n- Chang"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1125,
"preview": "name: CI\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n lint-and-typecheck:\n runs-on"
},
{
"path": ".github/workflows/publish.yml",
"chars": 556,
"preview": "name: Publish to npm\n\non:\n release:\n types: [published]\n\njobs:\n publish:\n runs-on: ubuntu-latest\n permissions"
},
{
"path": ".gitignore",
"chars": 463,
"preview": "# Dependencies\nnode_modules/\n\n# Build outputs (keep dist/ for npm publishing)\n# dist/\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo"
},
{
"path": "CLAUDE.md",
"chars": 4392,
"preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
},
{
"path": "CONTRIBUTING.md",
"chars": 3038,
"preview": "# Contributing to edgeFlow.js\n\nThank you for your interest in contributing to edgeFlow.js! This guide will help you get "
},
{
"path": "README.md",
"chars": 17733,
"preview": "# edgeFlow.js\n\n<div align=\"center\">\n\n**Browser ML inference framework with task scheduling and smart caching.**\n\n[\nexport { WebGPURuntime, createWebGP"
},
{
"path": "dist/backends/onnx.d.ts",
"chars": 1518,
"preview": "/**\n * edgeFlow.js - ONNX Runtime Backend\n *\n * Uses onnxruntime-web for real ONNX model inference.\n * onnxruntime-web i"
},
{
"path": "dist/backends/onnx.js",
"chars": 10707,
"preview": "/**\n * edgeFlow.js - ONNX Runtime Backend\n *\n * Uses onnxruntime-web for real ONNX model inference.\n * onnxruntime-web i"
},
{
"path": "dist/backends/transformers-adapter.d.ts",
"chars": 3899,
"preview": "/**\n * edgeFlow.js - transformers.js Adapter Backend\n *\n * Wraps transformers.js (by Hugging Face) as an inference backe"
},
{
"path": "dist/backends/transformers-adapter.js",
"chars": 6953,
"preview": "/**\n * edgeFlow.js - transformers.js Adapter Backend\n *\n * Wraps transformers.js (by Hugging Face) as an inference backe"
},
{
"path": "dist/backends/wasm.d.ts",
"chars": 1824,
"preview": "/**\n * edgeFlow.js - WebAssembly Backend\n *\n * Pure WASM runtime for universal browser support.\n * Features:\n * - Univer"
},
{
"path": "dist/backends/wasm.js",
"chars": 12745,
"preview": "/**\n * edgeFlow.js - WebAssembly Backend\n *\n * Pure WASM runtime for universal browser support.\n * Features:\n * - Univer"
},
{
"path": "dist/backends/webgpu.d.ts",
"chars": 4049,
"preview": "/**\n * edgeFlow.js - WebGPU Backend\n *\n * **Status: Planned** - This is a skeleton implementation that initializes\n * We"
},
{
"path": "dist/backends/webgpu.js",
"chars": 11143,
"preview": "/**\n * edgeFlow.js - WebGPU Backend\n *\n * **Status: Planned** - This is a skeleton implementation that initializes\n * We"
},
{
"path": "dist/backends/webnn.d.ts",
"chars": 3450,
"preview": "/**\n * edgeFlow.js - WebNN Backend\n *\n * **Status: Planned** - This is a skeleton implementation that initializes\n * a W"
},
{
"path": "dist/backends/webnn.js",
"chars": 6758,
"preview": "/**\n * edgeFlow.js - WebNN Backend\n *\n * **Status: Planned** - This is a skeleton implementation that initializes\n * a W"
},
{
"path": "dist/core/composer.d.ts",
"chars": 3696,
"preview": "/**\n * edgeFlow.js - Pipeline Composer\n *\n * Chain multiple pipelines together to build complex multi-model workflows.\n "
},
{
"path": "dist/core/composer.js",
"chars": 5671,
"preview": "/**\n * edgeFlow.js - Pipeline Composer\n *\n * Chain multiple pipelines together to build complex multi-model workflows.\n "
},
{
"path": "dist/core/device-profiler.d.ts",
"chars": 2320,
"preview": "/**\n * edgeFlow.js - Device Profiler\n *\n * Automatically profiles the current device and recommends optimal model\n * var"
},
{
"path": "dist/core/device-profiler.js",
"chars": 4082,
"preview": "/**\n * edgeFlow.js - Device Profiler\n *\n * Automatically profiles the current device and recommends optimal model\n * var"
},
{
"path": "dist/core/index.d.ts",
"chars": 1569,
"preview": "/**\n * edgeFlow.js - Core Module Exports\n */\nexport * from './types.js';\nexport { EdgeFlowTensor, tensor, zeros, ones, f"
},
{
"path": "dist/core/index.js",
"chars": 1313,
"preview": "/**\n * edgeFlow.js - Core Module Exports\n */\n// Types\nexport * from './types.js';\n// Tensor\nexport { EdgeFlowTensor, ten"
},
{
"path": "dist/core/memory.d.ts",
"chars": 6182,
"preview": "/**\n * edgeFlow.js - Memory Management\n *\n * Efficient memory management for tensors and models.\n * Features:\n * - Memor"
},
{
"path": "dist/core/memory.js",
"chars": 15641,
"preview": "/**\n * edgeFlow.js - Memory Management\n *\n * Efficient memory management for tensors and models.\n * Features:\n * - Memor"
},
{
"path": "dist/core/plugin.d.ts",
"chars": 2842,
"preview": "/**\n * edgeFlow.js - Plugin System\n *\n * Register custom pipelines, backends, and middleware via plugins.\n *\n * @example"
},
{
"path": "dist/core/plugin.js",
"chars": 2894,
"preview": "/**\n * edgeFlow.js - Plugin System\n *\n * Register custom pipelines, backends, and middleware via plugins.\n *\n * @example"
},
{
"path": "dist/core/runtime.d.ts",
"chars": 3799,
"preview": "/**\n * edgeFlow.js - Runtime Management\n *\n * Manages runtime backends and automatic selection.\n * Provides unified inte"
},
{
"path": "dist/core/runtime.js",
"chars": 11688,
"preview": "/**\n * edgeFlow.js - Runtime Management\n *\n * Manages runtime backends and automatic selection.\n * Provides unified inte"
},
{
"path": "dist/core/scheduler.d.ts",
"chars": 3574,
"preview": "/**\n * edgeFlow.js - Inference Scheduler\n *\n * Task scheduler for managing concurrent inference execution.\n * Supports p"
},
{
"path": "dist/core/scheduler.js",
"chars": 20386,
"preview": "/**\n * edgeFlow.js - Inference Scheduler\n *\n * Task scheduler for managing concurrent inference execution.\n * Supports p"
},
{
"path": "dist/core/tensor.d.ts",
"chars": 4393,
"preview": "/**\n * edgeFlow.js - Tensor Implementation\n *\n * Lightweight tensor implementation with efficient memory management.\n */"
},
{
"path": "dist/core/tensor.js",
"chars": 24861,
"preview": "/**\n * edgeFlow.js - Tensor Implementation\n *\n * Lightweight tensor implementation with efficient memory management.\n */"
},
{
"path": "dist/core/types.d.ts",
"chars": 11546,
"preview": "/**\n * edgeFlow.js - Core Type Definitions\n *\n * This file contains all the core types used throughout the framework.\n *"
},
{
"path": "dist/core/types.js",
"chars": 1742,
"preview": "/**\n * edgeFlow.js - Core Type Definitions\n *\n * This file contains all the core types used throughout the framework.\n *"
},
{
"path": "dist/core/worker.d.ts",
"chars": 5215,
"preview": "/**\n * edgeFlow.js - Web Worker Support\n *\n * Run inference in a Web Worker to avoid blocking the main thread.\n */\nimpor"
},
{
"path": "dist/core/worker.js",
"chars": 14967,
"preview": "/**\n * edgeFlow.js - Web Worker Support\n *\n * Run inference in a Web Worker to avoid blocking the main thread.\n */\n// =="
},
{
"path": "dist/edgeflow.browser.js",
"chars": 342668,
"preview": "/* edgeFlow.js - Browser Bundle */\n\nvar __defProp = Object.defineProperty;\nvar __getOwnPropNames = Object.getOwnProperty"
},
{
"path": "dist/index.d.ts",
"chars": 7244,
"preview": "/**\n * edgeFlow.js\n *\n * Lightweight, high-performance browser ML inference framework\n * with native concurrency support"
},
{
"path": "dist/index.js",
"chars": 7363,
"preview": "/**\n * edgeFlow.js\n *\n * Lightweight, high-performance browser ML inference framework\n * with native concurrency support"
},
{
"path": "dist/pipelines/automatic-speech-recognition.d.ts",
"chars": 2358,
"preview": "/**\n * edgeFlow.js - Automatic Speech Recognition Pipeline\n *\n * Transcribe audio to text using Whisper ONNX models (enc"
},
{
"path": "dist/pipelines/automatic-speech-recognition.js",
"chars": 11499,
"preview": "/**\n * edgeFlow.js - Automatic Speech Recognition Pipeline\n *\n * Transcribe audio to text using Whisper ONNX models (enc"
},
{
"path": "dist/pipelines/base.d.ts",
"chars": 3576,
"preview": "/**\n * edgeFlow.js - Base Pipeline\n *\n * Base class and utilities for all pipeline implementations.\n */\nimport { LoadedM"
},
{
"path": "dist/pipelines/base.js",
"chars": 4915,
"preview": "/**\n * edgeFlow.js - Base Pipeline\n *\n * Base class and utilities for all pipeline implementations.\n */\nimport { loadMod"
},
{
"path": "dist/pipelines/feature-extraction.d.ts",
"chars": 1485,
"preview": "/**\n * edgeFlow.js - Feature Extraction Pipeline\n *\n * Extract embeddings/features from text using sentence-transformer "
},
{
"path": "dist/pipelines/feature-extraction.js",
"chars": 6846,
"preview": "/**\n * edgeFlow.js - Feature Extraction Pipeline\n *\n * Extract embeddings/features from text using sentence-transformer "
},
{
"path": "dist/pipelines/image-classification.d.ts",
"chars": 1533,
"preview": "/**\n * edgeFlow.js - Image Classification Pipeline\n *\n * Classify images into categories using vision models.\n */\nimport"
},
{
"path": "dist/pipelines/image-classification.js",
"chars": 4086,
"preview": "/**\n * edgeFlow.js - Image Classification Pipeline\n *\n * Classify images into categories using vision models.\n */\nimport"
},
{
"path": "dist/pipelines/image-segmentation.d.ts",
"chars": 6195,
"preview": "/**\n * edgeFlow.js - Image Segmentation Pipeline\n *\n * Interactive image segmentation using SAM (Segment Anything Model)"
},
{
"path": "dist/pipelines/image-segmentation.js",
"chars": 20546,
"preview": "/**\n * edgeFlow.js - Image Segmentation Pipeline\n *\n * Interactive image segmentation using SAM (Segment Anything Model)"
},
{
"path": "dist/pipelines/index.d.ts",
"chars": 4573,
"preview": "/**\n * edgeFlow.js - Pipeline Exports\n */\nimport { RuntimeType, QuantizationType } from '../core/types.js';\nexport { Bas"
},
{
"path": "dist/pipelines/index.js",
"chars": 5374,
"preview": "/**\n * edgeFlow.js - Pipeline Exports\n */\nimport { getPluginPipeline } from '../core/plugin.js';\nimport { registerAllBac"
},
{
"path": "dist/pipelines/object-detection.d.ts",
"chars": 1690,
"preview": "/**\n * edgeFlow.js - Object Detection Pipeline\n *\n * Detect objects in images with bounding boxes and class labels.\n */\n"
},
{
"path": "dist/pipelines/object-detection.js",
"chars": 9127,
"preview": "/**\n * edgeFlow.js - Object Detection Pipeline\n *\n * Detect objects in images with bounding boxes and class labels.\n */\n"
},
{
"path": "dist/pipelines/question-answering.d.ts",
"chars": 1726,
"preview": "/**\n * edgeFlow.js - Question Answering Pipeline\n *\n * Extract answers from context given a question using real ONNX QA "
},
{
"path": "dist/pipelines/question-answering.js",
"chars": 7785,
"preview": "/**\n * edgeFlow.js - Question Answering Pipeline\n *\n * Extract answers from context given a question using real ONNX QA "
},
{
"path": "dist/pipelines/text-classification.d.ts",
"chars": 1810,
"preview": "/**\n * edgeFlow.js - Text Classification Pipeline\n *\n * High-level API for text classification tasks including\n * sentim"
},
{
"path": "dist/pipelines/text-classification.js",
"chars": 5685,
"preview": "/**\n * edgeFlow.js - Text Classification Pipeline\n *\n * High-level API for text classification tasks including\n * sentim"
},
{
"path": "dist/pipelines/text-generation.d.ts",
"chars": 8119,
"preview": "/**\n * edgeFlow.js - Text Generation Pipeline\n *\n * Autoregressive text generation with streaming support.\n * Supports G"
},
{
"path": "dist/pipelines/text-generation.js",
"chars": 27526,
"preview": "/**\n * edgeFlow.js - Text Generation Pipeline\n *\n * Autoregressive text generation with streaming support.\n * Supports G"
},
{
"path": "dist/pipelines/zero-shot-classification.d.ts",
"chars": 2064,
"preview": "/**\n * edgeFlow.js - Zero-shot Classification Pipeline\n *\n * Classify text into any set of labels without fine-tuning,\n "
},
{
"path": "dist/pipelines/zero-shot-classification.js",
"chars": 6236,
"preview": "/**\n * edgeFlow.js - Zero-shot Classification Pipeline\n *\n * Classify text into any set of labels without fine-tuning,\n "
},
{
"path": "dist/tools/benchmark.d.ts",
"chars": 2892,
"preview": "/**\n * edgeFlow.js - Benchmark Utilities\n *\n * Performance testing and comparison tools.\n */\nexport interface BenchmarkO"
},
{
"path": "dist/tools/benchmark.js",
"chars": 7857,
"preview": "/**\n * edgeFlow.js - Benchmark Utilities\n *\n * Performance testing and comparison tools.\n */\n// ========================"
},
{
"path": "dist/tools/debugger.d.ts",
"chars": 6270,
"preview": "/**\n * edgeFlow.js - Visual Debugging Tools\n *\n * In-browser debugging and visualization utilities for ML models.\n */\nim"
},
{
"path": "dist/tools/debugger.js",
"chars": 21391,
"preview": "/**\n * edgeFlow.js - Visual Debugging Tools\n *\n * In-browser debugging and visualization utilities for ML models.\n */\n//"
},
{
"path": "dist/tools/index.d.ts",
"chars": 5382,
"preview": "/**\n * edgeFlow.js - Tools and Utilities\n *\n * Model optimization, quantization, and analysis tools.\n */\nimport { Loaded"
},
{
"path": "dist/tools/index.js",
"chars": 9905,
"preview": "/**\n * edgeFlow.js - Tools and Utilities\n *\n * Model optimization, quantization, and analysis tools.\n */\n/**\n * Quantize"
},
{
"path": "dist/tools/monitor.d.ts",
"chars": 6708,
"preview": "/**\n * edgeFlow.js - Performance Monitoring Dashboard\n *\n * Real-time performance monitoring and metrics visualization.\n"
},
{
"path": "dist/tools/monitor.js",
"chars": 27914,
"preview": "/**\n * edgeFlow.js - Performance Monitoring Dashboard\n *\n * Real-time performance monitoring and metrics visualization.\n"
},
{
"path": "dist/tools/quantization.d.ts",
"chars": 7012,
"preview": "/**\n * edgeFlow.js - Model Compression & Quantization Tools\n *\n * In-browser model quantization and compression utilitie"
},
{
"path": "dist/tools/quantization.js",
"chars": 30251,
"preview": "/**\n * edgeFlow.js - Model Compression & Quantization Tools\n *\n * In-browser model quantization and compression utilitie"
},
{
"path": "dist/utils/cache.d.ts",
"chars": 3492,
"preview": "/**\n * edgeFlow.js - Caching Utilities\n *\n * Smart caching for models, tensors, and inference results.\n */\n/**\n * Cache "
},
{
"path": "dist/utils/cache.js",
"chars": 12206,
"preview": "/**\n * edgeFlow.js - Caching Utilities\n *\n * Smart caching for models, tensors, and inference results.\n */\n// =========="
},
{
"path": "dist/utils/hub.d.ts",
"chars": 5360,
"preview": "/**\n * edgeFlow.js - Hugging Face Hub Integration\n *\n * Automatically download models, tokenizers, and configs from Hugg"
},
{
"path": "dist/utils/hub.js",
"chars": 10338,
"preview": "/**\n * edgeFlow.js - Hugging Face Hub Integration\n *\n * Automatically download models, tokenizers, and configs from Hugg"
},
{
"path": "dist/utils/index.d.ts",
"chars": 1373,
"preview": "/**\n * edgeFlow.js - Utilities Exports\n */\nexport { Tokenizer, createBasicTokenizer, loadTokenizer, loadTokenizerFromHub"
},
{
"path": "dist/utils/index.js",
"chars": 1094,
"preview": "/**\n * edgeFlow.js - Utilities Exports\n */\n// Tokenizer\nexport { Tokenizer, createBasicTokenizer, loadTokenizer, loadTok"
},
{
"path": "dist/utils/model-loader.d.ts",
"chars": 3189,
"preview": "/**\n * edgeFlow.js - Advanced Model Loader\n *\n * Features:\n * - Preloading: Background model loading\n * - Sharding: Spli"
},
{
"path": "dist/utils/model-loader.js",
"chars": 25556,
"preview": "/**\n * edgeFlow.js - Advanced Model Loader\n *\n * Features:\n * - Preloading: Background model loading\n * - Sharding: Spli"
},
{
"path": "dist/utils/offline.d.ts",
"chars": 3709,
"preview": "/**\n * edgeFlow.js - Offline/PWA Support\n *\n * Utilities for offline-first ML inference.\n */\nexport interface OfflineCon"
},
{
"path": "dist/utils/offline.js",
"chars": 12773,
"preview": "/**\n * edgeFlow.js - Offline/PWA Support\n *\n * Utilities for offline-first ML inference.\n */\n// ========================"
},
{
"path": "dist/utils/preprocessor.d.ts",
"chars": 5995,
"preview": "/**\n * edgeFlow.js - Preprocessor\n *\n * Data preprocessing utilities for images, audio, and other data types.\n * Support"
},
{
"path": "dist/utils/preprocessor.js",
"chars": 23306,
"preview": "/**\n * edgeFlow.js - Preprocessor\n *\n * Data preprocessing utilities for images, audio, and other data types.\n * Support"
},
{
"path": "dist/utils/tokenizer.d.ts",
"chars": 6335,
"preview": "/**\n * edgeFlow.js - Tokenizer\n *\n * Full-featured tokenizer supporting HuggingFace tokenizer.json format.\n * Supports B"
},
{
"path": "dist/utils/tokenizer.js",
"chars": 22259,
"preview": "/**\n * edgeFlow.js - Tokenizer\n *\n * Full-featured tokenizer supporting HuggingFace tokenizer.json format.\n * Supports B"
},
{
"path": "docs/.vitepress/config.ts",
"chars": 2520,
"preview": "import { defineConfig } from 'vitepress';\n\nexport default defineConfig({\n title: 'edgeFlow.js',\n description: 'Product"
},
{
"path": "docs/api/model-loader.md",
"chars": 4929,
"preview": "# Model Loader API\n\n## 模型加载\n\n### loadModel()\n\n加载模型并准备推理。\n\n```typescript\nasync function loadModel(\n url: string,\n optio"
},
{
"path": "docs/api/pipeline.md",
"chars": 5580,
"preview": "# Pipeline API\n\n## pipeline()\n\n创建指定任务的 Pipeline。\n\n```typescript\nfunction pipeline(\n task: PipelineTask,\n options?: Pip"
},
{
"path": "docs/api/tensor.md",
"chars": 3379,
"preview": "# Tensor API\n\n## EdgeFlowTensor\n\n核心张量类,用于存储和操作多维数组。\n\n### 构造函数\n\n```typescript\nnew EdgeFlowTensor(\n data: TypedArray | nu"
},
{
"path": "docs/api/tokenizer.md",
"chars": 3766,
"preview": "# Tokenizer API\n\n## Tokenizer\n\n文本分词器,支持 BPE 和 WordPiece 算法。\n\n### 静态方法\n\n#### fromJSON()\n\n从 JSON 配置创建分词器。\n\n```typescript\ns"
},
{
"path": "docs/cookbook/composition.md",
"chars": 2183,
"preview": "# Pipeline Composition\n\nChain multiple ML models together to build complex workflows. No other browser ML framework supp"
},
{
"path": "docs/cookbook/transformers-adapter.md",
"chars": 2137,
"preview": "# transformers.js Adapter\n\nUse edgeFlow.js as an orchestration layer on top of [transformers.js](https://huggingface.co/"
},
{
"path": "docs/guide/architecture.md",
"chars": 3308,
"preview": "# Architecture Overview\n\nedgeFlow.js is a **production orchestration layer** for browser ML inference. It does not compe"
},
{
"path": "docs/guide/concepts.md",
"chars": 4283,
"preview": "# 核心概念\n\n## 架构概述\n\nedgeFlow.js 采用分层架构设计:\n\n```\n┌──────────────────────────────────────────────────────────┐\n│ "
},
{
"path": "docs/guide/device-profiling.md",
"chars": 1633,
"preview": "# Device Profiling\n\nedgeFlow.js can automatically profile the current device and recommend optimal model variants.\n\n## Q"
},
{
"path": "docs/guide/installation.md",
"chars": 867,
"preview": "# 安装\n\n## 通过包管理器安装\n\n### npm\n\n```bash\nnpm install edgeflowjs\n```\n\n### yarn\n\n```bash\nyarn add edgeflowjs\n```\n\n### pnpm\n\n```"
},
{
"path": "docs/guide/plugins.md",
"chars": 1877,
"preview": "# Plugin System\n\nedgeFlow.js supports plugins that register custom pipelines, backends, and middleware at runtime.\n\n## C"
},
{
"path": "docs/guide/quickstart.md",
"chars": 1985,
"preview": "# 快速入门\n\n本指南将帮助你在 5 分钟内开始使用 edgeFlow.js。\n\n## 基本用法\n\n### 1. 创建 Pipeline\n\n```typescript\nimport { pipeline } from 'edgeflowjs"
},
{
"path": "docs/index.md",
"chars": 626,
"preview": "# edgeFlow.js 文档\n\n欢迎使用 edgeFlow.js,一个轻量级、高性能的浏览器端机器学习推理框架。\n\n## 快速开始\n\n- [安装](./guide/installation.md)\n- [快速入门](./guide/qu"
},
{
"path": "docs/tutorials/text-classification.md",
"chars": 4431,
"preview": "# 文本分类教程\n\n本教程将介绍如何使用 edgeFlow.js 进行文本分类任务,如情感分析。\n\n## 基本用法\n\n### 1. 创建 Pipeline\n\n```typescript\nimport { pipeline } from 'e"
},
{
"path": "examples/basic-usage.ts",
"chars": 2898,
"preview": "/**\n * edgeFlow.js — Basic Usage Example\n *\n * Demonstrates the core APIs: pipeline creation, text generation,\n * image "
},
{
"path": "examples/multi-model-dashboard/index.html",
"chars": 10063,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, "
},
{
"path": "examples/offline-notepad/index.html",
"chars": 6281,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, "
},
{
"path": "examples/orchestration.ts",
"chars": 4957,
"preview": "/**\n * edgeFlow.js — Orchestration Example\n *\n * Demonstrates what makes edgeFlow.js unique: production orchestration\n *"
},
{
"path": "package.json",
"chars": 2641,
"preview": "{\n \"name\": \"edgeflowjs\",\n \"version\": \"0.1.0\",\n \"description\": \"Lightweight, high-performance browser ML inference fra"
},
{
"path": "playwright.config.ts",
"chars": 540,
"preview": "import { defineConfig, devices } from '@playwright/test';\n\nexport default defineConfig({\n testDir: './tests/e2e',\n tes"
},
{
"path": "scripts/build-browser.js",
"chars": 1634,
"preview": "/**\n * Build script for browser bundle\n */\nimport * as esbuild from 'esbuild';\nimport { fileURLToPath } from 'url';\nimpo"
},
{
"path": "src/backends/index.ts",
"chars": 1492,
"preview": "/**\n * edgeFlow.js - Backend Exports\n */\n\n// WebGPU Backend (planned - skeleton only)\nexport { WebGPURuntime, createWebG"
},
{
"path": "src/backends/onnx.ts",
"chars": 10848,
"preview": "/**\n * edgeFlow.js - ONNX Runtime Backend\n * \n * Uses onnxruntime-web for real ONNX model inference.\n * onnxruntime-web "
},
{
"path": "src/backends/transformers-adapter.ts",
"chars": 8647,
"preview": "/**\n * edgeFlow.js - transformers.js Adapter Backend\n *\n * Wraps transformers.js (by Hugging Face) as an inference backe"
},
{
"path": "src/backends/wasm.ts",
"chars": 13893,
"preview": "/**\n * edgeFlow.js - WebAssembly Backend\n * \n * Pure WASM runtime for universal browser support.\n * Features:\n * - Unive"
},
{
"path": "src/backends/webgpu.ts",
"chars": 13910,
"preview": "/**\n * edgeFlow.js - WebGPU Backend\n * \n * **Status: Planned** - This is a skeleton implementation that initializes\n * W"
},
{
"path": "src/backends/webnn.ts",
"chars": 9401,
"preview": "/**\n * edgeFlow.js - WebNN Backend\n * \n * **Status: Planned** - This is a skeleton implementation that initializes\n * a "
},
{
"path": "src/core/composer.ts",
"chars": 7133,
"preview": "/**\n * edgeFlow.js - Pipeline Composer\n *\n * Chain multiple pipelines together to build complex multi-model workflows.\n "
},
{
"path": "src/core/device-profiler.ts",
"chars": 5296,
"preview": "/**\n * edgeFlow.js - Device Profiler\n *\n * Automatically profiles the current device and recommends optimal model\n * var"
},
{
"path": "src/core/index.ts",
"chars": 1814,
"preview": "/**\n * edgeFlow.js - Core Module Exports\n */\n\n// Types\nexport * from './types.js';\n\n// Tensor\nexport {\n EdgeFlowTensor,"
},
{
"path": "src/core/memory.ts",
"chars": 15996,
"preview": "/**\n * edgeFlow.js - Memory Management\n * \n * Efficient memory management for tensors and models.\n * Features:\n * - Memo"
},
{
"path": "src/core/plugin.ts",
"chars": 4851,
"preview": "/**\n * edgeFlow.js - Plugin System\n *\n * Register custom pipelines, backends, and middleware via plugins.\n *\n * @example"
},
{
"path": "src/core/runtime.ts",
"chars": 12489,
"preview": "/**\n * edgeFlow.js - Runtime Management\n * \n * Manages runtime backends and automatic selection.\n * Provides unified int"
},
{
"path": "src/core/scheduler.ts",
"chars": 20748,
"preview": "/**\n * edgeFlow.js - Inference Scheduler\n * \n * Task scheduler for managing concurrent inference execution.\n * Supports "
},
{
"path": "src/core/tensor.ts",
"chars": 25691,
"preview": "/**\n * edgeFlow.js - Tensor Implementation\n * \n * Lightweight tensor implementation with efficient memory management.\n *"
},
{
"path": "src/core/types.ts",
"chars": 12754,
"preview": "/**\n * edgeFlow.js - Core Type Definitions\n * \n * This file contains all the core types used throughout the framework.\n "
},
{
"path": "src/core/worker.ts",
"chars": 16835,
"preview": "/**\n * edgeFlow.js - Web Worker Support\n * \n * Run inference in a Web Worker to avoid blocking the main thread.\n */\n\nimp"
},
{
"path": "src/index.ts",
"chars": 11138,
"preview": "/**\n * edgeFlow.js\n * \n * Lightweight, high-performance browser ML inference framework\n * with native concurrency suppor"
},
{
"path": "src/pipelines/automatic-speech-recognition.ts",
"chars": 12580,
"preview": "/**\n * edgeFlow.js - Automatic Speech Recognition Pipeline\n * \n * Transcribe audio to text using Whisper ONNX models (en"
},
{
"path": "src/pipelines/base.ts",
"chars": 6903,
"preview": "/**\n * edgeFlow.js - Base Pipeline\n * \n * Base class and utilities for all pipeline implementations.\n */\n\nimport {\n Loa"
},
{
"path": "src/pipelines/feature-extraction.ts",
"chars": 7659,
"preview": "/**\n * edgeFlow.js - Feature Extraction Pipeline\n * \n * Extract embeddings/features from text using sentence-transformer"
},
{
"path": "src/pipelines/image-classification.ts",
"chars": 5194,
"preview": "/**\n * edgeFlow.js - Image Classification Pipeline\n * \n * Classify images into categories using vision models.\n */\n\nimpo"
},
{
"path": "src/pipelines/image-segmentation.ts",
"chars": 22628,
"preview": "/**\n * edgeFlow.js - Image Segmentation Pipeline\n * \n * Interactive image segmentation using SAM (Segment Anything Model"
},
{
"path": "src/pipelines/index.ts",
"chars": 8055,
"preview": "/**\n * edgeFlow.js - Pipeline Exports\n */\n\nimport {\n PipelineConfig,\n PipelineTask,\n RuntimeType,\n QuantizationType,"
},
{
"path": "src/pipelines/object-detection.ts",
"chars": 9472,
"preview": "/**\n * edgeFlow.js - Object Detection Pipeline\n * \n * Detect objects in images with bounding boxes and class labels.\n */"
},
{
"path": "src/pipelines/question-answering.ts",
"chars": 9080,
"preview": "/**\n * edgeFlow.js - Question Answering Pipeline\n * \n * Extract answers from context given a question using real ONNX QA"
},
{
"path": "src/pipelines/text-classification.ts",
"chars": 6760,
"preview": "/**\n * edgeFlow.js - Text Classification Pipeline\n * \n * High-level API for text classification tasks including\n * senti"
},
{
"path": "src/pipelines/text-generation.ts",
"chars": 29553,
"preview": "/**\n * edgeFlow.js - Text Generation Pipeline\n * \n * Autoregressive text generation with streaming support.\n * Supports "
},
{
"path": "src/pipelines/zero-shot-classification.ts",
"chars": 7508,
"preview": "/**\n * edgeFlow.js - Zero-shot Classification Pipeline\n * \n * Classify text into any set of labels without fine-tuning,\n"
},
{
"path": "src/tools/benchmark.ts",
"chars": 9710,
"preview": "/**\n * edgeFlow.js - Benchmark Utilities\n * \n * Performance testing and comparison tools.\n */\n\n// ======================"
},
{
"path": "src/tools/debugger.ts",
"chars": 23383,
"preview": "/**\n * edgeFlow.js - Visual Debugging Tools\n * \n * In-browser debugging and visualization utilities for ML models.\n */\n\n"
},
{
"path": "src/tools/index.ts",
"chars": 14405,
"preview": "/**\n * edgeFlow.js - Tools and Utilities\n * \n * Model optimization, quantization, and analysis tools.\n */\n\nimport { \n L"
},
{
"path": "src/tools/monitor.ts",
"chars": 30528,
"preview": "/**\n * edgeFlow.js - Performance Monitoring Dashboard\n * \n * Real-time performance monitoring and metrics visualization."
},
{
"path": "src/tools/quantization.ts",
"chars": 35476,
"preview": "/**\n * edgeFlow.js - Model Compression & Quantization Tools\n * \n * In-browser model quantization and compression utiliti"
},
{
"path": "src/utils/cache.ts",
"chars": 12576,
"preview": "/**\n * edgeFlow.js - Caching Utilities\n * \n * Smart caching for models, tensors, and inference results.\n */\n\n// ========"
},
{
"path": "src/utils/hub.ts",
"chars": 12711,
"preview": "/**\n * edgeFlow.js - Hugging Face Hub Integration\n * \n * Automatically download models, tokenizers, and configs from Hug"
},
{
"path": "src/utils/index.ts",
"chars": 1612,
"preview": "/**\n * edgeFlow.js - Utilities Exports\n */\n\n// Tokenizer\nexport {\n Tokenizer,\n createBasicTokenizer,\n loadTokenizer,\n"
},
{
"path": "src/utils/model-loader.ts",
"chars": 27060,
"preview": "/**\n * edgeFlow.js - Advanced Model Loader\n * \n * Features:\n * - Preloading: Background model loading\n * - Sharding: Spl"
},
{
"path": "src/utils/offline.ts",
"chars": 13988,
"preview": "/**\n * edgeFlow.js - Offline/PWA Support\n * \n * Utilities for offline-first ML inference.\n */\n\n// ======================"
},
{
"path": "src/utils/preprocessor.ts",
"chars": 25642,
"preview": "/**\n * edgeFlow.js - Preprocessor\n * \n * Data preprocessing utilities for images, audio, and other data types.\n * Suppor"
},
{
"path": "src/utils/tokenizer.ts",
"chars": 24138,
"preview": "/**\n * edgeFlow.js - Tokenizer\n * \n * Full-featured tokenizer supporting HuggingFace tokenizer.json format.\n * Supports "
},
{
"path": "tests/e2e/browser.spec.ts",
"chars": 1923,
"preview": "/**\n * Playwright E2E tests for edgeFlow.js in a real browser environment.\n *\n * Requires the demo server to be running "
},
{
"path": "tests/e2e/browser.test.ts",
"chars": 5646,
"preview": "/**\n * E2E Browser Tests\n * \n * These tests verify that edgeFlow.js works correctly in a browser environment.\n * Run wit"
},
{
"path": "tests/e2e/localai-10s-check.spec.ts",
"chars": 2770,
"preview": "/**\n * E2E test: Check model dot status at 10s and 60s after Load Models\n * Run with: npx playwright test tests/e2e/loca"
},
{
"path": "tests/e2e/localai-clear-cache-load.spec.ts",
"chars": 5869,
"preview": "/**\n * E2E test: Clear IndexedDB cache, then Load Models and check for LOADING state\n * Run with: npx playwright test te"
},
{
"path": "tests/e2e/localai-knowledge-base.spec.ts",
"chars": 3015,
"preview": "/**\n * E2E test for LocalAI Knowledge Base app at http://localhost:5174/\n * Run with: npx playwright test tests/e2e/loca"
},
{
"path": "tests/e2e/localai-load-models.spec.ts",
"chars": 4867,
"preview": "/**\n * E2E test for LocalAI Knowledge Base - model loading flow\n * Run with: npx playwright test tests/e2e/localai-load-"
},
{
"path": "tests/e2e/localai-loading-check.spec.ts",
"chars": 4823,
"preview": "/**\n * E2E test: Check for LOADING state and capture all console messages\n * Run with: npx playwright test tests/e2e/loc"
},
{
"path": "tests/e2e/localai-network-audit.spec.ts",
"chars": 4467,
"preview": "/**\n * E2E test: Audit ALL network requests when Load Models is clicked\n * Captures requests to HuggingFace, xethub, mod"
},
{
"path": "tests/e2e/localai-network-failures.spec.ts",
"chars": 2174,
"preview": "/**\n * E2E test: Capture failed network requests when Load Models is clicked\n * Run with: npx playwright test tests/e2e/"
},
{
"path": "tests/e2e/localai-network-full.spec.ts",
"chars": 4326,
"preview": "/**\n * E2E test: Capture ALL network requests when Load Models is clicked\n * Run with: npx playwright test tests/e2e/loc"
},
{
"path": "tests/integration/pipeline.test.ts",
"chars": 14190,
"preview": "/**\n * Integration tests for Pipelines\n * \n * These tests mock the ONNX runtime to return realistic tensor shapes\n * wit"
},
{
"path": "tests/unit/memory.test.ts",
"chars": 13073,
"preview": "/**\n * Unit tests for MemoryManager\n */\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { MemoryManage"
},
{
"path": "tests/unit/model-loader.test.ts",
"chars": 2541,
"preview": "/**\n * Unit tests for model-loader (download, cache, IndexedDB quota handling)\n */\nimport { describe, it, expect, vi, be"
},
{
"path": "tests/unit/runtime.test.ts",
"chars": 2630,
"preview": "/**\n * Unit tests for Runtime registration, auto-selection, and fallback chain\n */\nimport { describe, it, expect, vi, be"
},
{
"path": "tests/unit/scheduler.test.ts",
"chars": 11787,
"preview": "/**\n * Unit tests for InferenceScheduler\n */\nimport { describe, it, expect, beforeEach, vi } from 'vitest';\nimport { Inf"
},
{
"path": "tests/unit/tensor.test.ts",
"chars": 6140,
"preview": "/**\n * Unit tests for EdgeFlowTensor\n */\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { EdgeFlowTen"
},
{
"path": "tests/unit/tokenizer.test.ts",
"chars": 8023,
"preview": "/**\n * Unit tests for Tokenizer\n */\nimport { describe, it, expect } from 'vitest';\nimport { Tokenizer } from '../../src/"
},
{
"path": "tests/unit/worker.test.ts",
"chars": 2521,
"preview": "/**\n * Unit tests for InferenceWorker and WorkerPool\n */\nimport { describe, it, expect, vi, beforeEach } from 'vitest';\n"
},
{
"path": "tsconfig.json",
"chars": 1125,
"preview": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"lib\": ["
},
{
"path": "vercel.json",
"chars": 538,
"preview": "{\n \"buildCommand\": \"npm run build\",\n \"outputDirectory\": \".\",\n \"headers\": [\n {\n \"source\": \"/(.*)\",\n \"head"
},
{
"path": "vitest.config.ts",
"chars": 406,
"preview": "import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n test: {\n globals: true,\n environmen"
}
]
About this extraction
This page contains the full source code of the s-zx/edgeFlow.js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 179 files (1.7 MB), approximately 447.4k tokens, and a symbol index with 2561 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.