diff --git a/packages/agents/CHANGELOG.md b/packages/agents/CHANGELOG.md new file mode 100644 index 0000000000..0c82cb1ed6 --- /dev/null +++ b/packages/agents/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +[Unreleased]: https://github.com/MetaMask/ocap-kernel/ diff --git a/packages/agents/README.md b/packages/agents/README.md new file mode 100644 index 0000000000..57ece91309 --- /dev/null +++ b/packages/agents/README.md @@ -0,0 +1,15 @@ +# `@ocap/agents` + +A starting point for LLM integration + +## Installation + +`yarn add @ocap/agents` + +or + +`npm install @ocap/agents` + +## Contributing + +This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/ocap-kernel#readme). diff --git a/packages/agents/llm-provider/ollama-browser.js b/packages/agents/llm-provider/ollama-browser.js new file mode 100644 index 0000000000..37186b54d1 --- /dev/null +++ b/packages/agents/llm-provider/ollama-browser.js @@ -0,0 +1,3 @@ +/* eslint-disable import-x/unambiguous */ +// Re-exported for compatibility with Browserify. +module.exports = require('../dist/llm-provider/ollama-browser.cjs'); diff --git a/packages/agents/llm-provider/ollama.js b/packages/agents/llm-provider/ollama.js new file mode 100644 index 0000000000..9dea3c680f --- /dev/null +++ b/packages/agents/llm-provider/ollama.js @@ -0,0 +1,3 @@ +/* eslint-disable import-x/unambiguous */ +// Re-exported for compatibility with Browserify. +module.exports = require('../dist/llm-provider/ollama.cjs'); diff --git a/packages/agents/llm-provider/web-llm.js b/packages/agents/llm-provider/web-llm.js new file mode 100644 index 0000000000..a0334758f2 --- /dev/null +++ b/packages/agents/llm-provider/web-llm.js @@ -0,0 +1,3 @@ +/* eslint-disable import-x/unambiguous */ +// Re-exported for compatibility with Browserify. +module.exports = require('../dist/llm-provider/web-llm.cjs'); diff --git a/packages/agents/package.json b/packages/agents/package.json new file mode 100644 index 0000000000..93a1f46491 --- /dev/null +++ b/packages/agents/package.json @@ -0,0 +1,121 @@ +{ + "name": "@ocap/agents", + "version": "0.0.0", + "private": true, + "description": "A starting point for LLM integration", + "homepage": "https://github.com/MetaMask/ocap-kernel/tree/main/packages/agents#readme", + "bugs": { + "url": "https://github.com/MetaMask/ocap-kernel/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/MetaMask/ocap-kernel.git" + }, + "type": "module", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./llm-provider/ollama": { + "import": { + "types": "./dist/llm-provider/ollama.d.mts", + "default": "./dist/llm-provider/ollama.mjs" + }, + "require": { + "types": "./dist/llm-provider/ollama.d.cts", + "default": "./dist/llm-provider/ollama.cjs" + } + }, + "./llm-provider/ollama-browser": { + "import": { + "types": "./dist/llm-provider/ollama-browser.d.mts", + "default": "./dist/llm-provider/ollama-browser.mjs" + }, + "require": { + "types": "./dist/llm-provider/ollama-browser.d.cts", + "default": "./dist/llm-provider/ollama-browser.cjs" + } + }, + "./llm-provider/web-llm": { + "import": { + "types": "./dist/llm-provider/web-llm.d.mts", + "default": "./dist/llm-provider/web-llm.mjs" + }, + "require": { + "types": "./dist/llm-provider/web-llm.d.cts", + "default": "./dist/llm-provider/web-llm.cjs" + } + } + }, + "files": [ + "dist/", + "wasm/" + ], + "scripts": { + "build": "ts-bridge --project tsconfig.build.json --clean", + "build:docs": "typedoc", + "changelog:validate": "../../scripts/validate-changelog.sh @ocap/agents", + "clean": "rimraf --glob './*.tsbuildinfo' ./.eslintcache ./coverage ./dist", + "lint": "yarn lint:eslint && yarn lint:misc --check && yarn constraints && yarn lint:dependencies", + "lint:dependencies": "depcheck", + "lint:eslint": "eslint . --cache", + "lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write && yarn constraints --fix && yarn lint:dependencies", + "lint:misc": "prettier --no-error-on-unmatched-pattern '**/*.json' '**/*.md' '**/*.html' '!**/CHANGELOG.old.md' '**/*.yml' '!.yarnrc.yml' '!merged-packages/**' --ignore-path ../../.gitignore", + "ollama:pull": "node scripts/ollama-pull.js", + "publish:preview": "yarn npm publish --tag preview", + "test": "vitest run --config vitest.config.ts", + "test:clean": "yarn test --no-cache --coverage.clean", + "test:dev": "yarn test --mode development", + "test:verbose": "yarn test --reporter verbose", + "test:watch": "vitest --config vitest.config.ts" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.4", + "@metamask/auto-changelog": "^5.0.1", + "@metamask/eslint-config": "^14.0.0", + "@metamask/eslint-config-nodejs": "^14.0.0", + "@metamask/eslint-config-typescript": "^14.0.0", + "@ocap/cli": "workspace:^", + "@ocap/test-utils": "workspace:^", + "@ts-bridge/cli": "^0.6.3", + "@ts-bridge/shims": "^0.1.1", + "@types/node": "^22.13.1", + "@typescript-eslint/eslint-plugin": "^8.29.0", + "@typescript-eslint/parser": "^8.29.0", + "@typescript-eslint/utils": "^8.29.0", + "@vitest/eslint-plugin": "^1.1.44", + "depcheck": "^1.4.7", + "eslint": "^9.23.0", + "eslint-config-prettier": "^10.1.1", + "eslint-import-resolver-typescript": "^4.3.1", + "eslint-plugin-import-x": "^4.10.0", + "eslint-plugin-jsdoc": "^50.6.9", + "eslint-plugin-n": "^17.17.0", + "eslint-plugin-prettier": "^5.2.6", + "eslint-plugin-promise": "^7.2.1", + "prettier": "^3.5.3", + "rimraf": "^6.0.1", + "typedoc": "^0.28.1", + "typescript": "~5.8.2", + "typescript-eslint": "^8.29.0", + "vite": "^6.3.5", + "vitest": "^3.1.3" + }, + "engines": { + "node": "^20 || >=22" + }, + "dependencies": { + "@endo/far": "^1.1.11", + "@metamask/streams": "workspace:^", + "@mlc-ai/web-llm": "^0.2.79", + "ollama": "^0.5.16" + } +} diff --git a/packages/agents/scripts/ollama-pull.js b/packages/agents/scripts/ollama-pull.js new file mode 100644 index 0000000000..c1f5d9407c --- /dev/null +++ b/packages/agents/scripts/ollama-pull.js @@ -0,0 +1,38 @@ +import { Ollama } from 'ollama'; + +main().catch(console.error); + +/** + * The main function for the script. + */ +async function main() { + // Make a new ollama client. + const ollama = new Ollama({ host: 'http://localhost:11434' }); + + let nDots = 0; + const interval = setInterval(() => (nDots = (nDots + 1) % 4), 250); + try { + const model = process.argv[2]; + const labelDuring = `Pulling ${model}`; + const labelAfter = `Pulled ${model}`; + const makeProgress = (fraction) => + [ + labelDuring, + `${'.'.repeat(nDots)}${' '.repeat(4 - nDots)}`, + '[', + `${'='.repeat(Math.floor(fraction * 10))}`, + `${' '.repeat(10 - Math.floor(fraction * 10))}`, + ']', + ` ${Math.floor(fraction * 100)}%`, + ].join(''); + const result = await ollama.pull({ model, stream: true }); + for await (const chunk of result) { + process.stdout.write(`${makeProgress(chunk.completed / chunk.total)}\r`); + } + console.log( + `${labelAfter} ${' '.repeat(15 + labelDuring.length - labelAfter.length)}`, + ); + } finally { + clearInterval(interval); + } +} diff --git a/packages/agents/src/constants.ts b/packages/agents/src/constants.ts new file mode 100644 index 0000000000..d1ddb5f800 --- /dev/null +++ b/packages/agents/src/constants.ts @@ -0,0 +1,12 @@ +/** + * The default archetypes to use when no archetype is provided. LLM service + * providers are not required to provide every model recorded here. The cost of + * this freedom is they should declare their own default archetype values. + */ +export const defaultArchetypes = { + general: 'llama3.2:latest', + fast: 'llama3.2:latest', + thinker: 'deepseek-r1:3b', + 'code:writer': 'llama3.2:latest', + 'code:reader': 'llama3.2:latest', +} as const; diff --git a/packages/agents/src/index.ts b/packages/agents/src/index.ts new file mode 100644 index 0000000000..d2ef0c777d --- /dev/null +++ b/packages/agents/src/index.ts @@ -0,0 +1,11 @@ +export { makeLlmService } from './llm-service.ts'; +export type { + InstanceConfig, + LlmInstance, + LlmProvider, + Message, + ModelArchetype, + ModelConfig, +} from './types.ts'; +export { defaultArchetypes } from './constants.ts'; +export { parseInstanceConfig } from './utils.ts'; diff --git a/packages/agents/src/llm-provider/ollama-browser.ts b/packages/agents/src/llm-provider/ollama-browser.ts new file mode 100644 index 0000000000..80663907e6 --- /dev/null +++ b/packages/agents/src/llm-provider/ollama-browser.ts @@ -0,0 +1,21 @@ +import { Ollama } from 'ollama/browser'; + +import { makeOllamaBaseLlmProvider } from './ollama-shared.ts'; +import type { OllamaFace, OllamaLlmProviderOptions } from './ollama-shared.ts'; +import type { LlmProvider } from '../types.ts'; + +/** + * Make an LLM provider that uses the `ollama/browser` import from ollama. + * + * @see https://ollama.com/ + * + * @param ollama - The Ollama instance to use. + * @param options - The options for the LLM provider. + * @returns An LLM provider that uses an `ollama/browser` client. + */ +export function makeOllamaBrowserLlmProvider( + ollama: Ollama, + options: OllamaLlmProviderOptions = {}, +): LlmProvider { + return makeOllamaBaseLlmProvider(ollama as unknown as OllamaFace, options); +} diff --git a/packages/agents/src/llm-provider/ollama-shared.ts b/packages/agents/src/llm-provider/ollama-shared.ts new file mode 100644 index 0000000000..c0784ce86a --- /dev/null +++ b/packages/agents/src/llm-provider/ollama-shared.ts @@ -0,0 +1,106 @@ +import type { + ModelArchetype, + InstanceConfig, + LlmInstance, + LlmProvider, + Message, + ModelConfig, +} from '../types.ts'; +import { parseInstanceConfig } from '../utils.ts'; + +// Exported for testing. +export const defaultArchetypes: Record = { + general: 'llama3.2:latest', + fast: 'llama3.2:latest', + thinker: 'llama3.2:latest', + 'code:writer': 'llama3.2:latest', + 'code:reader': 'llama3.2:latest', +}; + +export type OllamaLlmProviderOptions = { + archetypes?: Partial>; +}; + +type StreamedResponse = Promise>; + +/** + * The interface this library depends upon from `ollama[/browser]`. + */ +export type OllamaFace = { + generate: (params: { + prompt: string; + stream: true; + }) => StreamedResponse<{ response: string }>; + chat: (params: { + messages: Message[]; + stream: true; + }) => StreamedResponse<{ message: { content: string } }>; +}; + +/** + * Make an Ollama LLM provider. + * + * @param ollama - The Ollama instance to use. + * @param options - The options for the Ollama LLM provider. + * @param options.archetypes - The archetypes to use. + * @returns An LlmProvider which uses the provided ollama instance. + */ +export function makeOllamaBaseLlmProvider( + ollama: OllamaFace, + options: OllamaLlmProviderOptions = {}, +): LlmProvider { + const archetypes = { ...defaultArchetypes, ...options.archetypes }; + return { + /** + * Get the configuration for an archetype. + * + * @param archetype - The archetype to get the configuration for. + * @returns The configuration for the archetype. + */ + getArchetypeConfig(archetype: ModelArchetype): ModelConfig { + return { model: archetypes[archetype] }; + }, + /** + * Make an LLM instance. + * + * @param config - The configuration for the LLM instance. + * @returns An LLM instance. + */ + async makeInstance(config: InstanceConfig): Promise { + const requestParams = { + ...parseInstanceConfig(config, archetypes), + stream: true, + } as const; + return { + /** + * Generate text from the LLM. + * + * @param prompt - The prompt to generate text from. + * @returns A generator of text chunks. + */ + generate: async (prompt: string) => { + const response = await ollama.generate({ prompt, ...requestParams }); + return (async function* () { + for await (const chunk of response) { + yield chunk.response; + } + })(); + }, + /** + * Chat with the LLM. + * + * @param messages - The messages to chat with. + * @returns A generator of message chunks. + */ + chat: async (messages: Message[]) => { + const response = await ollama.chat({ messages, ...requestParams }); + return (async function* () { + for await (const chunk of response) { + yield chunk.message.content; + } + })(); + }, + }; + }, + }; +} diff --git a/packages/agents/src/llm-provider/ollama.ts b/packages/agents/src/llm-provider/ollama.ts new file mode 100644 index 0000000000..657e03896d --- /dev/null +++ b/packages/agents/src/llm-provider/ollama.ts @@ -0,0 +1,19 @@ +import { Ollama } from 'ollama'; + +import type { LlmProvider } from '../types.ts'; +import { makeOllamaBaseLlmProvider } from './ollama-shared.ts'; +import type { OllamaFace, OllamaLlmProviderOptions } from './ollama-shared.ts'; + +/** + * Make an LLM provider that uses the ollama library. + * + * @param ollama - The Ollama instance to use. + * @param options - The options for the LLM provider. + * @returns An LLM provider that uses the Ollama library. + */ +export function makeOllamaLlmProvider( + ollama: Ollama, + options: OllamaLlmProviderOptions = {}, +): LlmProvider { + return makeOllamaBaseLlmProvider(ollama as unknown as OllamaFace, options); +} diff --git a/packages/agents/src/llm-provider/web-llm.ts b/packages/agents/src/llm-provider/web-llm.ts new file mode 100644 index 0000000000..d4c964f3c5 --- /dev/null +++ b/packages/agents/src/llm-provider/web-llm.ts @@ -0,0 +1,94 @@ +import { CreateMLCEngine } from '@mlc-ai/web-llm'; +import type { + MLCEngineConfig, + ChatCompletionMessageParam, +} from '@mlc-ai/web-llm'; + +import type { + InstanceConfig, + LlmInstance, + LlmProvider, + ModelArchetype, + Message, + ModelConfig, +} from '../types.ts'; +import { parseInstanceConfig } from '../utils.ts'; + +const defaultArchetypes: Record = { + general: 'llama3.2:latest', + fast: 'llama3.2:latest', + thinker: 'deepseek-r1:3b', + 'code:writer': 'llama3.2:latest', + 'code:reader': 'llama3.2:latest', +}; + +export type MlcLlmProviderOptions = { + archetypes?: Partial>; + engineConfig?: MLCEngineConfig; +}; + +/** + * Make an LLM provider that uses the `@mlc-ai/web-llm` library. + * + * @param options - The options to configure the mlc-ai/web-llm engine. + * @param options.archetypes - The archetypes to use. + * @returns An LLM provider that uses the `@mlc-ai/web-llm` library. + */ +export function makeMlcLlmProvider( + options: MlcLlmProviderOptions = {}, +): LlmProvider { + const archetypes = { ...defaultArchetypes, ...options.archetypes }; + const { engineConfig = {} } = options; + + return { + getArchetypeConfig(archetype: ModelArchetype): ModelConfig { + return { model: archetypes[archetype] }; + }, + async makeInstance(config: InstanceConfig): Promise { + const { model } = parseInstanceConfig(config, archetypes); + const engine = await CreateMLCEngine(model, engineConfig); + const requestParams = { + stream: true, + // The library is written in parselmouth. + /* eslint-disable @typescript-eslint/naming-convention */ + stream_options: { include_usage: false }, + temperature: 0.6, + top_p: 0.7, + /* eslint-enable @typescript-eslint/naming-convention */ + } as const; + return { + generate: async (prompt: string): Promise> => { + const response = await engine.completions.create({ + prompt, + ...requestParams, + }); + return (async function* () { + for await (const chunk of response) { + const content = chunk.choices[0]?.text; + if (!content) { + return; + } + yield content; + } + })(); + }, + + chat: async (messages: Message[]): Promise> => { + const response = await engine.chat.completions.create({ + messages: messages as ChatCompletionMessageParam[], + ...requestParams, + }); + return (async function* () { + for await (const chunk of response) { + const content = chunk.choices[0]?.delta.content; + if (!content) { + return; + } + yield content; + } + })(); + }, + }; + }, + }; +} diff --git a/packages/agents/src/llm-service.test.ts b/packages/agents/src/llm-service.test.ts new file mode 100644 index 0000000000..477d8f9d88 --- /dev/null +++ b/packages/agents/src/llm-service.test.ts @@ -0,0 +1,73 @@ +import '@ocap/test-utils/mock-endoify'; +import { expect, describe, it, beforeEach, vi } from 'vitest'; + +import { makeLlmService } from './llm-service.ts'; +import type { LlmProvider } from './types.ts'; + +const mocks = vi.hoisted(() => ({ + makeFarGenerator: vi.fn(), +})); + +describe('llm', () => { + let llmProvider: LlmProvider; + + beforeEach(async () => { + llmProvider = { + makeInstance: async () => ({ + generate: vi.fn().mockResolvedValue({ + [Symbol.asyncIterator]: vi.fn(), + }), + chat: vi.fn().mockResolvedValue({ + [Symbol.asyncIterator]: vi.fn(), + }), + }), + getArchetypeConfig: () => ({ model: 'test' }), + }; + }); + + vi.mock('ollama/browser', () => ({ + Ollama: vi.fn(() => ({ + generate: vi.fn().mockResolvedValue({ + [Symbol.asyncIterator]: vi.fn(), + }), + chat: vi.fn().mockResolvedValue({ + [Symbol.asyncIterator]: vi.fn(), + }), + })), + })); + + vi.mock('@metamask/streams/vat', () => ({ + makeFarGenerator: mocks.makeFarGenerator, + })); + + vi.mock('@endo/far', () => ({ + E: vi.fn((obj) => obj), + Far: vi.fn((_name, methods) => ({ ...methods })), + })); + + describe('makeLlmService', () => { + it('should return an object with generate and chat methods', async () => { + const llmService = makeLlmService(llmProvider); + const llm = await llmService.makeInstance({ archetype: 'fast' }); + expect(llm).toMatchObject({ + generate: expect.any(Function), + chat: expect.any(Function), + }); + }); + + it.each([ + ['generate', ''], + ['chat', []], + ])( + 'should promise a FarGenerator from its %s method', + async (method, args) => { + const llmService = makeLlmService(llmProvider); + const llm = await llmService.makeInstance({ archetype: 'fast' }); + // @ts-expect-error The underlying ollama library is mocked in these tests + const result = await llm[method as keyof typeof llm](args); + expect(mocks.makeFarGenerator).toHaveBeenCalledOnce(); + expect(mocks.makeFarGenerator.mock.calls?.[0]).toMatchObject([result]); + }, + ); + }); +}); diff --git a/packages/agents/src/llm-service.ts b/packages/agents/src/llm-service.ts new file mode 100644 index 0000000000..62d9e45566 --- /dev/null +++ b/packages/agents/src/llm-service.ts @@ -0,0 +1,43 @@ +import { E, Far } from '@endo/far'; +import { makeFarGenerator } from '@metamask/streams/vat'; + +import type { Message, InstanceConfig, LlmProvider } from './types.ts'; + +/** + * Connect to a local LLM instance. + * + * @param llmProvider - The LLM provider to use. + * @returns An LLM instance. + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export function makeLlmService(llmProvider: LlmProvider) { + return Far('LlmService', { + makeInstance: async (config: InstanceConfig) => { + const instance = await llmProvider.makeInstance(config); + return Far('LlmInstance', { + /** + * Generate a response from the LLM. + * + * @param prompt - The prompt to generate a response for. + * @returns An iterator that yields the response. + */ + + generate: async (prompt: string) => { + const response = await instance.generate(prompt); + return makeFarGenerator(response[Symbol.asyncIterator]()); + }, + /** + * Chat with the LLM. + * + * @param messages - The messages to chat with. + * @returns An iterator that yields the response. + */ + + chat: async (messages: Message[]) => { + const response = await E(instance).chat(messages); + return makeFarGenerator(response[Symbol.asyncIterator]()); + }, + }); + }, + }); +} diff --git a/packages/agents/src/types.ts b/packages/agents/src/types.ts new file mode 100644 index 0000000000..94916555f3 --- /dev/null +++ b/packages/agents/src/types.ts @@ -0,0 +1,61 @@ +// TODO: use @metamask/superstruct + +import type { defaultArchetypes } from './constants.ts'; + +export type ModelName = string; +export type ModelConfig = { + model: ModelName; + thinking?: boolean; + contextWindowSize?: number; +}; + +export type Message = { role: string; content: string }; + +/** + * The recognized language model archetypes provide a loose categorization of + * models by capability and behavior. + */ +export type ModelArchetype = keyof typeof defaultArchetypes; + +/** + * The interface that language model providers must implement to be used by the + * agents package. + * The generate method is used to access raw completion results. + * The chat method is used to access chat-like interactions, which benefit from + * the context of previous messages remaining loaded in memory. + * Both methods are expected to stream results as they are generated, but a + * vexed provider may yield a single chunk containing the entire response. + */ +export type LlmInstance = { + generate: (prompt: string) => Promise>; + chat: (messages: Message[]) => Promise>; +}; + +/** + * In some cases, we may be able to address a model by name. But having seen a + * `vicuna-7b-instruct-distil-qwen-quantized-version-1.2-8k` in the wild, we + * should not expect different providers to map the same name to the same model. + * + * Providers are required to implement each archetype, but they are not required + * to do so well; they may return the same model for every archetype. The + * archetype is a hint to the provider what kind of context the model will be + * used in. Supposing the provider wishes their models to provide good results, + * an opinionated implementation of each archetype + */ +export type InstanceConfig = + | { + model: ModelName; + archetype?: never; + } + | { + model?: never; + archetype: ModelArchetype; + }; + +/** + * A provider is a factory for language model instances. + */ +export type LlmProvider = { + makeInstance: (config: InstanceConfig) => Promise; + getArchetypeConfig: (archetype: ModelArchetype) => ModelConfig; +}; diff --git a/packages/agents/src/utils.ts b/packages/agents/src/utils.ts new file mode 100644 index 0000000000..b6d15a9a34 --- /dev/null +++ b/packages/agents/src/utils.ts @@ -0,0 +1,36 @@ +import type { InstanceConfig, ModelArchetype, ModelConfig } from './types.ts'; + +/** + * Extract the model name from an instance config. + * + * @param config - The instance config to parse. + * @param archetypes - The archetypes to use to map archetypes to model names. + * @returns The model name as `{ model }`. + */ +export const parseInstanceConfig = ( + config: InstanceConfig, + archetypes: Record, +): ModelConfig => { + if (config.model && config.archetype) { + throw new Error('Cannot specify both model and archetype'); + } + if (!config.model && !config.archetype) { + throw new Error('Must specify either model or archetype'); + } + if (config.model) { + if (typeof config.model !== 'string') { + throw new Error('Model must be a string'); + } + return { model: config.model }; + } + if (config.archetype) { + if (typeof config.archetype !== 'string') { + throw new Error('Archetype must be a string'); + } + if (!archetypes[config.archetype]) { + throw new Error(`Archetype ${config.archetype} is not supported`); + } + return { model: archetypes[config.archetype] }; + } + throw new Error('Invalid instance config', { cause: config }); +}; diff --git a/packages/agents/tsconfig.build.json b/packages/agents/tsconfig.build.json new file mode 100644 index 0000000000..4dc75131f7 --- /dev/null +++ b/packages/agents/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.packages.build.json", + "compilerOptions": { + "baseUrl": "./", + "lib": ["ES2022"], + "outDir": "./dist", + "rootDir": "./src", + "types": ["node"] + }, + "references": [{ "path": "../streams/tsconfig.build.json" }], + "files": [], + "include": ["./src", "./wasm"] +} diff --git a/packages/agents/tsconfig.json b/packages/agents/tsconfig.json new file mode 100644 index 0000000000..7b357b253f --- /dev/null +++ b/packages/agents/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.packages.json", + "compilerOptions": { + "baseUrl": "./", + "lib": ["ES2022"], + "types": ["vitest", "node"] + }, + "references": [ + { "path": "../test-utils" }, + { "path": "../nodejs" }, + { "path": "../streams" } + ], + "include": [ + "../../vitest.config.ts", + "./src", + "./wasm", + "./vite.config.ts", + "./vitest.config.ts" + ] +} diff --git a/packages/agents/typedoc.json b/packages/agents/typedoc.json new file mode 100644 index 0000000000..f8eb78ae1a --- /dev/null +++ b/packages/agents/typedoc.json @@ -0,0 +1,8 @@ +{ + "entryPoints": [], + "excludePrivate": true, + "hideGenerator": true, + "out": "docs", + "tsconfig": "./tsconfig.build.json", + "projectDocuments": ["documents/*.md"] +} diff --git a/packages/agents/vitest.config.ts b/packages/agents/vitest.config.ts new file mode 100644 index 0000000000..97f9173f8b --- /dev/null +++ b/packages/agents/vitest.config.ts @@ -0,0 +1,16 @@ +import { mergeConfig } from '@ocap/test-utils/vitest-config'; +import { defineConfig, defineProject } from 'vitest/config'; + +import defaultConfig from '../../vitest.config.ts'; + +export default defineConfig((args) => { + return mergeConfig( + args, + defaultConfig, + defineProject({ + test: { + name: 'agents', + }, + }), + ); +}); diff --git a/packages/agents/wasm/TinyLlama-1.1B-Chat-v0.4-q4f32_1-ctx2k_cs1k-webgpu.wasm b/packages/agents/wasm/TinyLlama-1.1B-Chat-v0.4-q4f32_1-ctx2k_cs1k-webgpu.wasm new file mode 100644 index 0000000000..5d57526178 Binary files /dev/null and b/packages/agents/wasm/TinyLlama-1.1B-Chat-v0.4-q4f32_1-ctx2k_cs1k-webgpu.wasm differ diff --git a/packages/cli/src/commands/bundle.ts b/packages/cli/src/commands/bundle.ts index 7dc18ae3ff..cc691de3f1 100644 --- a/packages/cli/src/commands/bundle.ts +++ b/packages/cli/src/commands/bundle.ts @@ -1,5 +1,6 @@ import '@endo/init'; import endoBundleSource from '@endo/bundle-source'; +import { importHook } from '@metamask/kernel-utils/import-hook'; import { Logger } from '@metamask/logger'; import { glob } from 'glob'; import { writeFile } from 'node:fs/promises'; @@ -30,8 +31,10 @@ export async function bundleFile( const { logger, targetPath } = options; const sourceFullPath = resolve(sourcePath); const bundlePath = targetPath ?? resolveBundlePath(sourceFullPath); + const bundleOptions = { moduleFormat: 'endoZipBase64', importHook }; try { - const bundle = await endoBundleSource(sourceFullPath); + // @ts-expect-error no overload matches + const bundle = await endoBundleSource(sourceFullPath, bundleOptions); const bundleContent = JSON.stringify(bundle); await writeFile(bundlePath, bundleContent); logger.info(`wrote ${bundlePath}: ${new Blob([bundleContent]).size} bytes`); diff --git a/packages/extension/package.json b/packages/extension/package.json index 3a06c24f2f..5b9f0a142d 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -52,6 +52,7 @@ "@metamask/ocap-kernel": "workspace:^", "@metamask/streams": "workspace:^", "@metamask/utils": "^11.4.0", + "@ocap/agents": "workspace:^", "react": "^17.0.2", "react-dom": "^17.0.2", "ses": "^1.13.0" diff --git a/packages/extension/src/vats/sample-vat.js b/packages/extension/src/vats/sample-vat.js index 7653ae74a0..17aa8fe26a 100644 --- a/packages/extension/src/vats/sample-vat.js +++ b/packages/extension/src/vats/sample-vat.js @@ -4,15 +4,15 @@ import { Far } from '@endo/marshal'; /** * Build function for generic test vat. * - * @param {unknown} _vatPowers - Special powers granted to this vat (not used here). + * @param {unknown} vatPowers - Special powers granted to this vat. + * @param {unknown} vatPowers.llm - An llm service. * @param {unknown} parameters - Initialization parameters from the vat's config object. * @param {unknown} _baggage - Root of vat's persistent state (not used here). * @returns {unknown} The root object for the new vat. */ -export function buildRootObject(_vatPowers, parameters, _baggage) { +export function buildRootObject({ llm }, parameters, _baggage) { const name = parameters?.name ?? 'anonymous'; console.log(`buildRootObject "${name}"`); - return Far('root', { async bootstrap(vats) { console.log(`vat ${name} is bootstrap`); @@ -26,5 +26,6 @@ export function buildRootObject(_vatPowers, parameters, _baggage) { console.log(message); return message; }, + makeInstance: (archetype = 'fast') => llm.makeInstance({ archetype }), }); } diff --git a/packages/kernel-browser-runtime/package.json b/packages/kernel-browser-runtime/package.json index 4afbf20621..92451c355d 100644 --- a/packages/kernel-browser-runtime/package.json +++ b/packages/kernel-browser-runtime/package.json @@ -76,6 +76,7 @@ "@metamask/streams": "workspace:^", "@metamask/superstruct": "^3.2.1", "@metamask/utils": "^11.4.0", + "@ocap/agents": "workspace:^", "nanoid": "^5.1.5", "ses": "^1.13.0" }, @@ -109,7 +110,9 @@ "typescript-eslint": "^8.29.0", "vite": "^6.3.5", "vite-plugin-checker": "^0.9.1", + "vite-plugin-node-polyfills": "^0.24.0", "vite-plugin-static-copy": "^2.3.0", + "vite-plugin-wasm": "^3.5.0", "vitest": "^3.1.3" }, "engines": { diff --git a/packages/kernel-browser-runtime/src/vat/cache-polyfill.ts b/packages/kernel-browser-runtime/src/vat/cache-polyfill.ts new file mode 100644 index 0000000000..5c6f8edd93 --- /dev/null +++ b/packages/kernel-browser-runtime/src/vat/cache-polyfill.ts @@ -0,0 +1,129 @@ +type KnownRemotes = Record Promise>; + +class FileUrlCache { + readonly #cache: Map; + + readonly #knownRemotes: KnownRemotes; + + constructor(knownRemotes: KnownRemotes) { + this.#cache = new Map(); + this.#knownRemotes = knownRemotes; + } + + isValidFileUrl(url: string) { + const fileUrlPattern = /^file:\/\/.*$/u; + return fileUrlPattern.test(url); + } + + isKnownRemote(url: string): url is keyof KnownRemotes { + return url in this.#knownRemotes; + } + + async fetchKnownRemote(url: string): Promise { + const response = await this.#knownRemotes[url]?.(); + if (!response) { + throw new Error(`Unknown remote: ${url}`); + } + return new Response(response as ArrayBuffer); + } + + // Helper: Normalize the URL (to ensure consistency) + normalizeUrl(url: string | URL) { + try { + return new URL(url).href; + } catch { + throw new Error(`Invalid URL: ${url}`); + } + } + + // Match a request in the cache + async match(request: string | Request) { + const url = this.normalizeUrl((request as Request).url ?? request); + if (this.isKnownRemote(url)) { + return await this.fetchKnownRemote(url); + } + if (!this.isValidFileUrl(url)) { + return undefined; + } + return this.#cache.get(url) || undefined; + } + + // Match all requests in the cache + async matchAll(request: string | Request) { + if (!request) { + // Return all cached responses if no request is provided + return Array.from(this.#cache.values()); + } + const url = this.normalizeUrl((request as Request).url ?? request); + if (this.isKnownRemote(url)) { + return [await this.fetchKnownRemote(url)]; + } + if (!this.isValidFileUrl(url)) { + return []; + } + return this.#cache.has(url) ? [this.#cache.get(url)] : []; + } + + // Add a single request to the cache + async add(request: string | Request) { + const url = this.normalizeUrl((request as Request).url ?? request); + if (this.isKnownRemote(url)) { + return; + } + if (!this.isValidFileUrl(url)) { + throw new Error( + `Invalid URL: Only 'file://' URLs are allowed. Got: ${url}`, + ); + } + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to fetch: ${url}`); + } + this.#cache.set(url, response.clone()); + } + + // Add multiple requests to the cache + async addAll(requests: (string | Request)[]) { + const promises = requests.map(async (request) => this.add(request)); + await Promise.all(promises); + } + + // Put a request-response pair into the cache + async put(request: string | Request, response: Response) { + const url = this.normalizeUrl((request as Request).url ?? request); + if (this.isKnownRemote(url)) { + return; + } + if (!this.isValidFileUrl(url)) { + throw new Error(`Invalid URL: Only 'file://' URLs are allowed.`); + } + this.#cache.set(url, response.clone()); + } + + // Delete a request from the cache + async delete(request: string | Request) { + const url = this.normalizeUrl((request as Request).url ?? request); + if (this.isKnownRemote(url)) { + return false; + } + if (!this.isValidFileUrl(url)) { + return false; + } + return this.#cache.delete(url); + } + + // Get all keys (requests) in the cache + async keys() { + return [ + ...Object.keys(this.#knownRemotes), + ...Array.from(this.#cache.keys()), + ].map((url) => new Request(url)); + } +} + +export const makeCaches = (knownRemotes: KnownRemotes) => { + const cache = new FileUrlCache(knownRemotes); + return { + open: async (_cache: string) => cache, + }; +}; diff --git a/packages/kernel-browser-runtime/src/vat/iframe.ts b/packages/kernel-browser-runtime/src/vat/iframe.ts index 36183575bd..fb27071084 100644 --- a/packages/kernel-browser-runtime/src/vat/iframe.ts +++ b/packages/kernel-browser-runtime/src/vat/iframe.ts @@ -6,11 +6,19 @@ import { MessagePortDuplexStream, receiveMessagePort, } from '@metamask/streams/browser'; +import { makeMlcLlmProvider } from '@ocap/agents/llm-provider/web-llm'; + +import { makeCaches } from './cache-polyfill.ts'; +import webLlmConfigs from './web-llm-configs.ts'; const logger = new Logger('vat-iframe'); main().catch(logger.error); +Object.defineProperty(globalThis, 'caches', { + value: makeCaches(webLlmConfigs), +}); + /** * The main function for the iframe. */ @@ -28,11 +36,21 @@ async function main(): Promise { const urlParams = new URLSearchParams(window.location.search); const vatId = urlParams.get('vatId') ?? 'unknown'; + const llamaTinyLatest = 'TinyLlama-1.1B-Chat-v0.4-q4f32_1-MLC'; + // eslint-disable-next-line no-new new VatSupervisor({ id: vatId, kernelStream, logger: logger.subLogger(vatId), + vatPowers: { + llm: makeMlcLlmProvider({ + archetypes: { + general: llamaTinyLatest, + fast: llamaTinyLatest, + }, + }), + }, }); logger.info('VatSupervisor initialized with vatId:', vatId); diff --git a/packages/kernel-browser-runtime/src/vat/web-llm-configs.ts b/packages/kernel-browser-runtime/src/vat/web-llm-configs.ts new file mode 100644 index 0000000000..9cd80b6f3c --- /dev/null +++ b/packages/kernel-browser-runtime/src/vat/web-llm-configs.ts @@ -0,0 +1,96 @@ +import { stringify } from '@metamask/kernel-utils'; +import '../../../agents/wasm/TinyLlama-1.1B-Chat-v0.4-q4f32_1-ctx2k_cs1k-webgpu.wasm'; + +const tinyLlama = 'TinyLlama-1.1B-Chat-v0.4-q4f32_1'; +const huggingFace = 'https://huggingface.co/mlc-ai'; +const github = + 'https://raw.githubusercontent.com/mlc-ai/binary-mlc-llm-libs/main/web-llm-models/v0_2_48'; +const context = 'ctx2k_cs1k-webgpu'; +const root = '../../agents/wasm'; + +export default { + // @mlc-ai/web-llm is a pythonic library, so the names are snake_case. + /* eslint-disable @typescript-eslint/naming-convention */ + [`${huggingFace}/${tinyLlama}-MLC/resolve/main/mlc-chat-config.json`]: + async () => + ({ + model_type: 'llama', + quantization: 'q4f32_1', + model_config: { + hidden_size: 2048, + intermediate_size: 5632, + num_attention_heads: 32, + num_hidden_layers: 22, + rms_norm_eps: 1e-5, + vocab_size: 32003, + position_embedding_base: 10000.0, + context_window_size: 2048, + prefill_chunk_size: 2048, + num_key_value_heads: 4, + head_dim: 64, + tensor_parallel_shards: 1, + max_batch_size: 80, + }, + vocab_size: 32003, + context_window_size: 2048, + sliding_window_size: -1, + prefill_chunk_size: 2048, + attention_sink_size: -1, + tensor_parallel_shards: 1, + max_batch_size: 80, + mean_gen_len: 128, + max_gen_len: 512, + shift_fill_factor: 0.3, + temperature: 0.7, + repetition_penalty: 1.0, + top_p: 0.95, + conv_template: { + name: 'chatml', + system_template: '<|im_start|>system\n{system_message}', + system_message: + 'A conversation between a user and an LLM-based AI assistant. The assistant gives helpful and honest answers.', + add_role_after_system_message: true, + roles: { + user: '<|im_start|>user', + assistant: '<|im_start|>assistant', + }, + role_templates: { + user: '{user_message}', + assistant: '{assistant_message}', + tool: '{tool_message}', + }, + messages: [], + seps: ['<|im_end|>\n'], + role_content_sep: '\n', + role_empty_sep: '\n', + stop_str: ['<|im_end|>'], + stop_token_ids: [2], + function_string: '', + use_function_calling: false, + }, + pad_token_id: 0, + bos_token_id: 1, + eos_token_id: 2, + tokenizer_files: [ + 'tokenizer.model', + 'tokenizer.json', + 'added_tokens.json', + 'tokenizer_config.json', + ], + version: '0.1.0', + /* eslint-enable @typescript-eslint/naming-convention */ + }) as const, + [`${github}/${tinyLlama}-${context}.wasm`]: (() => { + let cached; + return async () => { + const url = `${root}/${tinyLlama}-${context}.wasm`; + try { + // eslint-disable-next-line require-atomic-updates + cached ??= await fetch(url); + } catch (problem: unknown) { + throw new Error(`Failed to fetch ${url}: ${stringify(problem)}`); + } + return cached; + }; + })(), +} as const; diff --git a/packages/kernel-browser-runtime/tsconfig.build.json b/packages/kernel-browser-runtime/tsconfig.build.json index 4a72d8bca5..da98586797 100644 --- a/packages/kernel-browser-runtime/tsconfig.build.json +++ b/packages/kernel-browser-runtime/tsconfig.build.json @@ -8,6 +8,7 @@ "types": ["ses"] }, "references": [ + { "path": "../agents/tsconfig.build.json" }, { "path": "../kernel-errors/tsconfig.build.json" }, { "path": "../kernel-rpc-methods/tsconfig.build.json" }, { "path": "../kernel-store/tsconfig.build.json" }, diff --git a/packages/kernel-browser-runtime/tsconfig.json b/packages/kernel-browser-runtime/tsconfig.json index 1e6198a5eb..68f7739799 100644 --- a/packages/kernel-browser-runtime/tsconfig.json +++ b/packages/kernel-browser-runtime/tsconfig.json @@ -6,6 +6,7 @@ "types": ["ses", "vitest"] }, "references": [ + { "path": "../agents" }, { "path": "../kernel-errors" }, { "path": "../kernel-rpc-methods" }, { "path": "../kernel-shims" }, diff --git a/packages/kernel-browser-runtime/vite.config.ts b/packages/kernel-browser-runtime/vite.config.ts index 679e70c6ab..304391b28b 100644 --- a/packages/kernel-browser-runtime/vite.config.ts +++ b/packages/kernel-browser-runtime/vite.config.ts @@ -6,8 +6,10 @@ import type { PreludeRecord } from '@ocap/vite-plugins'; import path from 'path'; import { defineConfig } from 'vite'; import { checker as viteChecker } from 'vite-plugin-checker'; +import { nodePolyfills } from 'vite-plugin-node-polyfills'; import { viteStaticCopy } from 'vite-plugin-static-copy'; import type { Target } from 'vite-plugin-static-copy'; +import wasm from 'vite-plugin-wasm'; // The importing files end up in `.//`, and we statically copy `endoify.js` // to `./`. @@ -24,6 +26,7 @@ export const trustedPreludes: PreludeRecord = { */ const staticCopyTargets: readonly (string | Target)[] = [ '../../kernel-shims/dist/endoify.js', + '../../agents/wasm/TinyLlama-1.1B-Chat-v0.4-q4f32_1-ctx2k_cs1k-webgpu.wasm', ]; // We will only run this where it's available, but ESLint doesn't know that @@ -96,6 +99,7 @@ export default defineConfig(({ mode }) => { plugins: [ jsTrustedPrelude({ trustedPreludes }), + wasm(), viteStaticCopy({ targets: staticCopyTargets.map((src) => typeof src === 'string' ? { src, dest: './' } : src, @@ -115,6 +119,9 @@ export default defineConfig(({ mode }) => { !fileName.includes('sqlite3-opfs-async-proxy'), expectedCount: 2, }), + nodePolyfills({ + include: ['fs', 'path'], + }), ], }; }); diff --git a/packages/kernel-test/package.json b/packages/kernel-test/package.json index 06eb4c2733..5ebe654beb 100644 --- a/packages/kernel-test/package.json +++ b/packages/kernel-test/package.json @@ -38,6 +38,7 @@ "lint:misc": "prettier --no-error-on-unmatched-pattern '**/*.json' '**/*.md' '**/*.html' '!**/CHANGELOG.old.md' '**/*.yml' '!.yarnrc.yml' '!merged-packages/**' --ignore-path ../../.gitignore", "publish:preview": "yarn npm publish --tag preview", "test": "vitest run --config vitest.config.ts", + "test:agents": "TEST_AGENTS=true yarn test", "test:clean": "yarn test --no-cache --coverage.clean", "test:dev": "yarn test --mode development", "test:verbose": "yarn test --reporter verbose", @@ -58,7 +59,9 @@ "@metamask/ocap-kernel": "workspace:^", "@metamask/streams": "workspace:^", "@metamask/utils": "^11.4.0", - "@ocap/nodejs": "workspace:^" + "@ocap/agents": "workspace:^", + "@ocap/nodejs": "workspace:^", + "ollama": "^0.5.16" }, "devDependencies": { "@arethetypeswrong/cli": "^0.17.4", diff --git a/packages/kernel-test/src/agents.test.ts b/packages/kernel-test/src/agents.test.ts new file mode 100644 index 0000000000..c9ccd654ec --- /dev/null +++ b/packages/kernel-test/src/agents.test.ts @@ -0,0 +1,41 @@ +import type { Kernel } from '@metamask/ocap-kernel'; +import { kunser } from '@metamask/ocap-kernel'; +import { makeKernel } from '@ocap/nodejs'; +import { describe, it, expect, beforeEach } from 'vitest'; + +import { getBundleSpec } from './utils.ts'; + +describe('agents', () => { + let kernel: Kernel; + + beforeEach(async () => { + const { port2: port } = new MessageChannel(); + kernel = await makeKernel({ port }); + }); + + // eslint-disable-next-line n/no-process-env + it.runIf(process.env.TEST_AGENTS === 'true')( + 'should be able to generate text', + { + timeout: 5_000, + }, + async () => { + console.log('Starting test'); + const prompt = 'Count to 6. Do not use any words.'; + const result = await kernel.launchSubcluster({ + bootstrap: 'user', + vats: { + user: { + bundleSpec: getBundleSpec('agents-user'), + parameters: { name: 'Alice', prompt }, + }, + }, + }); + expect(result).toBeDefined(); + console.log('Result:', result); + const llmResponse = kunser(result as Parameters[0]); + expect(typeof llmResponse).toBe('string'); + expect(llmResponse).toMatch(/1[^0-9]*2[^0-9]*3[^0-9]*4[^0-9]*5/u); + }, + ); +}); diff --git a/packages/kernel-test/src/vats/agents-user.js b/packages/kernel-test/src/vats/agents-user.js new file mode 100644 index 0000000000..017c30df5f --- /dev/null +++ b/packages/kernel-test/src/vats/agents-user.js @@ -0,0 +1,45 @@ +import { E, Far } from '@endo/far'; +// ESLint's import-x/no-unresolved rule with commonjs:false doesn't support subpath exports +// eslint-disable-next-line import-x/no-unresolved +import { makeEventualIterator } from '@metamask/streams/vat'; +// eslint-disable-next-line import-x/no-unresolved +import { makeLlmService } from '@ocap/agents'; +import { makeOllamaBrowserLlmProvider } from '@ocap/agents/llm-provider/ollama-browser'; +// eslint-disable-next-line import-x/no-unresolved +import { Ollama } from 'ollama/browser'; + +const ollama = new Ollama(); + +/** + * Build the root object for a synthetic user. + * + * @param {*} _ - Unused. + * @param {*} parameters - The parameters to use to build the root object. + * @param {string} parameters.name - The name of the user. + * @param {string} parameters.prompt - The prompt the user gives to the LLM. + * + * @returns {object} The root object. + */ +export function buildRootObject(_, { name, prompt }) { + let llm; + return Far(`user:${name}`, { + bootstrap: async () => { + const llmProvider = makeOllamaBrowserLlmProvider(ollama); + const llmService = makeLlmService(llmProvider); + console.log( + `Bootstrapping user with llmService ${JSON.stringify(llmService)}`, + ); + llm = await E(llmService).makeInstance({ archetype: 'fast' }); + console.log('llm is', llm); + const responseStream = makeEventualIterator( + await E(llm).generate(prompt), + ); + let response = ''; + for await (const chunk of responseStream) { + response += chunk; + console.log(chunk); + } + return response; + }, + }); +} diff --git a/packages/kernel-test/tsconfig.json b/packages/kernel-test/tsconfig.json index 48fef407b8..2ecee921c1 100644 --- a/packages/kernel-test/tsconfig.json +++ b/packages/kernel-test/tsconfig.json @@ -13,7 +13,8 @@ { "path": "../kernel-utils" }, { "path": "../nodejs" }, { "path": "../ocap-kernel" }, - { "path": "../kernel-store" } + { "path": "../kernel-store" }, + { "path": "../agents" } ], "include": ["../../vitest.config.ts", "./src", "./vitest.config.ts"] } diff --git a/packages/kernel-test/vitest.config.ts b/packages/kernel-test/vitest.config.ts index 8addc21a45..f7885ed414 100644 --- a/packages/kernel-test/vitest.config.ts +++ b/packages/kernel-test/vitest.config.ts @@ -3,11 +3,14 @@ import { defineProject, mergeConfig } from 'vitest/config'; import defaultConfig from '../../vitest.config.ts'; +const { NODE_ENV } = process.env; + const config = mergeConfig( defaultConfig, defineProject({ test: { name: 'kernel-test', + env: { NODE_ENV }, setupFiles: path.resolve(__dirname, '../kernel-shims/src/endoify.js'), testTimeout: 30_000, }, diff --git a/packages/kernel-ui/src/App.tsx b/packages/kernel-ui/src/App.tsx index 92a6c5dbf4..3b92bbd2fe 100644 --- a/packages/kernel-ui/src/App.tsx +++ b/packages/kernel-ui/src/App.tsx @@ -2,6 +2,7 @@ import type { NonEmptyArray } from '@metamask/utils'; import { useState } from 'react'; import styles from './App.module.css'; +import { AgentMonitor } from './components/AgentMonitor.tsx'; import { ControlPanel } from './components/ControlPanel.tsx'; import { DatabaseInspector } from './components/DatabaseInspector.tsx'; import { MessagePanel } from './components/MessagePanel.tsx'; @@ -26,6 +27,11 @@ const tabs: NonEmptyArray<{ value: 'database', component: , }, + { + label: 'Agents', + value: 'agents', + component: , + }, ]; export const App: React.FC = () => { diff --git a/packages/kernel-ui/src/components/AgentControls.tsx b/packages/kernel-ui/src/components/AgentControls.tsx new file mode 100644 index 0000000000..4e06dd98b5 --- /dev/null +++ b/packages/kernel-ui/src/components/AgentControls.tsx @@ -0,0 +1,30 @@ +import styles from '../App.module.css'; + +/** + * @returns A panel for controlling agents. + */ +export const AgentControls: React.FC = () => { + // const { startAgent, stopAgent } = useAgentActions(); + + return ( +
+ Agent controls placeholder. + {/* + {hasVats && ( + + )} + + + + */} +
+ ); +}; diff --git a/packages/kernel-ui/src/components/AgentMonitor.tsx b/packages/kernel-ui/src/components/AgentMonitor.tsx new file mode 100644 index 0000000000..1118ab30ee --- /dev/null +++ b/packages/kernel-ui/src/components/AgentMonitor.tsx @@ -0,0 +1,13 @@ +import { AgentControls } from './AgentControls.tsx'; +import { Chat } from './Chat.tsx'; +import styles from '../App.module.css'; + +export const AgentMonitor: React.FC = () => { + return ( +
+

Agents

+ + +
+ ); +}; diff --git a/packages/kernel-ui/src/components/Chat.tsx b/packages/kernel-ui/src/components/Chat.tsx new file mode 100644 index 0000000000..e2deb6c2a8 --- /dev/null +++ b/packages/kernel-ui/src/components/Chat.tsx @@ -0,0 +1,3 @@ +export const Chat: React.FC = () => { + return
Chat Placeholder
; +}; diff --git a/packages/kernel-ui/src/hooks/useChat.ts b/packages/kernel-ui/src/hooks/useChat.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/kernel-utils/package.json b/packages/kernel-utils/package.json index e2d0ad3944..9257e8535e 100644 --- a/packages/kernel-utils/package.json +++ b/packages/kernel-utils/package.json @@ -29,6 +29,16 @@ "default": "./dist/index.cjs" } }, + "./import-hook": { + "import": { + "types": "./dist/import-hook.d.mts", + "default": "./dist/import-hook.mjs" + }, + "require": { + "types": "./dist/import-hook.d.cts", + "default": "./dist/import-hook.cjs" + } + }, "./package.json": "./package.json" }, "main": "./dist/index.cjs", diff --git a/packages/kernel-utils/src/constants.ts b/packages/kernel-utils/src/constants.ts new file mode 100644 index 0000000000..03710e5fc1 --- /dev/null +++ b/packages/kernel-utils/src/constants.ts @@ -0,0 +1,2 @@ +export const ollamaRootMacOS = '~/.ollama'; +export const ollamaRootLinux = '/usr/share/ollama/.ollama/models'; diff --git a/packages/kernel-utils/src/hooks/fs.ts b/packages/kernel-utils/src/hooks/fs.ts new file mode 100644 index 0000000000..5fd4de0327 --- /dev/null +++ b/packages/kernel-utils/src/hooks/fs.ts @@ -0,0 +1,39 @@ +import fs from 'node:fs'; +import { isAbsolute, relative, resolve } from 'node:path'; + +import { ollamaRootMacOS } from '../constants.ts'; +import type { ModuleRecord } from '../types.ts'; + +export const ollamaRoot = resolve(ollamaRootMacOS); + +// **ATTN**: Beware symlinks! +export const makeSubdirCaveat = + (parent: string) => + (path: string): string => { + const vector = relative(parent, path); + const isSubdir = + Boolean(vector) && !vector.startsWith('..') && !isAbsolute(vector); + if (!isSubdir) { + throw new Error(`No such file or directory: ${path}`); + } + return path; + }; + +const withinOllamaRootDir = makeSubdirCaveat(ollamaRoot); + +// To remain hardcoded until we converge on an endowment specification format. +export default { + imports: [], + exports: ['readFile', 'writeFile', 'promises', 'default'], + execute: (moduleExports: Record) => { + moduleExports.promises = { + readFile: async (path: string) => + fs.promises?.readFile(withinOllamaRootDir(path)), + writeFile: async (path: string, data: string) => + fs.promises?.writeFile(withinOllamaRootDir(path), data), + access: async (path: string) => + fs.promises?.access(withinOllamaRootDir(path)), + }; + moduleExports.default = { existsSync: (_path: string) => false }; + }, +} as ModuleRecord; diff --git a/packages/kernel-utils/src/hooks/path.ts b/packages/kernel-utils/src/hooks/path.ts new file mode 100644 index 0000000000..7fde2d4c1d --- /dev/null +++ b/packages/kernel-utils/src/hooks/path.ts @@ -0,0 +1,17 @@ +import { resolve } from 'node:path'; + +import type { ModuleRecord } from '../types.ts'; + +// To remain hardcoded until we converge on an endowment specification format. +export default { + imports: [], + exports: ['resolve'], + execute: (moduleExports: Record) => { + // We allow resolution of paths, sure. This does leak things like the + // name of `~` and such, but since 'node:fs' is restricted, it is as bad + // as the decision to store protected information in the directory + // structure itself, rather than within the files residing therein. + moduleExports.resolve = resolve; + harden(moduleExports); + }, +} as ModuleRecord; diff --git a/packages/kernel-utils/src/import-hook.ts b/packages/kernel-utils/src/import-hook.ts new file mode 100644 index 0000000000..47774c2b1d --- /dev/null +++ b/packages/kernel-utils/src/import-hook.ts @@ -0,0 +1,12 @@ +import fs from './hooks/fs.ts'; +import path from './hooks/path.ts'; +import type { ImportHook, ModuleRecord } from './types.ts'; + +const holes = { + fs, + 'node:fs': fs, + path, + 'node:path': path, +} as Record; + +export const importHook: ImportHook = (specifier: string) => holes[specifier]; diff --git a/packages/kernel-utils/src/index.ts b/packages/kernel-utils/src/index.ts index 68092b95e4..2e2e8baa08 100644 --- a/packages/kernel-utils/src/index.ts +++ b/packages/kernel-utils/src/index.ts @@ -2,6 +2,7 @@ export { delay, makeCounter } from './misc.ts'; export { stringify } from './stringify.ts'; export type { ExtractGuardType, + ImportHook, JsonRpcCall, JsonRpcMessage, PromiseCallbacks, diff --git a/packages/kernel-utils/src/types.ts b/packages/kernel-utils/src/types.ts index 36fa619a09..7215432e6f 100644 --- a/packages/kernel-utils/src/types.ts +++ b/packages/kernel-utils/src/types.ts @@ -82,3 +82,11 @@ export const JsonRpcMessageStruct: Struct = union([ export const isJsonRpcMessage = (value: unknown): value is JsonRpcMessage => is(value, JsonRpcMessageStruct); + +export type ModuleRecord = { + imports: string[]; + exports: string[]; + execute: (moduleExports: Record) => void; +}; + +export type ImportHook = (specifier: string) => ModuleRecord | undefined; diff --git a/packages/nodejs/src/vat/vat-worker.ts b/packages/nodejs/src/vat/vat-worker.ts index a799a4979e..a8bfaddfc7 100644 --- a/packages/nodejs/src/vat/vat-worker.ts +++ b/packages/nodejs/src/vat/vat-worker.ts @@ -54,6 +54,17 @@ async function main(): Promise { logger, fetchBlob, vatPowers: { logger }, + endowmentsConfig: { + fetch: { + urls: [ + 'http://localhost:11434/api/pull', + 'http://127.0.0.1:11434/api/pull', + 'http://localhost:11434/api/generate', + 'http://127.0.0.1:11434/api/generate', + ], + }, + abort: undefined, + }, }); logger.debug('vat-worker main'); } diff --git a/packages/nodejs/tsconfig.json b/packages/nodejs/tsconfig.json index aa72934391..7f0c9207b4 100644 --- a/packages/nodejs/tsconfig.json +++ b/packages/nodejs/tsconfig.json @@ -8,6 +8,7 @@ "types": ["node", "ses", "vitest"] }, "references": [ + { "path": "../agents" }, { "path": "../ocap-kernel" }, { "path": "../logger" }, { "path": "../streams" }, diff --git a/packages/ocap-kernel/src/VatSupervisor.test.ts b/packages/ocap-kernel/src/VatSupervisor.test.ts index d01c425bdf..0535274ac3 100644 --- a/packages/ocap-kernel/src/VatSupervisor.test.ts +++ b/packages/ocap-kernel/src/VatSupervisor.test.ts @@ -6,6 +6,10 @@ import '@ocap/test-utils'; import { TestDuplexStream } from '@ocap/test-utils/streams'; import { describe, it, expect, vi } from 'vitest'; +import type { + EndowmentName, + MakeEndowmentsConfig, +} from './endowments/index.ts'; import { VatSupervisor } from './VatSupervisor.ts'; vi.mock('./syscall.ts', () => ({ @@ -22,28 +26,43 @@ vi.mock('@agoric/swingset-liveslots', () => ({ })), })); -const makeVatSupervisor = async ({ - dispatch, - logger, - vatPowers, +const makeMockLogger = (): Logger => { + const logger = { + log: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + subLogger: vi.fn(() => logger), + }; + return logger as unknown as Logger; +}; + +const makeVatSupervisor = async ({ + dispatch = vi.fn(), + logger = makeMockLogger(), + vatPowers = {}, + endowmentsConfig = {} as MakeEndowmentsConfig, }: { dispatch?: (input: unknown) => void | Promise; logger?: Logger; vatPowers?: Record; + endowmentsConfig?: MakeEndowmentsConfig; } = {}): Promise<{ - supervisor: VatSupervisor; + supervisor: VatSupervisor; stream: TestDuplexStream; }> => { const kernelStream = await TestDuplexStream.make< JsonRpcMessage, JsonRpcMessage - >(dispatch ?? (() => undefined), { validateInput: isJsonRpcMessage }); + >(dispatch, { validateInput: isJsonRpcMessage }); return { supervisor: new VatSupervisor({ id: 'test-id', kernelStream, - logger: logger ?? new Logger(), - vatPowers: vatPowers ?? {}, + logger, + vatPowers, + endowmentsConfig, }), stream: kernelStream, }; diff --git a/packages/ocap-kernel/src/VatSupervisor.ts b/packages/ocap-kernel/src/VatSupervisor.ts index 40423f5f13..4dfb2692f6 100644 --- a/packages/ocap-kernel/src/VatSupervisor.ts +++ b/packages/ocap-kernel/src/VatSupervisor.ts @@ -17,6 +17,11 @@ import { serializeError } from '@metamask/rpc-errors'; import type { DuplexStream } from '@metamask/streams'; import { isJsonRpcRequest, isJsonRpcResponse } from '@metamask/utils'; +import makeEndowments from './endowments/index.ts'; +import type { + EndowmentName, + MakeEndowmentsConfig, +} from './endowments/index.ts'; import { vatSyscallMethodSpecs, vatHandlers } from './rpc/index.ts'; import { makeGCAndFinalize } from './services/gc-finalize.ts'; import { makeDummyMeterControl } from './services/meter-control.ts'; @@ -36,19 +41,20 @@ type SupervisorRpcClient = Pick< 'notify' | 'handleResponse' >; -type SupervisorConstructorProps = { +type SupervisorConstructorProps = { id: VatId; kernelStream: DuplexStream; logger: Logger; vatPowers?: Record | undefined; fetchBlob?: FetchBlob; + endowmentsConfig?: MakeEndowmentsConfig; }; const marshal = makeMarshal(undefined, undefined, { serializeBodyFormat: 'smallcaps', }); -export class VatSupervisor { +export class VatSupervisor { /** The id of the vat being supervised */ readonly id: VatId; @@ -79,6 +85,9 @@ export class VatSupervisor { /** Capability to fetch the bundle of code to run in this vat. */ readonly #fetchBlob: FetchBlob; + /** The configuration for this vat's endowments. */ + readonly #endowmentsConfig: MakeEndowmentsConfig; + /** * Construct a new VatSupervisor instance. * @@ -88,6 +97,7 @@ export class VatSupervisor { * @param params.logger - The logger for this vat. * @param params.vatPowers - The external capabilities for this vat. * @param params.fetchBlob - Function to fetch the user code bundle for this vat. + * @param params.endowmentsConfig - The configuration for this vat's endowments. */ constructor({ id, @@ -95,7 +105,8 @@ export class VatSupervisor { logger, vatPowers, fetchBlob, - }: SupervisorConstructorProps) { + endowmentsConfig, + }: SupervisorConstructorProps) { this.id = id; this.#kernelStream = kernelStream; this.#logger = logger; @@ -104,6 +115,8 @@ export class VatSupervisor { const defaultFetchBlob: FetchBlob = async (bundleURL: string) => await fetch(bundleURL); this.#fetchBlob = fetchBlob ?? defaultFetchBlob; + this.#endowmentsConfig = + endowmentsConfig ?? ({} as MakeEndowmentsConfig); this.#rpcClient = new RpcClient( vatSyscallMethodSpecs, @@ -260,6 +273,7 @@ export class VatSupervisor { const workerEndowments = { console: this.#logger.subLogger({ tags: ['console'] }), assert: globalThis.assert, + ...makeEndowments(this.#endowmentsConfig), }; const { bundleSpec, parameters } = vatConfig; diff --git a/packages/ocap-kernel/src/endowments/abort.ts b/packages/ocap-kernel/src/endowments/abort.ts new file mode 100644 index 0000000000..dc2942cf2a --- /dev/null +++ b/packages/ocap-kernel/src/endowments/abort.ts @@ -0,0 +1,12 @@ +/** + * Make an endowment for the AbortController API. + * + * @returns An endowment that provides the AbortController API. + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default function makeAbortEndowment() { + return { + AbortController: harden(globalThis.AbortController ?? class {}), + DOMException: harden(globalThis.DOMException ?? class {}) as unknown, + }; +} diff --git a/packages/ocap-kernel/src/endowments/fetch-api.ts b/packages/ocap-kernel/src/endowments/fetch-api.ts new file mode 100644 index 0000000000..83b0727eae --- /dev/null +++ b/packages/ocap-kernel/src/endowments/fetch-api.ts @@ -0,0 +1,15 @@ +/** + * Make an endowment for the fetch API. + * + * @returns An endowment that provides the fetch API, but no fetch implementation. + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default function makeFetchEndowment() { + return { + /* eslint-disable n/no-unsupported-features/node-builtins */ + Headers: harden(globalThis.Headers ?? class {}), + Request: harden(globalThis.Request ?? class {}), + Response: harden(globalThis.Response ?? class {}), + /* eslint-enable n/no-unsupported-features/node-builtins */ + }; +} diff --git a/packages/ocap-kernel/src/endowments/fetch.ts b/packages/ocap-kernel/src/endowments/fetch.ts new file mode 100644 index 0000000000..7b27b2c11d --- /dev/null +++ b/packages/ocap-kernel/src/endowments/fetch.ts @@ -0,0 +1,19 @@ +import { stringify } from '@metamask/kernel-utils'; +/** + * Make an endowment for the fetch API. + * + * @param config - The configuration for the fetch endowment. + * @param config.urls - The URLs which the endowment can fetch. + * @returns An endowment that provides the fetch API. + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default function makeFetchEndowment({ urls }: { urls: string[] }) { + return { + fetch: harden(async (...[url, ...rest]: Parameters) => { + if (!urls.includes(url as string)) { + throw new Error(`FetchError: Invalid URL ${stringify(url)}`); + } + return fetch(url as string, ...rest); + }), + }; +} diff --git a/packages/ocap-kernel/src/endowments/index.ts b/packages/ocap-kernel/src/endowments/index.ts new file mode 100644 index 0000000000..6b7d545435 --- /dev/null +++ b/packages/ocap-kernel/src/endowments/index.ts @@ -0,0 +1,56 @@ +import makeAbortEndowment from './abort.ts'; +import makeFetchApiEndowment from './fetch-api.ts'; +import makeFetchEndowment from './fetch.ts'; +import makePerformanceEndowment from './performance.ts'; +import makeUrlEndowment from './url.ts'; + +const endowmentFactories = { + fetch: makeFetchEndowment, + fetchApi: makeFetchApiEndowment, + abort: makeAbortEndowment, + performance: makePerformanceEndowment, + url: makeUrlEndowment, +} as const; + +export type EndowmentName = keyof typeof endowmentFactories; + +type EndowmentConfig = Parameters< + (typeof endowmentFactories)[EndowmentName] +>[0]; + +type EndowmentFactory = (config: EndowmentConfig) => Record; + +type EndowmentFactories = typeof endowmentFactories; + +type EndowmentConfigs = { + [Name in EndowmentName]: Parameters[0]; +}; + +// The output of makeEndowments is a record ready to assign to global scope. +type Endowments = { + [Name in EndowmentNames]: ReturnType; +}[EndowmentNames]; + +/** + * The configuration for makeEndowments. + * It is a partial record mapping endowment names to the config objects to pass to their respective factories. + */ +export type MakeEndowmentsConfig = + Partial & { [Name in EndowmentNames]: unknown }; + +/** + * Make endowments from a configuration. + * + * @param config - A record mapping endowment names to the config objects to pass to their respective factories. Omitted endowments are not constructed. + * @returns The endowments, conglommerated into a single record. + */ +export default function makeEndowments( + config: MakeEndowmentsConfig, +): Endowments { + return Object.assign( + {}, + ...(Object.keys(config) as EndowmentName[]).map((name) => + (endowmentFactories[name] as EndowmentFactory)(config[name]), + ), + ); +} diff --git a/packages/ocap-kernel/src/endowments/performance.ts b/packages/ocap-kernel/src/endowments/performance.ts new file mode 100644 index 0000000000..342c4169b1 --- /dev/null +++ b/packages/ocap-kernel/src/endowments/performance.ts @@ -0,0 +1,11 @@ +/** + * Make an endowment for the Performance API. + * + * @returns An endowment that provides the Performance API. + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default function makePerformanceEndowment() { + return { + performance: harden({ now: () => 0 }), + }; +} diff --git a/packages/ocap-kernel/src/endowments/url.ts b/packages/ocap-kernel/src/endowments/url.ts new file mode 100644 index 0000000000..93aec30f12 --- /dev/null +++ b/packages/ocap-kernel/src/endowments/url.ts @@ -0,0 +1,11 @@ +/** + * Make an endowment for the Performance API. + * + * @returns An endowment that provides the Performance API. + */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default function makeUrlEndowment() { + return { + location: harden({ origin: undefined }), + }; +} diff --git a/tsconfig.build.json b/tsconfig.build.json index 32c1842122..c177d78a1d 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -2,6 +2,7 @@ "files": [], "include": [], "references": [ + { "path": "./packages/agents/tsconfig.build.json" }, { "path": "./packages/cli/tsconfig.build.json" }, { "path": "./packages/kernel-browser-runtime/tsconfig.build.json" }, { "path": "./packages/kernel-errors/tsconfig.build.json" }, diff --git a/tsconfig.json b/tsconfig.json index fe0eb50cc6..985e2bd13d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "files": [], "include": [], "references": [ + { "path": "./packages/agents" }, { "path": "./packages/cli" }, { "path": "./packages/create-package" }, { "path": "./packages/extension" }, diff --git a/vitest.config.ts b/vitest.config.ts index efb1e8573d..173e136373 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -67,11 +67,17 @@ export default defineConfig({ ], thresholds: { autoUpdate: true, + 'packages/agents/**': { + statements: 11.11, + functions: 19.04, + branches: 0, + lines: 11.11, + }, 'packages/cli/**': { - statements: 70, + statements: 70.22, functions: 66.66, branches: 88.57, - lines: 70, + lines: 70.22, }, 'packages/create-package/**': { statements: 100, @@ -122,10 +128,10 @@ export default defineConfig({ lines: 95.09, }, 'packages/kernel-utils/**': { - statements: 100, - functions: 100, - branches: 100, - lines: 100, + statements: 71.42, + functions: 65.38, + branches: 83.87, + lines: 71.42, }, 'packages/logger/**': { statements: 98.46, @@ -140,10 +146,10 @@ export default defineConfig({ lines: 73.58, }, 'packages/ocap-kernel/**': { - statements: 92.47, - functions: 95.28, - branches: 82.89, - lines: 92.44, + statements: 92.15, + functions: 94.03, + branches: 81.75, + lines: 92.13, }, 'packages/streams/**': { statements: 100, diff --git a/yarn.lock b/yarn.lock index f9163e3687..c470709f6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2036,6 +2036,7 @@ __metadata: "@metamask/streams": "workspace:^" "@metamask/superstruct": "npm:^3.2.1" "@metamask/utils": "npm:^11.4.0" + "@ocap/agents": "workspace:^" "@ocap/test-utils": "workspace:^" "@ocap/vite-plugins": "workspace:^" "@ts-bridge/cli": "npm:^0.6.3" @@ -2062,7 +2063,9 @@ __metadata: typescript-eslint: "npm:^8.29.0" vite: "npm:^6.3.5" vite-plugin-checker: "npm:^0.9.1" + vite-plugin-node-polyfills: "npm:^0.24.0" vite-plugin-static-copy: "npm:^2.3.0" + vite-plugin-wasm: "npm:^3.5.0" vitest: "npm:^3.1.3" languageName: unknown linkType: soft @@ -2722,6 +2725,15 @@ __metadata: languageName: node linkType: hard +"@mlc-ai/web-llm@npm:^0.2.79": + version: 0.2.79 + resolution: "@mlc-ai/web-llm@npm:0.2.79" + dependencies: + loglevel: "npm:^1.9.1" + checksum: 10/133a54b2efaa2d6bf2cb6773fbf1bdda07d7a1ba6c30d756ee2e93fedae1b4244c0d93c273d6a69b68b4addec3141c8ae3bc92e00a9d49875f76d89fc24cd7a4 + languageName: node + linkType: hard + "@multiformats/dns@npm:^1.0.3, @multiformats/dns@npm:^1.0.6": version: 1.0.6 resolution: "@multiformats/dns@npm:1.0.6" @@ -2970,6 +2982,47 @@ __metadata: languageName: node linkType: hard +"@ocap/agents@workspace:^, @ocap/agents@workspace:packages/agents": + version: 0.0.0-use.local + resolution: "@ocap/agents@workspace:packages/agents" + dependencies: + "@arethetypeswrong/cli": "npm:^0.17.4" + "@endo/far": "npm:^1.1.11" + "@metamask/auto-changelog": "npm:^5.0.1" + "@metamask/eslint-config": "npm:^14.0.0" + "@metamask/eslint-config-nodejs": "npm:^14.0.0" + "@metamask/eslint-config-typescript": "npm:^14.0.0" + "@metamask/streams": "workspace:^" + "@mlc-ai/web-llm": "npm:^0.2.79" + "@ocap/cli": "workspace:^" + "@ocap/test-utils": "workspace:^" + "@ts-bridge/cli": "npm:^0.6.3" + "@ts-bridge/shims": "npm:^0.1.1" + "@types/node": "npm:^22.13.1" + "@typescript-eslint/eslint-plugin": "npm:^8.29.0" + "@typescript-eslint/parser": "npm:^8.29.0" + "@typescript-eslint/utils": "npm:^8.29.0" + "@vitest/eslint-plugin": "npm:^1.1.44" + depcheck: "npm:^1.4.7" + eslint: "npm:^9.23.0" + eslint-config-prettier: "npm:^10.1.1" + eslint-import-resolver-typescript: "npm:^4.3.1" + eslint-plugin-import-x: "npm:^4.10.0" + eslint-plugin-jsdoc: "npm:^50.6.9" + eslint-plugin-n: "npm:^17.17.0" + eslint-plugin-prettier: "npm:^5.2.6" + eslint-plugin-promise: "npm:^7.2.1" + ollama: "npm:^0.5.16" + prettier: "npm:^3.5.3" + rimraf: "npm:^6.0.1" + typedoc: "npm:^0.28.1" + typescript: "npm:~5.8.2" + typescript-eslint: "npm:^8.29.0" + vite: "npm:^6.3.5" + vitest: "npm:^3.1.3" + languageName: unknown + linkType: soft + "@ocap/brow-2-brow@workspace:packages/brow-2-brow": version: 0.0.0-use.local resolution: "@ocap/brow-2-brow@workspace:packages/brow-2-brow" @@ -3132,6 +3185,7 @@ __metadata: "@metamask/ocap-kernel": "workspace:^" "@metamask/streams": "workspace:^" "@metamask/utils": "npm:^11.4.0" + "@ocap/agents": "workspace:^" "@ocap/cli": "workspace:^" "@ocap/test-utils": "workspace:^" "@ocap/vite-plugins": "workspace:^" @@ -3193,6 +3247,7 @@ __metadata: "@metamask/ocap-kernel": "workspace:^" "@metamask/streams": "workspace:^" "@metamask/utils": "npm:^11.4.0" + "@ocap/agents": "workspace:^" "@ocap/cli": "workspace:^" "@ocap/nodejs": "workspace:^" "@typescript-eslint/eslint-plugin": "npm:^8.29.0" @@ -3209,6 +3264,7 @@ __metadata: eslint-plugin-prettier: "npm:^5.2.6" eslint-plugin-promise: "npm:^7.2.1" jsdom: "npm:^26.0.0" + ollama: "npm:^0.5.16" prettier: "npm:^3.5.3" rimraf: "npm:^6.0.1" typescript: "npm:~5.8.2" @@ -3740,7 +3796,23 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.1.4": +"@rollup/plugin-inject@npm:^5.0.5": + version: 5.0.5 + resolution: "@rollup/plugin-inject@npm:5.0.5" + dependencies: + "@rollup/pluginutils": "npm:^5.0.1" + estree-walker: "npm:^2.0.2" + magic-string: "npm:^0.30.3" + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 10/1d0e68dff0a8785398a1b6a7dac0dc0a7f2ded22319c0b4c411053f34cbe237ca897d1fc97e5150fddbc3486480f21cbeeb69f0ae7f44ab1ae7307c164c7e704 + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.1.4": version: 5.2.0 resolution: "@rollup/pluginutils@npm:5.2.0" dependencies: @@ -5510,6 +5582,17 @@ __metadata: languageName: node linkType: hard +"asn1.js@npm:^4.10.1": + version: 4.10.1 + resolution: "asn1.js@npm:4.10.1" + dependencies: + bn.js: "npm:^4.0.0" + inherits: "npm:^2.0.1" + minimalistic-assert: "npm:^1.0.0" + checksum: 10/5a02104b9ba167917c786a3fdac9840a057d29e6b609250e6af924d0529ead1a32417da13eec809cadea8f991eb67782196f3df427c5b4f30eaf22044fc64fda + languageName: node + linkType: hard + "asn1js@npm:^3.0.5": version: 3.0.6 resolution: "asn1js@npm:3.0.6" @@ -5521,6 +5604,19 @@ __metadata: languageName: node linkType: hard +"assert@npm:^2.0.0": + version: 2.1.0 + resolution: "assert@npm:2.1.0" + dependencies: + call-bind: "npm:^1.0.2" + is-nan: "npm:^1.3.2" + object-is: "npm:^1.1.5" + object.assign: "npm:^4.1.4" + util: "npm:^0.12.5" + checksum: 10/6b9d813c8eef1c0ac13feac5553972e4bd180ae16000d4eb5c0ded2489188737c75a5aacefc97a985008b37502f62fe1bad34da1a7481a54bbfabec3964c8aa7 + languageName: node + linkType: hard + "assertion-error@npm:^2.0.1": version: 2.0.1 resolution: "assertion-error@npm:2.0.1" @@ -5622,6 +5718,13 @@ __metadata: languageName: node linkType: hard +"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": + version: 4.12.2 + resolution: "bn.js@npm:4.12.2" + checksum: 10/5803983405c087443e0e6c9bb5d0bc863d9f987d77e710f81b14c55616494f5a274e1650ee892531acb3529d52c0e0ea48aa12d2873dd80a75dde9d73a2ec518 + languageName: node + linkType: hard + "body-parser@npm:1.20.3": version: 1.20.3 resolution: "body-parser@npm:1.20.3" @@ -5677,6 +5780,97 @@ __metadata: languageName: node linkType: hard +"brorand@npm:^1.0.1, brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 10/8a05c9f3c4b46572dec6ef71012b1946db6cae8c7bb60ccd4b7dd5a84655db49fe043ecc6272e7ef1f69dc53d6730b9e2a3a03a8310509a3d797a618cbee52be + languageName: node + linkType: hard + +"browser-resolve@npm:^2.0.0": + version: 2.0.0 + resolution: "browser-resolve@npm:2.0.0" + dependencies: + resolve: "npm:^1.17.0" + checksum: 10/ad5314db3429a903b07d6445137588665c4677d6276298bb08f0623f05cb107762b73c78f03b4f954a712bd1ebaf98e349b9d98e423123a42804924327a5acd4 + languageName: node + linkType: hard + +"browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": + version: 1.2.0 + resolution: "browserify-aes@npm:1.2.0" + dependencies: + buffer-xor: "npm:^1.0.3" + cipher-base: "npm:^1.0.0" + create-hash: "npm:^1.1.0" + evp_bytestokey: "npm:^1.0.3" + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.0.1" + checksum: 10/2813058f74e083a00450b11ea9d5d1f072de7bf0133f5d122d4ff7b849bece56d52b9c51ad0db0fad21c0bc4e8272fd5196114bbe7b94a9b7feb0f9fbb33a3bf + languageName: node + linkType: hard + +"browserify-cipher@npm:^1.0.1": + version: 1.0.1 + resolution: "browserify-cipher@npm:1.0.1" + dependencies: + browserify-aes: "npm:^1.0.4" + browserify-des: "npm:^1.0.0" + evp_bytestokey: "npm:^1.0.0" + checksum: 10/2d8500acf1ee535e6bebe808f7a20e4c3a9e2ed1a6885fff1facbfd201ac013ef030422bec65ca9ece8ffe82b03ca580421463f9c45af6c8415fd629f4118c13 + languageName: node + linkType: hard + +"browserify-des@npm:^1.0.0": + version: 1.0.2 + resolution: "browserify-des@npm:1.0.2" + dependencies: + cipher-base: "npm:^1.0.1" + des.js: "npm:^1.0.0" + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.1.2" + checksum: 10/2fd9018e598b1b25e002abaf656d46d8e0f2ee2666ff18852d37e5c3d0e47701d6824256b060fac395420d56a0c49c2b0d40a194e6fbd837bfdd893e7eb5ade4 + languageName: node + linkType: hard + +"browserify-rsa@npm:^4.0.0, browserify-rsa@npm:^4.1.0": + version: 4.1.1 + resolution: "browserify-rsa@npm:4.1.1" + dependencies: + bn.js: "npm:^5.2.1" + randombytes: "npm:^2.1.0" + safe-buffer: "npm:^5.2.1" + checksum: 10/62ae0da60e49e8d5dd3b0922119b6edee94ebfa3a184211c804024b3a75f9dab31a1d124cc0545ed050e273f0325c2fd7aba6a51e44ba6f726fceae3210ddade + languageName: node + linkType: hard + +"browserify-sign@npm:^4.2.3": + version: 4.2.3 + resolution: "browserify-sign@npm:4.2.3" + dependencies: + bn.js: "npm:^5.2.1" + browserify-rsa: "npm:^4.1.0" + create-hash: "npm:^1.2.0" + create-hmac: "npm:^1.1.7" + elliptic: "npm:^6.5.5" + hash-base: "npm:~3.0" + inherits: "npm:^2.0.4" + parse-asn1: "npm:^5.1.7" + readable-stream: "npm:^2.3.8" + safe-buffer: "npm:^5.2.1" + checksum: 10/403a8061d229ae31266670345b4a7c00051266761d2c9bbeb68b1a9bcb05f68143b16110cf23a171a5d6716396a1f41296282b3e73eeec0a1871c77f0ff4ee6b + languageName: node + linkType: hard + +"browserify-zlib@npm:^0.2.0": + version: 0.2.0 + resolution: "browserify-zlib@npm:0.2.0" + dependencies: + pako: "npm:~1.0.5" + checksum: 10/852e72effdc00bf8acc6d167d835179eda9e5bd13721ae5d0a2d132dc542f33e73bead2959eb43a2f181a9c495bc2ae2bdb4ec37c4e37ff61a0277741cbaaa7a + languageName: node + linkType: hard + "browserslist@npm:^4.24.0": version: 4.24.4 resolution: "browserslist@npm:4.24.4" @@ -5691,7 +5885,14 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.5.0": +"buffer-xor@npm:^1.0.3": + version: 1.0.3 + resolution: "buffer-xor@npm:1.0.3" + checksum: 10/4a63d48b5117c7eda896d81cd3582d9707329b07c97a14b0ece2edc6e64220ea7ea17c94b295e8c2cb7b9f8291e2b079f9096be8ac14be238420a43e06ec66e2 + languageName: node + linkType: hard + +"buffer@npm:^5.5.0, buffer@npm:^5.7.1": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -5711,6 +5912,13 @@ __metadata: languageName: node linkType: hard +"builtin-status-codes@npm:^3.0.0": + version: 3.0.0 + resolution: "builtin-status-codes@npm:3.0.0" + checksum: 10/1119429cf4b0d57bf76b248ad6f529167d343156ebbcc4d4e4ad600484f6bc63002595cbb61b67ad03ce55cd1d3c4711c03bbf198bf24653b8392420482f3773 + languageName: node + linkType: hard + "bundle-name@npm:^4.1.0": version: 4.1.0 resolution: "bundle-name@npm:4.1.0" @@ -5791,7 +5999,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": version: 1.0.8 resolution: "call-bind@npm:1.0.8" dependencies: @@ -5977,6 +6185,16 @@ __metadata: languageName: node linkType: hard +"cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": + version: 1.0.6 + resolution: "cipher-base@npm:1.0.6" + dependencies: + inherits: "npm:^2.0.4" + safe-buffer: "npm:^5.2.1" + checksum: 10/faf232deff2351448ea23d265eb8723e035ebbb454baca45fb60c1bd71056ede8b153bef1b221e067f13e6b9288ebb83bb6ae2d5dd4cec285411f9fc22ec1f5b + languageName: node + linkType: hard + "cjs-module-lexer@npm:^1.2.3, cjs-module-lexer@npm:^1.3.1": version: 1.4.3 resolution: "cjs-module-lexer@npm:1.4.3" @@ -6147,6 +6365,20 @@ __metadata: languageName: node linkType: hard +"console-browserify@npm:^1.1.0": + version: 1.2.0 + resolution: "console-browserify@npm:1.2.0" + checksum: 10/4f16c471fa84909af6ae00527ce8d19dd9ed587eab85923c145cadfbc35414139f87e7bdd61746138e22cd9df45c2a1ca060370998c2c39f801d4a778105bac5 + languageName: node + linkType: hard + +"constants-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "constants-browserify@npm:1.0.0" + checksum: 10/49ef0babd907616dddde6905b80fe44ad5948e1eaaf6cf65d5f23a8c60c029ff63a1198c364665be1d6b2cb183d7e12921f33049cc126734ade84a3cfdbc83f6 + languageName: node + linkType: hard + "content-disposition@npm:0.5.2": version: 0.5.2 resolution: "content-disposition@npm:0.5.2" @@ -6200,6 +6432,13 @@ __metadata: languageName: node linkType: hard +"core-util-is@npm:~1.0.0": + version: 1.0.3 + resolution: "core-util-is@npm:1.0.3" + checksum: 10/9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 + languageName: node + linkType: hard + "cosmiconfig@npm:^7.1.0": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" @@ -6222,6 +6461,62 @@ __metadata: languageName: node linkType: hard +"create-ecdh@npm:^4.0.4": + version: 4.0.4 + resolution: "create-ecdh@npm:4.0.4" + dependencies: + bn.js: "npm:^4.1.0" + elliptic: "npm:^6.5.3" + checksum: 10/0dd7fca9711d09e152375b79acf1e3f306d1a25ba87b8ff14c2fd8e68b83aafe0a7dd6c4e540c9ffbdd227a5fa1ad9b81eca1f233c38bb47770597ba247e614b + languageName: node + linkType: hard + +"create-hash@npm:^1.1.0, create-hash@npm:^1.2.0": + version: 1.2.0 + resolution: "create-hash@npm:1.2.0" + dependencies: + cipher-base: "npm:^1.0.1" + inherits: "npm:^2.0.1" + md5.js: "npm:^1.3.4" + ripemd160: "npm:^2.0.1" + sha.js: "npm:^2.4.0" + checksum: 10/3cfef32043b47a8999602af9bcd74966db6971dd3eb828d1a479f3a44d7f58e38c1caf34aa21a01941cc8d9e1a841738a732f200f00ea155f8a8835133d2e7bc + languageName: node + linkType: hard + +"create-hash@npm:~1.1.3": + version: 1.1.3 + resolution: "create-hash@npm:1.1.3" + dependencies: + cipher-base: "npm:^1.0.1" + inherits: "npm:^2.0.1" + ripemd160: "npm:^2.0.0" + sha.js: "npm:^2.4.0" + checksum: 10/b9f675719321dd3a3c3540bb46afcbdaf7182366ce93da9265318290e928be881e5edeff8c48a5ee9263c342e5e3f705fad5eb48f2e2cddc5fed1eb54077e076 + languageName: node + linkType: hard + +"create-hmac@npm:^1.1.7": + version: 1.1.7 + resolution: "create-hmac@npm:1.1.7" + dependencies: + cipher-base: "npm:^1.0.3" + create-hash: "npm:^1.1.0" + inherits: "npm:^2.0.1" + ripemd160: "npm:^2.0.0" + safe-buffer: "npm:^5.0.1" + sha.js: "npm:^2.4.8" + checksum: 10/2b26769f87e99ef72150bf99d1439d69272b2e510e23a2b8daf4e93e2412f4842504237d726044fa797cb20ee0ec8bee78d414b11f2d7ca93299185c93df0dae + languageName: node + linkType: hard + +"create-require@npm:^1.1.1": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: 10/a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + languageName: node + linkType: hard + "cron-parser@npm:^4.5.0": version: 4.9.0 resolution: "cron-parser@npm:4.9.0" @@ -6242,6 +6537,26 @@ __metadata: languageName: node linkType: hard +"crypto-browserify@npm:^3.12.1": + version: 3.12.1 + resolution: "crypto-browserify@npm:3.12.1" + dependencies: + browserify-cipher: "npm:^1.0.1" + browserify-sign: "npm:^4.2.3" + create-ecdh: "npm:^4.0.4" + create-hash: "npm:^1.2.0" + create-hmac: "npm:^1.1.7" + diffie-hellman: "npm:^5.0.3" + hash-base: "npm:~3.0.4" + inherits: "npm:^2.0.4" + pbkdf2: "npm:^3.1.2" + public-encrypt: "npm:^4.0.3" + randombytes: "npm:^2.1.0" + randomfill: "npm:^1.0.4" + checksum: 10/13da0b5f61b3e8e68fcbebf0394f2b2b4d35a0d0ba6ab762720c13391d3697ea42735260a26328a6a3d872be7d4cb5abe98a7a8f88bc93da7ba59b993331b409 + languageName: node + linkType: hard + "css-select@npm:^5.1.0": version: 5.1.0 resolution: "css-select@npm:5.1.0" @@ -6583,6 +6898,16 @@ __metadata: languageName: node linkType: hard +"des.js@npm:^1.0.0": + version: 1.1.0 + resolution: "des.js@npm:1.1.0" + dependencies: + inherits: "npm:^2.0.1" + minimalistic-assert: "npm:^1.0.0" + checksum: 10/d35fc82b5a0b2127b12699212e90b54ddd8134e0cf8d27a8c30507ed3572aa574ab71800cbb473769128a52dcf21acc3271c5c359508a5aa772e990df3b1a698 + languageName: node + linkType: hard + "destroy@npm:1.2.0": version: 1.2.0 resolution: "destroy@npm:1.2.0" @@ -6641,6 +6966,17 @@ __metadata: languageName: node linkType: hard +"diffie-hellman@npm:^5.0.3": + version: 5.0.3 + resolution: "diffie-hellman@npm:5.0.3" + dependencies: + bn.js: "npm:^4.1.0" + miller-rabin: "npm:^4.0.0" + randombytes: "npm:^2.0.0" + checksum: 10/2ff28231f93b27a4903461432d2de831df02e3568ea7633d5d7b6167eb73077f823b2bca26de6ba4f5c7ecd10a3df5aa94d376d136ab6209948c03cc4e4ac1fe + languageName: node + linkType: hard + "dns-packet@npm:^5.6.1": version: 5.6.1 resolution: "dns-packet@npm:5.6.1" @@ -6693,6 +7029,13 @@ __metadata: languageName: node linkType: hard +"domain-browser@npm:4.22.0": + version: 4.22.0 + resolution: "domain-browser@npm:4.22.0" + checksum: 10/3ffbaf0cae8da717698d472ca85ab52f96c538fe1fe85e5eb3351d4e7af52423ce096b8a0c51bb318e1c9ccf9c2e94b3b0f68e5923ad0aa0c623a32b641ed11c + languageName: node + linkType: hard + "domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -6759,6 +7102,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.5.3, elliptic@npm:^6.5.5": + version: 6.6.1 + resolution: "elliptic@npm:6.6.1" + dependencies: + bn.js: "npm:^4.11.9" + brorand: "npm:^1.1.0" + hash.js: "npm:^1.0.0" + hmac-drbg: "npm:^1.0.1" + inherits: "npm:^2.0.4" + minimalistic-assert: "npm:^1.0.1" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 10/dc678c9febd89a219c4008ba3a9abb82237be853d9fd171cd602c8fb5ec39927e65c6b5e7a1b2a4ea82ee8e0ded72275e7932bb2da04a5790c2638b818e4e1c5 + languageName: node + linkType: hard + "emoji-regex@npm:^10.3.0": version: 10.4.0 resolution: "emoji-regex@npm:10.4.0" @@ -7561,13 +7919,24 @@ __metadata: languageName: node linkType: hard -"events@npm:^3.3.0": +"events@npm:^3.0.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: 10/a3d47e285e28d324d7180f1e493961a2bbb4cad6412090e4dec114f4db1f5b560c7696ee8e758f55e23913ede856e3689cd3aa9ae13c56b5d8314cd3b3ddd1be languageName: node linkType: hard +"evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": + version: 1.0.3 + resolution: "evp_bytestokey@npm:1.0.3" + dependencies: + md5.js: "npm:^1.3.4" + node-gyp: "npm:latest" + safe-buffer: "npm:^5.1.1" + checksum: 10/ad4e1577f1a6b721c7800dcc7c733fe01f6c310732bb5bf2240245c2a5b45a38518b91d8be2c610611623160b9d1c0e91f1ce96d639f8b53e8894625cf20fa45 + languageName: node + linkType: hard + "execa@npm:^5.1.1": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -8363,6 +8732,46 @@ __metadata: languageName: node linkType: hard +"hash-base@npm:^2.0.0": + version: 2.0.2 + resolution: "hash-base@npm:2.0.2" + dependencies: + inherits: "npm:^2.0.1" + checksum: 10/e39f3f2bb91679ed350bd2eb81035acb1e1e6e9bb86d9f1197fcfdc3cf39a2c56bf82a1870f000fae651477883b4c107fd6ac0c640a18ab06298b87c39939396 + languageName: node + linkType: hard + +"hash-base@npm:^3.0.0": + version: 3.1.0 + resolution: "hash-base@npm:3.1.0" + dependencies: + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.6.0" + safe-buffer: "npm:^5.2.0" + checksum: 10/26b7e97ac3de13cb23fc3145e7e3450b0530274a9562144fc2bf5c1e2983afd0e09ed7cc3b20974ba66039fad316db463da80eb452e7373e780cbee9a0d2f2dc + languageName: node + linkType: hard + +"hash-base@npm:~3.0, hash-base@npm:~3.0.4": + version: 3.0.5 + resolution: "hash-base@npm:3.0.5" + dependencies: + inherits: "npm:^2.0.4" + safe-buffer: "npm:^5.2.1" + checksum: 10/6a82675a5de2ea9347501bbe655a2334950c7ec972fd9810ae9529e06aeab8f7e8ef68fc2112e5e6f0745561a7e05326efca42ad59bb5fd116537f5f8b0a216d + languageName: node + linkType: hard + +"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: "npm:^2.0.3" + minimalistic-assert: "npm:^1.0.1" + checksum: 10/0c89ee4006606a40f92df5cc3c263342e7fea68110f3e9ef032bd2083650430505db01b6b7926953489517d4027535e4fdc7f970412893d3031c361d3ec8f4b3 + languageName: node + linkType: hard + "hashlru@npm:^2.3.0": version: 2.3.0 resolution: "hashlru@npm:2.3.0" @@ -8395,6 +8804,17 @@ __metadata: languageName: node linkType: hard +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: "npm:^1.0.3" + minimalistic-assert: "npm:^1.0.0" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 10/0298a1445b8029a69b713d918ecaa84a1d9f614f5857e0c6e1ca517abfa1357216987b2ee08cc6cc73ba82a6c6ddf2ff11b9717a653530ef03be599d4699b836 + languageName: node + linkType: hard + "homedir-polyfill@npm:^1.0.1": version: 1.0.3 resolution: "homedir-polyfill@npm:1.0.3" @@ -8471,6 +8891,13 @@ __metadata: languageName: node linkType: hard +"https-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "https-browserify@npm:1.0.0" + checksum: 10/2d707c457319e1320adf0e7556174c190865fb345b6a183f033cee440f73221dbe7fa3f0adcffb1e6b0664726256bd44771a82e50fe6c66976c10b237100536a + languageName: node + linkType: hard + "https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" @@ -8616,7 +9043,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:^2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 @@ -8682,7 +9109,7 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.1.1": +"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": version: 1.2.0 resolution: "is-arguments@npm:1.2.0" dependencies: @@ -8852,7 +9279,7 @@ __metadata: languageName: node linkType: hard -"is-generator-function@npm:^1.0.10": +"is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": version: 1.1.0 resolution: "is-generator-function@npm:1.1.0" dependencies: @@ -8912,6 +9339,16 @@ __metadata: languageName: node linkType: hard +"is-nan@npm:^1.3.2": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.0" + define-properties: "npm:^1.1.3" + checksum: 10/1f784d3472c09bc2e47acba7ffd4f6c93b0394479aa613311dc1d70f1bfa72eb0846c81350967722c959ba65811bae222204d6c65856fdce68f31986140c7b0e + languageName: node + linkType: hard + "is-network-error@npm:^1.0.0": version: 1.1.0 resolution: "is-network-error@npm:1.1.0" @@ -9027,7 +9464,7 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15, is-typed-array@npm:^1.1.3": version: 1.1.15 resolution: "is-typed-array@npm:1.1.15" dependencies: @@ -9099,6 +9536,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: 10/f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -9113,6 +9557,13 @@ __metadata: languageName: node linkType: hard +"isomorphic-timers-promises@npm:^1.0.1": + version: 1.0.1 + resolution: "isomorphic-timers-promises@npm:1.0.1" + checksum: 10/2dabe397039081dbf30039f295333a7f9888b072dd0afa3aa7d8ba8f812a6db5efcbda0861a4be43ecfec207d56314ecf27150187b8d0f924a93103fa93eac73 + languageName: node + linkType: hard + "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0, istanbul-lib-coverage@npm:^3.2.2": version: 3.2.2 resolution: "istanbul-lib-coverage@npm:3.2.2" @@ -9812,6 +10263,13 @@ __metadata: languageName: node linkType: hard +"loglevel@npm:^1.9.1": + version: 1.9.2 + resolution: "loglevel@npm:1.9.2" + checksum: 10/6153d8db308323f7ee20130bc40309e7a976c30a10379d8666b596d9c6441965c3e074c8d7ee3347fe5cfc059c0375b6f3e8a10b93d5b813cc5547f5aa412a29 + languageName: node + linkType: hard + "loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -9885,7 +10343,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.11, magic-string@npm:^0.30.17": +"magic-string@npm:^0.30.11, magic-string@npm:^0.30.17, magic-string@npm:^0.30.3": version: 0.30.17 resolution: "magic-string@npm:0.30.17" dependencies: @@ -10021,6 +10479,17 @@ __metadata: languageName: node linkType: hard +"md5.js@npm:^1.3.4": + version: 1.3.5 + resolution: "md5.js@npm:1.3.5" + dependencies: + hash-base: "npm:^3.0.0" + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.1.2" + checksum: 10/098494d885684bcc4f92294b18ba61b7bd353c23147fbc4688c75b45cb8590f5a95fd4584d742415dcc52487f7a1ef6ea611cfa1543b0dc4492fe026357f3f0c + languageName: node + linkType: hard + "mdurl@npm:^2.0.0": version: 2.0.0 resolution: "mdurl@npm:2.0.0" @@ -10089,6 +10558,18 @@ __metadata: languageName: node linkType: hard +"miller-rabin@npm:^4.0.0": + version: 4.0.1 + resolution: "miller-rabin@npm:4.0.1" + dependencies: + bn.js: "npm:^4.0.0" + brorand: "npm:^1.0.1" + bin: + miller-rabin: bin/miller-rabin + checksum: 10/2a38ba9d1e878d94ee8a8ab3505b40e8d44fb9700a7716570fe4c8ca7e20d49b69aea579106580618c877cc6ff969eff71705042fafb47573736bf89404417bc + languageName: node + linkType: hard + "mime-db@npm:1.52.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" @@ -10165,6 +10646,20 @@ __metadata: languageName: node linkType: hard +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-assert@npm:1.0.1" + checksum: 10/cc7974a9268fbf130fb055aff76700d7e2d8be5f761fb5c60318d0ed010d839ab3661a533ad29a5d37653133385204c503bfac995aaa4236f4e847461ea32ba7 + languageName: node + linkType: hard + +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 10/6e8a0422b30039406efd4c440829ea8f988845db02a3299f372fceba56ffa94994a9c0f2fd70c17f9969eedfbd72f34b5070ead9656a34d3f71c0bd72583a0ed + languageName: node + linkType: hard + "minimatch@npm:3.1.2, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -10611,6 +11106,41 @@ __metadata: languageName: node linkType: hard +"node-stdlib-browser@npm:^1.2.0": + version: 1.3.1 + resolution: "node-stdlib-browser@npm:1.3.1" + dependencies: + assert: "npm:^2.0.0" + browser-resolve: "npm:^2.0.0" + browserify-zlib: "npm:^0.2.0" + buffer: "npm:^5.7.1" + console-browserify: "npm:^1.1.0" + constants-browserify: "npm:^1.0.0" + create-require: "npm:^1.1.1" + crypto-browserify: "npm:^3.12.1" + domain-browser: "npm:4.22.0" + events: "npm:^3.0.0" + https-browserify: "npm:^1.0.0" + isomorphic-timers-promises: "npm:^1.0.1" + os-browserify: "npm:^0.3.0" + path-browserify: "npm:^1.0.1" + pkg-dir: "npm:^5.0.0" + process: "npm:^0.11.10" + punycode: "npm:^1.4.1" + querystring-es3: "npm:^0.2.1" + readable-stream: "npm:^3.6.0" + stream-browserify: "npm:^3.0.0" + stream-http: "npm:^3.2.0" + string_decoder: "npm:^1.0.0" + timers-browserify: "npm:^2.0.4" + tty-browserify: "npm:0.0.1" + url: "npm:^0.11.4" + util: "npm:^0.12.4" + vm-browserify: "npm:^1.0.1" + checksum: 10/5d5ace50868ef1a8ce9718a5fc64e4b6712f8be75bf6ab71f2eb7b5815f55f20507e427eac2fdb384e372f58891eb34089af3b55d3f9b5b60b547c8581a1c30e + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.1 resolution: "nopt@npm:7.2.1" @@ -10823,6 +11353,15 @@ __metadata: languageName: node linkType: hard +"ollama@npm:^0.5.16": + version: 0.5.16 + resolution: "ollama@npm:0.5.16" + dependencies: + whatwg-fetch: "npm:^3.6.20" + checksum: 10/40650813d7cc41058c25c9cb08374078b69f449e84c25dfa4b08176138db93af2f0546eb52431b538a055af30c84908330a8a5ac554595be3022e7f1fdac4a49 + languageName: node + linkType: hard + "on-finished@npm:2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" @@ -10894,6 +11433,13 @@ __metadata: languageName: node linkType: hard +"os-browserify@npm:^0.3.0": + version: 0.3.0 + resolution: "os-browserify@npm:0.3.0" + checksum: 10/16e37ba3c0e6a4c63443c7b55799ce4066d59104143cb637ecb9fce586d5da319cdca786ba1c867abbe3890d2cbf37953f2d51eea85e20dd6c4570d6c54bfebf + languageName: node + linkType: hard + "own-keys@npm:^1.0.1": version: 1.0.1 resolution: "own-keys@npm:1.0.1" @@ -10999,6 +11545,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:~1.0.5": + version: 1.0.11 + resolution: "pako@npm:1.0.11" + checksum: 10/1ad07210e894472685564c4d39a08717e84c2a68a70d3c1d9e657d32394ef1670e22972a433cbfe48976cb98b154ba06855dcd3fcfba77f60f1777634bec48c0 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -11008,6 +11561,20 @@ __metadata: languageName: node linkType: hard +"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.7": + version: 5.1.7 + resolution: "parse-asn1@npm:5.1.7" + dependencies: + asn1.js: "npm:^4.10.1" + browserify-aes: "npm:^1.2.0" + evp_bytestokey: "npm:^1.0.3" + hash-base: "npm:~3.0" + pbkdf2: "npm:^3.1.2" + safe-buffer: "npm:^5.2.1" + checksum: 10/f82c079f4d9a4d33159c7682f9c516680f4d659fde8060697a6b3c1be4795976e826d53a1e5751a81ddc800e9c6d6fa4629b59f6d1f3241ac8447a00c89a67d3 + languageName: node + linkType: hard + "parse-imports-exports@npm:^0.2.4": version: 0.2.4 resolution: "parse-imports-exports@npm:0.2.4" @@ -11219,6 +11786,20 @@ __metadata: languageName: node linkType: hard +"pbkdf2@npm:^3.1.2": + version: 3.1.3 + resolution: "pbkdf2@npm:3.1.3" + dependencies: + create-hash: "npm:~1.1.3" + create-hmac: "npm:^1.1.7" + ripemd160: "npm:=2.0.1" + safe-buffer: "npm:^5.2.1" + sha.js: "npm:^2.4.11" + to-buffer: "npm:^1.2.0" + checksum: 10/980cf2977aa84ec3166fde195a28464ab494131c0a5778fc8f20b8894410747e502159c19ef2b41842c728bc52ba49ffee6847e3ee61ac0d482689f85d8a1b30 + languageName: node + linkType: hard + "picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" @@ -11256,6 +11837,15 @@ __metadata: languageName: node linkType: hard +"pkg-dir@npm:^5.0.0": + version: 5.0.0 + resolution: "pkg-dir@npm:5.0.0" + dependencies: + find-up: "npm:^5.0.0" + checksum: 10/b167bb8dac7bbf22b1d5e30ec223e6b064b84b63010c9d49384619a36734caf95ed23ad23d4f9bd975e8e8082b60a83395f43a89bb192df53a7c25a38ecb57d9 + languageName: node + linkType: hard + "pkg-types@npm:^1.3.0": version: 1.3.1 resolution: "pkg-types@npm:1.3.1" @@ -11500,6 +12090,13 @@ __metadata: languageName: node linkType: hard +"process-nextick-args@npm:~2.0.0": + version: 2.0.1 + resolution: "process-nextick-args@npm:2.0.1" + checksum: 10/1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf + languageName: node + linkType: hard + "process@npm:^0.11.10": version: 0.11.10 resolution: "process@npm:0.11.10" @@ -11570,6 +12167,20 @@ __metadata: languageName: node linkType: hard +"public-encrypt@npm:^4.0.3": + version: 4.0.3 + resolution: "public-encrypt@npm:4.0.3" + dependencies: + bn.js: "npm:^4.1.0" + browserify-rsa: "npm:^4.0.0" + create-hash: "npm:^1.1.0" + parse-asn1: "npm:^5.0.0" + randombytes: "npm:^2.0.1" + safe-buffer: "npm:^5.1.2" + checksum: 10/059d64da8ba9ea0733377d23b57b6cbe5be663c8eb187b9c051eec85f799ff95c4e194eb3a69db07cc1f73a2a63519e67716ae9b8630e13e7149840d0abe044d + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.2 resolution: "pump@npm:3.0.2" @@ -11594,6 +12205,13 @@ __metadata: languageName: node linkType: hard +"punycode@npm:^1.4.1": + version: 1.4.1 + resolution: "punycode@npm:1.4.1" + checksum: 10/af2700dde1a116791ff8301348ff344c47d6c224e875057237d1b5112035655fb07a6175cfdb8bf0e3a8cdfd2dc82b3a622e0aefd605566c0e949a6d0d1256a4 + languageName: node + linkType: hard + "punycode@npm:^2.1.0, punycode@npm:^2.3.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -11626,6 +12244,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.12.3": + version: 6.14.0 + resolution: "qs@npm:6.14.0" + dependencies: + side-channel: "npm:^1.1.0" + checksum: 10/a60e49bbd51c935a8a4759e7505677b122e23bf392d6535b8fc31c1e447acba2c901235ecb192764013cd2781723dc1f61978b5fdd93cc31d7043d31cdc01974 + languageName: node + linkType: hard + "quansync@npm:^0.2.8": version: 0.2.10 resolution: "quansync@npm:0.2.10" @@ -11633,6 +12260,13 @@ __metadata: languageName: node linkType: hard +"querystring-es3@npm:^0.2.1": + version: 0.2.1 + resolution: "querystring-es3@npm:0.2.1" + checksum: 10/c99fccfe1a9c4c25ea6194fa7a559fdb83d2628f118f898af6f0ac02c4ffcd7e0576997bb80e7dfa892d193988b60e23d4968122426351819f87051862af991c + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -11654,6 +12288,25 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: "npm:^5.1.0" + checksum: 10/4efd1ad3d88db77c2d16588dc54c2b52fd2461e70fe5724611f38d283857094fe09040fa2c9776366803c3152cf133171b452ef717592b65631ce5dc3a2bdafc + languageName: node + linkType: hard + +"randomfill@npm:^1.0.4": + version: 1.0.4 + resolution: "randomfill@npm:1.0.4" + dependencies: + randombytes: "npm:^2.0.5" + safe-buffer: "npm:^5.1.0" + checksum: 10/33734bb578a868d29ee1b8555e21a36711db084065d94e019a6d03caa67debef8d6a1bfd06a2b597e32901ddc761ab483a85393f0d9a75838f1912461d4dbfc7 + languageName: node + linkType: hard + "range-parser@npm:1.2.0": version: 1.2.0 resolution: "range-parser@npm:1.2.0" @@ -11769,7 +12422,22 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.2": +"readable-stream@npm:^2.3.8": + version: 2.3.8 + resolution: "readable-stream@npm:2.3.8" + dependencies: + core-util-is: "npm:~1.0.0" + inherits: "npm:~2.0.3" + isarray: "npm:~1.0.0" + process-nextick-args: "npm:~2.0.0" + safe-buffer: "npm:~5.1.1" + string_decoder: "npm:~1.1.1" + util-deprecate: "npm:~1.0.1" + checksum: 10/8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4 + languageName: node + linkType: hard + +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0, readable-stream@npm:^3.6.2": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -11922,7 +12590,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:1.22.10, resolve@npm:^1.22.3, resolve@npm:^1.22.4, resolve@npm:~1.22.1, resolve@npm:~1.22.2": +"resolve@npm:1.22.10, resolve@npm:^1.17.0, resolve@npm:^1.22.3, resolve@npm:^1.22.4, resolve@npm:~1.22.1, resolve@npm:~1.22.2": version: 1.22.10 resolution: "resolve@npm:1.22.10" dependencies: @@ -11948,7 +12616,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A1.22.10#optional!builtin, resolve@patch:resolve@npm%3A^1.22.3#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin": +"resolve@patch:resolve@npm%3A1.22.10#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.3#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin": version: 1.22.10 resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" dependencies: @@ -12031,6 +12699,26 @@ __metadata: languageName: node linkType: hard +"ripemd160@npm:=2.0.1": + version: 2.0.1 + resolution: "ripemd160@npm:2.0.1" + dependencies: + hash-base: "npm:^2.0.0" + inherits: "npm:^2.0.1" + checksum: 10/f1a20b72b3ef897a981544c72a1fe15c2bd580f6f40e3062f7839af8e81232f746aa860964686e4b81e90929ad086f14823a9864e4e4bed3367e597fe14a0968 + languageName: node + linkType: hard + +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" + dependencies: + hash-base: "npm:^3.0.0" + inherits: "npm:^2.0.1" + checksum: 10/006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 + languageName: node + linkType: hard + "rollup@npm:^4.34.9": version: 4.40.0 resolution: "rollup@npm:4.40.0" @@ -12142,13 +12830,20 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10/32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 languageName: node linkType: hard +"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: 10/7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a + languageName: node + linkType: hard + "safe-push-apply@npm:^1.0.0": version: 1.0.0 resolution: "safe-push-apply@npm:1.0.0" @@ -12376,7 +13071,7 @@ __metadata: languageName: node linkType: hard -"setimmediate@npm:^1.0.5": +"setimmediate@npm:^1.0.4, setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" checksum: 10/76e3f5d7f4b581b6100ff819761f04a984fa3f3990e72a6554b57188ded53efce2d3d6c0932c10f810b7c59414f85e2ab3c11521877d1dea1ce0b56dc906f485 @@ -12390,6 +13085,19 @@ __metadata: languageName: node linkType: hard +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": + version: 2.4.12 + resolution: "sha.js@npm:2.4.12" + dependencies: + inherits: "npm:^2.0.4" + safe-buffer: "npm:^5.2.1" + to-buffer: "npm:^1.2.0" + bin: + sha.js: bin.js + checksum: 10/39c0993592c2ab34eb2daae2199a2a1d502713765aecb611fd97c0c4ab7cd53e902d628e1962aaf384bafd28f55951fef46dcc78799069ce41d74b03aa13b5a7 + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -12730,6 +13438,28 @@ __metadata: languageName: node linkType: hard +"stream-browserify@npm:^3.0.0": + version: 3.0.0 + resolution: "stream-browserify@npm:3.0.0" + dependencies: + inherits: "npm:~2.0.4" + readable-stream: "npm:^3.5.0" + checksum: 10/05a3cd0a0ce2d568dbdeb69914557c26a1b0a9d871839666b692eae42b96189756a3ed685affc90dab64ff588a8524c8aec6d85072c07905a1f0d941ea68f956 + languageName: node + linkType: hard + +"stream-http@npm:^3.2.0": + version: 3.2.0 + resolution: "stream-http@npm:3.2.0" + dependencies: + builtin-status-codes: "npm:^3.0.0" + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.6.0" + xtend: "npm:^4.0.2" + checksum: 10/4f85738cbc6de70ecf0a04bc38b6092b4d91dd5317d3d93c88a84c48e63b82a8724ab5fd591df9f587b5139fe439d1748e4e3db3cb09c2b1e23649cb9d89859e + languageName: node + linkType: hard + "stream-to-it@npm:^1.0.1": version: 1.0.1 resolution: "stream-to-it@npm:1.0.1" @@ -12848,7 +13578,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": +"string_decoder@npm:^1.0.0, string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -12857,6 +13587,15 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:~1.1.1": + version: 1.1.1 + resolution: "string_decoder@npm:1.1.1" + dependencies: + safe-buffer: "npm:~5.1.0" + checksum: 10/7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4 + languageName: node + linkType: hard + "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -13115,6 +13854,15 @@ __metadata: languageName: node linkType: hard +"timers-browserify@npm:^2.0.4": + version: 2.0.12 + resolution: "timers-browserify@npm:2.0.12" + dependencies: + setimmediate: "npm:^1.0.4" + checksum: 10/ec37ae299066bef6c464dcac29c7adafba1999e7227a9bdc4e105a459bee0f0b27234a46bfd7ab4041da79619e06a58433472867a913d01c26f8a203f87cee70 + languageName: node + linkType: hard + "tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" @@ -13185,6 +13933,17 @@ __metadata: languageName: node linkType: hard +"to-buffer@npm:^1.2.0": + version: 1.2.1 + resolution: "to-buffer@npm:1.2.1" + dependencies: + isarray: "npm:^2.0.5" + safe-buffer: "npm:^5.2.1" + typed-array-buffer: "npm:^1.0.3" + checksum: 10/f8d03f070b8567d9c949f1b59c8d47c83ed2e59b50b5449258f931df9a1fcb751aa8bb8756a9345adc529b6b1822521157c48e1a7d01779a47185060d7bf96d4 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -13301,6 +14060,13 @@ __metadata: languageName: node linkType: hard +"tty-browserify@npm:0.0.1": + version: 0.0.1 + resolution: "tty-browserify@npm:0.0.1" + checksum: 10/93b745d43fa5a7d2b948fa23be8d313576d1d884b48acd957c07710bac1c0d8ac34c0556ad4c57c73d36e11741763ef66b3fb4fb97b06b7e4d525315a3cd45f5 + languageName: node + linkType: hard + "tunnel-agent@npm:^0.6.0": version: 0.6.0 resolution: "tunnel-agent@npm:0.6.0" @@ -13742,6 +14508,16 @@ __metadata: languageName: node linkType: hard +"url@npm:^0.11.4": + version: 0.11.4 + resolution: "url@npm:0.11.4" + dependencies: + punycode: "npm:^1.4.1" + qs: "npm:^6.12.3" + checksum: 10/e787d070f0756518b982a4653ef6cdf4d9030d8691eee2d483344faf2b530b71d302287fa63b292299455fea5075c502a5ad5f920cb790e95605847f957a65e4 + languageName: node + linkType: hard + "utf8-byte-length@npm:^1.0.1": version: 1.0.5 resolution: "utf8-byte-length@npm:1.0.5" @@ -13749,13 +14525,26 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2": +"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" checksum: 10/474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 languageName: node linkType: hard +"util@npm:^0.12.4, util@npm:^0.12.5": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: "npm:^2.0.3" + is-arguments: "npm:^1.0.4" + is-generator-function: "npm:^1.0.7" + is-typed-array: "npm:^1.1.3" + which-typed-array: "npm:^1.1.2" + checksum: 10/61a10de7753353dd4d744c917f74cdd7d21b8b46379c1e48e1c4fd8e83f8190e6bd9978fc4e5102ab6a10ebda6019d1b36572fa4a325e175ec8b789a121f6147 + languageName: node + linkType: hard + "utils-merge@npm:1.0.1": version: 1.0.1 resolution: "utils-merge@npm:1.0.1" @@ -13888,6 +14677,18 @@ __metadata: languageName: node linkType: hard +"vite-plugin-node-polyfills@npm:^0.24.0": + version: 0.24.0 + resolution: "vite-plugin-node-polyfills@npm:0.24.0" + dependencies: + "@rollup/plugin-inject": "npm:^5.0.5" + node-stdlib-browser: "npm:^1.2.0" + peerDependencies: + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + checksum: 10/9c85b94bd74728c1d93c337b4032ba4bec56054caddb0205475abc8c281b047649bb5e1dcdd77206b0b13c707e49d379551df4fb18843e41ace03f62e5a06380 + languageName: node + linkType: hard + "vite-plugin-static-copy@npm:^2.3.0": version: 2.3.1 resolution: "vite-plugin-static-copy@npm:2.3.1" @@ -13903,6 +14704,15 @@ __metadata: languageName: node linkType: hard +"vite-plugin-wasm@npm:^3.5.0": + version: 3.5.0 + resolution: "vite-plugin-wasm@npm:3.5.0" + peerDependencies: + vite: ^2 || ^3 || ^4 || ^5 || ^6 || ^7 + checksum: 10/71edcd89f8550c673c32becb113fcb867dbbf23a64e9f4b445cf2f6ec0aa279eb30621bb779f32878aeaf893dc38c96d4b8e10ff84c5b4aaf1ceffa0adde7bd9 + languageName: node + linkType: hard + "vite-tsconfig-paths@npm:^5.1.4": version: 5.1.4 resolution: "vite-tsconfig-paths@npm:5.1.4" @@ -14037,6 +14847,13 @@ __metadata: languageName: node linkType: hard +"vm-browserify@npm:^1.0.1": + version: 1.1.2 + resolution: "vm-browserify@npm:1.1.2" + checksum: 10/ad5b17c9f7a9d9f1ed0e24c897782ab7a587c1fd40f370152482e1af154c7cf0b0bacc45c5ae76a44289881e083ae4ae127808fdff864aa9b562192aae8b5c3b + languageName: node + linkType: hard + "vscode-uri@npm:^3.0.8, vscode-uri@npm:^3.1.0": version: 3.1.0 resolution: "vscode-uri@npm:3.1.0" @@ -14092,6 +14909,13 @@ __metadata: languageName: node linkType: hard +"whatwg-fetch@npm:^3.6.20": + version: 3.6.20 + resolution: "whatwg-fetch@npm:3.6.20" + checksum: 10/2b4ed92acd6a7ad4f626a6cb18b14ec982bbcaf1093e6fe903b131a9c6decd14d7f9c9ca3532663c2759d1bdf01d004c77a0adfb2716a5105465c20755a8c57c + languageName: node + linkType: hard + "whatwg-mimetype@npm:^4.0.0": version: 4.0.0 resolution: "whatwg-mimetype@npm:4.0.0" @@ -14164,7 +14988,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18": +"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18, which-typed-array@npm:^1.1.2": version: 1.1.19 resolution: "which-typed-array@npm:1.1.19" dependencies: @@ -14332,7 +15156,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.1": +"xtend@npm:^4.0.1, xtend@npm:^4.0.2": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: 10/ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a