{"id":23206653,"url":"https://github.com/juampignr/partner","last_synced_at":"2026-05-01T16:36:29.196Z","repository":{"id":268609905,"uuid":"904914019","full_name":"juampignr/partner","owner":"juampignr","description":"A human-friendly and digestible way to use OpenAI Assistants API (ugh finally...)","archived":false,"fork":false,"pushed_at":"2024-12-23T21:47:10.000Z","size":29,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T11:16:09.745Z","etag":null,"topics":["ai","chatbot","chatgpt","copilot","gpt4all","llama","mistral","openai","sdk"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/juampignr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-12-17T19:44:48.000Z","updated_at":"2024-12-23T21:47:13.000Z","dependencies_parsed_at":"2024-12-17T21:18:55.547Z","dependency_job_id":"22f3f20f-c4dc-4721-97b0-dbf2f980269d","html_url":"https://github.com/juampignr/partner","commit_stats":null,"previous_names":["juampignr/partner"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/juampignr/partner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juampignr%2Fpartner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juampignr%2Fpartner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juampignr%2Fpartner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juampignr%2Fpartner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/juampignr","download_url":"https://codeload.github.com/juampignr/partner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/juampignr%2Fpartner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32505110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","chatbot","chatgpt","copilot","gpt4all","llama","mistral","openai","sdk"],"created_at":"2024-12-18T17:15:14.423Z","updated_at":"2026-05-01T16:36:29.178Z","avatar_url":"https://github.com/juampignr.png","language":"JavaScript","funding_links":["https://buymeacoffee.com/jpbehler"],"categories":[],"sub_categories":[],"readme":"# Partner AI\n\n![Partner Logo](https://drive.usercontent.google.com/download?id=1RejZmfUlZBr1NmSxpfR90B1C0NNZNXhA\u0026export=view\u0026authuser=0)\n\u003e\n\u003e A human-friendly and digestible way to use OpenAI Assistants API (ugh finally...)\n\u003e\n![NPM Downloads](https://img.shields.io/npm/dm/%40jpbehler%2Fpartner) ![NPM Last Update](https://img.shields.io/npm/last-update/%40jpbehler%2Fpartner) ![GitHub Repo stars](https://img.shields.io/github/stars/juampignr/partner)\n\n\n\n---\n\n## 🚀 Features\n\n- Enables you to create a full-fledged OpenAI Assistant with similar syntax like the ChatCompletion API\n- Admits both Event handlers and await/Promise syntax\n- Intuitive API, just write partner.sendMessage() to send a message and partner.remember() to add a file context\n- Able to store both files and JSON AI Context persistently for later use with partner.remember()\n- Works with a single instruction or multiple instructions as steps for the AI to tackle\n\n---\n\n## 📦 Installation\n\nInstall the package via npm:\n\n```bash\nnpm install @jpbehler/partner\n```\n\n---\n\n## 🧑‍💻 CLI/Command\n\nJust execute this command to start using the interactive command:\n\n```bash\nnpx @jpbehler/partner\n```\n\n---\n\n## 🛠️ Usage\n\n### Quick Start\n\n```javascript\nimport partner from \"@jpbehler/partner\";\nimport { input } from \"@inquirer/prompts\";\n\nlet salesman = new partner({\n  apiKey:\n    \"sk-***\",\n  assistantParams: {\n    name: \"iPhone Salesman\",\n    instructions: \"You are an iPhone Salesman. Do not offer MacBooks.\",\n    model: \"gpt-4o\",\n  },\n});\n\nconst receiveMessage = async (message) =\u003e {\n  console.log(message);\n\n  const question = await input({\n    message: \"Question\u003e\",\n  });\n  await salesman.sendMessage(question);\n};\n\n//Handle incoming messages async using eventHandlers\nsalesman.on(\"message\", receiveMessage);\nawait salesman.start(\"Let's start!\");\n\n//Or just use async/await syntax\n//await salesman.start();\n//const response = await salesman.sendMessage(\"Let's start!\");\n```\n\n### Define functions/code for the Partner to use\n\n```javascript\nimport partner from \"@jpbehler/partner\";\nimport { input } from \"@inquirer/prompts\";\n\n//Define a function as a tool the Partner should call whenever asked for a product\nconst GET_FROM_DB = {\n  type: \"function\",\n  function: {\n    name: \"getProduct\",\n    description: \"Gets stored product information\",\n    parameters: {\n      type: \"object\",\n      properties: {\n        _id: {\n          type: \"string\",\n          description: \"Entry or document ID to be fetched\",\n        },\n        database: {\n          type: \"string\",\n          description: \"Database to query from\",\n        },\n      },\n      required: [\"_id\", \"database\"],\n    },\n  },\n};\n\n//Define a Partner that makes use of the above function\nlet salesman = new partner({\n  apiKey:\n    \"sk-***\",\n\n  assistantParams: {\n    name: \"iPhone Salesman\",\n    instructions:\n      \"You are an iPhone Salesman. Do not offer MacBooks. (Please use the provided functions and files to get and recommend products)\",\n    model: \"gpt-4o\",\n    tools: [GET_FROM_DB, { type: \"file_search\" }],\n  },\n});\n\nconst receiveMessage = async (message) =\u003e {\n  console.log(message);\n\n  const question = await input({\n    message: \"Question\u003e\",\n  });\n  await salesman.sendMessage(question);\n};\n\n//Handle GET_FROM_DB function calls\nconst receiveRequest = async (request) =\u003e {\n  /* 1. Iterate request.required_action.submit_tool_outputs.tool_calls\n     2. Get the function and parameters the AI needs to request\n     3. Execute the associated function (eg. getProduct(_id,database))\n     4. Respond to the AI request so it can use the information\n  */\n\n  await salesman.respondRequest({\n    request: request,\n    status: \"success\",\n    response: \"Ok stored\",\n  });\n};\n\nsalesman.on(\"message\", receiveMessage);\nsalesman.on(\"request\", receiveRequest);\n\nawait salesman.start(\"Let's start\");\n```\n\n### Define multiple instructions as steps the Partner must resolve\n\n```javascript\nimport partner from \"@jpbehler/partner\";\nimport { input } from \"@inquirer/prompts\";\n\nlet salesman = new partner([\n  {\n    apiKey:\n      \"sk-***\",\n    assistantParams: {\n      name: \"Salesman\",\n      instructions: \"You are an iPhone Salesman. Do not offer MacBooks.\",\n      model: \"gpt-4o\",\n    },\n  },\n  {\n    apiKey:\n      \"sk-***\",\n    assistantParams: {\n      name: \"Cashier\",\n      instructions:\n        \"You are a store Cashier, please help the customer with his/her payment.\",\n      model: \"gpt-4o\",\n    },\n  },\n]);\n\nconst receiveMessage = async (message) =\u003e {\n  //Check the AI response and go to the next step by sending the \"\u003cdone\u003e\" special code\n  if (message.includes(\"pay\")) await salesman.sendMessage(\"\u003cdone\u003e\");\n\n  console.log(message);\n\n  const question = await input({\n    message: \"Question\u003e\",\n  });\n  await salesman.sendMessage(question);\n};\n\n//Handle incoming messages async using eventHandlers\nsalesman.on(\"message\", receiveMessage);\nawait salesman.start(\"Let's start!\");\n```\n---\n\n## 🌟 GitHub\n\nIf you notice a bug, be welcomed to open an [Issue](https://github.com/juampignr/partner)\nIf you just love it, please consider giving it a ⭐ on [GitHub](https://github.com/juampignr/partner)!\n\n---\n\n## 🧑‍💻 Author\n\nCreated with ❤️ \u0026 ☕ by [J.P. Behler](https://www.linkedin.com/in/juanpablobehler/).\n\n---\n\n## 🫀 Donate\n\nIf you really appreciate it, consider buying me a [Coffee](https://buymeacoffee.com/jpbehler). Remember we developers turn coffee into apps 😆\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuampignr%2Fpartner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuampignr%2Fpartner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuampignr%2Fpartner/lists"}