{"id":15165974,"url":"https://github.com/pikocloud/pikobrain","last_synced_at":"2025-10-25T10:30:46.345Z","repository":{"id":251639673,"uuid":"837999515","full_name":"pikocloud/pikobrain","owner":"pikocloud","description":"Function-calling API for LLM from multiple providers","archived":false,"fork":false,"pushed_at":"2024-08-10T14:08:54.000Z","size":418,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-31T06:51:18.307Z","etag":null,"topics":["api","aws-bedrock","function-calling","gemini","llm-server","ollama","openai","rag"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pikocloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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}},"created_at":"2024-08-04T16:49:00.000Z","updated_at":"2025-01-29T20:58:02.000Z","dependencies_parsed_at":"2024-09-13T22:42:47.812Z","dependency_job_id":"6e187f2b-e071-40c6-8a4d-7d8677de1580","html_url":"https://github.com/pikocloud/pikobrain","commit_stats":{"total_commits":12,"total_committers":1,"mean_commits":12.0,"dds":0.0,"last_synced_commit":"6587ae5a5416fe4da6813fe13c60d939e999bccd"},"previous_names":["pikocloud/pikobrain"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikocloud%2Fpikobrain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikocloud%2Fpikobrain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikocloud%2Fpikobrain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikocloud%2Fpikobrain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pikocloud","download_url":"https://codeload.github.com/pikocloud/pikobrain/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238120382,"owners_count":19419763,"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":["api","aws-bedrock","function-calling","gemini","llm-server","ollama","openai","rag"],"created_at":"2024-09-27T04:21:28.960Z","updated_at":"2025-10-25T10:30:45.966Z","avatar_url":"https://github.com/pikocloud.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PikoBrain\n\nPikoBrain is function-calling API for LLM from multiple providers.\n\nThe key project features:\n\n- allows you to define model configuration\n- provides universal API regardless of LLM\n- provides actual function calling (currently OpenAPI)\n- (optionally) supports different models for Vision and text\n- Basic UI\n\nIt allows set functions (RAG) without vendor lock-in.\n\nThe project LICENSED under MPL-2.0 Exhibit A which promotes collaboration (requires sharing changes) but does not\nrestrict for commercial or any other usage.\n\n## Roadmap\n\nProviders\n\n- [x] [OpenAI](#openai)\n- [x] [AWS Bedrock](#aws-bedrock)\n- [x] [Ollama](#ollama)\n- [x] [Google](#google)\n\nState\n\n- [x] [Threads](#threads)\n\nIntegration\n\n- [ ] Webhooks\n- [ ] NATS Notifications\n\nFunctions\n\n- [x] OpenAPI (including automatic reload)\n- [ ] Internal functions (threads)\n- [ ] Scripting functions\n\nLibraries\n\n- [ ] Python\n- [ ] Golang\n- [ ] Typescript\n\n## Installation\n\n- Source (requires go 1.22.5+) `go run github.com/pikocloud/pikobrain@latest \u003cargs\u003e`\n- Binary in [releases](https://github.com/pikocloud/pikobrain/releases/latest)\n- Docker `ghcr.io/pikocloud/pikobrain`\n\n## Usage\n\nBinary\n\n    pikobrain --config examples/brain.yaml --tools examples/tools.yaml\n\nDocker\n\n    docker run --rm -v $(pwd):/data -v $(pwd)/examples:/config:ro -p 8080:8080 ghcr.io/pikocloud/pikobrain\n\n- Define model and tools like in [examples/](examples/)\n- Run service\n- Call service\n\n**Basic UI**\n\n    http://127.0.0.1:8080\n\n![Screenshot from 2024-08-10 20-13-32](https://github.com/user-attachments/assets/9d5b8ab6-0c14-45d0-ae69-face46517a56)\n\n\u003e [!NOTE]  \n\u003e UI designed primarily for admin tasks. For user-friendly chat experience use something\n\u003e like [LibreChat](https://github.com/danny-avila/LibreChat)\n\n\n**Request**\n\n    POST http://127.0.0.1:8080\n\nInput can be:\n\n- `multipart/form-data payload` (preferred), where:\n    - each part can be text/plain (default if not set), application/x-www-form-urlencoded, application/json, image/png,\n      image/jpeg, image/webp, image/gif\n    - may contain header `X-User` in each part which maps to user field in providers\n    - may contain header `X-Role` where values could be `user` (default) or `assistant`\n    - multipart name doesn't matter\n- `application/x-www-form-urlencoded`; content will be decoded\n- `text/plain`, `application/json`\n- `image/png`, `image/jpeg`, `image/webp`, `image/gif`\n- without content type, then payload should be valid UTF-8 string and will be used as single payload\n\n\u003e Request may contain query parameter `user` which maps to user field and/or query `role` (user or assistant)\n\nMultipart payload allows caller provide full history context messages. For multipart, header `X-User` and `X-Role` may\noverride query parameters.\n\nOutput is the response from LLM.\n\n\n\u003e [!INFO]  \n\u003e User field is not used for inference. Only for audit.\n\n## Threads\n\nIn addition to normal [usage](#usage), it's possible to use stateful chat context within \"thread\".\n\nFor every request historical questions will be fetched (up to `depth`).\n\n**Add and run**\n\n    POST http://127.0.0.1:8080/\u003cthread name\u003e\n\nContent can be empty (just run)\n\n**Just add**\n\n    PUT http://127.0.0.1:8080/\u003cthread name\u003e\n\n### Clients\n\n\u003cdetails\u003e\n\u003csummary\u003ePython with aiohttp\u003c/summary\u003e\n\n```python3\nimport asyncio\nimport io\nfrom dataclasses import dataclass\nfrom datetime import timedelta\nfrom typing import Literal, Iterable\n\nimport aiohttp\n\n\n@dataclass(frozen=True, slots=True)\nclass Message:\n    content: str | bytes | io.BytesIO\n    mime: str | None = None\n    role: Literal['assistant', \"user\"] | None = None\n    user: str | None = None\n\n\n@dataclass(frozen=True, slots=True)\nclass Response:\n    content: bytes\n    mime: str\n    duration: timedelta\n    input_messages: int\n    input_tokens: int\n    output_tokens: int\n    total_tokens: int\n\n\nasync def request(url: str, messages: Iterable[Message]) -\u003e Response:\n    with aiohttp.MultipartWriter('form-data') as mpwriter:\n        for message in messages:\n            headers = {}\n            if message.mime:\n                headers[aiohttp.hdrs.CONTENT_TYPE] = message.mime\n            if message.role:\n                headers['X-Role'] = message.role\n            if message.user:\n                headers['X-User'] = message.user\n\n            mpwriter.append(message.content, headers)\n\n        async with aiohttp.ClientSession() as session, session.post(url, data=mpwriter) as res:\n            assert res.ok, await res.text()\n            return Response(\n                content=await res.read(),\n                mime=res.headers.get(aiohttp.hdrs.CONTENT_TYPE),\n                duration=timedelta(seconds=float(res.headers.get('X-Run-Duration'))),\n                input_messages=int(res.headers.get('X-Run-Context')),\n                input_tokens=int(res.headers.get('X-Run-Input-Tokens')),\n                output_tokens=int(res.headers.get('X-Run-Output-Tokens')),\n                total_tokens=int(res.headers.get('X-Run-Total-Tokens')),\n            )\n\n\nasync def example():\n    res = await request('http://127.0.0.1:8080', messages=[\n        Message(\"My name is RedDec. You name is Bot.\"),\n        Message(\"What is your and my name?\"),\n    ])\n    print(res)\n```\n\n\u003c/details\u003e\n\n#### cURL\n\nSimple\n\n    curl --data 'Why sky is blue?' http://127.0.0.1:8080\n\nText multipart\n\n    curl -F '_=my name is RedDec' -F '_=What is my name?' -v http://127.0.0.1:8080\n\nImage and text\n\n    curl -F '_=@eifeltower.jpeg' -F '_=Describe the picture' -v http://127.0.0.1:8080\n\n## CLI\n\n```\nApplication Options:\n      --timeout=                  LLM timeout (default: 30s) [$TIMEOUT]\n      --refresh=                  Refresh interval for tools (default: 30s) [$REFRESH]\n      --config=                   Config file (default: brain.yaml) [$CONFIG]\n      --tools=                    Tool file [$TOOLS]\n\nDebug:\n      --debug.enable              Enable debug mode [$DEBUG_ENABLE]\n\nDatabase configuration:\n      --db.url=                   Database URL (default: sqlite://data.sqlite?cache=shared\u0026_fk=1\u0026_pragma=foreign_keys(1)) [$DB_URL]\n      --db.max-conn=              Maximum number of opened connections to database (default: 10) [$DB_MAX_CONN]\n      --db.idle-conn=             Maximum number of idle connections to database (default: 1) [$DB_IDLE_CONN]\n      --db.idle-timeout=          Maximum amount of time a connection may be idle (default: 0) [$DB_IDLE_TIMEOUT]\n      --db.conn-life-time=        Maximum amount of time a connection may be reused (default: 0) [$DB_CONN_LIFE_TIME]\n\nHTTP server configuration:\n      --http.bind=                Bind address (default: :8080) [$HTTP_BIND]\n      --http.tls                  Enable TLS [$HTTP_TLS]\n      --http.ca=                  Path to CA files. Optional unless IGNORE_SYSTEM_CA set (default: ca.pem) [$HTTP_CA]\n      --http.cert=                Server certificate (default: cert.pem) [$HTTP_CERT]\n      --http.key=                 Server private key (default: key.pem) [$HTTP_KEY]\n      --http.mutual               Enable mutual TLS [$HTTP_MUTUAL]\n      --http.ignore-system-ca     Do not load system-wide CA [$HTTP_IGNORE_SYSTEM_CA]\n      --http.read-header-timeout= How long to read header from the request (default: 3s) [$HTTP_READ_HEADER_TIMEOUT]\n      --http.graceful=            Graceful shutdown timeout (default: 5s) [$HTTP_GRACEFUL]\n      --http.timeout=             Any request timeout (default: 30s) [$HTTP_TIMEOUT]\n      --http.max-body-size=       Maximum payload size in bytes (default: 1048576) [$HTTP_MAX_BODY_SIZE]\n```\n\n## Providers\n\n### OpenAI\n\nFirst-class support, everything works just fine.\n\n### Google\n\nGood support. Known limitations:\n\n- date-time not supported in tools\n- empty object (aka any JSON) is not supported\n- for complex schemas, `gemini-1.5-flash` may hallucinate and call with incorrect arguments. Use `gemini-1.5-pro`\n\n### Ollama\n\nRequires Ollama 0.3.3+\n\nRecommended model: `llava` for vision and `mistral:instruct` for general messages (including function calling).\n\n```yaml\nmodel: 'mistral:instruct'\nvision:\n  model: 'llava'\n```\n\n\u003e [!TIP]  \n\u003e Check https://ollama.com/library for models with 'tools' and 'vision' features. The bigger model then generally\n\u003e better.\n\u003e For non-vision models, `instruct` kind usually better.\n\n### AWS Bedrock\n\n\u003e [!WARNING]  \n\u003e Due to multiple limitations, only Claude 3+ models are working properly. Recommended multi-modal model for AWS\n\u003e Bedrock is Anthropic Claude-3-5.\n\nInitial support.\n\n- Some models may not support system prompt.\n- Some models may not support tools.\n- Authorization is ignored (use AWS environment variables)\n- `forceJSON` is not supported (workaround: use tools)\n\nRequired minimal set of environment variables\n\n    AWS_ACCESS_KEY_ID=\n    AWS_SECRET_ACCESS_KEY=\n    AWS_REGION=\n\nPlease refer\nto [AWS Environment variable cheatsheet](https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html#EVarSettings)\nfor configuration.\n\nBased on [function calling feature](https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html) the recommended\nmodels are:\n\n- Anthropic Claude 3 models\n- Mistral AI Mistral Large and Mistral Small\n- Cohere Command R and Command R+\n\nSee list of [compatibilities](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikocloud%2Fpikobrain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpikocloud%2Fpikobrain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikocloud%2Fpikobrain/lists"}