{"id":16695099,"url":"https://github.com/davidmyersdev/vellma","last_synced_at":"2026-02-13T16:02:34.967Z","repository":{"id":156736612,"uuid":"633138852","full_name":"davidmyersdev/vellma","owner":"davidmyersdev","description":"Virtual, Eloquent LLM Assistants","archived":false,"fork":false,"pushed_at":"2024-05-19T00:22:09.000Z","size":328,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-29T23:51:16.684Z","etag":null,"topics":["ai","chatgpt","gpt-4","llm","openai"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidmyersdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"davidmyersdev","ko_fi":"davidmyersdev","open_collective":"davidmyersdev","patreon":"davidmyersdev"}},"created_at":"2023-04-26T21:37:15.000Z","updated_at":"2024-08-22T12:05:37.000Z","dependencies_parsed_at":"2024-03-06T16:10:23.840Z","dependency_job_id":"23cb8097-302e-498a-b67a-668fbedeada4","html_url":"https://github.com/davidmyersdev/vellma","commit_stats":{"total_commits":166,"total_committers":1,"mean_commits":166.0,"dds":0.0,"last_synced_commit":"91b2b32f7869a4847dd8384f0330336590d7d4f9"},"previous_names":["davidmyersdev/chitty","davidmyersdev/ellma"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmyersdev%2Fvellma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmyersdev%2Fvellma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmyersdev%2Fvellma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmyersdev%2Fvellma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidmyersdev","download_url":"https://codeload.github.com/davidmyersdev/vellma/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294567,"owners_count":20915341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","chatgpt","gpt-4","llm","openai"],"created_at":"2024-10-12T17:05:19.020Z","updated_at":"2026-02-13T16:02:29.928Z","avatar_url":"https://github.com/davidmyersdev.png","language":"TypeScript","funding_links":["https://github.com/sponsors/davidmyersdev","https://ko-fi.com/davidmyersdev","https://opencollective.com/davidmyersdev","https://patreon.com/davidmyersdev"],"categories":[],"sub_categories":[],"readme":"[![Sponsor me](https://img.shields.io/badge/sponsor-DB61A2?style=for-the-badge\u0026logo=GitHub-Sponsors\u0026logoColor=white)](https://voracious.link/sponsor)\n[![Donate](https://img.shields.io/badge/donate-FF5F5F?style=for-the-badge\u0026logo=ko-fi\u0026logoColor=white)](https://voracious.link/donate)\n\n# `vellma` \u003c!-- omit in toc --\u003e\n\nVirtual, Eloquent LLM Assistants\n\n## Overview \u003c!-- omit in toc --\u003e\n\n- [How to use `vellma`](#how-to-use-vellma)\n  - [Example: Terminal chat](#example-terminal-chat)\n- [Concepts](#concepts)\n  - [Interfaces and adapters](#interfaces-and-adapters)\n    - [Example: Mapping `api.openai.com/v1/chat/completions` to `ChatIntegration`](#example-mapping-apiopenaicomv1chatcompletions-to-chatintegration)\n  - [Peripherals](#peripherals)\n    - [Example: Getting input from or displaying output to a user](#example-getting-input-from-or-displaying-output-to-a-user)\n  - [Models](#models)\n    - [Embedding models](#embedding-models)\n  - [Integrations](#integrations)\n- [How to contribute to `vellma`](#how-to-contribute-to-vellma)\n  - [Set up your development environment](#set-up-your-development-environment)\n\n## How to use `vellma`\n\nInstall it with your preferred package manager.\n\n```bash\n# npm\nnpm i vellma\n\n# pnpm\npnpm add vellma\n\n# yarn\nyarn add vellma\n```\n\n### Example: Terminal chat\n\nLet's use the `openai` integration to create a chat model that uses the terminal for user input and output.\n\n```ts\nimport { openai } from 'vellma/integrations'\nimport { useChat } from 'vellma/models'\nimport { terminalIo, useIo } from 'vellma/peripherals'\n\n// Initialize the integration, model, and peripherals.\nconst integration = openai({ apiKey: 'your-api-key' })\nconst { factory, model } = useChat({ integration })\nconst io = useIo(terminalIo())\n\n// Chat loop\nwhile (true) {\n  // On each iteration, you will be prompted for input.\n  const yourInput = await io.prompt(`You:\\n`)\n  const yourMessage = factory.human({ text: yourInput })\n\n  // Then, a response will be generated.\n  const theirReply = model.generate(yourMessage)\n\n  await io.write(`Assistant:\\n`)\n\n  // The response will be written to the terminal in real-time.\n  for await (const { textDelta } of theirReply) {\n    await io.write(textDelta)\n  }\n\n  // Write a final newline to the terminal to prepare for the next iteration.\n  await io.write(`\\n`)\n}\n```\n\nRunning the code above will allow you to have a basic conversation that looks something like this.\n\n```\nYou:\nExplain human existence in 1 sentence.\nAssistant:\nHuman existence is the intricate dance of biological life, consciousness, relationships, growth, emotions, knowledge, and experience on a small planet in a vast universe.\nYou:\n\u003cYour next prompt here\u003e\n```\n\nFor more examples, check out the [`playground`](./playground) directory.\n\n## Concepts\n\nTo get the best out of `vellma`, there are some concepts that you should understand.\n\n### Interfaces and adapters\n\nIn order to keep this library flexible, while also maintaining reasonable defaults, features that relate to _external_ runtime functionality should be implemented with the adapter pattern. In this library, the adapter pattern consists of 2 main concepts: the **interface** and the **adapter**. The interface refers to the _internal_ interface that we will use throughout the codebase. The adapter maps that _internal_ interface to the _external_ interface that a given implementation provides. Some examples of this are:\n\n- Mapping the `openai` endpoint for chat completions to the `ChatIntegration` interface used by the Chat model.\n- Mapping the `node:readline` terminal IO utilities to the `IoPeripheral` interface used by features that deal with user input and output.\n\n#### Example: Mapping `api.openai.com/v1/chat/completions` to `ChatIntegration`\n\nTake a look at the following interface for [`ChatIntegration`](./integrations/src/index.ts#7).\n\n```ts\nexport type ChatIntegration = {\n  chat: (messages: ChatMessage[]) =\u003e Promise\u003cConsumable\u003cChatMessage\u003e\u003e,\n}\n```\n\nThe interface is meant to be simple for the generic chat model to consume, so it has a single `chat` property. The `chat` property is a function that takes an array of `ChatMessage` objects (the conversation so far) and returns a single `Consumable\u003cChatMessage\u003e` object (the reply). The interface for the function that calls `/v1/chat/completions`, however, is a bit more complicated.\n\n```ts\nexport type OpenAiChatApi = (config: {\n  apiKey: string,\n  messages: OpenAiChatMessage[],\n  model?: string,\n  organizationId?: string,\n  peripherals?: Partial\u003cPeripherals\u003e,\n}) =\u003e Promise\u003cOpenAiChatApiResponse\u003e\n```\n\nNot only do we need the messages, but we also need the API key, the preferred model, and more. The function is essentially a raw implementation of the corresponding `openai` endpoint, and an adapter must be used to map it to the `ChatIntegration` interface.\n\n### Peripherals\n\nPeripherals wrap environment-specific functionality that we use in our models, integrations, or even other peripherals. Some examples of this are:\n\n- Making HTTP requests\n- Getting input from or displaying output to a user\n- Storing data temporarily or permanently\n\n#### Example: Getting input from or displaying output to a user\n\nTo better understand this concept, take a look at [the `io` implementation under `./peripherals`](./peripherals/src/io/index.ts). The adapter interface is defined by `IoAdapter` as an object that has two async function properties: `read` and `write`. The `terminal` adapter conforms to that interface, and the `useIo` peripheral maps the `terminal` adapter to the `IoPeripheral` interface. This allows us to use the `IoPeripheral` interface throughout the codebase without knowledge about specific implementations that end-users might choose to use. Additionally, we can expose helper functions in the peripheral that utilize the underlying adapter interface without requiring adapters to implement the function directly. The `prompt` function is one example that uses the `write` function to output something to a user followed by the `read` function to receive user input.\n\n### Models\n\nThese are the various types of AI models that we can use in our agents. Models are responsible for taking input and producing output. They can be used in a variety of ways, but they are typically used as the higher-level building blocks of an agent. For example, a model might be used to generate a response to a user's input, or it might be used to generate a new piece of content based on a given prompt. Some examples of this are:\n\n- Chat-based LLMs\n- Completion-based LLMs\n- Text-to-embedding transformers\n\n#### Embedding models\n\nThe embedding model is a special type of model that is used to convert text into a vector representation. This is useful for a variety of tasks, including Q\u0026A on a specific dataset. For example, we can generate vector representations of text with the embedding model and then store those vectors in a database alongside the text they represent. Then, we can generate a vector representation of a given input, query the database for the most similar pieces of text, and include one or more of those results in the prompt for the model.\n\n### Integrations\n\nThese are the interfaces that allow us to communicate with third-party services. Integrations wrap the functionality of third-party services for use by **models** or **peripherals**. Integrations are organized by provider (e.g. `openai`) and may expose multiple models or peripherals. The interface for an integration is defined by the consumer of the specific implementation. For example, the `openai` integration exposes a `chat` function that conforms to the `ChatIntegration` interface defined by the chat model in [`./models`](./models/src/chat/index.ts).\n\nExample model integrations\n\n- OpenAI\n- PaLM 2\n\nIntegrations can also be used to wrap peripherals. An integration for `firebase`, for example, could be used by a custom adapter for the `storage` peripheral.\n\nExample storage integrations\n\n- AWS S3\n- Google Cloud Storage\n- Supabase\n\n## How to contribute to `vellma`\n\nThings are still changing, but I recommend you read through the \"Concepts\" section above before you get started.\n\n### Set up your development environment\n\nClone the repo to your machine.\n\n```bash\ngit clone git@github.com:davidmyersdev/vellma.git\n```\n\nInstall dependencies with `pnpm`.\n\n```bash\n# ~/path/to/vellma\npnpm i\n```\n\nCreate your `.env` file.\n\n```bash\n# ~/path/to/vellma\ncp .env.example .env\n```\n\nAdd your OpenAI API key and (optionally) add your organization and user keys if you have them.\n\n```bash\n# ~/path/to/vellma/.env\nVITE_OPENAI_API_KEY=your-api-key\n# The rest are optional.\nVITE_OPENAI_ORGANIZATION_ID=\nVITE_OPENAI_USER_ID=\n```\n\nRun a playground example `pnpm playground:\u003cexample\u003e`. To try out the basic chat implementation, run the following.\n\n```bash\n# ~/path/to/vellma\npnpm playground:simple-chat\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmyersdev%2Fvellma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidmyersdev%2Fvellma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmyersdev%2Fvellma/lists"}